blob: aab7ac54bc7ca1628b51b6bbccc3dc64846afb29 [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
70#define IF_NAME_SIZE 16
71#define CONFIG_PREFIX "/nvram/hostapd"
72#define ACL_PREFIX "/nvram/hostapd-acl"
73#define DENY_PREFIX "/nvram/hostapd-deny"
74//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
75#define SOCK_PREFIX "/var/run/hostapd/wifi"
76#define VAP_STATUS_FILE "/nvram/vap-status"
77#define ESSID_FILE "/tmp/essid"
78#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
79#define CHANNEL_STATS_FILE "/tmp/channel_stats"
80#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
81#define VLAN_FILE "/nvram/hostapd.vlan"
82#define PSK_FILE "/nvram/hostapd"
83#define MCS_FILE "/tmp/MCS"
developera1255e42023-05-13 17:45:02 +080084#define POWER_PERCENTAGE "/tmp/POWER"
85#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
86/*LOGAN_DAT_FILE: may be different on customer's platform.*/
87#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
developerb2977562023-05-24 17:54:12 +080088#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
developera1255e42023-05-13 17:45:02 +080089
developer72fb0bb2023-01-11 09:46:29 +080090#define NOACK_MAP_FILE "/tmp/NoAckMap"
developerfead3972023-05-25 20:15:02 +080091#define RADIO_RESET_FILE "/nvram/radio_reset"
developerf6a87542023-05-16 15:47:28 +080092
developer72fb0bb2023-01-11 09:46:29 +080093#define BRIDGE_NAME "brlan0"
developerd1824452023-05-18 12:30:04 +080094#define BASE_PHY_INDEX 1
95#define BASE_RADIO_INDEX 0
developer72fb0bb2023-01-11 09:46:29 +080096
97/*
98 MAX_APS - Number of all AP available in system
99 2x Home AP
100 2x Backhaul AP
101 2x Guest AP
102 2x Secure Onboard AP
103 2x Service AP
104
105*/
106
107
108#define MAX_APS MAX_NUM_RADIOS*5
developer7e4a2a62023-04-06 19:56:03 +0800109
110#define PREFIX_WIFI2G "ra"
111#define PREFIX_WIFI5G "rai"
112#define PREFIX_WIFI6G "rax"
developer72fb0bb2023-01-11 09:46:29 +0800113
developer47cc27a2023-05-17 23:09:58 +0800114#define PREFIX_SSID_2G "RDKB_2G"
115#define PREFIX_SSID_5G "RDKB_5G"
116#define PREFIX_SSID_6G "RDKB_6G"
117
developer72fb0bb2023-01-11 09:46:29 +0800118#ifndef RADIO_PREFIX
119#define RADIO_PREFIX "wlan"
120#endif
121
122#define MAX_ASSOCIATED_STA_NUM 2007
123
124//Uncomment to enable debug logs
125//#define WIFI_DEBUG
developer49b17232023-05-19 16:35:19 +0800126enum {
127 DEBUG_OFF = 0,
128 DEBUG_ERROR = 1,
129 DEBUG_WARN = 2,
130 DEBUG_NOTICE = 3,
131 DEBUG_INFO = 4
132};
133int wifi_debug_level = DEBUG_NOTICE;
134#define wifi_debug(level, fmt, args...) \
135{ \
136 if (level <= wifi_debug_level) \
137 { \
developer2edaf012023-05-24 14:24:53 +0800138 printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \
developer49b17232023-05-19 16:35:19 +0800139 } \
140}
developer72fb0bb2023-01-11 09:46:29 +0800141
142#ifdef WIFI_DEBUG
143#define wifi_dbg_printf printf
144#define WIFI_ENTRY_EXIT_DEBUG printf
145#else
146#define wifi_dbg_printf(format, args...) printf("")
147#define WIFI_ENTRY_EXIT_DEBUG(format, args...) printf("")
148#endif
149
150#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
151#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
152#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
153#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
154#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
155#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
156#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
157#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
158#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
159#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
160
161#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
162
163#define BW_FNAME "/nvram/bw_file.txt"
164
165#define PS_MAX_TID 16
166
developer96b38512023-02-22 11:17:45 +0800167#define MAX_CARD_INDEX 3
168
developer72fb0bb2023-01-11 09:46:29 +0800169static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
170 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
171 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
172 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
173 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
174 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
175 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
176 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
177 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
178 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
179 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
180 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
181 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
182 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
183 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
184 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
185 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
186};
187
188typedef unsigned long long u64;
189
190/* Enum to define WiFi Bands */
191typedef enum
192{
193 band_invalid = -1,
194 band_2_4 = 0,
195 band_5 = 1,
196 band_6 = 2,
197} wifi_band;
198
developer17038e62023-03-02 14:43:43 +0800199char* wifi_band_str[] = {
200 "2G",
201 "5G",
202 "6G",
203};
204
developer72fb0bb2023-01-11 09:46:29 +0800205typedef enum {
206 WIFI_MODE_A = 0x01,
207 WIFI_MODE_B = 0x02,
208 WIFI_MODE_G = 0x04,
209 WIFI_MODE_N = 0x08,
210 WIFI_MODE_AC = 0x10,
211 WIFI_MODE_AX = 0x20,
developera1255e42023-05-13 17:45:02 +0800212 WIFI_MODE_BE = 0x40,
developer72fb0bb2023-01-11 09:46:29 +0800213} wifi_ieee80211_Mode;
214
developerd1824452023-05-18 12:30:04 +0800215typedef enum ht_config_bw{
216 HT_BW_20,
217 HT_BW_40,
218};
219
220typedef enum vht_config_bw{
221 VHT_BW_2040,
222 VHT_BW_80,
223 VHT_BW_160,
224 VHT_BW_8080,
225};
226
227typedef enum eht_config_bw{
228 EHT_BW_20,
229 EHT_BW_40,
230 EHT_BW_80,
231 EHT_BW_160,
232 EHT_BW_320,
233};
234
developer72fb0bb2023-01-11 09:46:29 +0800235#ifdef WIFI_HAL_VERSION_3
236
237// Return number of elements in array
238#ifndef ARRAY_SIZE
239#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
240#endif /* ARRAY_SIZE */
241
242#ifndef ARRAY_AND_SIZE
243#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
244#endif /* ARRAY_AND_SIZE */
245
246#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
247
248typedef struct {
249 int32_t value;
250 int32_t param;
251 intptr_t key;
252 intptr_t data;
253} wifi_secur_list;
254
255static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
256static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
257wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
258wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
259char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
260static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
developer47cc27a2023-05-17 23:09:58 +0800261static void wifi_PrepareDefaultHostapdConfigs(void);
262static void wifi_psk_file_reset();
developerb2977562023-05-24 17:54:12 +0800263static void wifi_psk_file_reset_by_radio(char radio_idx);
264static void wifi_dat_file_reset();
265static 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);
developer47cc27a2023-05-17 23:09:58 +0800267
developer49b17232023-05-19 16:35:19 +0800268/*type define the nl80211 call back func*/
269typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
270
271/**
272*struct mtk_nl80211_param
273* init mtk nl80211 using parameters
274* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
275* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
276* @if_idx: the index should match the interface or wiphy.
277* Note: NA
278**/
279struct mtk_nl80211_param {
280 unsigned int sub_cmd;
281 int if_type;
282 int if_idx;
283};
284
285/**
developer121a8e72023-05-22 09:19:39 +0800286*struct mtk_nl80211_cb_data
287* init mtk nl80211 call back parameters
288* @out_buf: store the mtk vendor output msg for wifi hal buffer.
289* @out_len: the output buffer length.
290* Note: NA
291**/
292struct mtk_nl80211_cb_data {
293 char * out_buf;
294 unsigned int out_len;
295};
296
297/**
developer49b17232023-05-19 16:35:19 +0800298*mtk_nl80211_init
299* init mtk nl80211 netlink and init the vendor msg common part.
300* @nl: netlink, just init it.
301* @msg: netlink message will alloc it.
302* the msg send success/fails is not free by app
303* only the nla_put etc api fails should use nlmsg_free.
304* @msg_data: vendor data msg attr pointer.
305* @param: init using interface and sub_cmd parameter.
306*
307*init the netlink context and mtk netlink vendor msg.
308*
309*return:
310* 0: success
311* other: fail
312**/
313
314int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
315 struct nlattr **msg_data, struct mtk_nl80211_param *param) {
316 /*sanity check here*/
317 if (!nl || !param) {
318 (void)fprintf(stderr,
319 "[%s][%d]:nl(0x%lx) or param(0x%lx) is null, error!\n",
320 __func__, __LINE__, nl, param);
321 return -1;
322 }
323 /*if_type check*/
324 if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
325 (void)fprintf(stderr,
326 "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
327 __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
328 return -1;
329 }
330 /*init the nl*/
331 if (unl_genl_init(nl, "nl80211") < 0) {
332 (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n",
333 __func__, __LINE__);
334 return -1;
335 }
336 /*init the msg*/
337 *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
338
339 if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
340 nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
341 nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
342 (void)fprintf(stderr,
343 "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
344 __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
345 goto err;
346 }
347
348 *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
349 if (!*msg_data) {
350 (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
351 __func__, __LINE__);
352 goto err;
353 }
354
355 return 0;
356err:
developer49b17232023-05-19 16:35:19 +0800357 nlmsg_free(*msg);
358 unl_free(nl);
359 return -1;
360}
361
362/**
363*mtk_nl80211_send
364* set the vendor cmd call back and sent the vendor msg.
365* @nl: netlink.
366* @msg: netlink message.
367* @msg_data: vendor data msg attr pointer.
368* @handler: if the msg have call back shoud add the call back func
369* the event msg will handle by the call back func(exp:get cmd)
370* other set it as NULL(exp:set cmd).
371* @arg:call back func arg parameter.
372*add end of the netlink msg, set the call back and send msg
373*
374*return:
375* 0: success
376* other: fail
377**/
378int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
379 struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
380 int ret = 0;
381 /*sanity check*/
382 if (!nl || !msg || !msg_data) {
383 (void)fprintf(stderr,
384 "[%s][%d]:nl(0x%lx),msg(0x%lx) or msg_data(0x%lx) is null, error!\n",
385 __func__, __LINE__, nl, msg, msg_data);
386 return -1;
387 }
388 /*end the msg attr of vendor data*/
389 nla_nest_end(msg, msg_data);
390 /*send the msg and set call back */
391 ret = unl_genl_request(nl, msg, handler, arg);
392 if (ret)
393 (void)fprintf(stderr, "send nl80211 cmd fails\n");
394 return ret;
395}
396
397/**
398*mtk_nl80211_deint
developer2edaf012023-05-24 14:24:53 +0800399* deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800400* @nl: netlink.
401*
developer2edaf012023-05-24 14:24:53 +0800402*free deinit the netlink.
developer49b17232023-05-19 16:35:19 +0800403*
404*return:
405* 0: success
406**/
407
408int mtk_nl80211_deint(struct unl *nl) {
409 unl_free(nl);
410 return 0;
411}
412
developer72fb0bb2023-01-11 09:46:29 +0800413
414static wifi_secur_list map_security[] =
415{
416 WIFI_ITEM_STR(wifi_security_mode_none, "None"),
417 WIFI_ITEM_STR(wifi_security_mode_wep_64, "WEP-64"),
418 WIFI_ITEM_STR(wifi_security_mode_wep_128, "WEP-128"),
419 WIFI_ITEM_STR(wifi_security_mode_wpa_personal, "WPA-Personal"),
420 WIFI_ITEM_STR(wifi_security_mode_wpa_enterprise, "WPA-Enterprise"),
421 WIFI_ITEM_STR(wifi_security_mode_wpa2_personal, "WPA2-Personal"),
422 WIFI_ITEM_STR(wifi_security_mode_wpa2_enterprise, "WPA2-Enterprise"),
423 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_personal, "WPA-WPA2-Personal"),
424 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_enterprise, "WPA-WPA2-Enterprise"),
425 WIFI_ITEM_STR(wifi_security_mode_wpa3_personal, "WPA3-Personal"),
426 WIFI_ITEM_STR(wifi_security_mode_wpa3_transition, "WPA3-Personal-Transition"),
427 WIFI_ITEM_STR(wifi_security_mode_wpa3_enterprise, "WPA3-Enterprise")
428};
429
430wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
431{
432 wifi_secur_list *item;
433 int i;
434
435 for (item = list,i = 0;i < list_sz; item++, i++) {
436 if ((int)(item->key) == key) {
437 return item;
438 }
439 }
440
441 return NULL;
442}
443
444char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
445{
446 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
447
448 if (!item) {
449 return "";
450 }
451
452 return (char *)(item->data);
453}
454
455wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
456{
457 wifi_secur_list *item;
458 int i;
459
460 for (item = list,i = 0;i < list_sz; item++, i++) {
461 if (strcmp((char *)(item->data), str) == 0) {
462 return item;
463 }
464 }
465
466 return NULL;
467}
468#endif /* WIFI_HAL_VERSION_3 */
469
developer96b38512023-02-22 11:17:45 +0800470
471static char l1profile[32] = "/etc/wireless/l1profile.dat";
developer17038e62023-03-02 14:43:43 +0800472char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
473char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
474#define MAX_SSID_LEN 64
475char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
developer745f0bd2023-03-06 14:32:53 +0800476int radio_band[MAX_NUM_RADIOS];
developer17038e62023-03-02 14:43:43 +0800477
478static int array_index_to_vap_index(UINT radioIndex, int arrayIndex);
479static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
480
developer96b38512023-02-22 11:17:45 +0800481
482static int
483get_value(const char *conf_file, const char *param, char *value, int len)
484{
485 FILE *fp;
486 int ret = -1;
487 int param_len = strlen(param);
488 int buf_len;
489 char buf[256];
490
491 fp = fopen(conf_file, "r");
492 if (!fp) {
493 return -1;
494 }
495
496 while (fgets(buf, sizeof(buf), fp)) {
497 buf_len = strlen(buf);
498 if (buf[buf_len - 1] == '\n') {
499 buf_len--;
500 buf[buf_len] = '\0';
501 }
502 if ((buf_len > param_len) &&
503 (strncmp(buf, param, param_len) == 0) &&
504 (buf[param_len] == '=')) {
505
506 if (buf_len == (param_len + 1)) {
507 value[0] = '\0';
508 ret = 0;
509 } else {
510 ret = snprintf(value, len, "%s", buf + (param_len + 1));
511 }
512 fclose(fp);
513 return ret;
514 }
515 }
516 fclose(fp);
517 return -1;
518}
519
520static int
521get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
522{
523 char buf[256];
524 int ret;
525 char *save_ptr = NULL;
526 char *tok = NULL;
527
528 ret = get_value(conf_file, param, buf, sizeof(buf));
529 if (ret < 0)
530 return ret;
531
532 tok = strtok_r(buf, ";", &save_ptr);
533 do {
534 if (idx == 0 || tok == NULL)
535 break;
536 else
537 idx--;
538
539 tok = strtok_r(NULL, ";", &save_ptr);
540 } while (tok != NULL);
541
542 if (tok) {
543 ret = snprintf(value, len, "%s", tok);
544 } else {
545 ret = 0;
546 value[0] = '\0';
547 }
548
549 return ret;
550}
551
552
developer72fb0bb2023-01-11 09:46:29 +0800553#ifdef HAL_NETLINK_IMPL
554typedef struct {
555 int id;
556 struct nl_sock* socket;
557 struct nl_cb* cb;
558} Netlink;
559
560static int mac_addr_aton(unsigned char *mac_addr, char *arg)
561{
562 unsigned int mac_addr_int[6]={};
563 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);
564 mac_addr[0] = mac_addr_int[0];
565 mac_addr[1] = mac_addr_int[1];
566 mac_addr[2] = mac_addr_int[2];
567 mac_addr[3] = mac_addr_int[3];
568 mac_addr[4] = mac_addr_int[4];
569 mac_addr[5] = mac_addr_int[5];
570 return 0;
571}
572
573static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
574{
575 unsigned int mac_addr_int[6]={};
576 mac_addr_int[0] = arg[0];
577 mac_addr_int[1] = arg[1];
578 mac_addr_int[2] = arg[2];
579 mac_addr_int[3] = arg[3];
580 mac_addr_int[4] = arg[4];
581 mac_addr_int[5] = arg[5];
582 snprintf(mac_addr, 20, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int[0], mac_addr_int[1],mac_addr_int[2],mac_addr_int[3],mac_addr_int[4],mac_addr_int[5]);
583 return;
584}
585
586static int ieee80211_frequency_to_channel(int freq)
587{
588 /* see 802.11-2007 17.3.8.3.2 and Annex J */
589 if (freq == 2484)
590 return 14;
591 /* see 802.11ax D6.1 27.3.23.2 and Annex E */
592 else if (freq == 5935)
593 return 2;
594 else if (freq < 2484)
595 return (freq - 2407) / 5;
596 else if (freq >= 4910 && freq <= 4980)
597 return (freq - 4000) / 5;
598 else if (freq < 5950)
599 return (freq - 5000) / 5;
600 else if (freq <= 45000) /* DMG band lower limit */
601 /* see 802.11ax D6.1 27.3.23.2 */
602 return (freq - 5950) / 5;
603 else if (freq >= 58320 && freq <= 70200)
604 return (freq - 56160) / 2160;
605 else
606 return 0;
607}
608
609static int initSock80211(Netlink* nl) {
610 nl->socket = nl_socket_alloc();
611 if (!nl->socket) {
612 fprintf(stderr, "Failing to allocate the sock\n");
613 return -ENOMEM;
614 }
615
616 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
617
618 if (genl_connect(nl->socket)) {
619 fprintf(stderr, "Failed to connect\n");
620 nl_close(nl->socket);
621 nl_socket_free(nl->socket);
622 return -ENOLINK;
623 }
624
625 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
626 if (nl->id< 0) {
627 fprintf(stderr, "interface not found.\n");
628 nl_close(nl->socket);
629 nl_socket_free(nl->socket);
630 return -ENOENT;
631 }
632
633 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
634 if ((!nl->cb)) {
635 fprintf(stderr, "Failed to allocate netlink callback.\n");
636 nl_close(nl->socket);
637 nl_socket_free(nl->socket);
638 return ENOMEM;
639 }
640
641 return nl->id;
642}
643
644static int nlfree(Netlink *nl)
645{
646 nl_cb_put(nl->cb);
647 nl_close(nl->socket);
648 nl_socket_free(nl->socket);
649 return 0;
650}
651
652static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
653 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
654 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
655 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
656};
657
658static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
659};
660
661static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
662};
663
664typedef struct _wifi_channelStats_loc {
665 INT array_size;
666 INT ch_number;
667 BOOL ch_in_pool;
668 INT ch_noise;
669 BOOL ch_radar_noise;
670 INT ch_max_80211_rssi;
671 INT ch_non_80211_noise;
672 INT ch_utilization;
673 ULLONG ch_utilization_total;
674 ULLONG ch_utilization_busy;
675 ULLONG ch_utilization_busy_tx;
676 ULLONG ch_utilization_busy_rx;
677 ULLONG ch_utilization_busy_self;
678 ULLONG ch_utilization_busy_ext;
679} wifi_channelStats_t_loc;
680
681typedef struct wifi_device_info {
682 INT wifi_devIndex;
683 UCHAR wifi_devMacAddress[6];
684 CHAR wifi_devIPAddress[64];
685 BOOL wifi_devAssociatedDeviceAuthentiationState;
686 INT wifi_devSignalStrength;
687 INT wifi_devTxRate;
688 INT wifi_devRxRate;
689} wifi_device_info_t;
690
691#endif
692
693//For 5g Alias Interfaces
694static BOOL priv_flag = TRUE;
695static BOOL pub_flag = TRUE;
696static BOOL Radio_flag = TRUE;
697//wifi_setApBeaconRate(1, beaconRate);
698
699BOOL multiple_set = FALSE;
700
701struct params
702{
703 char * name;
704 char * value;
705};
706
707static int _syscmd(char *cmd, char *retBuf, int retBufSize)
708{
709 FILE *f;
710 char *ptr = retBuf;
711 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
712
713 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
714 if((f = popen(cmd, "r")) == NULL) {
715 fprintf(stderr,"\npopen %s error\n", cmd);
716 return RETURN_ERR;
717 }
718
719 while(!feof(f))
720 {
721 *ptr = 0;
722 if(bufSize>=128) {
723 bufbytes=128;
724 } else {
725 bufbytes=bufSize-1;
726 }
727
728 fgets(ptr,bufbytes,f);
729 readbytes=strlen(ptr);
730
731 if(!readbytes)
732 break;
733
734 bufSize-=readbytes;
735 ptr += readbytes;
736 }
737 cmd_ret = pclose(f);
738 retBuf[retBufSize-1]=0;
739 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
740
741 return cmd_ret >> 8;
742}
743
744INT radio_index_to_phy(int radioIndex)
745{
developer17038e62023-03-02 14:43:43 +0800746 /* TODO */
747 return radioIndex;
developer72fb0bb2023-01-11 09:46:29 +0800748}
749
750INT wifi_getMaxRadioNumber(INT *max_radio_num)
751{
752 char cmd[64] = {0};
753 char buf[4] = {0};
754
755 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
756
757 snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l");
758 _syscmd(cmd, buf, sizeof(buf));
759 *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10);
760
761 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
762
763 return RETURN_OK;
764}
765
developer17038e62023-03-02 14:43:43 +0800766wifi_band radio_index_to_band(int radioIndex)
767{
developer745f0bd2023-03-06 14:32:53 +0800768 return radio_band[radioIndex];
developer17038e62023-03-02 14:43:43 +0800769}
770
developer72fb0bb2023-01-11 09:46:29 +0800771wifi_band wifi_index_to_band(int apIndex)
772{
773 char cmd[128] = {0};
774 char buf[64] = {0};
775 int nl80211_band = 0;
776 int i = 0;
777 int phyIndex = 0;
778 int radioIndex = 0;
779 int max_radio_num = 0;
780 wifi_band band = band_invalid;
781
782 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
783
784 wifi_getMaxRadioNumber(&max_radio_num);
785 radioIndex = apIndex % max_radio_num;
786 phyIndex = radio_index_to_phy(radioIndex);
787 while(i < 10){
788 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
789 _syscmd(cmd, buf, sizeof(buf));
790 nl80211_band = strtol(buf, NULL, 10);
791 if (nl80211_band == 1)
792 band = band_2_4;
793 else if (nl80211_band == 2)
794 band = band_5;
795 else if (nl80211_band == 4) // band == 3 is 60GHz
796 band = band_6;
797
798 if(band != band_invalid)
799 break;
developer69b61b02023-03-07 17:17:44 +0800800
developer72fb0bb2023-01-11 09:46:29 +0800801 i++;
802 sleep(1);
803 }
804
805 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
806 return band;
807}
808
809static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
810{
developer7e4a2a62023-04-06 19:56:03 +0800811 char cmd[MAX_CMD_SIZE] = {0};
812 char buf[MAX_BUF_SIZE] = {0};
813 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +0800814
developer7e4a2a62023-04-06 19:56:03 +0800815 ret = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
816 conf_file, param);
developer72fb0bb2023-01-11 09:46:29 +0800817
developer7e4a2a62023-04-06 19:56:03 +0800818 if (ret < 0) {
819 printf("%s: snprintf error!", __func__);
820 return -1;
821 }
822
823 ret = _syscmd(cmd, buf, sizeof(buf));
824 if ((ret != 0) && (strlen(buf) == 0)) {
825 printf("%s: _syscmd error!", __func__);
826 return -1;
827 }
828
829 snprintf(output, output_size, "%s", buf);
830
831 return 0;
developer72fb0bb2023-01-11 09:46:29 +0800832}
833
834static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
835{
developer7e4a2a62023-04-06 19:56:03 +0800836 char cmd[MAX_CMD_SIZE] = {0};
837 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +0800838
developer7e4a2a62023-04-06 19:56:03 +0800839 for (int i = 0; i < item_count; i++) {
developer72fb0bb2023-01-11 09:46:29 +0800840 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +0800841 if (strlen(buf) == 0) /*no such item, insert it*/
developera1255e42023-05-13 17:45:02 +0800842 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 +0800843 else /*find the item, update it*/
developer72fb0bb2023-01-11 09:46:29 +0800844 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 +0800845
developer72fb0bb2023-01-11 09:46:29 +0800846 if(_syscmd(cmd, buf, sizeof(buf)))
847 return -1;
848 }
849
developera1255e42023-05-13 17:45:02 +0800850 return 0;
851}
developerfde01262023-05-22 15:15:24 +0800852
developera1255e42023-05-13 17:45:02 +0800853static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
854{
855 char cmd[MAX_CMD_SIZE] = {0};
developera1255e42023-05-13 17:45:02 +0800856 int ret = 0;
developerfde01262023-05-22 15:15:24 +0800857 int len;
858
859 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param);
860 if (ret < 0) {
861 printf("%s: snprintf error!", __func__);
862 return -1;
863 }
864
865 ret = _syscmd(cmd, output, output_size);
866 if ((ret != 0) && (strlen(output) == 0)) {
867 printf("%s: _syscmd error!", __func__);
868 return -1;
869 }
developera1255e42023-05-13 17:45:02 +0800870
developerfde01262023-05-22 15:15:24 +0800871 len = strlen(output);
872 if ((len > 0) && (output[len - 1] == '\n')) {
873 output[len - 1] = '\0';
874 }
875
876 return 0;
877}
developera1255e42023-05-13 17:45:02 +0800878
developer3a85ab82023-05-25 11:59:38 +0800879static int wifi_datfileRead2(char *conf_file, int idx, char *param, char *output, int output_size)
developerfde01262023-05-22 15:15:24 +0800880{
881 char cmd[MAX_CMD_SIZE] = {0};
882 int ret = 0;
883 int len;
884
developer3a85ab82023-05-25 11:59:38 +0800885 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s %d", conf_file, param, idx);
developera1255e42023-05-13 17:45:02 +0800886 if (ret < 0) {
887 printf("%s: snprintf error!", __func__);
888 return -1;
889 }
890
developerfde01262023-05-22 15:15:24 +0800891 ret = _syscmd(cmd, output, output_size);
892 if ((ret != 0) && (strlen(output) == 0)) {
developera1255e42023-05-13 17:45:02 +0800893 printf("%s: _syscmd error!", __func__);
894 return -1;
895 }
896
developerfde01262023-05-22 15:15:24 +0800897 len = strlen(output);
898 if ((len > 0) && (output[len - 1] == '\n')) {
899 output[len - 1] = '\0';
900 }
developera1255e42023-05-13 17:45:02 +0800901
developer72fb0bb2023-01-11 09:46:29 +0800902 return 0;
903}
904
developera1255e42023-05-13 17:45:02 +0800905static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
906{
developerfde01262023-05-22 15:15:24 +0800907 int ret;
developera1255e42023-05-13 17:45:02 +0800908 char cmd[MAX_CMD_SIZE] = {0};
909 char buf[MAX_BUF_SIZE] = {0};
910
911 for (int i = 0; i < item_count; i++) {
developerfde01262023-05-22 15:15:24 +0800912 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
913 if (ret < 0) {
914 printf("%s: snprintf error!", __func__);
915 return -1;
916 }
developera1255e42023-05-13 17:45:02 +0800917
918 if(_syscmd(cmd, buf, sizeof(buf)))
919 return -1;
920 }
921
922 return 0;
923}
924
developer3a85ab82023-05-25 11:59:38 +0800925static int wifi_datfileWrite2(char *conf_file, int idx, struct params *list, int item_count)
developerfde01262023-05-22 15:15:24 +0800926{
927 int ret;
928 char cmd[MAX_CMD_SIZE] = {0};
929 char buf[MAX_BUF_SIZE] = {0};
930
931 for (int i = 0; i < item_count; i++) {
developer3a85ab82023-05-25 11:59:38 +0800932 ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s %d \"%s\"", conf_file, list[i].name, idx, list[i].value);
developerfde01262023-05-22 15:15:24 +0800933 if (ret < 0) {
934 printf("%s: snprintf error!", __func__);
935 return -1;
936 }
937
938 if(_syscmd(cmd, buf, sizeof(buf)))
939 return -1;
940 }
941
942 return 0;
943}
944
945static int wifi_l1ProfileRead(char *param, char *output, int output_size)
946{
947 char buf[MAX_BUF_SIZE] = {0};
948 int ret;
949
950 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
951 if (!param || !output || (output_size <= 0)) {
952 fprintf(stderr, "%s: invalid parameters", __func__);
953 return RETURN_ERR;
954 }
955
956 ret = wifi_datfileRead(l1profile, param, output, output_size);
957 if (ret != 0) {
958 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, l1profile, ret);
959 return RETURN_ERR;
960 }
961
962 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
963 return RETURN_OK;
964}
965
developer3a85ab82023-05-25 11:59:38 +0800966static int wifi_l1ProfileRead2(char *param, int idx, char *output, int output_size)
967{
968 char buf[MAX_BUF_SIZE] = {0};
969 int ret;
970
971 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
972 if (!param || !output || (output_size <= 0)) {
973 fprintf(stderr, "%s: invalid parameters", __func__);
974 return RETURN_ERR;
975 }
976
977 ret = wifi_datfileRead2(l1profile, idx, param, output, output_size);
978 if (ret != 0) {
979 fprintf(stderr, "%s: wifi_datfileRead2 %s from %s failed, ret:%d", __func__, param, l1profile, ret);
980 return RETURN_ERR;
981 }
982
983 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
984 return RETURN_OK;
985}
986
987
developerfde01262023-05-22 15:15:24 +0800988static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
989{
990 char option[64];
991 char card_profile_path[64];
992 int ret;
993
994 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
995
996 if (!param || !output || (output_size <= 0)) {
997 fprintf(stderr, "%s: invalid parameters", __func__);
998 return RETURN_ERR;
999 }
1000
1001 snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
1002 ret = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
1003 if (ret != 0) {
1004 fprintf(stderr, "%s: wifi_l1ProfileRead %s failed, ret:%d", __func__, option, ret);
1005 return RETURN_ERR;
1006 }
1007
1008 ret = wifi_datfileRead(card_profile_path, param, output, output_size);
1009 if (ret != 0) {
1010 fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, card_profile_path, ret);
1011 return RETURN_ERR;
1012 }
1013
1014 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1015 return RETURN_OK;
1016}
1017
1018static int wifi_BandProfileRead(int card_idx,
1019 int radio_idx,
1020 char *param,
1021 char *output,
1022 int output_size,
1023 char *default_value)
1024{
1025 char option[64];
1026 char band_profile_path[64];
1027 int ret;
1028
1029 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1030 if (!param || !output || (output_size <= 0)) {
1031 fprintf(stderr, "%s: invalid parameters", __func__);
1032 return RETURN_ERR;
1033 }
1034
1035 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1036 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1037 if (ret != 0) {
1038 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1039 return RETURN_ERR;
1040 }
1041
1042 ret = wifi_datfileRead(band_profile_path, param, output, output_size);
1043 if (ret != 0) {
1044 if (default_value) {
1045 snprintf(output, output_size, "%s", default_value);
1046 } else {
1047 output[0] = '\0';
1048 }
1049 }
1050
1051 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1052 return RETURN_OK;
1053}
1054
1055static int wifi_BandProfileRead2(int card_idx,
1056 int radio_idx,
developer3a85ab82023-05-25 11:59:38 +08001057 int idx,
developerfde01262023-05-22 15:15:24 +08001058 char *param,
1059 char *output,
1060 int output_size,
1061 char* default_value)
1062{
1063 char option[64];
1064 char band_profile_path[64];
1065 int ret;
1066
1067 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1068 if (!param || !output || (output_size <= 0)) {
1069 fprintf(stderr, "%s: invalid parameters", __func__);
1070 return RETURN_ERR;
1071 }
1072
1073 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1074 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1075 if (ret != 0) {
1076 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1077 return RETURN_ERR;
1078 }
1079
developer3a85ab82023-05-25 11:59:38 +08001080 ret = wifi_datfileRead2(band_profile_path, idx, param, output, output_size);
developerfde01262023-05-22 15:15:24 +08001081 if (ret != 0) {
1082 if (default_value) {
1083 snprintf(output, output_size, "%s", default_value);
1084 } else {
1085 output[0] = '\0';
1086 }
1087 }
1088
1089 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1090 return RETURN_OK;
1091
1092}
1093
1094static int wifi_BandProfileWrite(int card_idx, int radio_idx, struct params *list, int item_count)
1095{
1096 char option[64];
1097 char band_profile_path[64];
1098 int ret;
1099
1100 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1101
1102 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1103 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1104 if (ret != 0) {
1105 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1106 return RETURN_ERR;
1107 }
1108
1109 for (int i = 0; i < item_count; i++) {
1110 }
1111 ret = wifi_datfileWrite(band_profile_path, list, item_count);
1112 if (ret != 0) {
1113 fprintf(stderr, "%s: wifi_datfileWrite failed, ret:%d", __func__);
1114 return RETURN_ERR;
1115 }
1116
1117 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1118 return RETURN_OK;
1119
1120}
1121
1122static int wifi_BandProfileWrite2(int card_idx,
1123 int radio_idx,
developer3a85ab82023-05-25 11:59:38 +08001124 int idx,
developerfde01262023-05-22 15:15:24 +08001125 struct params *list,
1126 int item_count)
1127{
1128 char option[64];
1129 char band_profile_path[64];
1130 char buf[64];
1131 char buf2[MAX_BUF_SIZE];
1132 int ret;
1133
1134 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1135
1136 snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
1137 ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
1138 if (ret != 0) {
1139 fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option);
1140 return RETURN_ERR;
1141 }
1142
developer3a85ab82023-05-25 11:59:38 +08001143 ret = wifi_datfileWrite2(band_profile_path, idx, list, item_count);
developerfde01262023-05-22 15:15:24 +08001144 if (ret != 0) {
1145 fprintf(stderr, "%s: wifi_datfileWrite failed, ret:%d", __func__);
1146 return RETURN_ERR;
1147 }
1148
1149 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1150 return RETURN_OK;
1151
1152}
1153
1154
1155
developer72fb0bb2023-01-11 09:46:29 +08001156//For Getting Current Interface Name from corresponding hostapd configuration
1157static int wifi_GetInterfaceName(int apIndex, char *interface_name)
1158{
1159 char config_file[128] = {0};
1160
1161 if (interface_name == NULL)
1162 return RETURN_ERR;
1163
1164 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1165
1166 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
1167 wifi_hostapdRead(config_file, "interface", interface_name, 16);
1168 if (strlen(interface_name) == 0)
1169 return RETURN_ERR;
1170
1171 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1172 return RETURN_OK;
1173}
1174
developera1255e42023-05-13 17:45:02 +08001175static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
1176{
1177 char interface_name[IF_NAME_SIZE] = {0};
1178 char cmd[MAX_BUF_SIZE]={'\0'};
1179 char buf[MAX_CMD_SIZE]={'\0'};
1180 UCHAR channel = 0;
1181
1182 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
1183 return RETURN_ERR;
1184 /*interface name to channel number*/
1185 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
1186 _syscmd(cmd, buf, sizeof(buf));
1187 channel = atoi(buf);
1188 WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
1189 /*count dev number with the same channel*/
1190 snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel);
1191 _syscmd(cmd, buf, sizeof(buf));
1192 *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
1193 WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
1194 return RETURN_OK;
1195}
developer72fb0bb2023-01-11 09:46:29 +08001196
1197static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
1198{
1199 char interface_name[16] = {0};
1200 if (multiple_set == TRUE)
1201 return RETURN_OK;
1202 char cmd[MAX_CMD_SIZE]="", output[32]="";
1203 FILE *fp;
1204 int i;
1205 //NOTE RELOAD should be done in ApplySSIDSettings
1206 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1207 return RETURN_ERR;
1208 for(i=0; i<item_count; i++, list++)
1209 {
developerf6a87542023-05-16 15:47:28 +08001210 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
developer72fb0bb2023-01-11 09:46:29 +08001211 if((fp = popen(cmd, "r"))==NULL)
1212 {
1213 perror("popen failed");
1214 return -1;
1215 }
1216 if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2))
1217 {
1218 pclose(fp);
1219 perror("fgets failed");
1220 return -1;
1221 }
1222 pclose(fp);
1223 }
1224 return 0;
1225}
1226
developer7e4a2a62023-04-06 19:56:03 +08001227static int wifi_quick_reload_ap(int apIndex)
1228{
1229 char interface_name[IF_NAME_SIZE] = {0};
1230 char cmd[MAX_CMD_SIZE] = {0};
1231 char buf[MAX_BUF_SIZE] = {0};
1232
1233 if (multiple_set == TRUE)
1234 return RETURN_OK;
1235
1236 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1237 return RETURN_ERR;
1238
1239 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1240 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1241 return RETURN_ERR;
1242
1243 return RETURN_OK;
1244}
1245
developer72fb0bb2023-01-11 09:46:29 +08001246static int wifi_reloadAp(int apIndex)
1247{
1248 char interface_name[16] = {0};
1249 if (multiple_set == TRUE)
1250 return RETURN_OK;
1251 char cmd[MAX_CMD_SIZE]="";
1252 char buf[MAX_BUF_SIZE]="";
1253
1254 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
1255 return RETURN_ERR;
1256 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name);
1257 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1258 return RETURN_ERR;
1259
1260 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name);
1261 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1262 return RETURN_ERR;
1263
1264 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name);
1265 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
1266 return RETURN_ERR;
1267
1268 return RETURN_OK;
1269}
1270
1271INT File_Reading(CHAR *file, char *Value)
1272{
1273 FILE *fp = NULL;
1274 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
1275 int count = 0;
1276
1277 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1278 fp = popen(file,"r");
1279 if(fp == NULL)
1280 return RETURN_ERR;
1281
1282 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
1283 {
1284 for(count=0;buf[count]!='\n';count++)
1285 copy_buf[count]=buf[count];
1286 copy_buf[count]='\0';
1287 }
1288 strcpy(Value,copy_buf);
1289 pclose(fp);
1290 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1291
1292 return RETURN_OK;
1293}
1294
1295void wifi_RestartHostapd_2G()
1296{
1297 int Public2GApIndex = 4;
1298
1299 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1300 wifi_setApEnable(Public2GApIndex, FALSE);
1301 wifi_setApEnable(Public2GApIndex, TRUE);
1302 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1303}
1304
1305void wifi_RestartHostapd_5G()
1306{
1307 int Public5GApIndex = 5;
1308
1309 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1310 wifi_setApEnable(Public5GApIndex, FALSE);
1311 wifi_setApEnable(Public5GApIndex, TRUE);
1312 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1313}
1314
1315void wifi_RestartPrivateWifi_2G()
1316{
1317 int PrivateApIndex = 0;
1318
1319 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1320 wifi_setApEnable(PrivateApIndex, FALSE);
1321 wifi_setApEnable(PrivateApIndex, TRUE);
1322 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1323}
1324
1325void wifi_RestartPrivateWifi_5G()
1326{
1327 int Private5GApIndex = 1;
1328
1329 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1330 wifi_setApEnable(Private5GApIndex, FALSE);
1331 wifi_setApEnable(Private5GApIndex, TRUE);
1332 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1333}
1334
1335static int writeBandWidth(int radioIndex,char *bw_value)
1336{
1337 char buf[MAX_BUF_SIZE];
1338 char cmd[MAX_CMD_SIZE];
1339
1340 snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
1341 if(_syscmd(cmd, buf, sizeof(buf)))
1342 {
1343 snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
1344 _syscmd(cmd, buf, sizeof(buf));
1345 return RETURN_OK;
1346 }
1347
1348 sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
1349 _syscmd(cmd,buf,sizeof(buf));
1350 return RETURN_OK;
1351}
1352
1353static int readBandWidth(int radioIndex,char *bw_value)
1354{
1355 char buf[MAX_BUF_SIZE] = {0};
1356 char cmd[MAX_CMD_SIZE] = {0};
1357 sprintf(cmd,"grep 'SET_BW%d=' %s | sed 's/^.*=//'",radioIndex,BW_FNAME);
1358 _syscmd(cmd,buf,sizeof(buf));
1359 if(NULL!=strstr(buf,"20MHz"))
developer72fb0bb2023-01-11 09:46:29 +08001360 strcpy(bw_value,"20MHz");
developer72fb0bb2023-01-11 09:46:29 +08001361 else if(NULL!=strstr(buf,"40MHz"))
developer72fb0bb2023-01-11 09:46:29 +08001362 strcpy(bw_value,"40MHz");
developer72fb0bb2023-01-11 09:46:29 +08001363 else if(NULL!=strstr(buf,"80MHz"))
developer72fb0bb2023-01-11 09:46:29 +08001364 strcpy(bw_value,"80MHz");
developerd1824452023-05-18 12:30:04 +08001365 else if(NULL!=strstr(buf,"160MHz"))
1366 strcpy(bw_value,"160MHz");
1367 else if(NULL!=strstr(buf,"320MHz"))
1368 strcpy(bw_value,"320MHz");
developer72fb0bb2023-01-11 09:46:29 +08001369 else
developer72fb0bb2023-01-11 09:46:29 +08001370 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08001371 return RETURN_OK;
1372}
1373
1374// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
1375INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
1376{
1377 struct params params={'\0'};
1378 char config_file[MAX_BUF_SIZE] = {0};
1379 char buf[MAX_BUF_SIZE] = {'\0'};
1380
1381 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1382 // Copy the numeric value
1383 if (strlen (beaconRate) >= 5) {
1384 strncpy(buf, beaconRate, strlen(beaconRate) - 4);
1385 buf[strlen(beaconRate) - 4] = '\0';
1386 } else if (strlen(beaconRate) > 0)
1387 strcpy(buf, beaconRate);
1388 else
1389 return RETURN_ERR;
1390
1391 params.name = "beacon_rate";
1392 // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
1393 if (strncmp(buf, "5.5", 3) == 0) {
1394 snprintf(buf, sizeof(buf), "55");
1395 params.value = buf;
1396 } else {
1397 strcat(buf, "0");
1398 params.value = buf;
1399 }
1400
1401 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1402 wifi_hostapdWrite(config_file, &params, 1);
1403 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
1404 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1405
1406 return RETURN_OK;
1407}
1408
1409INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
1410{
1411 char config_file[128] = {'\0'};
1412 char temp_output[128] = {'\0'};
1413 char buf[128] = {'\0'};
1414 char cmd[128] = {'\0'};
1415 int rate = 0;
1416 int phyId = 0;
1417
1418 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1419 if (NULL == beaconRate)
1420 return RETURN_ERR;
1421
1422 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1423 wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
1424 phyId = radio_index_to_phy(radioIndex);
1425 // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
1426 if(strlen(buf) > 0) {
1427 if (strncmp(buf, "55", 2) == 0)
1428 snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
1429 else {
1430 rate = strtol(buf, NULL, 10)/10;
1431 snprintf(temp_output, sizeof(temp_output), "%dMbps", rate);
1432 }
1433 } else {
1434 // config not set, so we would use lowest rate as default
1435 sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
1436 _syscmd(cmd, buf, sizeof(buf));
1437 snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
1438 }
1439 strncpy(beaconRate, temp_output, sizeof(temp_output));
1440 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1441
1442 return RETURN_OK;
1443}
1444
1445INT wifi_setLED(INT radioIndex, BOOL enable)
1446{
1447 return 0;
1448}
1449INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
1450{
1451 return RETURN_OK;
1452}
1453/**********************************************************************************
1454 *
developer69b61b02023-03-07 17:17:44 +08001455 * Wifi Subsystem level function prototypes
developer72fb0bb2023-01-11 09:46:29 +08001456 *
1457**********************************************************************************/
1458//---------------------------------------------------------------------------------------------------
1459//Wifi system api
1460//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 +08001461INT wifi_getHalVersion(CHAR *output_string) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08001462{
1463 if(!output_string)
1464 return RETURN_ERR;
1465 snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
1466
1467 return RETURN_OK;
1468}
1469
1470
1471/* wifi_factoryReset() function */
1472/**
developer69b61b02023-03-07 17:17:44 +08001473* @description Clears internal variables to implement a factory reset of the Wi-Fi
developer72fb0bb2023-01-11 09:46:29 +08001474* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
1475*
1476* @param None
1477*
1478* @return The status of the operation.
1479* @retval RETURN_OK if successful.
1480* @retval RETURN_ERR if any error is detected
1481*
1482* @execution Synchronous
1483* @sideeffect None
1484*
1485* @note This function must not suspend and must not invoke any blocking system
1486* calls. It should probably just send a message to a driver event handler task.
1487*
1488*/
1489INT wifi_factoryReset()
1490{
developer47cc27a2023-05-17 23:09:58 +08001491 char cmd[MAX_CMD_SIZE] = {0};
1492 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08001493
developer47cc27a2023-05-17 23:09:58 +08001494 /*delete running hostapd conf files*/
1495 wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__);
1496 snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf");
1497 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08001498
developer47cc27a2023-05-17 23:09:58 +08001499 wifi_PrepareDefaultHostapdConfigs();
1500 wifi_psk_file_reset();
1501
1502 memset(cmd, 0, MAX_CMD_SIZE);
1503 memset(buf, 0, MAX_BUF_SIZE);
1504
1505 snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service");
1506 _syscmd(cmd, buf, sizeof(buf));
1507
1508 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001509}
1510
1511/* wifi_factoryResetRadios() function */
1512/**
1513* @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.
1514*
1515* @param None
1516* @return The status of the operation
1517* @retval RETURN_OK if successful
1518* @retval RETURN_ERR if any error is detected
1519*
1520* @execution Synchronous
1521*
1522* @sideeffect None
1523*
1524* @note This function must not suspend and must not invoke any blocking system
1525* calls. It should probably just send a message to a driver event handler task.
1526*
1527*/
1528INT wifi_factoryResetRadios()
1529{
1530 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
1531 return RETURN_OK;
1532
1533 return RETURN_ERR;
1534}
1535
developerfead3972023-05-25 20:15:02 +08001536ULONG get_radio_reset_cnt(int radioIndex)
1537{
1538 char cmd[MAX_CMD_SIZE] = {0};
1539 char buf[MAX_BUF_SIZE] = {0};
1540 ULONG reset_count = 0;
1541
1542 snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
1543 RADIO_RESET_FILE, radioIndex);
1544 _syscmd(cmd, buf, sizeof(buf));
1545
1546 if (strlen(buf) == 0)
1547 return 0;
1548 else {
1549 reset_count = atol(buf);
1550 return reset_count;
1551 }
1552}
1553void update_radio_reset_cnt(int radioIndex)
1554{
1555 char cmd[MAX_CMD_SIZE] = {0};
1556 char buf[MAX_BUF_SIZE] = {0};
1557 ULONG reset_count = 0;
1558
1559 snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
1560 RADIO_RESET_FILE, radioIndex);
1561 _syscmd(cmd, buf, sizeof(buf));
1562
1563 if (strlen(buf) == 0)
1564 snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
1565 else {
1566 reset_count = atol(buf);
1567 reset_count++;
1568 snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
1569 }
1570 _syscmd(cmd, buf, sizeof(buf));
1571}
developer72fb0bb2023-01-11 09:46:29 +08001572
1573/* wifi_factoryResetRadio() function */
1574/**
1575* @description Restore selected radio parameters without touching access point parameters
1576*
1577* @param radioIndex - Index of Wi-Fi Radio channel
1578*
1579* @return The status of the operation.
1580* @retval RETURN_OK if successful.
1581* @retval RETURN_ERR if any error is detected
1582*
1583* @execution Synchronous.
1584* @sideeffect None.
1585*
1586* @note This function must not suspend and must not invoke any blocking system
1587* calls. It should probably just send a message to a driver event handler task.
1588*
1589*/
1590INT wifi_factoryResetRadio(int radioIndex) //RDKB
1591{
developer47cc27a2023-05-17 23:09:58 +08001592 char cmd[MAX_CMD_SIZE] = {0};
1593 char buf[MAX_BUF_SIZE] = {0};
1594 char vap_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08001595
developer47cc27a2023-05-17 23:09:58 +08001596 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08001597
developerb2977562023-05-24 17:54:12 +08001598 wifi_dat_file_reset_by_radio(radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001599
developerb2977562023-05-24 17:54:12 +08001600 /*reset gi setting*/
1601 snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
developer47cc27a2023-05-17 23:09:58 +08001602 _syscmd(cmd, buf, sizeof(buf));
1603
developerb2977562023-05-24 17:54:12 +08001604 /*TBD: check mbss issue*/
1605 wifi_factoryResetAP(radioIndex);
developerfead3972023-05-25 20:15:02 +08001606 update_radio_reset_cnt(radioIndex);
developerb2977562023-05-24 17:54:12 +08001607
developer47cc27a2023-05-17 23:09:58 +08001608 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
1609 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08001610}
1611
1612/* wifi_initRadio() function */
1613/**
1614* Description: This function call initializes the specified radio.
developer69b61b02023-03-07 17:17:44 +08001615* Implementation specifics may dictate the functionality since
developer72fb0bb2023-01-11 09:46:29 +08001616* different hardware implementations may have different initilization requirements.
1617* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
1618*
1619* @return The status of the operation.
1620* @retval RETURN_OK if successful.
1621* @retval RETURN_ERR if any error is detected
1622*
1623* @execution Synchronous.
1624* @sideeffect None.
1625*
1626* @note This function must not suspend and must not invoke any blocking system
1627* calls. It should probably just send a message to a driver event handler task.
1628*
1629*/
1630INT wifi_initRadio(INT radioIndex)
1631{
1632 //TODO: Initializes the wifi subsystem (for specified radio)
1633 return RETURN_OK;
1634}
1635void macfilter_init()
1636{
1637 char count[4]={'\0'};
1638 char buf[253]={'\0'};
1639 char tmp[19]={'\0'};
1640 int dev_count,block,mac_entry=0;
1641 char res[4]={'\0'};
1642 char acl_file_path[64] = {'\0'};
1643 FILE *fp = NULL;
1644 int index=0;
1645 char iface[10]={'\0'};
1646 char config_file[MAX_BUF_SIZE] = {0};
1647
1648
1649 sprintf(acl_file_path,"/tmp/mac_filter.sh");
1650
1651 fp=fopen(acl_file_path,"w+");
1652 if (fp == NULL) {
1653 fprintf(stderr, "%s: failed to open file %s.\n", __func__, acl_file_path);
developer17038e62023-03-02 14:43:43 +08001654 return;
developer72fb0bb2023-01-11 09:46:29 +08001655 }
1656 sprintf(buf,"#!/bin/sh \n");
1657 fprintf(fp,"%s\n",buf);
1658
1659 system("chmod 0777 /tmp/mac_filter.sh");
1660
1661 for(index=0;index<=1;index++)
1662 {
1663 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index);
1664 wifi_hostapdRead(config_file, "interface", iface, sizeof(iface));
1665 sprintf(buf,"syscfg get %dcountfilter",index);
1666 _syscmd(buf,count,sizeof(count));
1667 mac_entry=atoi(count);
1668
1669 sprintf(buf,"syscfg get %dblockall",index);
1670 _syscmd(buf,res,sizeof(res));
1671 block = atoi(res);
1672
1673 //Allow only those macs mentioned in ACL
1674 if(block==1)
1675 {
1676 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1677 fprintf(fp,"%s\n",buf);
1678 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1679 {
1680 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1681 _syscmd(buf,tmp,sizeof(tmp));
1682 fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp);
1683 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp);
1684 fprintf(fp,"%s\n",buf);
1685 }
1686 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp);
1687 fprintf(fp,"%s\n",buf);
1688 }
1689
1690 //Block all the macs mentioned in ACL
1691 else if(block==2)
1692 {
1693 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
1694 fprintf(fp,"%s\n",buf);
1695
1696 for(dev_count=1;dev_count<=mac_entry;dev_count++)
1697 {
1698 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
1699 _syscmd(buf,tmp,sizeof(tmp));
1700 fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp);
1701 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp);
1702 fprintf(fp,"%s\n",buf);
1703 }
1704 }
1705 }
1706 fclose(fp);
1707}
1708
developer17038e62023-03-02 14:43:43 +08001709
1710static void
1711wifi_ParseProfile(void)
1712{
1713 int i;
1714 int max_radio_num = 0;
1715 int card_idx;
1716 int band_idx;
1717 int phy_idx = 0;
developer745f0bd2023-03-06 14:32:53 +08001718 int wireless_mode = 0;
developer17038e62023-03-02 14:43:43 +08001719 char buf[MAX_BUF_SIZE] = {0};
1720 char chip_name[12];
1721 char card_profile[MAX_BUF_SIZE] = {0};
1722 char band_profile[MAX_BUF_SIZE] = {0};
1723 FILE* fp;
1724
1725 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1726
1727 memset(main_prefix, 0, sizeof(main_prefix));
1728 memset(ext_prefix, 0, sizeof(ext_prefix));
1729 memset(default_ssid, 0, sizeof(default_ssid));
developer745f0bd2023-03-06 14:32:53 +08001730 for (i = 0; i < MAX_NUM_RADIOS; i++)
1731 radio_band[i] = band_invalid;
developer17038e62023-03-02 14:43:43 +08001732
1733 if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
1734 /* LOG */
1735 return;
1736 }
1737
1738 for (card_idx = 0; card_idx < 3; card_idx++) {
1739 snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
1740 if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
1741 break;
1742 }
1743 snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
1744 if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
1745 break;
1746 }
1747 for (band_idx = 0; band_idx < 3; band_idx++) {
1748 snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
1749 if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
1750 /* LOG */
1751 break;
1752 }
1753
1754 snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
1755 if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
1756 /* LOG */
1757 }
1758
1759 snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
1760 if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
1761 /* LOG */
1762 }
1763
1764 if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
1765 /* LOG */
1766 }
developer745f0bd2023-03-06 14:32:53 +08001767 if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
1768 /* LOG */
1769 }
1770
1771 wireless_mode = atoi(buf);
1772 switch (wireless_mode) {
1773 case 22:
1774 case 16:
1775 case 6:
1776 case 4:
1777 case 1:
1778 radio_band[phy_idx] = band_2_4;
1779 break;
1780 case 23:
1781 case 17:
1782 case 14:
1783 case 11:
1784 case 2:
1785 radio_band[phy_idx] = band_5;
1786 break;
1787 case 24:
1788 case 18:
1789 radio_band[phy_idx] = band_6;
1790 break;
1791 }
developer17038e62023-03-02 14:43:43 +08001792 phy_idx++;
1793 }
1794 }
1795
1796 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1797}
1798
1799static void
1800wifi_PrepareDefaultHostapdConfigs(void)
1801{
developer0132ed92023-03-21 13:48:53 +08001802 int radio_idx;
1803 int bss_idx;
1804 int ap_idx;
developer0132ed92023-03-21 13:48:53 +08001805 char buf[MAX_BUF_SIZE] = {0};
1806 char config_file[MAX_BUF_SIZE] = {0};
1807 char ssid[MAX_BUF_SIZE] = {0};
1808 char interface[32] = {0};
1809 char ret_buf[MAX_BUF_SIZE] = {0};
1810 char psk_file[64] = {0};
1811 struct params params[3];
developer47cc27a2023-05-17 23:09:58 +08001812 char *band_str[3] = {"2G", "5G", "6G"};
developer17038e62023-03-02 14:43:43 +08001813
developer0132ed92023-03-21 13:48:53 +08001814 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1815 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001816
developer0132ed92023-03-21 13:48:53 +08001817 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer47cc27a2023-05-17 23:09:58 +08001818 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
developer0132ed92023-03-21 13:48:53 +08001819
developer47cc27a2023-05-17 23:09:58 +08001820 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
developere740c2a2023-05-23 18:34:32 +08001821 snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
developer47cc27a2023-05-17 23:09:58 +08001822 _syscmd(buf, ret_buf, sizeof(ret_buf));
developer17038e62023-03-02 14:43:43 +08001823
developer47cc27a2023-05-17 23:09:58 +08001824 if (radio_idx == band_2_4) {
1825 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
1826 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
1827 } else if (radio_idx == band_5) {
1828 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
1829 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
1830 } else if (radio_idx == band_6) {
1831 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
1832 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
1833 }
developer17038e62023-03-02 14:43:43 +08001834
developer47cc27a2023-05-17 23:09:58 +08001835 /* fix wpa_psk_file path */
1836 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx);
developer17038e62023-03-02 14:43:43 +08001837
developer47cc27a2023-05-17 23:09:58 +08001838 params[0].name = "ssid";
1839 params[0].value = ssid;
1840 params[1].name = "interface";
1841 params[1].value = interface;
1842 params[2].name = "wpa_psk_file";
1843 params[2].value = psk_file;
developer17038e62023-03-02 14:43:43 +08001844
developer47cc27a2023-05-17 23:09:58 +08001845 wifi_hostapdWrite(config_file, params, 3);
developer0132ed92023-03-21 13:48:53 +08001846 }
1847 }
1848 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001849}
1850
1851static void
1852wifiBringUpInterfacesForRadio(int radio_idx)
1853{
developer0132ed92023-03-21 13:48:53 +08001854 int bss_idx;
1855 int ap_idx;
1856 int band_idx;
1857 char cmd[MAX_CMD_SIZE] = {0};
1858 char config_file[MAX_BUF_SIZE] = {0};
1859 char ret_buf[MAX_BUF_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08001860 char inf_name[IF_NAME_SIZE] = {0};
developer17038e62023-03-02 14:43:43 +08001861
1862 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer8a3bbbf2023-03-15 17:47:23 +08001863
developered997d32023-04-18 22:45:39 +08001864 bss_idx = 0;
1865 /*TBD: we need refine setup flow and mbss flow*/
1866// for (bss_idx = 0; bss_idx < 5; bss_idx++) {
developer0132ed92023-03-21 13:48:53 +08001867 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
1868
1869 snprintf(cmd, sizeof(cmd), "touch %s%d.psk", PSK_FILE, ap_idx);
1870 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1871
1872 memset(cmd, 0, MAX_CMD_SIZE);
1873 memset(ret_buf, 0, MAX_BUF_SIZE);
developer17038e62023-03-02 14:43:43 +08001874
developer0132ed92023-03-21 13:48:53 +08001875 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
1876 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radio_idx, config_file);
1877 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer8a3bbbf2023-03-15 17:47:23 +08001878
1879 wifi_GetInterfaceName(ap_idx, inf_name);
1880
1881 memset(cmd, 0, MAX_CMD_SIZE);
1882 memset(ret_buf, 0, MAX_BUF_SIZE);
1883
1884 /* fix vap-status file */
1885 snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=1/\" %s", inf_name, inf_name, VAP_STATUS_FILE);
1886 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developered997d32023-04-18 22:45:39 +08001887// }
1888
1889 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001890}
1891
1892static void
1893wifi_BringUpInterfaces(void)
1894{
1895 int radio_idx;
1896 int bss_idx;
1897 int ap_idx;
1898 int band_idx;
1899 char cmd[MAX_BUF_SIZE] = {0};
1900 char config_file[MAX_BUF_SIZE] = {0};
1901 char ret_buf[MAX_BUF_SIZE]={'\0'};
1902
1903 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1904 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1905 band_idx = radio_index_to_band(radio_idx);
1906 if (band_idx < 0) {
1907 break;
1908 }
1909 wifiBringUpInterfacesForRadio(radio_idx);
1910 }
1911 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1912}
1913
1914static void
1915wifi_BringDownInterfacesForRadio(int radio_idx)
1916{
1917 int bss_idx;
1918 int ap_idx;
1919 int band_idx;
1920 char cmd[MAX_BUF_SIZE] = {0};
1921 char config_file[MAX_BUF_SIZE] = {0};
1922 char ret_buf[MAX_BUF_SIZE]={'\0'};
1923
1924 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer17038e62023-03-02 14:43:43 +08001925
developer8a3bbbf2023-03-15 17:47:23 +08001926 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
1927 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1928
1929
developer17038e62023-03-02 14:43:43 +08001930 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1931}
1932
1933
1934static void
1935wifi_BringDownInterfaces(void)
1936{
1937 int radio_idx;
1938 int bss_idx;
1939 int ap_idx;
1940 int band_idx;
1941 char cmd[MAX_BUF_SIZE] = {0};
1942 char config_file[MAX_BUF_SIZE] = {0};
1943 char ret_buf[MAX_BUF_SIZE]={'\0'};
1944
1945 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1946 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
1947 band_idx = radio_index_to_band(radio_idx);
1948 if (band_idx < 0) {
1949 break;
1950 }
1951 wifi_BringDownInterfacesForRadio(radio_idx);
1952 }
1953 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1954}
1955
developerb2977562023-05-24 17:54:12 +08001956static void wifi_dat_file_reset()
1957{
1958 char radio_idx = 0;
1959
1960 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
1961 wifi_dat_file_reset_by_radio(radio_idx);
1962}
1963
1964static void wifi_dat_file_reset_by_radio(char radio_idx)
1965{
1966 char cmd[MAX_CMD_SIZE] = {0};
1967 char ret_buf[MAX_BUF_SIZE] = {0};
1968 char rom_dat_file[MAX_CMD_SIZE]= {0};
1969 char dat_file[MAX_CMD_SIZE]= {0};
1970
1971 snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
1972 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
1973 snprintf(cmd, MAX_CMD_SIZE, "cp -rf %s %s", rom_dat_file, dat_file);
1974 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1975
1976}
1977
developer47cc27a2023-05-17 23:09:58 +08001978static void wifi_psk_file_reset()
1979{
1980 char cmd[MAX_CMD_SIZE] = {0};
1981 char ret_buf[MAX_BUF_SIZE] = {0};
1982 char psk_file[MAX_CMD_SIZE]= {0};
1983 char vap_idx = 0;
1984
1985 for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
1986 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
1987
1988 if (access(psk_file, F_OK) != 0) {
1989 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
1990 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1991 } else {
1992 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
1993 _syscmd(cmd, ret_buf, sizeof(ret_buf));
1994 }
1995 }
1996}
1997
developerb2977562023-05-24 17:54:12 +08001998static void wifi_psk_file_reset_by_radio(char radio_idx)
1999{
2000 char cmd[MAX_CMD_SIZE] = {0};
2001 char ret_buf[MAX_BUF_SIZE] = {0};
2002 char psk_file[MAX_CMD_SIZE]= {0};
2003 char vap_idx = 0;
2004
2005 for (vap_idx = radio_idx; vap_idx < MAX_APS; vap_idx += MAX_NUM_RADIOS) {
2006 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
2007
2008 if (access(psk_file, F_OK) != 0) {
2009 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
2010 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2011 } else {
2012 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
2013 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2014 }
2015 }
2016
2017}
2018
2019
developer8a3bbbf2023-03-15 17:47:23 +08002020static void wifi_vap_status_reset()
2021{
2022 char cmd[MAX_CMD_SIZE] = {0};
2023 char ret_buf[MAX_BUF_SIZE] = {0};
2024 char radio_idx = 0;
2025 char bss_idx = 0;
developer8666b312023-03-24 14:05:31 +08002026
developer8a3bbbf2023-03-15 17:47:23 +08002027 if (access(VAP_STATUS_FILE, F_OK) != 0) {
2028 snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE);
2029 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2030 } else {
2031 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE);
2032 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2033 }
2034
2035 memset(cmd, 0, MAX_CMD_SIZE);
2036 memset(ret_buf, 0, MAX_BUF_SIZE);
2037
2038 for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
2039 for (bss_idx = 0; bss_idx < 5; bss_idx++) {
2040 snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE);
2041 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2042 }
2043
developerfead3972023-05-25 20:15:02 +08002044}
2045
2046static void wifi_radio_reset_count_reset()
2047{
2048 char cmd[MAX_CMD_SIZE] = {0};
2049 char ret_buf[MAX_BUF_SIZE] = {0};
2050
2051 if (access(VAP_STATUS_FILE, F_OK) != 0) {
2052 snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE);
2053 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2054 } else {
2055 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE);
2056 _syscmd(cmd, ret_buf, sizeof(ret_buf));
2057 }
developer8a3bbbf2023-03-15 17:47:23 +08002058}
developer17038e62023-03-02 14:43:43 +08002059
developer72fb0bb2023-01-11 09:46:29 +08002060// Initializes the wifi subsystem (all radios)
2061INT wifi_init() //RDKB
2062{
developer96b38512023-02-22 11:17:45 +08002063 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2064 //Not intitializing macfilter for Turris-Omnia Platform for now
2065 //macfilter_init();
developer17038e62023-03-02 14:43:43 +08002066 wifi_ParseProfile();
2067 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08002068 wifi_psk_file_reset();
developer17038e62023-03-02 14:43:43 +08002069 //system("/usr/sbin/iw reg set US");
2070 system("systemctl start hostapd.service");
2071 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002072
2073 wifi_vap_status_reset();
developerfead3972023-05-25 20:15:02 +08002074 wifi_radio_reset_count_reset();
developer96b38512023-02-22 11:17:45 +08002075
2076 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002077
2078 return RETURN_OK;
2079}
2080
2081/* wifi_reset() function */
2082/**
2083* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
developer69b61b02023-03-07 17:17:44 +08002084* Implementation specifics may dictate what is actualy reset since
developer72fb0bb2023-01-11 09:46:29 +08002085* different hardware implementations may have different requirements.
2086* Parameters : None
2087*
2088* @return The status of the operation.
2089* @retval RETURN_OK if successful.
2090* @retval RETURN_ERR if any error is detected
2091*
2092* @execution Synchronous.
2093* @sideeffect None.
2094*
2095* @note This function must not suspend and must not invoke any blocking system
2096* calls. It should probably just send a message to a driver event handler task.
2097*
2098*/
2099INT wifi_reset()
2100{
developer17038e62023-03-02 14:43:43 +08002101
2102 wifi_BringDownInterfaces();
2103 sleep(2);
2104
developer96b38512023-02-22 11:17:45 +08002105 //TODO: resets the wifi subsystem, deletes all APs
2106 system("systemctl stop hostapd.service");
2107 sleep(2);
developer17038e62023-03-02 14:43:43 +08002108
developer96b38512023-02-22 11:17:45 +08002109 system("systemctl start hostapd.service");
2110 sleep(5);
developer17038e62023-03-02 14:43:43 +08002111
2112 wifi_PrepareDefaultHostapdConfigs();
developer47cc27a2023-05-17 23:09:58 +08002113 wifi_psk_file_reset();
developer17038e62023-03-02 14:43:43 +08002114 sleep(2);
developer8a3bbbf2023-03-15 17:47:23 +08002115
2116 wifi_vap_status_reset();
2117
developer72fb0bb2023-01-11 09:46:29 +08002118 return RETURN_OK;
2119}
2120
2121/* wifi_down() function */
2122/**
2123* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
developer69b61b02023-03-07 17:17:44 +08002124* Implementation specifics may dictate some functionality since
developer72fb0bb2023-01-11 09:46:29 +08002125* different hardware implementations may have different requirements.
2126*
2127* @param None
2128*
2129* @return The status of the operation
2130* @retval RETURN_OK if successful
2131* @retval RETURN_ERR if any error is detected
2132*
2133* @execution Synchronous
2134* @sideeffect None
2135*
2136* @note This function must not suspend and must not invoke any blocking system
2137* calls. It should probably just send a message to a driver event handler task.
2138*
2139*/
2140INT wifi_down()
2141{
developer96b38512023-02-22 11:17:45 +08002142 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
developerb2977562023-05-24 17:54:12 +08002143 int max_num_radios = 0;
2144 wifi_getMaxRadioNumber(&max_num_radios);
developer17038e62023-03-02 14:43:43 +08002145
developerb2977562023-05-24 17:54:12 +08002146 for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++)
2147 wifi_setRadioEnable(radioIndex, FALSE);
2148
developer72fb0bb2023-01-11 09:46:29 +08002149 return RETURN_OK;
2150}
2151
2152
2153/* wifi_createInitialConfigFiles() function */
2154/**
2155* @description This function creates wifi configuration files. The format
developer69b61b02023-03-07 17:17:44 +08002156* and content of these files are implementation dependent. This function call is
2157* used to trigger this task if necessary. Some implementations may not need this
2158* function. If an implementation does not need to create config files the function call can
developer72fb0bb2023-01-11 09:46:29 +08002159* do nothing and return RETURN_OK.
2160*
2161* @param None
2162*
2163* @return The status of the operation
2164* @retval RETURN_OK if successful
2165* @retval RETURN_ERR if any error is detected
2166*
2167* @execution Synchronous
2168* @sideeffect None
2169*
2170* @note This function must not suspend and must not invoke any blocking system
2171* calls. It should probably just send a message to a driver event handler task.
2172*
2173*/
2174INT wifi_createInitialConfigFiles()
2175{
2176 //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)
2177 return RETURN_OK;
2178}
2179
developer7e4a2a62023-04-06 19:56:03 +08002180/* outputs the country code to a max 64 character string */
developer72fb0bb2023-01-11 09:46:29 +08002181INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
2182{
developerfde01262023-05-22 15:15:24 +08002183 int ret;
developer72fb0bb2023-01-11 09:46:29 +08002184
developerfde01262023-05-22 15:15:24 +08002185 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002186
developerfde01262023-05-22 15:15:24 +08002187 ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
2188 if (ret != 0) {
2189 fprintf(stderr, "%s: wifi_BandProfileRead CountryCode failed\n", __func__);
2190 return RETURN_ERR;
2191 }
developer7e4a2a62023-04-06 19:56:03 +08002192
developerfde01262023-05-22 15:15:24 +08002193 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer7e4a2a62023-04-06 19:56:03 +08002194
developerfde01262023-05-22 15:15:24 +08002195 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002196}
2197
2198INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
2199{
developer7e4a2a62023-04-06 19:56:03 +08002200 /*Set wifi config. Wait for wifi reset to apply*/
2201 char str[MAX_BUF_SIZE] = {0};
2202 char cmd[MAX_CMD_SIZE] = {0};
2203 struct params params;
2204 char config_file[MAX_BUF_SIZE] = {0};
2205 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08002206
developer7e4a2a62023-04-06 19:56:03 +08002207 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002208
developer7e4a2a62023-04-06 19:56:03 +08002209 if(NULL == CountryCode || strlen(CountryCode) >= 32 ) {
2210 printf("%s: input para error!!!\n", __func__);
2211 return RETURN_ERR;
2212 }
developer72fb0bb2023-01-11 09:46:29 +08002213
developer7e4a2a62023-04-06 19:56:03 +08002214 if (!strlen(CountryCode))
2215 strncpy(CountryCode, "US", sizeof("US")); /*default set the code to US*/
developer72fb0bb2023-01-11 09:46:29 +08002216
developer7e4a2a62023-04-06 19:56:03 +08002217 params.name = "country_code";
2218 params.value = CountryCode;
developer72fb0bb2023-01-11 09:46:29 +08002219
developer7e4a2a62023-04-06 19:56:03 +08002220 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2221 ret = wifi_hostapdWrite(config_file, &params, 1);
2222
2223 if (ret) {
2224 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n",
2225 __func__, ret);
2226 }
2227
2228 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
2229
2230 if (ret) {
2231 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n",
2232 __func__, ret);
2233 }
2234
2235 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2236
2237 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002238}
2239
2240INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
2241{
2242 char interface_name[16] = {0};
2243 char channel_util_file[64] = {0};
2244 char cmd[128] = {0};
2245 char buf[128] = {0};
2246 char line[128] = {0};
2247 char *param = NULL, *value = NULL;
2248 int read = 0;
2249 unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
2250 unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
2251 size_t len = 0;
2252 FILE *f = NULL;
2253
2254 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2255
2256 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2257 return RETURN_ERR;
2258 snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
2259 _syscmd(cmd, buf, sizeof(buf));
2260 outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10);
2261
2262 memset(cmd, 0, sizeof(cmd));
2263 memset(buf, 0, sizeof(buf));
2264 snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
2265 if ((f = popen(cmd, "r")) == NULL) {
2266 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
2267 return RETURN_ERR;
2268 }
2269
2270 read = getline(&line, &len, f);
2271 while (read != -1) {
2272 param = strtok(line, ":\t");
2273 value = strtok(NULL, " ");
2274 if(strstr(param, "frequency") != NULL) {
2275 outputChannelStats2->ch_Frequency = strtol(value, NULL, 10);
2276 }
2277 if(strstr(param, "noise") != NULL) {
2278 outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10);
2279 outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10);
2280 }
2281 if(strstr(param, "channel active time") != NULL) {
2282 ActiveTime = strtol(value, NULL, 10);
2283 }
2284 if(strstr(param, "channel busy time") != NULL) {
2285 BusyTime = strtol(value, NULL, 10);
2286 }
2287 if(strstr(param, "channel transmit time") != NULL) {
2288 TransmitTime = strtol(value, NULL, 10);
2289 }
2290 read = getline(&line, &len, f);
2291 }
2292 pclose(f);
2293
2294 // The file should store the last active, busy and transmit time
2295 snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
2296 f = fopen(channel_util_file, "r");
2297 if (f != NULL) {
2298 read = getline(&line, &len, f);
2299 preActiveTime = strtol(line, NULL, 10);
2300 read = getline(&line, &len, f);
2301 preBusyTime = strtol(line, NULL, 10);
2302 read = getline(&line, &len, f);
2303 preTransmitTime = strtol(line, NULL, 10);
2304 fclose(f);
2305 }
2306
2307 outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
2308 outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
2309
2310 f = fopen(channel_util_file, "w");
2311 if (f != NULL) {
2312 fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime);
2313 fclose(f);
2314 }
2315 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2316 return RETURN_OK;
2317}
2318
2319/**********************************************************************************
2320 *
2321 * Wifi radio level function prototypes
2322 *
2323**********************************************************************************/
2324
2325//Get the total number of radios in this wifi subsystem
2326INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
2327{
2328 if (NULL == output)
2329 return RETURN_ERR;
2330 *output = MAX_NUM_RADIOS;
2331
2332 return RETURN_OK;
2333}
2334
developer69b61b02023-03-07 17:17:44 +08002335//Get the total number of SSID entries in this wifi subsystem
developer72fb0bb2023-01-11 09:46:29 +08002336INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
2337{
2338 if (NULL == output)
2339 return RETURN_ERR;
2340 *output = MAX_APS;
2341
2342 return RETURN_OK;
2343}
2344
2345//Get the Radio enable config parameter
2346INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
2347{
developer3a85ab82023-05-25 11:59:38 +08002348 char option[64] = {};
developer72fb0bb2023-01-11 09:46:29 +08002349 char buf[128] = {0}, cmd[128] = {0};
developer3a85ab82023-05-25 11:59:38 +08002350 int ret;
2351
2352 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002353
2354 if (NULL == output_bool)
2355 return RETURN_ERR;
2356
developer3a85ab82023-05-25 11:59:38 +08002357 snprintf(option, sizeof(option), "INDEX%d_main_ifname", 0);
2358 ret = wifi_l1ProfileRead2(option, radioIndex, buf, sizeof(buf));
2359 if ((ret != 0) || (strlen(buf) <= 0)) {
2360 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08002361 return RETURN_ERR;
developer3a85ab82023-05-25 11:59:38 +08002362 }
developer72fb0bb2023-01-11 09:46:29 +08002363
developer3a85ab82023-05-25 11:59:38 +08002364 snprintf(cmd, sizeof(cmd), "iw %s info | grep channel", buf);
2365 _syscmd(cmd, buf, sizeof(buf));
2366 if (strlen(buf) == 0) {
2367 *output_bool = 0;
2368 } else {
2369 *output_bool = 1;
2370 }
developer72fb0bb2023-01-11 09:46:29 +08002371
developer3a85ab82023-05-25 11:59:38 +08002372 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08002373 return RETURN_OK;
2374}
2375
developere82c0ca2023-05-10 16:25:35 +08002376typedef long time_t;
2377static time_t radio_up_time[MAX_NUM_RADIOS];
2378
developer72fb0bb2023-01-11 09:46:29 +08002379INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2380{
2381 char interface_name[16] = {0};
2382 char cmd[MAX_CMD_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08002383 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002384 int apIndex, ret;
developer69b61b02023-03-07 17:17:44 +08002385 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +08002386 int phyId = 0;
2387
2388 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2389
2390 phyId = radio_index_to_phy(radioIndex);
2391
2392 wifi_getMaxRadioNumber(&max_radio_num);
2393
developer8a3bbbf2023-03-15 17:47:23 +08002394 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002395
2396 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2397 return RETURN_ERR;
2398
2399 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002400 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002401 if(strncmp(buf, "OK", 2))
2402 fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002403 } else {
developere82c0ca2023-05-10 16:25:35 +08002404 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developer72fb0bb2023-01-11 09:46:29 +08002405 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2406 return RETURN_ERR;
2407
developer8a3bbbf2023-03-15 17:47:23 +08002408 memset(cmd, 0, MAX_CMD_SIZE);
2409 memset(buf, 0, MAX_BUF_SIZE);
2410
developer72fb0bb2023-01-11 09:46:29 +08002411 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2412 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002413
2414 if(*buf == '1') {
2415
2416 memset(cmd, 0, MAX_CMD_SIZE);
2417 memset(buf, 0, MAX_BUF_SIZE);
2418
developer72fb0bb2023-01-11 09:46:29 +08002419 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
2420 phyId, apIndex);
2421 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002422
developer72fb0bb2023-01-11 09:46:29 +08002423 }
2424 }
developere82c0ca2023-05-10 16:25:35 +08002425 time(&radio_up_time[radioIndex]);
developer72fb0bb2023-01-11 09:46:29 +08002426 }
2427
2428 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2429 return RETURN_OK;
2430}
2431
2432//Get the Radio enable status
2433INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2434{
2435 if (NULL == output_bool)
2436 return RETURN_ERR;
2437
2438 return wifi_getRadioEnable(radioIndex, output_bool);
2439}
2440
2441//Get the Radio Interface name from platform, eg "wlan0"
2442INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2443{
2444 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2445 return RETURN_ERR;
2446 return wifi_GetInterfaceName(radioIndex, output_string);
2447}
2448
2449//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2450//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.
2451INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2452{
2453 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2454 // For max bit rate, we should always choose the best MCS
2455 char mode[64] = {0};
2456 char channel_bandwidth_str[64] = {0};
2457 char *tmp = NULL;
2458 UINT mode_map = 0;
2459 UINT num_subcarrier = 0;
2460 UINT code_bits = 0;
2461 float code_rate = 0; // use max code rate
2462 int NSS = 0;
2463 UINT Symbol_duration = 0;
developer69b61b02023-03-07 17:17:44 +08002464 UINT GI_duration = 0;
developer72fb0bb2023-01-11 09:46:29 +08002465 wifi_band band = band_invalid;
2466 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2467 BOOL enable = FALSE;
2468 float bit_rate = 0;
developera1255e42023-05-13 17:45:02 +08002469 int ant_bitmap = 0;
developer72fb0bb2023-01-11 09:46:29 +08002470
2471 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2472 if (NULL == output_string)
2473 return RETURN_ERR;
2474
2475 wifi_getRadioEnable(radioIndex, &enable);
2476 if (enable == FALSE) {
2477 snprintf(output_string, 64, "0 Mb/s");
2478 return RETURN_OK;
2479 }
2480
2481 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
2482 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
2483 return RETURN_ERR;
2484 }
2485
2486 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
2487 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
2488 return RETURN_ERR;
2489 }
2490
2491 if (gi == wifi_guard_interval_3200)
2492 GI_duration = 32;
2493 else if (gi == wifi_guard_interval_1600)
2494 GI_duration = 16;
2495 else if (gi == wifi_guard_interval_800)
2496 GI_duration = 8;
2497 else // auto, 400
2498 GI_duration = 4;
2499
2500 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
2501 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
2502 return RETURN_ERR;
2503 }
2504
2505 if (strstr(channel_bandwidth_str, "80+80") != NULL)
2506 strcpy(channel_bandwidth_str, "160");
2507
2508 if (mode_map & WIFI_MODE_AX) {
2509 if (strstr(channel_bandwidth_str, "160") != NULL)
2510 num_subcarrier = 1960;
2511 else if (strstr(channel_bandwidth_str, "80") != NULL)
2512 num_subcarrier = 980;
2513 else if (strstr(channel_bandwidth_str, "40") != NULL)
2514 num_subcarrier = 468;
2515 else if (strstr(channel_bandwidth_str, "20") != NULL)
2516 num_subcarrier = 234;
2517 code_bits = 10;
2518 code_rate = (float)5/6;
2519 Symbol_duration = 128;
developera1255e42023-05-13 17:45:02 +08002520 GI_duration = 8;/*HE no GI 400ns*/
developer72fb0bb2023-01-11 09:46:29 +08002521 } else if (mode_map & WIFI_MODE_AC) {
2522 if (strstr(channel_bandwidth_str, "160") != NULL)
2523 num_subcarrier = 468;
2524 else if (strstr(channel_bandwidth_str, "80") != NULL)
2525 num_subcarrier = 234;
2526 else if (strstr(channel_bandwidth_str, "40") != NULL)
2527 num_subcarrier = 108;
2528 else if (strstr(channel_bandwidth_str, "20") != NULL)
2529 num_subcarrier = 52;
2530 code_bits = 8;
2531 code_rate = (float)5/6;
2532 Symbol_duration = 32;
2533 } else if (mode_map & WIFI_MODE_N) {
2534 if (strstr(channel_bandwidth_str, "160") != NULL)
2535 num_subcarrier = 468;
2536 else if (strstr(channel_bandwidth_str, "80") != NULL)
2537 num_subcarrier = 234;
2538 else if (strstr(channel_bandwidth_str, "40") != NULL)
2539 num_subcarrier = 108;
2540 else if (strstr(channel_bandwidth_str, "20") != NULL)
2541 num_subcarrier = 52;
2542 code_bits = 6;
2543 code_rate = (float)3/4;
2544 Symbol_duration = 32;
2545 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2546 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
2547 snprintf(output_string, 64, "65 Mb/s");
2548 return RETURN_OK;
2549 } else {
2550 snprintf(output_string, 64, "0 Mb/s");
2551 return RETURN_OK;
2552 }
2553
2554 // Spatial streams
developera1255e42023-05-13 17:45:02 +08002555 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +08002556 fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
2557 return RETURN_ERR;
2558 }
developera1255e42023-05-13 17:45:02 +08002559 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2560 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002561
2562 // multiple 10 is to align duration unit (0.1 us)
2563 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
2564 snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
developera1255e42023-05-13 17:45:02 +08002565 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2566 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
developer72fb0bb2023-01-11 09:46:29 +08002567 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2568
2569 return RETURN_OK;
2570}
2571#if 0
2572INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2573{
2574 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2575 char cmd[64];
2576 char buf[1024];
2577 int apIndex;
2578
developer69b61b02023-03-07 17:17:44 +08002579 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002580 return RETURN_ERR;
2581
2582 apIndex=(radioIndex==0)?0:1;
2583
2584 snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name);
2585 _syscmd(cmd,buf, sizeof(buf));
2586
2587 snprintf(output_string, 64, "%s", buf);
2588 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2589 return RETURN_OK;
2590}
2591#endif
2592
2593
2594//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2595//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.
2596INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2597{
2598 wifi_band band = band_invalid;
2599
2600 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2601 if (NULL == output_string)
2602 return RETURN_ERR;
2603
2604 band = wifi_index_to_band(radioIndex);
2605
2606 memset(output_string, 0, 10);
2607 if (band == band_2_4)
2608 strcpy(output_string, "2.4GHz");
2609 else if (band == band_5)
2610 strcpy(output_string, "5GHz");
2611 else if (band == band_6)
2612 strcpy(output_string, "6GHz");
2613 else
2614 return RETURN_ERR;
2615 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2616
2617 return RETURN_OK;
2618#if 0
2619 char buf[MAX_BUF_SIZE]={'\0'};
2620 char str[MAX_BUF_SIZE]={'\0'};
2621 char cmd[MAX_CMD_SIZE]={'\0'};
2622 char *ch=NULL;
2623 char *ch2=NULL;
2624
2625 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2626 if (NULL == output_string)
2627 return RETURN_ERR;
2628
2629
2630 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2631
2632 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2633 {
2634 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2635 return RETURN_ERR;
2636 }
2637 ch=strchr(buf,'\n');
2638 *ch='\0';
2639 ch=strchr(buf,'=');
2640 if(ch==NULL)
2641 return RETURN_ERR;
2642
2643
2644 ch++;
2645
2646 /* prepend 0 for channel with single digit. for ex, 6 would be 06 */
2647 strcpy(buf,"0");
2648 if(strlen(ch) == 1)
2649 ch=strcat(buf,ch);
2650
2651
2652 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2653
2654 if(_syscmd(cmd,str,64) == RETURN_ERR)
2655 {
2656 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2657 return RETURN_ERR;
2658 }
2659
2660
2661 ch2=strchr(str,'\n');
2662 //replace \n with \0
2663 *ch2='\0';
2664 ch2=strchr(str,'=');
2665 if(ch2==NULL)
2666 {
2667 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2668 return RETURN_ERR;
2669 }
2670 else
2671 wifi_dbg_printf("%s",ch2+1);
2672
2673
2674 ch2++;
2675
2676
2677 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch);
2678
2679 memset(buf,'\0',sizeof(buf));
2680 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2681 {
2682 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2683 return RETURN_ERR;
2684 }
2685 if (strstr(buf,"2.4") != NULL )
2686 strcpy(output_string,"2.4GHz");
2687 else if(strstr(buf,"5.") != NULL )
2688 strcpy(output_string,"5GHz");
2689 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2690
2691 return RETURN_OK;
2692#endif
2693}
2694
2695//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2696//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.
2697INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2698{
2699 wifi_band band = band_invalid;
2700 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2701 if (NULL == output_string)
2702 return RETURN_ERR;
2703 band = wifi_index_to_band(radioIndex);
2704
developer69b61b02023-03-07 17:17:44 +08002705 if (band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08002706 snprintf(output_string, 64, "2.4GHz");
2707 else if (band == band_5)
developer69b61b02023-03-07 17:17:44 +08002708 snprintf(output_string, 64, "5GHz");
developer72fb0bb2023-01-11 09:46:29 +08002709 else if (band == band_6)
2710 snprintf(output_string, 64, "6GHz");
2711
2712 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2713
2714 return RETURN_OK;
2715#if 0
2716 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2717 char buf[MAX_BUF_SIZE]={'\0'};
2718 char str[MAX_BUF_SIZE]={'\0'};
2719 char cmd[MAX_CMD_SIZE]={'\0'};
2720 char *ch=NULL;
2721 char *ch2=NULL;
2722 char ch1[5]="0";
2723
2724 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2725
2726 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2727 {
2728 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2729 return RETURN_ERR;
2730 }
2731
2732 ch=strchr(buf,'\n');
2733 *ch='\0';
2734 ch=strchr(buf,'=');
2735 if(ch==NULL)
2736 return RETURN_ERR;
2737 ch++;
2738
2739 if(strlen(ch)==1)
2740 {
2741 strcat(ch1,ch);
2742
2743 }
2744 else
2745 {
2746 strcpy(ch1,ch);
2747 }
2748
2749
2750
2751 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2752 if(_syscmd(cmd,str,64) == RETURN_ERR)
2753 {
2754 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2755 return RETURN_ERR;
2756 }
2757
2758
2759 ch2=strchr(str,'\n');
2760 //replace \n with \0
2761 *ch2='\0';
2762 ch2=strchr(str,'=');
2763 if(ch2==NULL)
2764 {
2765 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2766 return RETURN_ERR;
2767 }
2768 else
2769 wifi_dbg_printf("%s",ch2+1);
2770 ch2++;
2771
2772
2773 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1);
2774 memset(buf,'\0',sizeof(buf));
2775 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2776 {
2777 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2778 return RETURN_ERR;
2779 }
2780
2781
2782 if(strstr(buf,"2.4")!=NULL)
2783 {
2784 strcpy(output_string,"2.4GHz");
2785 }
2786 if(strstr(buf,"5.")!=NULL)
2787 {
2788 strcpy(output_string,"5GHz");
2789 }
2790 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2791 return RETURN_OK;
2792#endif
2793}
2794
2795//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2796//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.
2797INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2798{
2799 char cmd[128]={0};
2800 char buf[128]={0};
2801 char temp_output[128] = {0};
2802 wifi_band band;
2803 int phyId = 0;
2804
2805 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08002806 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002807 return RETURN_ERR;
2808
2809 band = wifi_index_to_band(radioIndex);
2810 if (band == band_2_4) {
2811 strcat(temp_output, "b,g,");
2812 } else if (band == band_5) {
2813 strcat(temp_output, "a,");
2814 }
2815 phyId = radio_index_to_phy(radioIndex);
2816 // ht capabilities
2817 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);
2818 _syscmd(cmd, buf, sizeof(buf));
2819 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
2820 strcat(temp_output, "n,");
2821 }
2822
2823 // vht capabilities
2824 if (band == band_5) {
2825 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2826 _syscmd(cmd, buf, sizeof(buf));
2827 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
2828 strcat(temp_output, "ac,");
2829 }
2830 }
2831
2832 // he capabilities
2833 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);
2834 _syscmd(cmd, buf, sizeof(buf));
2835 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2836 strcat(temp_output, "ax,");
2837 }
2838
developere82c0ca2023-05-10 16:25:35 +08002839 // eht capabilities
2840 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);
2841 _syscmd(cmd, buf, sizeof(buf));
2842 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2843 strcat(temp_output, "be,");
2844 }
2845
developer72fb0bb2023-01-11 09:46:29 +08002846 // Remove the last comma
2847 if (strlen(temp_output) != 0)
2848 temp_output[strlen(temp_output)-1] = '\0';
2849 strncpy(output_string, temp_output, strlen(temp_output));
2850 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2851 return RETURN_OK;
2852}
2853
2854//Get the radio operating mode, and pure mode flag. eg: "ac"
2855//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.
2856INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
2857{
2858 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2859 if (NULL == output_string)
2860 return RETURN_ERR;
2861
2862 if (radioIndex == 0) {
2863 snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
2864 *gOnly = FALSE;
2865 *nOnly = TRUE;
2866 *acOnly = FALSE;
2867 } else {
2868 snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
2869 *gOnly = FALSE;
2870 *nOnly = FALSE;
2871 *acOnly = FALSE;
2872 }
2873 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2874
2875 return RETURN_OK;
2876#if 0
2877 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2878 char buf[64] = {0};
2879 char config_file[MAX_BUF_SIZE] = {0};
2880
developer69b61b02023-03-07 17:17:44 +08002881 if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly))
developer72fb0bb2023-01-11 09:46:29 +08002882 return RETURN_ERR;
2883
2884 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2885 wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf));
2886
2887 wifi_dbg_printf("\nhw_mode=%s\n",buf);
developer69b61b02023-03-07 17:17:44 +08002888 if (strlen(buf) == 0)
developer72fb0bb2023-01-11 09:46:29 +08002889 {
2890 wifi_dbg_printf("\nwifi_hostapdRead returned none\n");
2891 return RETURN_ERR;
2892 }
2893 if(strcmp(buf,"g")==0)
2894 {
2895 wifi_dbg_printf("\nG\n");
2896 *gOnly=TRUE;
2897 *nOnly=FALSE;
2898 *acOnly=FALSE;
2899 }
2900 else if(strcmp(buf,"n")==0)
2901 {
2902 wifi_dbg_printf("\nN\n");
2903 *gOnly=FALSE;
2904 *nOnly=TRUE;
2905 *acOnly=FALSE;
2906 }
2907 else if(strcmp(buf,"ac")==0)
2908 {
2909 wifi_dbg_printf("\nac\n");
2910 *gOnly=FALSE;
2911 *nOnly=FALSE;
2912 *acOnly=TRUE;
2913 }
2914 /* hostapd-5G.conf has "a" as hw_mode */
2915 else if(strcmp(buf,"a")==0)
2916 {
2917 wifi_dbg_printf("\na\n");
2918 *gOnly=FALSE;
2919 *nOnly=FALSE;
2920 *acOnly=FALSE;
2921 }
2922 else
2923 wifi_dbg_printf("\nInvalid Mode %s\n", buf);
2924
2925 //for a,n mode
2926 if(radioIndex == 1)
2927 {
2928 wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf));
2929 if(strcmp(buf,"1")==0)
2930 {
2931 strncpy(output_string, "n", 1);
2932 *nOnly=FALSE;
2933 }
2934 }
2935
2936 wifi_dbg_printf("\nReturning from getRadioStandard\n");
2937 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2938 return RETURN_OK;
2939#endif
2940}
2941
developer0f10c772023-05-16 21:43:39 +08002942enum WIFI_MODE {
2943 WMODE_INVALID = 0,
2944 WMODE_A = 1 << 0,
2945 WMODE_B = 1 << 1,
2946 WMODE_G = 1 << 2,
2947 WMODE_GN = 1 << 3,
2948 WMODE_AN = 1 << 4,
2949 WMODE_AC = 1 << 5,
2950 WMODE_AX_24G = 1 << 6,
2951 WMODE_AX_5G = 1 << 7,
2952 WMODE_AX_6G = 1 << 8,
2953 WMODE_BE_24G = 1 << 9,
2954 WMODE_BE_5G = 1 << 10,
2955 WMODE_BE_6G = 1 << 11,
2956 /*
2957 * total types of supported wireless mode,
2958 * add this value once yow add new type
2959 */
2960 WMODE_COMP = 12,
2961};
2962
2963#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08002964
2965int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08002966{
developerfead3972023-05-25 20:15:02 +08002967 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2968 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
2969 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2970 unsigned int *phymode;
2971 int err = 0;
2972 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08002973
developerfead3972023-05-25 20:15:02 +08002974 if (!msg || !cb_data) {
2975 wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data);
2976 return NL_SKIP;
2977 }
developer72fb0bb2023-01-11 09:46:29 +08002978
developerfead3972023-05-25 20:15:02 +08002979 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2980 genlmsg_attrlen(gnlh, 0), NULL);
2981 if (err < 0) {
2982 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
2983 return NL_SKIP;
2984 }
developer0f10c772023-05-16 21:43:39 +08002985
developerfead3972023-05-25 20:15:02 +08002986 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2987 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
2988 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2989 if (err < 0)
2990 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08002991
developerfead3972023-05-25 20:15:02 +08002992 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
2993 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
2994
2995 memset(cb_data->out_buf, 0, cb_data->out_len);
2996 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
2997 }
2998 } else
2999 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
3000
3001 return NL_OK;
3002}
developer0f10c772023-05-16 21:43:39 +08003003
developerfead3972023-05-25 20:15:02 +08003004void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
3005{
3006 wifi_band band;
3007 unsigned char radio_mode_tem_len;
3008
3009 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08003010 // puremode is a bit map
developer72fb0bb2023-01-11 09:46:29 +08003011 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08003012 memset(output_string, 0, RADIO_MODE_LEN);
3013
3014 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3015
3016 switch (band) {
3017 case band_2_4:
3018 if (phymode & WMODE_B) {
3019 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
3020 *pureMode |= WIFI_MODE_B;
3021 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3022 }
3023 if (phymode & WMODE_G) {
3024 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
3025 *pureMode |= WIFI_MODE_G;
3026 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3027 }
3028 if (phymode & WMODE_GN) {
3029 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3030 *pureMode |= WIFI_MODE_N;
3031 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3032 }
3033 if (phymode & WMODE_AX_24G) {
3034 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3035 *pureMode |= WIFI_MODE_AX;
3036 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3037 }
3038 if (phymode & WMODE_BE_24G) {
3039 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3040 *pureMode |= WIFI_MODE_BE;
3041 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3042 }
3043 break;
3044 case band_5:
3045 if (phymode & WMODE_A) {
3046 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
3047 *pureMode |= WIFI_MODE_A;
3048 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3049 }
3050 if (phymode & WMODE_AN) {
3051 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3052 *pureMode |= WIFI_MODE_N;
3053 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3054 }
3055 if (phymode & WMODE_AC) {
3056 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
3057 *pureMode |= WIFI_MODE_AC;
3058 }
3059 if (phymode & WMODE_AX_5G) {
3060 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3061 *pureMode |= WIFI_MODE_AX;
3062 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3063 }
3064 if (phymode & WMODE_BE_5G) {
3065 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3066 *pureMode |= WIFI_MODE_BE;
3067 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3068 }
3069 break;
3070 case band_6:
3071 if (phymode & WMODE_AX_6G) {
3072 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3073 *pureMode |= WIFI_MODE_AX;
3074 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3075 }
3076 if (phymode & WMODE_BE_6G) {
3077 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3078 *pureMode |= WIFI_MODE_BE;
3079 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3080 }
3081 break;
3082 default:
3083 fprintf(stderr, "%s band_idx invalid\n", __func__);
3084 break;
3085 }
3086
3087 /* Remove the last comma */
3088 if (strlen(output_string) != 0)
3089 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08003090
developerfead3972023-05-25 20:15:02 +08003091}
3092
3093INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
3094{
3095 unsigned int phymode;
3096 char interface_name[IF_NAME_SIZE] = {0};
3097 struct mtk_nl80211_param params;
3098 int ret = -1;
3099 unsigned int if_idx = 0;
3100 struct unl unl_ins;
3101 struct nl_msg *msg = NULL;
3102 struct nlattr * msg_data = NULL;
3103 struct mtk_nl80211_param param;
3104 struct mtk_nl80211_cb_data cb_data;
3105
3106 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3107 if(NULL == output_string || NULL == pureMode)
3108 return RETURN_ERR;
3109
3110 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3111 return RETURN_ERR;
3112
3113 if_idx = if_nametoindex(interface_name);
3114 if (!if_idx) {
3115 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
3116 return RETURN_ERR;
3117 }
3118 /*init mtk nl80211 vendor cmd*/
3119 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
3120 param.if_type = NL80211_ATTR_IFINDEX;
3121 param.if_idx = if_idx;
3122
3123 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3124 if (ret) {
3125 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3126 return RETURN_ERR;
3127 }
3128
3129 /*add mtk vendor cmd data*/
3130 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
3131 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
3132 nlmsg_free(msg);
3133 goto err;
3134 }
3135
3136 /*send mtk nl80211 vendor msg*/
3137 cb_data.out_buf = (char *)&phymode;
3138 cb_data.out_len = sizeof(unsigned int);
3139
3140 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
3141
3142 if (ret) {
3143 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3144 goto err;
3145 }
3146 /*deinit mtk nl80211 vendor msg*/
3147 mtk_nl80211_deint(&unl_ins);
3148
3149 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
3150 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
3151
developer72fb0bb2023-01-11 09:46:29 +08003152 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3153 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003154err:
3155 mtk_nl80211_deint(&unl_ins);
3156 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
3157 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003158}
3159
3160// Set the radio operating mode, and pure mode flag.
3161INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
3162{
developer69b61b02023-03-07 17:17:44 +08003163 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003164 if (strcmp (channelMode,"11A") == 0)
3165 {
3166 writeBandWidth(radioIndex,"20MHz");
3167 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3168 printf("\nChannel Mode is 802.11a (5GHz)\n");
3169 }
3170 else if (strcmp (channelMode,"11NAHT20") == 0)
3171 {
3172 writeBandWidth(radioIndex,"20MHz");
3173 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3174 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
3175 }
3176 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
3177 {
3178 writeBandWidth(radioIndex,"40MHz");
3179 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3180 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3181 }
3182 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
3183 {
3184 writeBandWidth(radioIndex,"40MHz");
3185 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3186 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3187 }
3188 else if (strcmp (channelMode,"11ACVHT20") == 0)
3189 {
3190 writeBandWidth(radioIndex,"20MHz");
3191 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3192 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
3193 }
3194 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
3195 {
3196 writeBandWidth(radioIndex,"40MHz");
3197 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3198 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3199 }
3200 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
3201 {
3202 writeBandWidth(radioIndex,"40MHz");
3203 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3204 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3205 }
3206 else if (strcmp (channelMode,"11ACVHT80") == 0)
3207 {
3208 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
3209 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
3210 }
3211 else if (strcmp (channelMode,"11ACVHT160") == 0)
3212 {
3213 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
3214 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
developer69b61b02023-03-07 17:17:44 +08003215 }
developer72fb0bb2023-01-11 09:46:29 +08003216 else if (strcmp (channelMode,"11B") == 0)
3217 {
3218 writeBandWidth(radioIndex,"20MHz");
3219 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3220 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
3221 }
3222 else if (strcmp (channelMode,"11G") == 0)
3223 {
3224 writeBandWidth(radioIndex,"20MHz");
3225 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3226 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
3227 }
3228 else if (strcmp (channelMode,"11NGHT20") == 0)
3229 {
3230 writeBandWidth(radioIndex,"20MHz");
3231 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3232 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3233 }
3234 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3235 {
3236 writeBandWidth(radioIndex,"40MHz");
3237 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3238 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3239 }
3240 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3241 {
3242 writeBandWidth(radioIndex,"40MHz");
3243 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3244 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3245 }
developer69b61b02023-03-07 17:17:44 +08003246 else
developer72fb0bb2023-01-11 09:46:29 +08003247 {
3248 return RETURN_ERR;
3249 }
3250 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3251
3252 return RETURN_OK;
3253}
3254
developer0f10c772023-05-16 21:43:39 +08003255typedef enum _RT_802_11_PHY_MODE {
3256 PHY_11BG_MIXED = 0,
3257 PHY_11B = 1,
3258 PHY_11A = 2,
3259 PHY_11ABG_MIXED = 3,
3260 PHY_11G = 4,
3261 PHY_11ABGN_MIXED = 5, /* both band 5 */
3262 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3263 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3264 PHY_11AN_MIXED = 8, /* 5G band 8 */
3265 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3266 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3267 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
3268 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3269 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3270 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3271 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3272 PHY_11AX_24G = 16,
3273 PHY_11AX_5G = 17,
3274 PHY_11AX_6G = 18,
3275 PHY_11AX_24G_6G = 19,
3276 PHY_11AX_5G_6G = 20,
3277 PHY_11AX_24G_5G_6G = 21,
3278 PHY_11BE_24G = 22,
3279 PHY_11BE_5G = 23,
3280 PHY_11BE_6G = 24,
3281 PHY_11BE_24G_6G = 25,
3282 PHY_11BE_5G_6G = 26,
3283 PHY_11BE_24G_5G_6G = 27,
3284 PHY_MODE_MAX,
3285} RT_802_11_PHY_MODE;
3286
3287unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3288{
3289 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003290 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003291
3292 band_idx = radio_index_to_band(radioIndex);
3293
3294 switch (band_idx) {
3295 case band_2_4:
3296 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3297 wireless_mode = PHY_11GN_MIXED;
3298 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3299 wireless_mode = PHY_11BGN_MIXED;
3300 if (pureMode & WIFI_MODE_AX)
3301 wireless_mode = PHY_11AX_24G;
3302 if (pureMode & WIFI_MODE_BE)
3303 wireless_mode = PHY_11BE_24G;
3304 break;
3305 case band_5:
3306 if (pureMode == WIFI_MODE_N)
3307 wireless_mode = PHY_11N_5G;
3308 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3309 wireless_mode = PHY_11VHT_N_MIXED;
3310 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3311 wireless_mode = PHY_11VHT_N_A_MIXED;
3312 if (pureMode & WIFI_MODE_AX)
3313 wireless_mode = PHY_11AX_5G;
3314 if (pureMode & WIFI_MODE_BE)
3315 wireless_mode = PHY_11BE_5G;
3316 break;
3317 case band_6:
3318 if (pureMode & WIFI_MODE_AX)
3319 wireless_mode = PHY_11AX_6G;
3320 if (pureMode & WIFI_MODE_BE)
3321 wireless_mode = PHY_11BE_6G;
3322 break;
3323 default:
3324 fprintf(stderr, "%s band_idx invalid\n", __func__);
3325 break;
3326 }
3327
3328 return wireless_mode;
3329}
3330
developer72fb0bb2023-01-11 09:46:29 +08003331// Set the radio operating mode, and pure mode flag.
3332INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3333{
developerfead3972023-05-25 20:15:02 +08003334 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003335
developer0f10c772023-05-16 21:43:39 +08003336 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003337 int ret = -1;
3338 unsigned int if_idx = 0;
3339 struct unl unl_ins;
3340 struct nl_msg *msg = NULL;
3341 struct nlattr * msg_data = NULL;
3342 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003343
developer0f10c772023-05-16 21:43:39 +08003344 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003345
developer0f10c772023-05-16 21:43:39 +08003346 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003347
developer0f10c772023-05-16 21:43:39 +08003348 if (wireless_mode == PHY_MODE_MAX) {
3349 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3350 return RETURN_ERR;
3351 }
developer72fb0bb2023-01-11 09:46:29 +08003352
developer0f10c772023-05-16 21:43:39 +08003353 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3354 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003355
3356 if_idx = if_nametoindex(interface_name);
3357 if (!if_idx) {
3358 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3359 return RETURN_ERR;
3360 }
3361 /*init mtk nl80211 vendor cmd*/
3362 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3363 param.if_type = NL80211_ATTR_IFINDEX;
3364 param.if_idx = if_idx;
3365
3366 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3367 if (ret) {
3368 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3369 return RETURN_ERR;
3370 }
3371
3372 /*add mtk vendor cmd data*/
3373 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3374 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3375 nlmsg_free(msg);
3376 goto err;
3377 }
3378 /*send mtk nl80211 vendor msg*/
3379 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3380 if (ret) {
3381 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3382 goto err;
3383 }
3384 /*deinit mtk nl80211 vendor msg*/
3385 mtk_nl80211_deint(&unl_ins);
3386 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003387
developer0f10c772023-05-16 21:43:39 +08003388 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3389
3390 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003391err:
3392 mtk_nl80211_deint(&unl_ins);
3393 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3394 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003395}
3396
3397INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3398{
developerfead3972023-05-25 20:15:02 +08003399 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003400 char interface_name[IF_NAME_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003401 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003402 char dat_file[MAX_BUF_SIZE] = {0};
3403 struct params params={0};
3404
3405 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3406
3407 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3408
3409 if (wireless_mode == PHY_MODE_MAX) {
3410 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3411 return RETURN_ERR;
3412 }
3413
3414 params.name = "WirelessMode";
3415 snprintf(buf, sizeof(buf), "%d", wireless_mode);
3416 params.value = buf;
3417
3418 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3419 wifi_datfileWrite(dat_file, &params, 1);
3420
developer72fb0bb2023-01-11 09:46:29 +08003421 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3422
3423 return RETURN_OK;
3424}
3425
3426INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3427
3428 char config_file[64] = {0};
3429 char buf[64] = {0};
3430 struct params params = {0};
3431 wifi_band band = band_invalid;
3432
3433 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3434
3435 band = wifi_index_to_band(radioIndex);
3436
3437 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3438 return RETURN_ERR;
3439 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3440 return RETURN_ERR;
3441 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3442 return RETURN_ERR;
3443
3444 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3445 params.name = "hw_mode";
3446 params.value = hw_mode;
3447 wifi_hostapdWrite(config_file, &params, 1);
3448 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3449
3450 if (band == band_2_4) {
3451 if (strncmp(hw_mode, "b", 1) == 0) {
3452 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
3453 snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3454 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3455 snprintf(buf, sizeof(buf), "%s", "1,2");
3456 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3457 } else {
3458 // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
3459
3460 snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3461 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3462 snprintf(buf, sizeof(buf), "%s", "6,12,24");
3463 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3464 }
3465 }
3466
3467 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3468 return RETURN_OK;
3469}
3470
3471INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3472{
3473 char config_file[64] = {0};
3474 struct params params = {0};
3475 wifi_band band = band_invalid;
3476
3477 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3478
3479 band = wifi_index_to_band(radioIndex);
3480 if (band != band_2_4)
3481 return RETURN_OK;
3482
3483 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3484 params.name = "noscan";
3485 params.value = noscan;
3486 wifi_hostapdWrite(config_file, &params, 1);
3487 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3488
3489 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3490 return RETURN_OK;
3491}
3492
3493//Get the list of supported channel. eg: "1-11"
3494//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.
3495INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3496{
3497 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08003498 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08003499 return RETURN_ERR;
3500 char cmd[256] = {0};
3501 char buf[128] = {0};
3502 BOOL dfs_enable = false;
3503 int phyId = 0;
3504
3505 // Parse possible channel number and separate them with commas.
3506 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3507 phyId = radio_index_to_phy(radioIndex);
3508 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3509 if (dfs_enable)
3510 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 +08003511 else
developer72fb0bb2023-01-11 09:46:29 +08003512 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);
3513
3514 _syscmd(cmd,buf,sizeof(buf));
3515 strncpy(output_string, buf, sizeof(buf));
3516
3517 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3518 return RETURN_OK;
3519}
developerd1824452023-05-18 12:30:04 +08003520//Getting current radio extension channel
3521INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3522{
3523 CHAR buf[150] = {0};
3524 CHAR cmd[150] = {0};
3525
3526 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer262f4cb2023-05-24 12:22:04 +08003527 if (strncmp(buf, "Below", 5) == 0) //below
developerd1824452023-05-18 12:30:04 +08003528 strcpy(Value,"BelowControlChannel");
developer262f4cb2023-05-24 12:22:04 +08003529 if(strncmp(buf, "Above", 5) == 0) //above
developerd1824452023-05-18 12:30:04 +08003530 strcpy(Value,"AboveControlChannel");
3531 return RETURN_OK;
3532}
developerf6a87542023-05-16 15:47:28 +08003533
developer72fb0bb2023-01-11 09:46:29 +08003534//Get the list for used channel. eg: "1,6,9,11"
3535//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.
3536INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3537{
3538 char interface_name[16] = {0};
3539 char cmd[128] = {0};
3540 char buf[128] = {0};
3541 char config_file[64] = {0};
3542 int channel = 0;
3543 int freq = 0;
3544 int bandwidth = 0;
3545 int center_freq = 0;
3546 int center_channel = 0;
3547 int channel_delta = 0;
3548 wifi_band band = band_invalid;
3549
3550 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3551
3552 if (NULL == output_string)
3553 return RETURN_ERR;
3554
3555 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3556 return RETURN_ERR;
3557 sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3558 _syscmd(cmd, buf, sizeof(buf));
3559 if (strlen(buf) == 0) {
3560 fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__);
3561 return RETURN_ERR;
3562 }
3563 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
3564
3565 if (bandwidth == 20) {
3566 snprintf(output_string, 256, "%d", channel);
3567 return RETURN_OK;
3568 }
3569
3570 center_channel = ieee80211_frequency_to_channel(center_freq);
3571
3572 band = wifi_index_to_band(radioIndex);
3573 if (band == band_2_4 && bandwidth == 40) {
developerd1824452023-05-18 12:30:04 +08003574 sprintf(config_file, "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08003575 memset(buf, 0, sizeof(buf));
3576 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
3577
3578 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
3579 snprintf(output_string, 256, "%d,%d", channel, channel+4);
3580 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
3581 snprintf(output_string, 256, "%d,%d", channel-4, channel);
3582 } else {
3583 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
3584 return RETURN_ERR;
3585 }
3586 } else if (band == band_5 || band == band_6){
3587 // 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 +08003588 // 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 +08003589 channel_delta = (bandwidth-20)/10;
developerd1824452023-05-18 12:30:04 +08003590 memset(output_string, 0, 256);
3591 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3592 // If i is not the last channel, we add a comma.
3593 snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
3594 strncat(output_string, buf, strlen(buf));
3595 }
developer72fb0bb2023-01-11 09:46:29 +08003596 } else
3597 return RETURN_ERR;
3598
3599 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3600 return RETURN_OK;
3601}
3602
developer69b61b02023-03-07 17:17:44 +08003603//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003604INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003605{
3606 char channel_str[16] = {0};
3607 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +08003608 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003609
3610 if (output_ulong == NULL)
3611 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003612 band = wifi_index_to_band(radioIndex);
3613 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3614 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
developer72fb0bb2023-01-11 09:46:29 +08003615
3616 *output_ulong = strtoul(channel_str, NULL, 10);
3617
3618 return RETURN_OK;
3619}
3620
3621
3622INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
3623{
3624 char cmd[1024] = {0}, buf[5] = {0};
3625 char interface_name[16] = {0};
3626
3627 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3628 if (NULL == output_ulong)
3629 return RETURN_ERR;
3630
3631 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name);
3632 if (wifi_getApName(apIndex,interface_name) != RETURN_OK)
3633 return RETURN_ERR;
3634 _syscmd(cmd,buf,sizeof(buf));
3635 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
3636 if (*output_ulong == 0) {
3637 return RETURN_ERR;
3638 }
3639
3640 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3641 return RETURN_OK;
3642}
3643
3644//Storing the previous channel value
3645INT wifi_storeprevchanval(INT radioIndex)
3646{
3647 char buf[256] = {0};
3648 char output[4]={'\0'};
3649 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08003650 wifi_band band = band_invalid;
3651
3652 band = wifi_index_to_band(radioIndex);
3653 if (band == band_invalid) {
3654 return RETURN_ERR;
3655 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
3656 }
3657 snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
3658 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
3659
3660 if(band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08003661 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003662 else if(band == band_5)
developer72fb0bb2023-01-11 09:46:29 +08003663 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003664 else
3665 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
developer72fb0bb2023-01-11 09:46:29 +08003666 system(buf);
3667 Radio_flag = FALSE;
3668 return RETURN_OK;
3669}
3670
3671//Set the running channel number
3672INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
3673{
3674 // We only write hostapd config here
3675 char str_channel[8]={0};
3676 char *list_channel;
3677 char config_file[128] = {0};
3678 char possible_channels[256] = {0};
developerd1824452023-05-18 12:30:04 +08003679 char config_file_dat[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003680 int max_radio_num = 0;
3681 struct params list = {0};
developerd1824452023-05-18 12:30:04 +08003682 struct params dat = {0};
3683 struct params acs = {0};
3684 wifi_band band = band_invalid;
3685 bool acs_channel = false;
developer72fb0bb2023-01-11 09:46:29 +08003686
3687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3688
developerd1824452023-05-18 12:30:04 +08003689 if (channel == 0)
3690 acs_channel = true;
developer72fb0bb2023-01-11 09:46:29 +08003691 // Check valid
3692 sprintf(str_channel, "%lu", channel);
3693
developerd1824452023-05-18 12:30:04 +08003694
developer72fb0bb2023-01-11 09:46:29 +08003695 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
3696 list_channel = strtok(possible_channels, ",");
3697 while(true)
3698 {
3699 if(list_channel == NULL) { // input not in the list
3700 fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel);
3701 return RETURN_ERR;
3702 }
3703 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
3704 break;
3705 list_channel = strtok(NULL, ",");
3706 }
developerd1824452023-05-18 12:30:04 +08003707 /*
developer72fb0bb2023-01-11 09:46:29 +08003708 list.name = "channel";
3709 list.value = str_channel;
3710 wifi_getMaxRadioNumber(&max_radio_num);
3711 for(int i=0; i<=MAX_APS/max_radio_num;i++)
3712 {
3713 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3714 wifi_hostapdWrite(config_file, &list, 1);
3715 }
developerd1824452023-05-18 12:30:04 +08003716 */
3717 dat.name = "Channel";
3718 dat.value = str_channel;
3719 band = wifi_index_to_band(radioIndex);
3720 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3721 wifi_datfileWrite(config_file_dat, &dat, 1);
3722 if (acs_channel == true) {
3723 acs.name = "AutoChannelSelect";
3724 acs.value = "3";
3725 } else {
3726 acs.name = "AutoChannelSelect";
3727 acs.value = "0";
3728 }
3729 wifi_datfileWrite(config_file_dat, &acs, 1);
developerc0772e62023-05-18 15:10:48 +08003730 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003731 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3732 return RETURN_OK;
3733}
3734
3735INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
3736{
3737 struct params list[2];
3738 char str_idx[16];
3739 char config_file[64];
3740 int max_num_radios = 0;
3741 wifi_band band = band_invalid;
3742
3743 band = wifi_index_to_band(radioIndex);
3744 if (band == band_2_4)
3745 return RETURN_OK;
3746
3747 snprintf(str_idx, sizeof(str_idx), "%lu", channel);
3748 list[0].name = "vht_oper_centr_freq_seg0_idx";
3749 list[0].value = str_idx;
3750 list[1].name = "he_oper_centr_freq_seg0_idx";
3751 list[1].value = str_idx;
3752
3753 wifi_getMaxRadioNumber(&max_num_radios);
3754 for(int i=0; i<=MAX_APS/max_num_radios; i++)
3755 {
3756 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
3757 if (band == band_6)
3758 wifi_hostapdWrite(config_file, &list[1], 1);
3759 else
3760 wifi_hostapdWrite(config_file, list, 2);
3761 }
3762
3763 return RETURN_OK;
3764}
3765
3766//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
3767//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
3768INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
3769{
3770 //Set to wifi config only. Wait for wifi reset to apply.
3771 char buf[256] = {0};
3772 char str_channel[256] = {0};
3773 int count = 0;
3774 ULONG Value = 0;
3775 FILE *fp = NULL;
3776 if(enable == TRUE)
3777 {
3778 wifi_setRadioChannel(radioIndex,Value);
3779 }
3780 return RETURN_OK;
3781}
3782
3783INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
3784{
3785 if (output_bool == NULL)
3786 return RETURN_ERR;
3787
3788 *output_bool = TRUE;
3789
3790 return RETURN_OK;
3791}
3792
3793INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
3794{
developer69b61b02023-03-07 17:17:44 +08003795 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003796 return RETURN_ERR;
3797 *output_bool=FALSE;
3798 return RETURN_OK;
3799}
3800
3801INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
3802{
developer69b61b02023-03-07 17:17:44 +08003803 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003804 return RETURN_ERR;
3805 *output_bool=FALSE;
3806 return RETURN_OK;
3807}
3808
3809INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
3810{
3811 //Set to wifi config only. Wait for wifi reset to apply.
3812 return RETURN_OK;
3813}
3814
3815INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
3816{
3817 return RETURN_OK;
3818}
3819
3820INT wifi_factoryResetAP(int apIndex)
3821{
developer47cc27a2023-05-17 23:09:58 +08003822 char ap_config_file[MAX_CMD_SIZE] = {0};
3823 char cmd[MAX_CMD_SIZE] = {0};
3824 char ret_buf[MAX_BUF_SIZE] = {0};
3825 int radio_idx = 0;
3826 int bss_idx = 0;
3827 char ssid[32] = {0};
3828 char interface[IF_NAME_SIZE] = {0};
3829 char psk_file[MAX_CMD_SIZE] = {0};
3830 struct params params[3] = {0};
3831 char *band_str[3] = {"2G", "5G", "6G"};
developer72fb0bb2023-01-11 09:46:29 +08003832
3833 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3834
developer47cc27a2023-05-17 23:09:58 +08003835 /*del old config file*/
3836 snprintf(ap_config_file, MAX_CMD_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
3837 snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
3838 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003839
developer47cc27a2023-05-17 23:09:58 +08003840 memset(cmd, 0, sizeof(cmd));
3841 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003842
developer47cc27a2023-05-17 23:09:58 +08003843 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
3844
3845 /*prepare new config file*/
developere740c2a2023-05-23 18:34:32 +08003846 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
developer47cc27a2023-05-17 23:09:58 +08003847 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3848
3849 if (radio_idx == band_2_4) {
3850 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
3851 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
3852 } else if (radio_idx == band_5) {
3853 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
3854 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
3855 } else if (radio_idx == band_6) {
3856 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
3857 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
3858 }
3859
3860 /* fix wpa_psk_file path */
3861 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
3862
3863 params[0].name = "ssid";
3864 params[0].value = ssid;
3865 params[1].name = "interface";
3866 params[1].value = interface;
3867 params[2].name = "wpa_psk_file";
3868 params[2].value = psk_file;
3869
3870 wifi_hostapdWrite(ap_config_file, params, 3);
3871
3872 /*clear psk file*/
3873 memset(cmd, 0, sizeof(cmd));
3874 memset(ret_buf, 0, sizeof(ret_buf));
3875
3876 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
3877
3878 if (access(psk_file, F_OK) != 0) {
3879 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
3880 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3881 } else {
3882 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
3883 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3884 }
3885
3886 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3887
3888 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003889}
3890
3891//To set Band Steering AP group
3892//To-do
3893INT wifi_setBandSteeringApGroup(char *ApGroup)
3894{
3895 return RETURN_OK;
3896}
3897
3898INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
3899{
3900 char config_file[128] = {'\0'};
3901 char buf[128] = {'\0'};
3902
3903 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3904 if (dtimInterval == NULL)
3905 return RETURN_ERR;
3906
3907 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer885b56c2023-05-22 15:02:46 +08003908 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003909
3910 if (strlen(buf) == 0) {
3911 *dtimInterval = 2;
3912 } else {
3913 *dtimInterval = strtoul(buf, NULL, 10);
3914 }
3915
3916 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3917 return RETURN_OK;
3918}
3919
3920INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
3921{
3922 struct params params={0};
3923 char config_file[MAX_BUF_SIZE] = {'\0'};
3924 char buf[MAX_BUF_SIZE] = {'\0'};
3925
3926 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3927 if (dtimInterval < 1 || dtimInterval > 255) {
3928 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
3929 return RETURN_ERR;
3930 }
developer69b61b02023-03-07 17:17:44 +08003931
developer72fb0bb2023-01-11 09:46:29 +08003932 params.name = "dtim_period";
3933 snprintf(buf, sizeof(buf), "%d", dtimInterval);
3934 params.value = buf;
3935
3936 sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex);
3937 wifi_hostapdWrite(config_file, &params, 1);
3938 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3939
3940 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3941 return RETURN_OK;
3942}
3943
3944//Check if the driver support the Dfs
3945INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
3946{
3947 wifi_band band = band_invalid;
developer69b61b02023-03-07 17:17:44 +08003948 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003949 return RETURN_ERR;
3950 *output_bool=FALSE;
3951
3952 band = wifi_index_to_band(radioIndex);
3953 if (band == band_5)
3954 *output_bool = TRUE;
3955 return RETURN_OK;
3956}
3957
3958//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.
3959//The value of this parameter is a comma seperated list of channel number
3960INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
3961{
developer69b61b02023-03-07 17:17:44 +08003962 if (NULL == output_pool)
developer72fb0bb2023-01-11 09:46:29 +08003963 return RETURN_ERR;
3964 if (radioIndex==1)
developer69b61b02023-03-07 17:17:44 +08003965 return RETURN_OK;//TODO need to handle for 5GHz band, i think
developer72fb0bb2023-01-11 09:46:29 +08003966 snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
3967
3968 return RETURN_OK;
3969}
3970
3971INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
3972{
3973 //Set to wifi config. And apply instantly.
3974 return RETURN_OK;
3975}
3976
3977INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
3978{
developer69b61b02023-03-07 17:17:44 +08003979 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
developer72fb0bb2023-01-11 09:46:29 +08003980 return RETURN_ERR;
3981 *output_interval_seconds=1800;
3982 *output_dwell_milliseconds=40;
3983
3984 return RETURN_OK;
3985}
3986
3987INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
3988{
3989 //Set to wifi config. And apply instantly.
3990 return RETURN_OK;
3991}
3992
3993INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
3994{
3995 if (output_bool == NULL)
3996 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08003997 *output_bool = true;
3998 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003999}
4000
4001INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
4002{
4003 return RETURN_OK;
4004}
4005
4006//Get the Dfs enable status
4007INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
4008{
4009 char buf[16] = {0};
4010 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08004011 char config_file_dat[128] = {0};
developerd1824452023-05-18 12:30:04 +08004012 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004013
4014 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4015
4016 if (output_bool == NULL)
4017 return RETURN_ERR;
developerf6a87542023-05-16 15:47:28 +08004018 *output_bool = TRUE; // default
developerd1824452023-05-18 12:30:04 +08004019 band = wifi_index_to_band(radioIndex);
4020 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4021
developer262f4cb2023-05-24 12:22:04 +08004022 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08004023
4024 if (strncmp(buf, "0", 1) == 0)
4025 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08004026 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4027 return RETURN_OK;
4028}
4029
4030//Set the Dfs enable status
4031INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
4032{
4033 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +08004034 char config_dat_file[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004035 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08004036 struct params dat = {0};
4037 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004038
4039 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4040
4041 f = fopen(DFS_ENABLE_FILE, "w");
4042 if (f == NULL)
4043 return RETURN_ERR;
4044 fprintf(f, "%d", enable);
4045 fclose(f);
4046
developer72fb0bb2023-01-11 09:46:29 +08004047 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
4048
developerd1824452023-05-18 12:30:04 +08004049 dat.name = "DfsEnable";
developer262f4cb2023-05-24 12:22:04 +08004050 dat.value = enable?"1":"0";
developerd1824452023-05-18 12:30:04 +08004051 band = wifi_index_to_band(radioIndex);
4052 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4053 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08004054 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4055 return RETURN_OK;
4056}
4057
4058//Check if the driver support the AutoChannelRefreshPeriod
4059INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
4060{
developer69b61b02023-03-07 17:17:44 +08004061 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08004062 return RETURN_ERR;
4063 *output_bool=FALSE; //not support
4064
4065 return RETURN_OK;
4066}
4067
4068//Get the ACS refresh period in seconds
4069INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
4070{
developer69b61b02023-03-07 17:17:44 +08004071 if (NULL == output_ulong)
developer72fb0bb2023-01-11 09:46:29 +08004072 return RETURN_ERR;
4073 *output_ulong=300;
4074
4075 return RETURN_OK;
4076}
4077
4078//Set the ACS refresh period in seconds
4079INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
4080{
4081 return RETURN_ERR;
4082}
4083
4084//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
4085//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.
4086INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
4087{
developer8666b312023-03-24 14:05:31 +08004088 char cmd[MAX_CMD_SIZE] = {0}, buf[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004089 char extchannel[128] = {0};
developer8666b312023-03-24 14:05:31 +08004090 char interface_name[64] = {0};
4091 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08004092 BOOL radio_enable = FALSE;
4093 wifi_band band;
4094
4095 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4096
developerd1824452023-05-18 12:30:04 +08004097 if (NULL == output_string) {
4098 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004099 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004100 }
4101 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
4102 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004103 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004104 }
4105 if (radio_enable != TRUE) {
4106 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004107 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08004108 }
developer8666b312023-03-24 14:05:31 +08004109 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4110 return RETURN_ERR;
4111 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08004112
developer8666b312023-03-24 14:05:31 +08004113 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
4114 ret = _syscmd(cmd, buf, sizeof(buf));
4115 len = strlen(buf);
4116 if((ret != 0) || (len == 0))
4117 {
4118 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4119 return RETURN_ERR;
4120 }
4121
developer72fb0bb2023-01-11 09:46:29 +08004122 band = wifi_index_to_band(radioIndex);
developer8666b312023-03-24 14:05:31 +08004123 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
developer72fb0bb2023-01-11 09:46:29 +08004124 wifi_getRadioExtChannel(radioIndex, extchannel);
developer8666b312023-03-24 14:05:31 +08004125 if (strncmp(extchannel, "Auto", 4) != 0) // not auto means we have set HT40+/-
4126 snprintf(buf, sizeof(buf), "40");
developer72fb0bb2023-01-11 09:46:29 +08004127 }
developer8666b312023-03-24 14:05:31 +08004128 snprintf(output_string, 64, "%sMHz", buf);
developer72fb0bb2023-01-11 09:46:29 +08004129 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4130
4131 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004132}
4133
4134enum mwctl_chan_width {
4135 MWCTL_CHAN_WIDTH_20,
4136 MWCTL_CHAN_WIDTH_40,
4137 MWCTL_CHAN_WIDTH_80,
4138 MWCTL_CHAN_WIDTH_160,
4139 MWCTL_CHAN_WIDTH_320,
4140};
4141
4142struct bw_option {
4143 unsigned int bandwith;
4144 enum mwctl_chan_width mode;
4145};
4146
4147struct bw_option bw_opt[] = {
4148 {20, MWCTL_CHAN_WIDTH_20},
4149 {40, MWCTL_CHAN_WIDTH_40},
4150 {80, MWCTL_CHAN_WIDTH_80},
4151 {160, MWCTL_CHAN_WIDTH_160},
4152 {320, MWCTL_CHAN_WIDTH_320},
4153};
4154
4155INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
4156{
4157 int ret = -1;
4158 int i;
4159 struct unl unl_ins;
4160 struct nl_msg *msg = NULL;
4161 struct nlattr * msg_data = NULL;
4162 struct mtk_nl80211_param param;
4163 bool b_match = FALSE;
4164
4165 /*init mtk nl80211 vendor cmd*/
4166 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
4167 param.if_type = NL80211_ATTR_WIPHY;
4168 param.if_idx = radio_index_to_phy(radioIndex);
4169
4170 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4171 if (ret) {
4172 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4173 return RETURN_ERR;
4174 }
4175
4176 /*add mtk vendor cmd data*/
4177 if (channel != NULL)
4178 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
4179 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
4180 nlmsg_free(msg);
4181 goto err;
4182 }
4183
4184 if (bandwidth != NULL) {
4185 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
4186 if (bw_opt[i].bandwith == *bandwidth) {
4187 b_match = true;
4188 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
4189 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
4190 nlmsg_free(msg);
4191 goto err;
4192 }
4193 break;
4194 }
4195 }
4196
4197 if (!b_match) {
4198 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
4199 nlmsg_free(msg);
4200 goto err;
4201 }
4202 }
4203
4204 /*send mtk nl80211 vendor msg*/
4205 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4206 if (ret) {
4207 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4208 goto err;
4209 }
4210 /*deinit mtk nl80211 vendor msg*/
4211 mtk_nl80211_deint(&unl_ins);
4212 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
4213 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4214
4215 return RETURN_OK;
4216err:
4217 mtk_nl80211_deint(&unl_ins);
4218 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4219 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004220}
developerfead3972023-05-25 20:15:02 +08004221
developer72fb0bb2023-01-11 09:46:29 +08004222//Set the Operating Channel Bandwidth.
4223INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
4224{
4225 char config_file[128];
developerd1824452023-05-18 12:30:04 +08004226 char ht_value[16];
4227 char vht_value[16];
4228 char eht_value[16];
4229 struct params dat[3];
4230 wifi_band band = band_invalid;
developerfead3972023-05-25 20:15:02 +08004231 unsigned int bw = 20;
4232 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08004233
4234 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4235
4236 if(NULL == bandwidth)
4237 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004238 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004239
developerd1824452023-05-18 12:30:04 +08004240 if(strstr(bandwidth,"320") != NULL) {
4241 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4242 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4243 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developer262f4cb2023-05-24 12:22:04 +08004244 bw = 320;
developerd1824452023-05-18 12:30:04 +08004245 } else if(strstr(bandwidth,"160") != NULL) {
4246 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4247 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4248 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developer262f4cb2023-05-24 12:22:04 +08004249 bw = 160;
developerd1824452023-05-18 12:30:04 +08004250 } else if(strstr(bandwidth,"80") != NULL) {
4251 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4252 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
4253 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developer262f4cb2023-05-24 12:22:04 +08004254 bw = 80;
developerd1824452023-05-18 12:30:04 +08004255 } else if(strstr(bandwidth,"40") != NULL) {
4256 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4257 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4258 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developerfead3972023-05-25 20:15:02 +08004259 bw = 40;
developerd1824452023-05-18 12:30:04 +08004260 } else if(strstr(bandwidth,"20") != NULL) {
4261 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
4262 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4263 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developer262f4cb2023-05-24 12:22:04 +08004264 bw = 20;
developerd1824452023-05-18 12:30:04 +08004265 } else {
developer72fb0bb2023-01-11 09:46:29 +08004266 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
4267 return RETURN_ERR;
4268 }
4269
developerd1824452023-05-18 12:30:04 +08004270 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4271 dat[0].name = "HT_BW";
4272 dat[0].value = ht_value;
4273 dat[1].name = "VHT_BW";
4274 dat[1].value = vht_value;
4275 dat[2].name = "EHT_ApBw";
4276 dat[2].value = eht_value;
4277 wifi_datfileWrite(config_file, dat, 3);
developerfead3972023-05-25 20:15:02 +08004278 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
4279 if (ret != RETURN_OK) {
4280 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
4281 return RETURN_ERR;
4282 }
developer72fb0bb2023-01-11 09:46:29 +08004283
4284 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4285 return RETURN_OK;
4286}
4287
developer72fb0bb2023-01-11 09:46:29 +08004288//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
4289//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.
4290INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
4291{
4292 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004293 char config_dat_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004294 char mode_str[16] = {0};
4295 char buf[64] = {0};
developerd1824452023-05-18 12:30:04 +08004296 char cmd[MAX_CMD_SIZE] = {0};
4297 char interface_name[64] = {0};
4298 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08004299 wifi_band band;
developerd1824452023-05-18 12:30:04 +08004300 ULONG channel = 0;
4301 int centr_channel = 0;
developer72fb0bb2023-01-11 09:46:29 +08004302 UINT mode_map = 0;
developerd1824452023-05-18 12:30:04 +08004303 int freq=0;
developer72fb0bb2023-01-11 09:46:29 +08004304
4305 if (output_string == NULL)
4306 return RETURN_ERR;
4307
4308 wifi_getRadioMode(radioIndex, mode_str, &mode_map);
4309
4310 band = wifi_index_to_band(radioIndex);
4311 if (band == band_invalid)
4312 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004313 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4314 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004315
4316 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4317
4318 snprintf(output_string, 64, "Auto");
developer23e71282023-01-18 10:25:19 +08004319 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
developerd1824452023-05-18 12:30:04 +08004320 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
4321 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4322 wifi_halgetRadioExtChannel(config_dat_file, output_string);
developer23e71282023-01-18 10:25:19 +08004323 if (!(mode_map&WIFI_MODE_N))
developer72fb0bb2023-01-11 09:46:29 +08004324 snprintf(output_string, 64, "Auto");
4325 } else {
4326 // 5G and 6G band with ac or ax mode.
4327 wifi_getRadioChannel(radioIndex, &channel);
developerd1824452023-05-18 12:30:04 +08004328 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
4329
4330 ret = _syscmd(cmd, buf, sizeof(buf));
4331 len = strlen(buf);
4332 if((ret != 0) || (len == 0))
4333 {
4334 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4335 return RETURN_ERR;
4336 }
4337 sscanf(buf, "%d", &freq);
4338 centr_channel = ieee80211_frequency_to_channel(freq);
4339 if (centr_channel > (int)channel)
developer72fb0bb2023-01-11 09:46:29 +08004340 snprintf(output_string, 64, "AboveControlChannel");
4341 else
4342 snprintf(output_string, 64, "BelowControlChannel");
4343 }
4344
4345 return RETURN_OK;
4346}
4347
4348//Set the extension channel.
4349INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08004350{
developer72fb0bb2023-01-11 09:46:29 +08004351 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4352 struct params params={0};
4353 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004354 char config_dat_file[64] = {0};
4355 char ext_channel[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004356 char buf[128] = {0};
4357 char cmd[128] = {0};
4358 int max_radio_num =0, ret = 0, bandwidth = 0;
4359 unsigned long channel = 0, centr_channel = 0;
4360 bool stbcEnable = FALSE;
4361 params.name = "ht_capab";
4362 wifi_band band;
4363
4364 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4365 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
4366 _syscmd(cmd, buf, sizeof(buf));
4367 if (strlen(buf) != 0)
4368 stbcEnable = TRUE;
4369 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
4370 return RETURN_ERR;
4371 bandwidth = strtol(buf, NULL, 10);
4372 // TDK expected to get error with 20MHz
developer262f4cb2023-05-24 12:22:04 +08004373 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
developer72fb0bb2023-01-11 09:46:29 +08004374 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
4375 return RETURN_ERR;
4376
4377 band = wifi_index_to_band(radioIndex);
4378 if (band == band_invalid)
4379 return RETURN_ERR;
4380
4381 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
4382 return RETURN_ERR;
4383
developer262f4cb2023-05-24 12:22:04 +08004384 snprintf(buf, sizeof(buf), "HT%d", bandwidth);
4385 ret = util_get_sec_chan_offset(channel, buf);
4386 if (ret == -EINVAL)
4387 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004388
4389 if(NULL!= strstr(string,"Above")) {
developer262f4cb2023-05-24 12:22:04 +08004390 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
4391 return RETURN_OK;
4392 strcpy(ext_channel, "Above");
developer72fb0bb2023-01-11 09:46:29 +08004393 } else if(NULL!= strstr(string,"Below")) {
developer262f4cb2023-05-24 12:22:04 +08004394 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
4395 return RETURN_OK;
4396 strcpy(ext_channel, "Below");
4397 } else {
developerd1824452023-05-18 12:30:04 +08004398 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08004399 return RETURN_ERR;
4400 }
developerd1824452023-05-18 12:30:04 +08004401 params.name = "HT_EXTCHA";
developer72fb0bb2023-01-11 09:46:29 +08004402 params.value = ext_channel;
4403
developerd1824452023-05-18 12:30:04 +08004404 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4405 wifi_datfileWrite(config_dat_file, &params, 1);
4406
developer72fb0bb2023-01-11 09:46:29 +08004407 wifi_getMaxRadioNumber(&max_radio_num);
4408 for(int i=0; i<=MAX_APS/max_radio_num; i++)
4409 {
4410 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
developer72fb0bb2023-01-11 09:46:29 +08004411 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
4412 }
4413
4414 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
4415 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4416 return RETURN_OK;
4417}
4418
4419//Get the guard interval value. eg "400nsec" or "800nsec"
4420//The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this.
4421INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
4422{
4423 wifi_guard_interval_t GI;
4424
4425 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4426
4427 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
4428 return RETURN_ERR;
4429
4430 if (GI == wifi_guard_interval_400)
4431 strcpy(output_string, "400nsec");
4432 else if (GI == wifi_guard_interval_800)
4433 strcpy(output_string, "800nsec");
4434 else if (GI == wifi_guard_interval_1600)
4435 strcpy(output_string, "1600nsec");
4436 else if (GI == wifi_guard_interval_3200)
4437 strcpy(output_string, "3200nsec");
4438 else
4439 strcpy(output_string, "Auto");
4440
4441 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4442 return RETURN_OK;
4443}
4444
4445//Set the guard interval value.
4446INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
4447{
4448 wifi_guard_interval_t GI;
4449 int ret = 0;
4450
4451 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4452
4453 if (strcmp(string, "400nsec") == 0)
4454 GI = wifi_guard_interval_400;
4455 else if (strcmp(string , "800nsec") == 0)
4456 GI = wifi_guard_interval_800;
4457 else if (strcmp(string , "1600nsec") == 0)
4458 GI = wifi_guard_interval_1600;
4459 else if (strcmp(string , "3200nsec") == 0)
4460 GI = wifi_guard_interval_3200;
4461 else
4462 GI = wifi_guard_interval_auto;
4463
4464 ret = wifi_setGuardInterval(radioIndex, GI);
4465
4466 if (ret == RETURN_ERR) {
4467 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
4468 return RETURN_ERR;
4469 }
4470
4471 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4472 return RETURN_OK;
4473}
4474
4475//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
4476INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
4477{
4478 char buf[32]={0};
4479 char mcs_file[64] = {0};
4480 char cmd[64] = {0};
4481 int mode_bitmap = 0;
4482
4483 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4484 if(output_int == NULL)
4485 return RETURN_ERR;
4486 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4487
4488 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
4489 _syscmd(cmd, buf, sizeof(buf));
4490 if (strlen(buf) > 0)
4491 *output_int = strtol(buf, NULL, 10);
4492 else {
4493 // output the max MCS for the current radio mode
4494 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
4495 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
4496 return RETURN_ERR;
4497 }
4498 if (mode_bitmap & WIFI_MODE_AX) {
4499 *output_int = 11;
4500 } else if (mode_bitmap & WIFI_MODE_AC) {
4501 *output_int = 9;
4502 } else if (mode_bitmap & WIFI_MODE_N) {
4503 *output_int = 7;
4504 }
4505 }
4506 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4507
4508 return RETURN_OK;
4509}
4510
4511//Set the Modulation Coding Scheme index
4512INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
4513{
developera1255e42023-05-13 17:45:02 +08004514 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
4515 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 +08004516 char config_file[64] = {0};
4517 char set_value[16] = {0};
4518 char mcs_file[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004519 struct params set_config = {0};
4520 FILE *f = NULL;
developera1255e42023-05-13 17:45:02 +08004521 INT nss = 0;
4522 int ant_bitmap = 0;
4523 unsigned short cal_value = 0;
4524 UCHAR tval = 0, i = 0;
developer72fb0bb2023-01-11 09:46:29 +08004525
4526 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4527
4528 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4529
4530 // -1 means auto
4531 if (MCS > 15 || MCS < -1) {
4532 fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS);
4533 return RETURN_ERR;
4534 }
developera1255e42023-05-13 17:45:02 +08004535 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
4536 for(; ant_bitmap > 0; ant_bitmap >>= 1)
4537 nss += 1;
4538 //printf("%s:nss = %d\n", __func__, nss);
4539 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
4540 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
developer72fb0bb2023-01-11 09:46:29 +08004541 if (MCS > 9 || MCS == -1)
developera1255e42023-05-13 17:45:02 +08004542 tval = 2;/*one stream value*/
developer72fb0bb2023-01-11 09:46:29 +08004543 else if (MCS > 7)
developera1255e42023-05-13 17:45:02 +08004544 tval = 1;
developer72fb0bb2023-01-11 09:46:29 +08004545 else
developera1255e42023-05-13 17:45:02 +08004546 tval = 0;
4547 for (i = 0; i < nss; i++)
4548 cal_value |= (tval << (2*i));
4549 snprintf(set_value, sizeof(set_value), "%x", cal_value);
4550 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
4551 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
developer72fb0bb2023-01-11 09:46:29 +08004552 set_config.value = set_value;
4553
4554 wifi_hostapdWrite(config_file, &set_config, 1);
4555 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
4556
4557 // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
4558 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4559 f = fopen(mcs_file, "w");
4560 if (f == NULL) {
4561 fprintf(stderr, "%s: fopen failed\n", __func__);
4562 return RETURN_ERR;
4563 }
4564 fprintf(f, "%d", MCS);
4565 fclose(f);
4566
4567 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4568 return RETURN_OK;
4569}
4570
4571//Get supported Transmit Power list, eg : "0,25,50,75,100"
4572//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.
4573INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
4574{
4575 if (NULL == output_list)
4576 return RETURN_ERR;
4577 snprintf(output_list, 64,"0,25,50,75,100");
4578 return RETURN_OK;
4579}
4580
4581//Get current Transmit Power in dBm units.
4582//The transmite power level is in units of full power for this radio.
4583INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
4584{
4585 char interface_name[16] = {0};
4586 char cmd[128]={0};
4587 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08004588 char pwr_file[128]={0};
4589
developer72fb0bb2023-01-11 09:46:29 +08004590 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4591
4592 if(output_ulong == NULL)
4593 return RETURN_ERR;
4594
4595 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4596 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004597/*
developer72fb0bb2023-01-11 09:46:29 +08004598 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
4599 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004600 *output_ulong = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +08004601*/
4602 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4603 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
4604 _syscmd(cmd, buf, sizeof(buf));
4605 if (strlen(buf) > 0)
4606 *output_ulong = strtol(buf, NULL, 10);
4607 else
4608 *output_ulong = 100;
developer72fb0bb2023-01-11 09:46:29 +08004609 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4610 return RETURN_OK;
4611}
4612
4613//Set Transmit Power
4614//The transmite power level is in units of full power for this radio.
4615INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
4616{
4617 char interface_name[16] = {0};
4618 char *support;
developer72fb0bb2023-01-11 09:46:29 +08004619 char buf[128]={0};
4620 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08004621 char pwr_file[128]={0};
4622 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08004623 int if_idx, ret = 0;
4624 struct nl_msg *msg = NULL;
4625 struct nlattr * msg_data = NULL;
4626 struct mtk_nl80211_param param;
4627 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +08004628
4629 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4630
4631 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4632 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004633 // Get the Tx power supported list and check that is the input in the list
4634 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4635 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4636 support = strtok(buf, ",");
4637 while(true)
4638 {
4639 if(support == NULL) { // input not in the list
4640 wifi_dbg_printf("Input value is invalid.\n");
4641 return RETURN_ERR;
4642 }
4643 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4644 break;
4645 }
4646 support = strtok(NULL, ",");
4647 }
developerfead3972023-05-25 20:15:02 +08004648
4649 if_idx = if_nametoindex(interface_name);
4650 /*init mtk nl80211 vendor cmd*/
4651 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
4652 param.if_type = NL80211_ATTR_IFINDEX;
4653 param.if_idx = if_idx;
4654 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4655 if (ret) {
4656 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4657 return RETURN_ERR;
4658 }
4659 /*add mtk vendor cmd data*/
4660 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
4661 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4662 nlmsg_free(msg);
4663 goto err;
4664 }
4665
4666 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
4667 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4668 nlmsg_free(msg);
4669 goto err;
4670 }
4671
4672 /*send mtk nl80211 vendor msg*/
4673 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4674 if (ret) {
4675 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4676 goto err;
4677 }
4678 /*deinit mtk nl80211 vendor msg*/
4679 mtk_nl80211_deint(&unl_ins);
4680 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
4681
developera1255e42023-05-13 17:45:02 +08004682 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4683 f = fopen(pwr_file, "w");
4684 if (f == NULL) {
4685 fprintf(stderr, "%s: fopen failed\n", __func__);
4686 return RETURN_ERR;
4687 }
4688 fprintf(f, "%d", TransmitPower);
4689 fclose(f);
4690/* 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 +08004691 _syscmd(cmd, buf, sizeof(buf));
4692 maximum_tx = strtol(buf, NULL, 10);
4693
4694 // Get the Tx power supported list and check that is the input in the list
4695 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4696 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4697 support = strtok(buf, ",");
4698 while(true)
4699 {
4700 if(support == NULL) { // input not in the list
4701 wifi_dbg_printf("Input value is invalid.\n");
4702 return RETURN_ERR;
4703 }
4704 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4705 break;
4706 }
4707 support = strtok(NULL, ",");
4708 }
4709 txpower = TransmitPower*maximum_tx/100;
4710 phyId = radio_index_to_phy(radioIndex);
4711 snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower);
4712 _syscmd(cmd, buf, sizeof(buf));
4713 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +08004714*/
4715 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004716err:
4717 mtk_nl80211_deint(&unl_ins);
4718 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4719 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004720}
4721
4722//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
4723INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
4724{
developer69b61b02023-03-07 17:17:44 +08004725 if (NULL == Supported)
developer72fb0bb2023-01-11 09:46:29 +08004726 return RETURN_ERR;
4727 *Supported = TRUE;
4728
4729 return RETURN_OK;
4730}
4731
4732//Get 80211h feature enable
4733INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
4734{
4735 char buf[64]={'\0'};
4736 char config_file[64] = {'\0'};
4737
4738 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4739 if(enable == NULL)
4740 return RETURN_ERR;
4741
4742 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
developerd1824452023-05-18 12:30:04 +08004743 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
4744 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004745
4746 if (strncmp(buf, "1", 1) == 0)
4747 *enable = TRUE;
4748 else
4749 *enable = FALSE;
4750
4751 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4752 return RETURN_OK;
4753}
4754
4755//Set 80211h feature enable
4756INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
4757{
4758 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4759 struct params params={'\0'};
developerd1824452023-05-18 12:30:04 +08004760 struct params dat={0};
developer72fb0bb2023-01-11 09:46:29 +08004761 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08004762 char config_dat_file[MAX_BUF_SIZE] = {0};
4763 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004764
4765 params.name = "ieee80211h";
4766
4767 if (enable) {
4768 params.value = "1";
4769 } else {
4770 params.value = "0";
4771 }
4772
developerd1824452023-05-18 12:30:04 +08004773 dat.name = "IEEE80211H";
4774 dat.value = params.value;
4775
4776 band = wifi_index_to_band(radioIndex);
4777 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4778 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer69b61b02023-03-07 17:17:44 +08004779
developerd1824452023-05-18 12:30:04 +08004780 wifi_hostapdWrite(config_file, &params, 1);
4781 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08004782 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4783 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4784 return RETURN_OK;
4785}
4786
4787//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.
4788INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
4789{
4790 if (NULL == output)
4791 return RETURN_ERR;
4792 *output=100;
4793
4794 return RETURN_OK;
4795}
4796
4797//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.
4798INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
4799{
4800 if (NULL == output)
4801 return RETURN_ERR;
4802 *output = -99;
4803
4804 return RETURN_OK;
4805}
4806
4807INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
4808{
4809 return RETURN_ERR;
4810}
4811
4812
4813//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
4814INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
4815{
4816 char interface_name[16] = {0};
4817 char cmd[MAX_BUF_SIZE]={'\0'};
4818 char buf[MAX_CMD_SIZE]={'\0'};
4819
4820 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4821 if(output == NULL)
4822 return RETURN_ERR;
4823
4824 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4825 return RETURN_ERR;
4826 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
4827 _syscmd(cmd, buf, sizeof(buf));
4828 *output = atoi(buf);
4829
4830 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4831 return RETURN_OK;
4832}
developer69b61b02023-03-07 17:17:44 +08004833
developer72fb0bb2023-01-11 09:46:29 +08004834INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
4835{
4836 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4837 struct params params={'\0'};
4838 char buf[MAX_BUF_SIZE] = {'\0'};
4839 char config_file[MAX_BUF_SIZE] = {'\0'};
4840
4841 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
4842 return RETURN_ERR;
4843
4844 params.name = "beacon_int";
4845 snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
4846 params.value = buf;
4847
4848 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4849 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08004850
developer72fb0bb2023-01-11 09:46:29 +08004851 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4852 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4853 return RETURN_OK;
4854}
4855
4856//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.
4857INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
4858{
4859 //TODO: need to revisit below implementation
4860 char *temp;
4861 char temp_output[128] = {0};
4862 char temp_TransmitRates[64] = {0};
4863 char config_file[64] = {0};
4864
4865 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4866 if (NULL == output)
4867 return RETURN_ERR;
4868 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4869 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08004870
developer72fb0bb2023-01-11 09:46:29 +08004871 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
4872 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
4873 } else {
4874 temp = strtok(temp_TransmitRates," ");
4875 while(temp!=NULL)
4876 {
4877 // Convert 100 kbps to Mbps
4878 temp[strlen(temp)-1]=0;
4879 if((temp[0]=='5') && (temp[1]=='\0'))
4880 {
4881 temp="5.5";
4882 }
4883 strcat(temp_output,temp);
4884 temp = strtok(NULL," ");
4885 if(temp!=NULL)
4886 {
4887 strcat(temp_output,",");
4888 }
4889 }
4890 strcpy(output,temp_output);
4891 }
4892 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4893 return RETURN_OK;
4894}
4895
4896INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
4897{
4898 char *temp;
4899 char temp1[128];
4900 char temp_output[128];
4901 char temp_TransmitRates[128];
4902 char set[128];
4903 char sub_set[128];
4904 int set_count=0,subset_count=0;
4905 int set_index=0,subset_index=0;
4906 char *token;
4907 int flag=0, i=0;
4908 struct params params={'\0'};
4909 char config_file[MAX_BUF_SIZE] = {0};
4910 wifi_band band = wifi_index_to_band(radioIndex);
4911
4912 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4913 if(NULL == TransmitRates)
4914 return RETURN_ERR;
4915 strcpy(sub_set,TransmitRates);
4916
4917 //Allow only supported Data transmit rate to be set
4918 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
4919 token = strtok(sub_set,",");
4920 while( token != NULL ) /* split the basic rate to be set, by comma */
4921 {
4922 sub_set[subset_count]=atoi(token);
4923 subset_count++;
4924 token=strtok(NULL,",");
4925 }
4926 token=strtok(set,",");
4927 while(token!=NULL) /* split the supported rate by comma */
4928 {
4929 set[set_count]=atoi(token);
4930 set_count++;
4931 token=strtok(NULL,",");
4932 }
4933 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
4934 {
4935 for(set_index=0;set_index < set_count;set_index++)
4936 {
4937 flag=0;
4938 if(sub_set[subset_index]==set[set_index])
4939 break;
4940 else
4941 flag=1; /* No match found */
4942 }
4943 if(flag==1)
4944 return RETURN_ERR; //If value not found return Error
4945 }
4946 strcpy(temp_TransmitRates,TransmitRates);
4947
4948 for(i=0;i<strlen(temp_TransmitRates);i++)
4949 {
4950 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
4951 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
4952 {
4953 continue;
4954 }
4955 else
4956 {
4957 return RETURN_ERR;
4958 }
4959 }
4960 strcpy(temp_output,"");
4961 temp = strtok(temp_TransmitRates,",");
4962 while(temp!=NULL)
4963 {
4964 strcpy(temp1,temp);
4965 if(band == band_5)
4966 {
4967 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
4968 {
4969 return RETURN_ERR;
4970 }
4971 }
4972
4973 if(strcmp(temp,"5.5")==0)
4974 {
4975 strcpy(temp1,"55");
4976 }
4977 else
4978 {
4979 strcat(temp1,"0");
4980 }
4981 strcat(temp_output,temp1);
4982 temp = strtok(NULL,",");
4983 if(temp!=NULL)
4984 {
4985 strcat(temp_output," ");
4986 }
4987 }
4988 strcpy(TransmitRates,temp_output);
4989
4990 params.name= "basic_rates";
4991 params.value =TransmitRates;
4992
4993 wifi_dbg_printf("\n%s:",__func__);
4994 wifi_dbg_printf("\nparams.value=%s\n",params.value);
4995 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
4996 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4997 wifi_hostapdWrite(config_file,&params,1);
4998 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4999 return RETURN_OK;
5000}
5001
5002//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
5003INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
5004{
5005 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5006 FILE *fp = NULL;
5007 char path[256] = {0}, output_string[256] = {0};
5008 int count = 0;
5009 char *interface = NULL;
5010
5011 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
5012 if (fp == NULL)
5013 {
5014 printf("Failed to run command in Function %s\n", __FUNCTION__);
5015 return RETURN_ERR;
5016 }
5017 if (fgets(path, sizeof(path) - 1, fp) != NULL)
5018 {
5019 interface = strchr(path, '=');
5020
5021 if (interface != NULL)
5022 {
5023 strcpy(output_string, interface + 1);
5024 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
5025 interface_name[count] = output_string[count];
5026
5027 interface_name[count] = '\0';
5028 }
5029 }
5030 pclose(fp);
5031 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5032 return RETURN_OK;
5033}
5034
5035INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
5036{
5037 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5038 output_struct->radio_BytesSent = 0;
5039 output_struct->radio_BytesReceived = 0;
5040 output_struct->radio_PacketsSent = 0;
5041 output_struct->radio_PacketsReceived = 0;
5042 output_struct->radio_ErrorsSent = 0;
5043 output_struct->radio_ErrorsReceived = 0;
5044 output_struct->radio_DiscardPacketsSent = 0;
5045 output_struct->radio_DiscardPacketsReceived = 0;
5046 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5047 return RETURN_OK;
5048}
5049
5050
5051INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
5052{
5053 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5054 CHAR buf[MAX_CMD_SIZE] = {0};
5055 CHAR Value[MAX_BUF_SIZE] = {0};
5056 FILE *fp = NULL;
5057
5058 if (ifname == NULL || strlen(ifname) <= 1)
5059 return RETURN_OK;
5060
5061 snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
5062 system(buf);
5063
5064 fp = fopen("/tmp/Radio_Stats.txt", "r");
5065 if(fp == NULL)
5066 {
5067 printf("/tmp/Radio_Stats.txt not exists \n");
5068 return RETURN_ERR;
5069 }
5070 fclose(fp);
5071
5072 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5073 File_Reading(buf, Value);
5074 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
5075
5076 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5077 File_Reading(buf, Value);
5078 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
5079
5080 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5081 File_Reading(buf, Value);
5082 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
5083
5084 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5085 File_Reading(buf, Value);
5086 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
5087
5088 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5089 File_Reading(buf, Value);
5090 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
5091
5092 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5093 File_Reading(buf, Value);
5094 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
5095
5096 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5097 File_Reading(buf, Value);
5098 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
5099
5100 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5101 File_Reading(buf, Value);
5102 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
5103
5104 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5105 return RETURN_OK;
5106}
5107
5108INT GetIfacestatus(CHAR *interface_name, CHAR *status)
5109{
developer7e4a2a62023-04-06 19:56:03 +08005110 CHAR buf[MAX_CMD_SIZE] = {0};
5111 INT count = 0;
developer72fb0bb2023-01-11 09:46:29 +08005112
developer7e4a2a62023-04-06 19:56:03 +08005113 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5114
5115 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
5116 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
5117 File_Reading(buf, status);
5118 }
5119
5120 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5121 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005122}
5123
5124//Get detail radio traffic static info
5125INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
5126{
5127
developer69b61b02023-03-07 17:17:44 +08005128#if 0
5129 //ifconfig radio_x
developer72fb0bb2023-01-11 09:46:29 +08005130 output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters.
5131 output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters.
5132 output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface.
5133 output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface.
5134
5135 output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors.
5136 output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
5137 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.
5138 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.
5139
developer69b61b02023-03-07 17:17:44 +08005140 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 +08005141 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].
5142 output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error.
5143 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.
5144 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
5145 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
5146 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
5147 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
5148 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
5149
5150 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
5151 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
5152 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
5153 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.
5154
5155 return RETURN_OK;
5156#endif
5157
5158 CHAR interface_name[64] = {0};
5159 BOOL iface_status = FALSE;
5160 wifi_radioTrafficStats2_t radioTrafficStats = {0};
5161
5162 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5163 if (NULL == output_struct)
5164 return RETURN_ERR;
5165
5166 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5167 return RETURN_ERR;
5168
5169 wifi_getApEnable(radioIndex, &iface_status);
5170
5171 if (iface_status == TRUE)
5172 wifi_halGetIfStats(interface_name, &radioTrafficStats);
5173 else
5174 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
5175
5176 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
5177 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
5178 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
5179 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
5180 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
5181 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
5182 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
5183 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
5184
5185 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
5186 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].
5187 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
5188 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.
5189 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
5190 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
5191 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
5192 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
5193 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
5194
5195 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
5196 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
5197 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
5198 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.
5199
5200 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5201
5202 return RETURN_OK;
5203}
5204
5205//Set radio traffic static Measureing rules
5206INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
5207{
5208 //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
5209 // Else, save the MeasuringRate and MeasuringInterval for future usage
5210
5211 return RETURN_OK;
5212}
5213
5214//To start or stop RadioTrafficStats
5215INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
5216{
5217 //zqiu: If the RadioTrafficStats process running
5218 // if(enable)
5219 // return RETURN_OK.
5220 // else
5221 // Stop RadioTrafficStats process
developer69b61b02023-03-07 17:17:44 +08005222 // Else
developer72fb0bb2023-01-11 09:46:29 +08005223 // if(enable)
5224 // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds
5225 // else
5226 // return RETURN_OK.
5227
5228 return RETURN_OK;
5229}
5230
5231//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
5232INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
5233{
5234 //zqiu: Please ignor signalIndex.
developer69b61b02023-03-07 17:17:44 +08005235 if (NULL == SignalLevel)
developer72fb0bb2023-01-11 09:46:29 +08005236 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08005237
developer72fb0bb2023-01-11 09:46:29 +08005238 *SignalLevel=(radioIndex==0)?-19:-19;
5239
5240 return RETURN_OK;
5241}
5242
5243//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5244INT wifi_applyRadioSettings(INT radioIndex)
5245{
5246 return RETURN_OK;
5247}
5248
5249//Get the radio index assocated with this SSID entry
5250INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
5251{
5252 if(NULL == radioIndex)
5253 return RETURN_ERR;
5254 int max_radio_num = 0;
5255 wifi_getMaxRadioNumber(&max_radio_num);
5256 *radioIndex = ssidIndex%max_radio_num;
5257 return RETURN_OK;
5258}
5259
5260//Device.WiFi.SSID.{i}.Enable
5261//Get SSID enable configuration parameters (not the SSID enable status)
5262INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
5263{
developer69b61b02023-03-07 17:17:44 +08005264 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08005265 return RETURN_ERR;
5266
5267 return wifi_getApEnable(ssidIndex, output_bool);
5268}
5269
5270//Device.WiFi.SSID.{i}.Enable
5271//Set SSID enable configuration parameters
5272INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
5273{
5274 return wifi_setApEnable(ssidIndex, enable);
5275}
5276
5277//Device.WiFi.SSID.{i}.Status
5278//Get the SSID enable status
5279INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
5280{
5281 char cmd[MAX_CMD_SIZE]={0};
5282 char buf[MAX_BUF_SIZE]={0};
5283 BOOL output_bool;
5284
5285 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5286 if (NULL == output_string)
5287 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08005288
developer72fb0bb2023-01-11 09:46:29 +08005289 wifi_getApEnable(ssidIndex,&output_bool);
5290 snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
5291
5292 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5293 return RETURN_OK;
5294}
5295
5296// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
5297INT wifi_getSSIDName(INT apIndex, CHAR *output)
5298{
5299 char config_file[MAX_BUF_SIZE] = {0};
5300
developer69b61b02023-03-07 17:17:44 +08005301 if (NULL == output)
developer72fb0bb2023-01-11 09:46:29 +08005302 return RETURN_ERR;
5303
5304 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5305 wifi_hostapdRead(config_file,"ssid",output,32);
5306
5307 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
5308 return RETURN_OK;
5309}
5310
developer69b61b02023-03-07 17:17:44 +08005311// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08005312INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
5313{
5314 char str[MAX_BUF_SIZE]={'\0'};
5315 char cmd[MAX_CMD_SIZE]={'\0'};
5316 struct params params;
5317 char config_file[MAX_BUF_SIZE] = {0};
5318
5319 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5320 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
5321 return RETURN_ERR;
5322
5323 params.name = "ssid";
5324 params.value = ssid_string;
5325 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5326 wifi_hostapdWrite(config_file, &params, 1);
5327 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5328 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5329
5330 return RETURN_OK;
5331}
5332
5333//Get the BSSID
5334INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
5335{
developer7e4a2a62023-04-06 19:56:03 +08005336 char cmd[MAX_CMD_SIZE] = {0};
5337 char inf_name[IF_NAME_SIZE] = {0};
5338 char conf_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005339
developer7e4a2a62023-04-06 19:56:03 +08005340 if (!output_string)
developer72fb0bb2023-01-11 09:46:29 +08005341 return RETURN_ERR;
5342
developer47cc27a2023-05-17 23:09:58 +08005343 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
5344 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08005345
developer5b2f10c2023-05-25 17:02:21 +08005346 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
5347 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
5348 strncpy(output_string, "\0", 1);
5349 return RETURN_ERR;
5350 }
5351 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
5352 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08005353
developer5b2f10c2023-05-25 17:02:21 +08005354 /* if hostapd does not control interface even if this interface has been brought up,
5355 * try to get its mac address by iw command.
5356 */
5357 if(strlen(output_string) == 0) {
5358 memset(cmd, 0, sizeof(cmd));
5359 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
5360 _syscmd(cmd, output_string, 64);
5361 }
developer72fb0bb2023-01-11 09:46:29 +08005362
developer5b2f10c2023-05-25 17:02:21 +08005363 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005364}
5365
5366//Get the MAC address associated with this Wifi SSID
5367INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
5368{
5369 wifi_getBaseBSSID(ssidIndex,output_string);
5370 return RETURN_OK;
5371}
5372
5373//Get the basic SSID traffic static info
5374//Apply SSID and AP (in the case of Acess Point devices) to the hardware
5375//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5376INT wifi_applySSIDSettings(INT ssidIndex)
5377{
5378 char interface_name[16] = {0};
5379 BOOL status = false;
5380 char cmd[MAX_CMD_SIZE] = {0};
5381 char buf[MAX_CMD_SIZE] = {0};
5382 int apIndex, ret;
5383 int max_radio_num = 0;
5384 int radioIndex = 0;
5385
5386 wifi_getMaxRadioNumber(&max_radio_num);
5387
5388 radioIndex = ssidIndex % max_radio_num;
5389
5390 wifi_getApEnable(ssidIndex,&status);
5391 // Do not apply when ssid index is disabled
5392 if (status == false)
5393 return RETURN_OK;
5394
5395 /* Doing full remove and add for ssid Index
5396 * Not all hostapd options are supported with reload
5397 * for example macaddr_acl
5398 */
5399 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
5400 return RETURN_ERR;
5401
5402 ret = wifi_setApEnable(ssidIndex,true);
5403
5404 /* Workaround for hostapd issue with multiple bss definitions
5405 * when first created interface will be removed
5406 * then all vaps other vaps on same phy are removed
5407 * after calling setApEnable to false readd all enabled vaps */
5408 for(int i=0; i < MAX_APS/max_radio_num; i++) {
5409 apIndex = max_radio_num*i+radioIndex;
5410 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5411 return RETURN_ERR;
5412 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
5413 _syscmd(cmd, buf, sizeof(buf));
5414 if(*buf == '1')
5415 wifi_setApEnable(apIndex, true);
5416 }
5417
5418 return ret;
5419}
5420
5421struct channels_noise {
5422 int channel;
5423 int noise;
5424};
5425
5426// Return noise array for each channel
5427int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
5428{
5429 char interface_name[16] = {0};
5430 FILE *f = NULL;
5431 char cmd[128] = {0};
5432 char line[256] = {0};
5433 size_t len = 0;
5434 ssize_t read = 0;
5435 int tmp = 0, arr_index = -1;
5436
5437 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5438 return RETURN_ERR;
5439 sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
5440
5441 if ((f = popen(cmd, "r")) == NULL) {
5442 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5443 return RETURN_ERR;
5444 }
developer69b61b02023-03-07 17:17:44 +08005445
developer72fb0bb2023-01-11 09:46:29 +08005446 while(fgets(line, sizeof(line), f) != NULL) {
5447 if(arr_index < channels_num){
5448 sscanf(line, "%d", &tmp);
5449 if (tmp > 0) { // channel frequency, the first line must be frequency
5450 arr_index++;
5451 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
5452 } else { // noise
5453 channels_noise_arr[arr_index].noise = tmp;
5454 }
5455 }else{
5456 break;
5457 }
5458 }
5459 pclose(f);
5460 return RETURN_OK;
5461}
5462
5463//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
5464//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08005465INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08005466{
5467 int index = -1;
5468 wifi_neighbor_ap2_t *scan_array = NULL;
5469 char cmd[256]={0};
5470 char buf[128]={0};
5471 char file_name[32] = {0};
5472 char filter_SSID[32] = {0};
5473 char line[256] = {0};
5474 char interface_name[16] = {0};
5475 char *ret = NULL;
5476 int freq=0;
5477 FILE *f = NULL;
5478 size_t len=0;
5479 int channels_num = 0;
5480 int vht_channel_width = 0;
5481 int get_noise_ret = RETURN_ERR;
5482 bool filter_enable = false;
5483 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
5484 int phyId = 0;
5485
5486 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
5487
5488 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5489 return RETURN_ERR;
5490
5491 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
5492 f = fopen(file_name, "r");
5493 if (f != NULL) {
5494 fgets(filter_SSID, sizeof(file_name), f);
5495 if (strlen(filter_SSID) != 0)
5496 filter_enable = true;
5497 fclose(f);
5498 }
5499
5500 phyId = radio_index_to_phy(radioIndex);
5501 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
5502 _syscmd(cmd, buf, sizeof(buf));
5503 channels_num = strtol(buf, NULL, 10);
5504
5505
5506
5507 sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
5508 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
5509 fprintf(stderr, "cmd: %s\n", cmd);
5510 if ((f = popen(cmd, "r")) == NULL) {
5511 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5512 return RETURN_ERR;
5513 }
developer69b61b02023-03-07 17:17:44 +08005514
developer72fb0bb2023-01-11 09:46:29 +08005515 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
5516 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08005517
developer72fb0bb2023-01-11 09:46:29 +08005518 ret = fgets(line, sizeof(line), f);
5519 while (ret != NULL) {
5520 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +08005521 // 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 +08005522 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
5523 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
5524
5525 if (!filter_BSS) {
5526 index++;
5527 wifi_neighbor_ap2_t *tmp;
5528 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
5529 if (tmp == NULL) { // no more memory to use
5530 index--;
5531 wifi_dbg_printf("%s: realloc failed\n", __func__);
5532 break;
5533 }
5534 scan_array = tmp;
5535 }
5536 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5537
5538 filter_BSS = false;
5539 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
5540 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
5541 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
5542 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
5543 } else if (strstr(line, "freq") != NULL) {
5544 sscanf(line," freq: %d", &freq);
5545 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
5546
5547 if (freq >= 2412 && freq <= 2484) {
5548 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
5549 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
5550 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
5551 }
5552 else if (freq >= 5160 && freq <= 5805) {
5553 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
5554 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
5555 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
5556 }
5557
5558 scan_array[index].ap_Noise = 0;
5559 if (get_noise_ret == RETURN_OK) {
5560 for (int i = 0; i < channels_num; i++) {
5561 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
5562 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
5563 break;
5564 }
5565 }
5566 }
5567 } else if (strstr(line, "beacon interval") != NULL) {
5568 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
5569 } else if (strstr(line, "signal") != NULL) {
5570 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
5571 } else if (strstr(line,"SSID") != NULL) {
5572 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
5573 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
5574 filter_BSS = true;
5575 }
5576 } else if (strstr(line, "Supported rates") != NULL) {
5577 char SRate[80] = {0}, *tmp = NULL;
5578 memset(buf, 0, sizeof(buf));
5579 strcpy(SRate, line);
5580 tmp = strtok(SRate, ":");
5581 tmp = strtok(NULL, ":");
5582 strcpy(buf, tmp);
5583 memset(SRate, 0, sizeof(SRate));
5584
5585 tmp = strtok(buf, " \n");
5586 while (tmp != NULL) {
5587 strcat(SRate, tmp);
5588 if (SRate[strlen(SRate) - 1] == '*') {
5589 SRate[strlen(SRate) - 1] = '\0';
5590 }
5591 strcat(SRate, ",");
5592
5593 tmp = strtok(NULL, " \n");
5594 }
5595 SRate[strlen(SRate) - 1] = '\0';
5596 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
5597 } else if (strstr(line, "DTIM") != NULL) {
5598 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
5599 } else if (strstr(line, "VHT capabilities") != NULL) {
5600 strcat(scan_array[index].ap_SupportedStandards, ",ac");
5601 strcpy(scan_array[index].ap_OperatingStandards, "ac");
5602 } else if (strstr(line, "HT capabilities") != NULL) {
5603 strcat(scan_array[index].ap_SupportedStandards, ",n");
5604 strcpy(scan_array[index].ap_OperatingStandards, "n");
5605 } else if (strstr(line, "VHT operation") != NULL) {
5606 ret = fgets(line, sizeof(line), f);
5607 sscanf(line," * channel width: %d", &vht_channel_width);
5608 if(vht_channel_width == 1) {
5609 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
5610 } else {
5611 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
5612 }
5613 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5614 continue;
5615 } else if (strstr(line, "HT operation") != NULL) {
5616 ret = fgets(line, sizeof(line), f);
5617 sscanf(line," * secondary channel offset: %s", &buf);
5618 if (!strcmp(buf, "above")) {
5619 //40Mhz +
5620 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
5621 }
5622 else if (!strcmp(buf, "below")) {
5623 //40Mhz -
5624 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
5625 } else {
5626 //20Mhz
5627 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
5628 }
5629 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5630 continue;
5631 } else if (strstr(line, "HE capabilities") != NULL) {
5632 strcat(scan_array[index].ap_SupportedStandards, ",ax");
5633 strcpy(scan_array[index].ap_OperatingStandards, "ax");
5634 ret = fgets(line, sizeof(line), f);
5635 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
5636 if (strstr(line, "HE40/2.4GHz") != NULL)
5637 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
5638 else
5639 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
5640 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
5641 if (strstr(line, "HE80/5GHz") != NULL) {
5642 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
5643 ret = fgets(line, sizeof(line), f);
5644 } else
5645 continue;
5646 if (strstr(line, "HE160/5GHz") != NULL)
5647 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
5648 }
5649 continue;
5650 } else if (strstr(line, "WPA") != NULL) {
5651 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
5652 } else if (strstr(line, "RSN") != NULL) {
5653 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
5654 } else if (strstr(line, "Group cipher") != NULL) {
5655 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
5656 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
5657 strcpy(scan_array[index].ap_EncryptionMode, "AES");
5658 }
5659 }
5660 ret = fgets(line, sizeof(line), f);
5661 }
5662
5663 if (!filter_BSS) {
5664 *output_array_size = index + 1;
5665 } else {
5666 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5667 *output_array_size = index;
5668 }
5669 *neighbor_ap_array = scan_array;
5670 pclose(f);
5671 free(channels_noise_arr);
5672 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5673 return RETURN_OK;
5674}
5675
5676//>> Deprecated: used for old RDKB code.
5677INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
5678{
5679 INT status = RETURN_ERR;
5680
5681 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5682 output_struct->wifi_PLCPErrorCount = 0;
5683 output_struct->wifi_FCSErrorCount = 0;
5684 output_struct->wifi_InvalidMACCount = 0;
5685 output_struct->wifi_PacketsOtherReceived = 0;
5686 output_struct->wifi_Noise = 0;
5687 status = RETURN_OK;
5688 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5689 return status;
5690}
5691
5692INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
5693{
5694 char interface_name[16] = {0};
5695 char cmd[128] = {0};
5696 char buf[1280] = {0};
5697 char *pos = NULL;
5698
5699 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5700 if (NULL == output_struct)
5701 return RETURN_ERR;
5702
5703 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5704 return RETURN_ERR;
5705
5706 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5707
5708 snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
5709 _syscmd(cmd, buf, sizeof(buf));
5710
5711 pos = buf;
5712 if ((pos = strstr(pos, "RX packets:")) == NULL)
5713 return RETURN_ERR;
5714 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
5715
5716 if ((pos = strstr(pos, "TX packets:")) == NULL)
5717 return RETURN_ERR;
5718 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
5719
5720 if ((pos = strstr(pos, "RX bytes:")) == NULL)
5721 return RETURN_ERR;
5722 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
5723
5724 if ((pos = strstr(pos, "TX bytes:")) == NULL)
5725 return RETURN_ERR;
5726 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
5727
5728 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
5729 _syscmd(cmd, buf, sizeof(buf));
5730 sscanf(buf, "%lu", &output_struct->wifi_Associations);
5731
5732#if 0
5733 //TODO: need to revisit below implementation
5734 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5735 char interface_name[MAX_BUF_SIZE] = {0};
5736 char interface_status[MAX_BUF_SIZE] = {0};
5737 char Value[MAX_BUF_SIZE] = {0};
5738 char buf[MAX_CMD_SIZE] = {0};
5739 char cmd[MAX_CMD_SIZE] = {0};
5740 FILE *fp = NULL;
5741
5742 if (NULL == output_struct) {
5743 return RETURN_ERR;
5744 }
5745
5746 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5747
5748 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
5749 {
5750 if(apIndex == 0) //private_wifi for 2.4G
5751 {
5752 wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
5753 }
5754 else if(apIndex == 1) //private_wifi for 5G
5755 {
5756 wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
5757 }
5758 else if(apIndex == 4) //public_wifi for 2.4G
5759 {
5760 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
5761 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
5762 {
5763 return RETURN_ERR;
5764 }
5765 if(buf[0] == '#')//tp-link
5766 wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
5767 else//tenda
5768 wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name);
5769 }
5770 else if(apIndex == 5) //public_wifi for 5G
5771 {
5772 wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
5773 }
5774
5775 GetIfacestatus(interface_name, interface_status);
5776
5777 if(0 != strcmp(interface_status, "1"))
5778 return RETURN_ERR;
5779
5780 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5781 system(cmd);
5782
5783 fp = fopen("/tmp/SSID_Stats.txt", "r");
5784 if(fp == NULL)
5785 {
5786 printf("/tmp/SSID_Stats.txt not exists \n");
5787 return RETURN_ERR;
5788 }
5789 fclose(fp);
5790
5791 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5792 File_Reading(buf, Value);
5793 output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10);
5794
5795 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5796 File_Reading(buf, Value);
5797 output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10);
5798
5799 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5800 File_Reading(buf, Value);
5801 output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10);
5802
5803 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5804 File_Reading(buf, Value);
5805 output_struct->wifi_BytesSent = strtoul(Value, NULL, 10);
5806
5807 /* There is no specific parameter from caller to associate the value wifi_Associations */
5808 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);
5809 //_syscmd(cmd, buf, sizeof(buf));
5810 //sscanf(buf,"%lu", &output_struct->wifi_Associations);
5811 }
5812#endif
5813 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5814 return RETURN_OK;
5815}
5816
5817INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
5818{
5819 char interface_name[MAX_BUF_SIZE] = {0};
5820 char interface_status[MAX_BUF_SIZE] = {0};
5821 char Value[MAX_BUF_SIZE] = {0};
5822 char buf[MAX_CMD_SIZE] = {0};
5823 char cmd[MAX_CMD_SIZE] = {0};
5824 FILE *fp = NULL;
5825
5826 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5827 if (NULL == output_struct)
5828 return RETURN_ERR;
5829
5830 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
5831
5832 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
5833 return RETURN_ERR;
5834 GetIfacestatus(interface_name, interface_status);
5835
5836 if(0 != strcmp(interface_status, "1"))
5837 return RETURN_ERR;
5838
5839 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5840 system(cmd);
5841
5842 fp = fopen("/tmp/SSID_Stats.txt", "r");
5843 if(fp == NULL)
5844 {
5845 printf("/tmp/SSID_Stats.txt not exists \n");
5846 return RETURN_ERR;
5847 }
5848 fclose(fp);
5849
5850 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5851 File_Reading(buf, Value);
5852 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
5853
5854 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5855 File_Reading(buf, Value);
5856 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
5857
5858 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5859 File_Reading(buf, Value);
5860 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
5861
5862 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5863 File_Reading(buf, Value);
5864 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
5865
5866 output_struct->wifi_UnicastPacketsSent = 0;
5867 output_struct->wifi_UnicastPacketsReceived = 0;
5868 output_struct->wifi_MulticastPacketsSent = 0;
5869 output_struct->wifi_MulticastPacketsReceived = 0;
5870 output_struct->wifi_BroadcastPacketsSent = 0;
5871 output_struct->wifi_BroadcastPacketsRecevied = 0;
5872 output_struct->wifi_UnknownPacketsReceived = 0;
5873
5874 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5875 return RETURN_OK;
5876}
5877
5878INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
5879{
5880 INT status = RETURN_ERR;
5881
5882 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5883 //Below values should get updated from hal
5884 output_struct->wifi_RetransCount=0;
5885 output_struct->wifi_FailedRetransCount=0;
5886 output_struct->wifi_RetryCount=0;
5887 output_struct->wifi_MultipleRetryCount=0;
5888 output_struct->wifi_ACKFailureCount=0;
5889 output_struct->wifi_AggregatedPacketCount=0;
5890
5891 status = RETURN_OK;
5892 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5893
5894 return status;
5895}
5896
5897INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
5898{
5899 INT status = RETURN_ERR;
5900 UINT index;
5901 wifi_neighbor_ap_t *pt=NULL;
5902
5903 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5904 *output_array_size=2;
5905 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
5906 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
5907 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
5908 strcpy(pt->ap_Radio,"");
5909 strcpy(pt->ap_SSID,"");
5910 strcpy(pt->ap_BSSID,"");
5911 strcpy(pt->ap_Mode,"");
5912 pt->ap_Channel=1;
5913 pt->ap_SignalStrength=0;
5914 strcpy(pt->ap_SecurityModeEnabled,"");
5915 strcpy(pt->ap_EncryptionMode,"");
5916 strcpy(pt->ap_OperatingFrequencyBand,"");
5917 strcpy(pt->ap_SupportedStandards,"");
5918 strcpy(pt->ap_OperatingStandards,"");
5919 strcpy(pt->ap_OperatingChannelBandwidth,"");
5920 pt->ap_BeaconPeriod=1;
5921 pt->ap_Noise=0;
5922 strcpy(pt->ap_BasicDataTransferRates,"");
5923 strcpy(pt->ap_SupportedDataTransferRates,"");
5924 pt->ap_DTIMPeriod=1;
5925 pt->ap_ChannelUtilization = 1;
5926 }
5927
5928 status = RETURN_OK;
5929 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5930
5931 return status;
5932}
5933
5934//----------------- AP HAL -------------------------------
5935
5936//>> Deprecated: used for old RDKB code.
5937INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
5938{
5939 if (NULL == output_ulong || NULL == output_struct)
5940 return RETURN_ERR;
5941 *output_ulong = 0;
5942 *output_struct = NULL;
5943 return RETURN_OK;
5944}
5945
5946#ifdef HAL_NETLINK_IMPL
5947static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
5948 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5949 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5950 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
5951 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
5952 char mac_addr[20];
5953 static int count=0;
5954 int rate=0;
5955
5956 wifi_device_info_t *out = (wifi_device_info_t*)arg;
5957
5958 nla_parse(tb,
5959 NL80211_ATTR_MAX,
5960 genlmsg_attrdata(gnlh, 0),
5961 genlmsg_attrlen(gnlh, 0),
5962 NULL);
5963
5964 if(!tb[NL80211_ATTR_STA_INFO]) {
5965 fprintf(stderr, "sta stats missing!\n");
5966 return NL_SKIP;
5967 }
5968
5969
5970 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
5971 fprintf(stderr, "failed to parse nested attributes!\n");
5972 return NL_SKIP;
5973 }
5974
5975 //devIndex starts from 1
5976 if( ++count == out->wifi_devIndex )
5977 {
5978 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
5979 //Getting the mac addrress
5980 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
5981
5982 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
5983 fprintf(stderr, "failed to parse nested rate attributes!");
5984 return NL_SKIP;
5985 }
5986
5987 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
5988 if(rinfo[NL80211_RATE_INFO_BITRATE])
5989 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5990 out->wifi_devTxRate = rate/10;
5991 }
5992
5993 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
5994 fprintf(stderr, "failed to parse nested rate attributes!");
5995 return NL_SKIP;
5996 }
5997
5998 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
5999 if(rinfo[NL80211_RATE_INFO_BITRATE])
6000 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
6001 out->wifi_devRxRate = rate/10;
6002 }
6003 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
6004 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
6005
6006 out->wifi_devAssociatedDeviceAuthentiationState = 1;
6007 count = 0; //starts the count for next cycle
6008 return NL_STOP;
6009 }
6010
6011 return NL_SKIP;
6012
6013}
6014#endif
6015
6016INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
6017{
6018#ifdef HAL_NETLINK_IMPL
6019 Netlink nl = {0};
6020 char if_name[10] = {0};
6021 char interface_name[16] = {0};
6022
6023 wifi_device_info_t info = {0};
6024 info.wifi_devIndex = devIndex;
6025
6026 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6027 return RETURN_ERR;
6028
6029 snprintf(if_name,sizeof(if_name),"%s", interface_name);
6030
6031 nl.id = initSock80211(&nl);
6032
6033 if (nl.id < 0) {
6034 fprintf(stderr, "Error initializing netlink \n");
6035 return -1;
6036 }
6037
6038 struct nl_msg* msg = nlmsg_alloc();
6039
6040 if (!msg) {
6041 fprintf(stderr, "Failed to allocate netlink message.\n");
6042 nlfree(&nl);
6043 return -2;
6044 }
6045
6046 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +08006047 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +08006048 NL_AUTO_SEQ,
6049 nl.id,
6050 0,
6051 NLM_F_DUMP,
6052 NL80211_CMD_GET_STATION,
6053 0);
6054
6055 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +08006056 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +08006057 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
6058 nl_recvmsgs(nl.socket, nl.cb);
6059 nlmsg_free(msg);
6060 nlfree(&nl);
6061
6062 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
6063 output_struct->wifi_devRxRate = info.wifi_devRxRate;
6064 output_struct->wifi_devTxRate = info.wifi_devTxRate;
6065 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
6066 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
6067 return RETURN_OK;
6068#else
6069 //iw utility to retrieve station information
6070#define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt"
6071#define SIGNALFILE "/tmp/wifi_signalstrength.txt"
6072#define MACFILE "/tmp/wifi_AssoMac.txt"
6073#define TXRATEFILE "/tmp/wifi_txrate.txt"
6074#define RXRATEFILE "/tmp/wifi_rxrate.txt"
6075 FILE *file = NULL;
6076 char if_name[10] = {'\0'};
6077 char pipeCmd[256] = {'\0'};
6078 char line[256] = {0};
6079 char interface_name[16] = {0};
6080 int count = 0, device = 0;
6081
6082 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6083 return RETURN_ERR;
6084
6085 snprintf(if_name,sizeof(if_name),"%s", interface_name);
6086
6087 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name);
6088 file = popen(pipeCmd, "r");
6089
6090 if(file == NULL)
6091 return RETURN_ERR; //popen failed
6092
6093 fgets(line, sizeof line, file);
6094 device = atoi(line);
6095 pclose(file);
6096
6097 if(device == 0)
6098 return RETURN_ERR; //No devices are connected
6099
6100 sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name);
6101 system(pipeCmd);
6102
6103 system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE);
6104
6105 system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE);
6106
6107 system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE);
6108
6109 system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE);
6110
6111 //devIndex starts from 1, ++count
6112 if((file = fopen(SIGNALFILE, "r")) != NULL )
6113 {
6114 for(count =0;fgets(line, sizeof line, file) != NULL;)
6115 {
6116 if (++count == devIndex)
6117 {
6118 output_struct->wifi_devSignalStrength = atoi(line);
6119 break;
6120 }
6121 }
6122 fclose(file);
6123 }
6124 else
6125 fprintf(stderr,"fopen wifi_signalstrength.txt failed");
6126
6127 if((file = fopen(MACFILE, "r")) != NULL )
6128 {
6129 for(count =0;fgets(line, sizeof line, file) != NULL;)
6130 {
6131 if (++count == devIndex)
6132 {
6133 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]);
6134 break;
6135 }
6136 }
6137 fclose(file);
6138 }
6139 else
6140 fprintf(stderr,"fopen wifi_AssoMac.txt failed");
6141
6142 if((file = fopen(TXRATEFILE, "r")) != NULL )
6143 {
6144 for(count =0;fgets(line, sizeof line, file) != NULL;)
6145 {
6146 if (++count == devIndex)
6147 {
6148 output_struct->wifi_devTxRate = atoi(line);
6149 break;
6150 }
6151 }
6152 fclose(file);
6153 }
6154 else
6155 fprintf(stderr,"fopen wifi_txrate.txt failed");
6156
6157 if((file = fopen(RXRATEFILE, "r")) != NULL)
6158 {
6159 for(count =0;fgets(line, sizeof line, file) != NULL;)
6160 {
6161 if (++count == devIndex)
6162 {
6163 output_struct->wifi_devRxRate = atoi(line);
6164 break;
6165 }
6166 }
6167 fclose(file);
6168 }
6169 else
6170 fprintf(stderr,"fopen wifi_rxrate.txt failed");
6171
6172 output_struct->wifi_devAssociatedDeviceAuthentiationState = 1;
6173
6174 return RETURN_OK;
6175#endif
6176}
6177
6178INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
6179{
6180 if (NULL == device)
6181 return RETURN_ERR;
6182 return RETURN_OK;
6183}
6184//<<
6185
6186
6187//--------------wifi_ap_hal-----------------------------
6188//enables CTS protection for the radio used by this AP
6189INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
6190{
6191 //save config and Apply instantly
6192 return RETURN_ERR;
6193}
6194
6195// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
6196INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
6197{
6198 char config_file[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08006199 char config_dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006200 char buf[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08006201 struct params list = {0};
6202 struct params dat = {0};
6203 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08006204
6205 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6206 list.name = "ht_coex";
6207 snprintf(buf, sizeof(buf), "%d", enable);
6208 list.value = buf;
6209
developerd1824452023-05-18 12:30:04 +08006210 dat.name = "HT_BSSCoexistence";
6211 dat.value = buf;
6212
6213 band = wifi_index_to_band(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006214 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd1824452023-05-18 12:30:04 +08006215 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08006216 wifi_hostapdWrite(config_file, &list, 1);
developer262f4cb2023-05-24 12:22:04 +08006217 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08006218 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6219
6220 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6221
6222 return RETURN_OK;
6223}
6224
6225//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
6226INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
6227{
6228 char config_file[MAX_BUF_SIZE] = {'\0'};
6229 char buf[MAX_BUF_SIZE] = {'\0'};
6230 struct params list;
6231
6232 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6233 if (threshold < 256 || threshold > 2346 )
6234 return RETURN_ERR;
6235 list.name = "fragm_threshold";
6236 snprintf(buf, sizeof(buf), "%d", threshold);
6237 list.value = buf;
6238
6239 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6240 wifi_hostapdWrite(config_file, &list, 1);
6241 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6242
6243 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6244
6245 return RETURN_OK;
6246}
6247
6248// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
6249INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
6250{
6251 char config_file[64] = {'\0'};
6252 char cmd[512] = {'\0'};
6253 char buf[512] = {'\0'};
6254 char stbc_config[16] = {'\0'};
6255 wifi_band band;
6256 int iterator = 0;
6257 BOOL current_stbc = FALSE;
6258 int ant_count = 0;
6259 int ant_bitmap = 0;
6260 struct params list;
developera1255e42023-05-13 17:45:02 +08006261 char dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006262
6263 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6264
6265 band = wifi_index_to_band(radioIndex);
6266 if (band == band_invalid)
6267 return RETURN_ERR;
6268
6269 if (band == band_2_4)
6270 iterator = 1;
developera1255e42023-05-13 17:45:02 +08006271 else if ((band == band_5) || (band == band_6))
developer72fb0bb2023-01-11 09:46:29 +08006272 iterator = 2;
6273 else
6274 return RETURN_OK;
6275
6276 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
6277 for (; ant_bitmap > 0; ant_bitmap >>= 1)
6278 ant_count += ant_bitmap & 1;
6279
6280 if (ant_count == 1 && STBC_Enable == TRUE) {
6281 fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__);
6282 return RETURN_OK;
6283 }
6284
6285 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6286
6287 // set ht and vht config
6288 for (int i = 0; i < iterator; i++) {
6289 memset(stbc_config, 0, sizeof(stbc_config));
6290 memset(cmd, 0, sizeof(cmd));
6291 memset(buf, 0, sizeof(buf));
6292 list.name = (i == 0)?"ht_capab":"vht_capab";
6293 snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
6294 snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
6295 _syscmd(cmd, buf, sizeof(buf));
6296 if (strlen(buf) != 0)
6297 current_stbc = TRUE;
6298 if (current_stbc == STBC_Enable)
6299 continue;
6300
6301 if (STBC_Enable == TRUE) {
6302 // Append the STBC flags in capab config
6303 memset(cmd, 0, sizeof(cmd));
6304 if (i == 0)
6305 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
6306 else
6307 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
6308 _syscmd(cmd, buf, sizeof(buf));
6309 } else if (STBC_Enable == FALSE) {
6310 // Remove the STBC flags and remain other flags in capab
6311 memset(cmd, 0, sizeof(cmd));
6312 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6313 _syscmd(cmd, buf, sizeof(buf));
6314 memset(cmd, 0, sizeof(cmd));
6315 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
6316 _syscmd(cmd, buf, sizeof(buf));
6317 }
6318 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
6319 list.value = buf;
6320 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
6321 }
developera1255e42023-05-13 17:45:02 +08006322 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6323 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
6324 _syscmd(cmd, buf, sizeof(buf));
6325 if ((band == band_5) || (band == band_6)) {
6326 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
6327 _syscmd(cmd, buf, sizeof(buf));
6328 }
6329 /*wifi_reloadAp(radioIndex);
6330 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08006331
6332 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6333 return RETURN_OK;
6334}
6335
6336// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
6337INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
6338{
developer2c22d832023-05-18 17:46:26 +08006339 char dat_file[128] = {0};
6340 BOOL enable;
6341 wifi_band band;
6342 char amdus_buff[8] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006343
developer2c22d832023-05-18 17:46:26 +08006344 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006345
developer2c22d832023-05-18 17:46:26 +08006346 band = wifi_index_to_band(radioIndex);
6347 if (band == band_invalid) {
6348 printf("%s:Band Error\n", __func__);
6349 return RETURN_ERR;
6350 }
6351 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6352 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6353 if (strncmp(amdus_buff, "1", 1) == 0)
developer72fb0bb2023-01-11 09:46:29 +08006354 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08006355 else
6356 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006357
developer2c22d832023-05-18 17:46:26 +08006358 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6359
6360 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006361}
6362
6363// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
6364INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
6365{
developer2c22d832023-05-18 17:46:26 +08006366 char dat_file[128] = {0};
6367 BOOL enable;
6368 wifi_band band;
6369 char amdus_buff[8] = {'\0'};
6370 struct params params = {0};
developer72fb0bb2023-01-11 09:46:29 +08006371
developer2c22d832023-05-18 17:46:26 +08006372 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006373
developer2c22d832023-05-18 17:46:26 +08006374 band = wifi_index_to_band(radioIndex);
6375 if (band == band_invalid) {
6376 printf("%s:Band Error\n", __func__);
6377 return RETURN_ERR;
6378 }
6379 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6380 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6381 if (strncmp(amdus_buff, "1", 1) == 0)
6382 enable = TRUE;
6383 else
6384 enable = FALSE;
6385 if (amsduEnable == enable)
6386 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006387
developer2c22d832023-05-18 17:46:26 +08006388 params.name = "HT_AMSDU";
6389 if (amsduEnable)
6390 params.value = "1";
6391 else
6392 params.value = "0";
6393 wifi_datfileWrite(dat_file, &params, 1);
6394 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006395
developer2c22d832023-05-18 17:46:26 +08006396 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006397
developer72fb0bb2023-01-11 09:46:29 +08006398 return RETURN_OK;
6399}
6400
6401//P2 // outputs the number of Tx streams
6402INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
6403{
6404 char buf[8] = {0};
6405 char cmd[128] = {0};
6406 int phyId = 0;
6407
6408 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6409
6410 phyId = radio_index_to_phy(radioIndex);
6411 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
6412 _syscmd(cmd, buf, sizeof(buf));
6413
6414 *output_int = (INT)strtol(buf, NULL, 16);
6415
6416 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6417
6418 return RETURN_OK;
6419}
6420
6421INT fitChainMask(INT radioIndex, int antcount)
6422{
6423 char buf[128] = {0};
6424 char cmd[128] = {0};
6425 char config_file[64] = {0};
6426 wifi_band band;
6427 struct params list[2] = {0};
6428
6429 band = wifi_index_to_band(radioIndex);
6430 if (band == band_invalid)
6431 return RETURN_ERR;
6432
6433 list[0].name = "he_mu_beamformer";
6434 list[1].name = "he_su_beamformer";
6435
6436 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6437 if (antcount == 1) {
6438 // remove config about multiple antennas
6439 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6440 _syscmd(cmd, buf, sizeof(buf));
6441
6442 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
6443 _syscmd(cmd, buf, sizeof(buf));
6444
6445 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
6446 _syscmd(cmd, buf, sizeof(buf));
6447
6448 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
6449 _syscmd(cmd, buf, sizeof(buf));
6450
6451 list[0].value = "0";
6452 list[1].value = "0";
6453 } else {
6454 // 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.
6455 if (band == band_2_4 || band == band_5) {
6456 snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6457 _syscmd(cmd, buf, sizeof(buf));
6458 if (strlen(buf) > 0) {
6459 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
6460 _syscmd(cmd, buf, sizeof(buf));
6461 }
6462 }
6463 if (band == band_5) {
6464 snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6465 _syscmd(cmd, buf, sizeof(buf));
6466 if (strlen(buf) > 0) {
6467 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
6468 _syscmd(cmd, buf, sizeof(buf));
6469 }
6470 }
6471
6472 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
6473 _syscmd(cmd, buf, sizeof(buf));
6474 if (strlen(buf) == 0) {
6475 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
6476 _syscmd(cmd, buf, sizeof(buf));
6477 }
6478
6479 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
6480 _syscmd(cmd, buf, sizeof(buf));
6481 if (strlen(buf) == 0) {
6482 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
6483 _syscmd(cmd, buf, sizeof(buf));
6484 }
6485
6486 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
6487 _syscmd(cmd, buf, sizeof(buf));
6488 if (strlen(buf) == 0) {
6489 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
6490 } else {
6491 snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
6492 }
6493 _syscmd(cmd, buf, sizeof(buf));
6494
6495 list[0].value = "1";
6496 list[1].value = "1";
6497 }
6498 wifi_hostapdWrite(config_file, list, 2);
6499}
6500
6501//P2 // sets the number of Tx streams to an enviornment variable
6502INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
6503{
6504 char cmd[128] = {0};
6505 char buf[128] = {0};
6506 int phyId = 0;
6507 int cur_mask = 0;
developera1255e42023-05-13 17:45:02 +08006508 int antcountmsk = 0;
6509 INT cur_nss = 0;
6510 UCHAR dat_file[64] = {0};
6511 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08006512
6513 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6514
6515 if (numStreams <= 0) {
6516 fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams);
6517 return RETURN_ERR;
6518 }
6519
developera1255e42023-05-13 17:45:02 +08006520 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
6521 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
6522 cur_nss += 1;
6523 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
6524 if (cur_nss == numStreams)
developer72fb0bb2023-01-11 09:46:29 +08006525 return RETURN_OK;
6526
6527 wifi_setRadioEnable(radioIndex, FALSE);
6528
6529 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08006530 //iw need mask value.
6531 for (;numStreams > 0; numStreams--)
6532 antcountmsk |= 0x1 << (numStreams - 1);
6533 snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
developer72fb0bb2023-01-11 09:46:29 +08006534 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006535 if (strlen(buf) > 0) {
6536 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6537 return RETURN_ERR;
6538 }
developera1255e42023-05-13 17:45:02 +08006539 band = wifi_index_to_band(radioIndex);
6540 if (band == band_invalid) {
6541 printf("%s:Band Error\n", __func__);
6542 return RETURN_ERR;
6543 }
6544 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6545 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
6546 _syscmd(cmd, buf, sizeof(buf));
6547 if (strlen(buf) > 0) {
6548 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6549 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006550 }
developera1255e42023-05-13 17:45:02 +08006551 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
6552 _syscmd(cmd, buf, sizeof(buf));
6553 if (strlen(buf) > 0) {
6554 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6555 return RETURN_ERR;
6556 }
6557 fitChainMask(radioIndex, numStreams);
developer72fb0bb2023-01-11 09:46:29 +08006558 wifi_setRadioEnable(radioIndex, TRUE);
6559
6560 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6561 return RETURN_OK;
6562}
6563
6564//P2 // outputs the number of Rx streams
6565INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
6566{
6567 char buf[8] = {0};
6568 char cmd[128] = {0};
6569 int phyId = 0;
6570
6571 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6572
6573 phyId = radio_index_to_phy(radioIndex);
6574 sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
6575 _syscmd(cmd, buf, sizeof(buf));
6576
6577 *output_int = (INT)strtol(buf, NULL, 16);
6578
6579 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6580
6581 return RETURN_OK;
6582}
6583
6584//P2 // sets the number of Rx streams to an enviornment variable
6585INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
6586{
6587 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6588 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
6589 fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__);
6590 return RETURN_ERR;
6591 }
6592 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6593 return RETURN_ERR;
6594}
6595
6596//Get radio RDG enable setting
6597INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
6598{
developer47cc27a2023-05-17 23:09:58 +08006599 if (NULL == output_bool)
6600 return RETURN_ERR;
6601
6602 *output_bool = TRUE;
6603 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006604}
6605
6606//Get radio RDG enable setting
6607INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
6608{
developer47cc27a2023-05-17 23:09:58 +08006609 char cmd[MAX_CMD_SIZE] = {0};
6610 char buf[MAX_BUF_SIZE] = {0};
6611 char rdg_status[2] = {0};
6612 char dat_file[MAX_CMD_SIZE] = {0};
6613 struct params params = {0};
6614
6615 if (NULL == output_bool)
6616 return RETURN_ERR;
6617
6618 /*prepare dat file path*/
6619 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6620
6621 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
6622 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
6623 *output_bool = TRUE;
6624 else
6625 *output_bool = FALSE;
6626
6627 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006628}
6629
6630//Set radio RDG enable setting
6631INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
6632{
developer47cc27a2023-05-17 23:09:58 +08006633 char cmd[MAX_CMD_SIZE] = {0};
6634 char buf[MAX_BUF_SIZE] = {0};
6635 char dat_file[MAX_CMD_SIZE] = {0};
6636 struct params params = {0};
6637
6638 /*prepare dat file path*/
6639 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6640
6641 params.name = "HT_RDG";
6642
6643 if (enable) {
6644 params.value = "1";
6645 } else {
6646 params.value = "0";
6647 }
6648
6649 wifi_datfileWrite(dat_file, &params, 1);
6650
6651 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006652}
6653
developer5cd4c862023-05-26 09:34:42 +08006654
6655int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006656{
developer5cd4c862023-05-26 09:34:42 +08006657 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6658 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6659 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6660 unsigned char status;
6661 unsigned char *out_status = data;
6662 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08006663
developer5cd4c862023-05-26 09:34:42 +08006664 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6665 genlmsg_attrlen(gnlh, 0), NULL);
6666 if (err < 0){
6667 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6668 return err;
6669 }
developer8e6583c2023-05-23 13:36:06 +08006670
developer5cd4c862023-05-26 09:34:42 +08006671 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6672 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6673 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6674 if (err < 0){
6675 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6676 return err;
6677 }
developer8e6583c2023-05-23 13:36:06 +08006678
developer5cd4c862023-05-26 09:34:42 +08006679 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
6680 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
6681 if (status == 0) {
6682 wifi_debug(DEBUG_NOTICE, "disabled\n");
6683 } else {
6684 wifi_debug(DEBUG_NOTICE, "enabled\n");
6685 }
6686 *out_status = status;
6687 }
6688 }
developer8e6583c2023-05-23 13:36:06 +08006689
developer5cd4c862023-05-26 09:34:42 +08006690 return 0;
6691}
developer8e6583c2023-05-23 13:36:06 +08006692
developer5cd4c862023-05-26 09:34:42 +08006693int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
6694{
6695 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6696 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6697 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6698 unsigned char status;
6699 unsigned char *out_status = data;
6700 int err = 0;
6701
6702 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6703 genlmsg_attrlen(gnlh, 0), NULL);
6704 if (err < 0) {
6705 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6706 return err;
6707 }
6708
6709 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6710 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6711 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6712 if (err < 0) {
6713 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6714 return err;
6715 }
6716
6717 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
6718 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
6719 if (status == 0) {
6720 wifi_debug(DEBUG_NOTICE, "disabled\n");
6721 } else {
6722 wifi_debug(DEBUG_NOTICE, "enabled\n");
6723 }
6724 *out_status = status;
6725 }
6726 }
6727
6728 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08006729}
6730
developer5cd4c862023-05-26 09:34:42 +08006731INT mtk_wifi_get_ba_decl_auto_status(
6732 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
6733{
6734 char inf_name[IF_NAME_SIZE] = {0};
6735 struct mtk_nl80211_param params;
6736 unsigned int if_idx = 0;
6737 int ret = -1;
6738 struct unl unl_ins;
6739 struct nl_msg *msg = NULL;
6740 struct nlattr * msg_data = NULL;
6741 struct mtk_nl80211_param param;
6742
6743 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6744 return RETURN_ERR;
6745 if_idx = if_nametoindex(inf_name);
6746 if (!if_idx) {
6747 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6748 return RETURN_ERR;
6749 }
6750 /*init mtk nl80211 vendor cmd*/
6751 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
6752 param.if_type = NL80211_ATTR_IFINDEX;
6753 param.if_idx = if_idx;
6754
6755 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6756 if (ret) {
6757 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6758 return RETURN_ERR;
6759 }
6760 /*add mtk vendor cmd data*/
6761 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
6762 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6763 nlmsg_free(msg);
6764 goto err;
6765 }
6766
6767 /*send mtk nl80211 vendor msg*/
6768 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6769 if (ret) {
6770 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6771 goto err;
6772 }
6773 /*deinit mtk nl80211 vendor msg*/
6774 mtk_nl80211_deint(&unl_ins);
6775 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
6776 return RETURN_OK;
6777err:
6778 mtk_nl80211_deint(&unl_ins);
6779 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6780 return RETURN_ERR;
6781}
6782//Get radio ADDBA enable setting
6783INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
6784{
6785 if (output_bool == NULL) {
6786 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6787 return RETURN_ERR;
6788 }
6789 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6790 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
6791 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
6792 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
6793 return RETURN_ERR;
6794 }
6795 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6796 return RETURN_OK;
6797}
6798
developer72fb0bb2023-01-11 09:46:29 +08006799//Set radio ADDBA enable setting
6800INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
6801{
6802 return RETURN_ERR;
6803}
6804
6805//Get radio auto block ack enable setting
6806INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
6807{
developer5cd4c862023-05-26 09:34:42 +08006808 if (output_bool == NULL) {
6809 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6810 return RETURN_ERR;
6811 }
developer8e6583c2023-05-23 13:36:06 +08006812
developer5cd4c862023-05-26 09:34:42 +08006813 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6814 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
6815 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
6816 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
6817 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
6818 return RETURN_ERR;
6819 }
6820 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6821 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006822}
6823
6824//Set radio auto block ack enable setting
6825INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
6826{
6827 return RETURN_ERR;
6828}
6829
6830//Get radio 11n pure mode enable support
6831INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
6832{
6833 if (NULL == output_bool)
6834 return RETURN_ERR;
6835 *output_bool = TRUE;
6836 return RETURN_OK;
6837}
6838
6839//Get radio 11n pure mode enable setting
6840INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
6841{
6842 if (NULL == output_bool)
6843 return RETURN_ERR;
6844 *output_bool = TRUE;
6845 return RETURN_OK;
6846}
6847
6848//Set radio 11n pure mode enable setting
6849INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
6850{
6851 return RETURN_ERR;
6852}
6853
developer5cd4c862023-05-26 09:34:42 +08006854
6855int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006856{
developer5cd4c862023-05-26 09:34:42 +08006857 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6858 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
6859 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6860 unsigned char status = 0, *out_status = data;
6861 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08006862
developer5cd4c862023-05-26 09:34:42 +08006863 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6864 genlmsg_attrlen(gnlh, 0), NULL);
6865 if (err < 0) {
6866 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6867 return err;
6868 }
developer72fb0bb2023-01-11 09:46:29 +08006869
developer5cd4c862023-05-26 09:34:42 +08006870 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6871 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
6872 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6873 if (err < 0){
6874 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
6875 return err;
6876 }
developer72fb0bb2023-01-11 09:46:29 +08006877
developer5cd4c862023-05-26 09:34:42 +08006878 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
6879 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
6880 if (status == 0) {
6881 wifi_debug(DEBUG_NOTICE, "disabled\n");
6882 } else {
6883 wifi_debug(DEBUG_NOTICE, "enabled\n");
6884 }
6885 *out_status = status;
6886 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
6887 }
6888 }
6889
6890 return 0;
6891}
6892
6893INT mtk_wifi_set_igmp_en_status(
6894 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
6895 unsigned char in_en_stat, BOOL *output_bool)
6896{
6897 char inf_name[IF_NAME_SIZE] = {0};
6898 struct mtk_nl80211_param params;
6899 unsigned int if_idx = 0;
6900 int ret = -1;
6901 struct unl unl_ins;
6902 struct nl_msg *msg = NULL;
6903 struct nlattr * msg_data = NULL;
6904 struct mtk_nl80211_param param;
6905
6906 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6907 return RETURN_ERR;
6908 if_idx = if_nametoindex(inf_name);
6909 if (!if_idx) {
6910 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6911 return RETURN_ERR;
6912 }
6913 /*init mtk nl80211 vendor cmd*/
6914 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
6915 param.if_type = NL80211_ATTR_IFINDEX;
6916 param.if_idx = if_idx;
6917
6918 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6919 if (ret) {
6920 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6921 return RETURN_ERR;
6922 }
6923 /*add mtk vendor cmd data*/
6924 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
6925 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6926 nlmsg_free(msg);
6927 goto err;
6928 }
6929
6930 /*send mtk nl80211 vendor msg*/
6931 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6932 if (ret) {
6933 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6934 goto err;
6935 }
6936 /*deinit mtk nl80211 vendor msg*/
6937 mtk_nl80211_deint(&unl_ins);
6938 if (output_bool) {
6939 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
6940 } else {
6941 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
6942 }
6943 return RETURN_OK;
6944err:
6945 mtk_nl80211_deint(&unl_ins);
6946 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6947 return RETURN_ERR;
6948}
6949
6950
6951//Get radio IGMP snooping enable setting
6952INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
6953{
6954 if (output_bool == NULL) {
6955 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6956 return RETURN_ERR;
6957 }
6958 if (mtk_wifi_set_igmp_en_status
6959 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
6960 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
6961 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
6962 return RETURN_ERR;
6963 }
6964 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006965 return RETURN_OK;
6966}
6967
6968//Set radio IGMP snooping enable setting
6969INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
6970{
developer5cd4c862023-05-26 09:34:42 +08006971 if (mtk_wifi_set_igmp_en_status
6972 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
6973 NULL, enable, NULL) != RETURN_OK) {
6974 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
6975 return RETURN_ERR;
6976 }
6977 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developer72fb0bb2023-01-11 09:46:29 +08006978 return RETURN_OK;
6979}
6980
6981//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08006982INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08006983{
developer69b61b02023-03-07 17:17:44 +08006984 if (NULL == output_int)
developer72fb0bb2023-01-11 09:46:29 +08006985 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08006986 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006987
6988 return RETURN_OK;
6989}
6990
6991
6992//---------------------------------------------------------------------------------------------------
6993//
6994// Additional Wifi AP level APIs used for Access Point devices
6995//
6996//---------------------------------------------------------------------------------------------------
6997
6998// creates a new ap and pushes these parameters to the hardware
6999INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
7000{
7001 // Deprecated when use hal version 3, use wifi_createVap() instead.
7002 return RETURN_OK;
7003}
7004
7005// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
7006INT wifi_deleteAp(INT apIndex)
7007{
developer7e4a2a62023-04-06 19:56:03 +08007008 char interface_name[16] = {0};
7009 char buf[MAX_BUF_SIZE];
7010 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08007011
developer7e4a2a62023-04-06 19:56:03 +08007012 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7013 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08007014
developer7e4a2a62023-04-06 19:56:03 +08007015 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
7016 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007017
developer7e4a2a62023-04-06 19:56:03 +08007018 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007019
developer7e4a2a62023-04-06 19:56:03 +08007020 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007021}
7022
7023// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
7024INT wifi_getApName(INT apIndex, CHAR *output_string)
7025{
developer7e4a2a62023-04-06 19:56:03 +08007026 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08007027 int radio_idx = 0;
7028 int bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08007029
developer7e4a2a62023-04-06 19:56:03 +08007030 if(!output_string)
7031 return RETURN_ERR;
7032
7033 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
7034 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
7035
7036 snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model.
7037 } else
7038 snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
7039
7040 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007041}
7042
7043// Outputs the index number in that corresponds to the SSID string
7044INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
7045{
developer7e4a2a62023-04-06 19:56:03 +08007046 char cmd [128] = {0};
7047 char buf[32] = {0};
7048 char ap_idx = 0;
7049 char *apIndex_str = NULL;
7050 char radio_idx = 0;
7051 char bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08007052
developer7e4a2a62023-04-06 19:56:03 +08007053 snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
7054 inputSsidString);
7055 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007056
developer7e4a2a62023-04-06 19:56:03 +08007057 if (strlen(buf)) {
7058 apIndex_str = strtok(buf, "\n");
7059 *output_int = strtoul(apIndex_str, NULL, 10);
7060 return RETURN_OK;
7061 }
developer72fb0bb2023-01-11 09:46:29 +08007062
developer7e4a2a62023-04-06 19:56:03 +08007063 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
7064 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
7065 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
7066 radio_idx = 2;
7067 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
7068 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
7069 radio_idx = 1;
7070 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
7071 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
7072 radio_idx = 0;
7073 } else {
7074 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
7075 __func__, inputSsidString, ap_idx);
7076 *output_int = -1;
7077 return RETURN_ERR;
7078 }
7079
7080 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
7081
7082 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
7083 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
7084 __func__, inputSsidString, ap_idx);
7085 *output_int = ap_idx;
7086 return RETURN_OK;
7087 }
7088
7089 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007090}
7091
7092INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
7093{
7094 return wifi_getIndexFromName(inputSsidString, output_int);
7095}
7096
7097// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
7098INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
7099{
7100 char buf[MAX_BUF_SIZE] = {0};
7101 char cmd[MAX_CMD_SIZE] = {0};
7102 char config_file[MAX_BUF_SIZE] = {0};
7103
7104 if(NULL == output_string)
7105 return RETURN_ERR;
7106
7107 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7108 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
7109 if((strcmp(buf,"3")==0))
7110 snprintf(output_string, 32, "WPAand11i");
7111 else if((strcmp(buf,"2")==0))
7112 snprintf(output_string, 32, "11i");
7113 else if((strcmp(buf,"1")==0))
7114 snprintf(output_string, 32, "WPA");
7115 else
7116 snprintf(output_string, 32, "None");
7117
7118 return RETURN_OK;
7119}
7120
7121// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
7122INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
7123{
7124 char config_file[MAX_BUF_SIZE] = {0};
7125 struct params list;
7126
7127 if (NULL == beaconTypeString)
7128 return RETURN_ERR;
7129 list.name = "wpa";
7130 list.value = "0";
7131
7132 if((strcmp(beaconTypeString,"WPAand11i")==0))
7133 list.value="3";
7134 else if((strcmp(beaconTypeString,"11i")==0))
7135 list.value="2";
7136 else if((strcmp(beaconTypeString,"WPA")==0))
7137 list.value="1";
7138
7139 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7140 wifi_hostapdWrite(config_file, &list, 1);
7141 wifi_hostapdProcessUpdate(apIndex, &list, 1);
7142 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
7143 return RETURN_OK;
7144}
7145
7146// sets the beacon interval on the hardware for this AP
7147INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
7148{
7149 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7150 struct params params={'\0'};
7151 char buf[MAX_BUF_SIZE] = {'\0'};
7152 char config_file[MAX_BUF_SIZE] = {'\0'};
7153
7154 params.name = "beacon_int";
7155 snprintf(buf, sizeof(buf), "%u", beaconInterval);
7156 params.value = buf;
7157
7158 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7159 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08007160
developer72fb0bb2023-01-11 09:46:29 +08007161 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7162 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7163 return RETURN_OK;
7164}
7165
7166INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
7167{
7168 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
7169 return RETURN_ERR;
7170 return RETURN_OK;
7171}
7172
7173// Get the packet size threshold supported.
7174INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
7175{
7176 //save config and apply instantly
7177 if (NULL == output_bool)
7178 return RETURN_ERR;
7179 *output_bool = TRUE;
7180 return RETURN_OK;
7181}
7182
7183// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
7184INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
7185{
developer72fb0bb2023-01-11 09:46:29 +08007186 char buf[16] = {0};
7187 char config_file[128] = {0};
7188 struct params param = {0};
7189
7190 if (threshold > 65535) {
7191 fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold);
7192 return RETURN_ERR;
7193 }
7194
developer23e71282023-01-18 10:25:19 +08007195 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007196 snprintf(buf, sizeof(buf), "%u", threshold);
7197 param.name = "rts_threshold";
7198 param.value = buf;
7199 wifi_hostapdWrite(config_file, &param, 1);
7200 wifi_hostapdProcessUpdate(apIndex, &param, 1);
7201 wifi_reloadAp(apIndex);
7202
7203 return RETURN_OK;
7204}
7205
7206// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7207INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
7208{
7209 if (NULL == output_string)
7210 return RETURN_ERR;
7211 snprintf(output_string, 32, "TKIPandAESEncryption");
7212 return RETURN_OK;
7213
7214}
7215
7216// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7217INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
7218{
7219 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7220 char *param_name = NULL;
7221 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
7222
7223 if(NULL == output_string)
7224 return RETURN_ERR;
7225
7226 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7227 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
7228
7229 if(strcmp(buf,"0")==0)
7230 {
7231 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
7232 snprintf(output_string, 32, "None");
7233 return RETURN_OK;
7234 }
7235 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
7236 param_name = "rsn_pairwise";
7237 else if((strcmp(buf,"1")==0))
7238 param_name = "wpa_pairwise";
7239 else
7240 return RETURN_ERR;
7241 memset(output_string,'\0',32);
7242 wifi_hostapdRead(config_file,param_name,output_string,32);
7243 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
7244 param_name = "wpa_pairwise";
7245 memset(output_string, '\0', 32);
7246 wifi_hostapdRead(config_file, param_name, output_string, 32);
7247 }
7248 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
7249
developere5750452023-05-15 16:46:42 +08007250 if(strcmp(output_string,"TKIP CCMP") == 0)
7251 strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption"));
7252 else if(strcmp(output_string,"TKIP") == 0)
developer72fb0bb2023-01-11 09:46:29 +08007253 strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption"));
7254 else if(strcmp(output_string,"CCMP") == 0)
7255 strncpy(output_string,"AESEncryption", strlen("AESEncryption"));
developer72fb0bb2023-01-11 09:46:29 +08007256
7257 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7258 return RETURN_OK;
7259}
7260
7261// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7262INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
7263{
7264 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7265 struct params params={'\0'};
7266 char output_string[32];
7267 char config_file[MAX_BUF_SIZE] = {0};
7268
7269 memset(output_string,'\0',32);
developere5750452023-05-15 16:46:42 +08007270 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08007271
7272 if(strcmp(encMode, "TKIPEncryption") == 0)
7273 params.value = "TKIP";
7274 else if(strcmp(encMode,"AESEncryption") == 0)
7275 params.value = "CCMP";
7276 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
7277 params.value = "TKIP CCMP";
7278
7279 if((strcmp(output_string,"WPAand11i")==0))
7280 {
7281 params.name = "wpa_pairwise";
7282 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7283 wifi_hostapdWrite(config_file, &params, 1);
7284 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7285
7286 params.name = "rsn_pairwise";
7287 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7288 wifi_hostapdWrite(config_file, &params, 1);
7289 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7290
7291 return RETURN_OK;
7292 }
7293 else if((strcmp(output_string,"11i")==0))
7294 {
7295 params.name = "rsn_pairwise";
7296 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7297 wifi_hostapdWrite(config_file, &params, 1);
7298 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7299 return RETURN_OK;
7300 }
7301 else if((strcmp(output_string,"WPA")==0))
7302 {
7303 params.name = "wpa_pairwise";
7304 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7305 wifi_hostapdWrite(config_file, &params, 1);
7306 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7307 return RETURN_OK;
7308 }
7309
7310 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7311 return RETURN_OK;
7312}
7313
7314// deletes internal security varable settings for this ap
7315INT wifi_removeApSecVaribles(INT apIndex)
7316{
7317 //TODO: remove the entry in hostapd config file
7318 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name);
7319 //_syscmd(cmd, buf, sizeof(buf));
7320
7321 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name);
7322 //_syscmd(cmd, buf, sizeof(buf));
7323 return RETURN_ERR;
7324}
7325
7326// changes the hardware settings to disable encryption on this ap
7327INT wifi_disableApEncryption(INT apIndex)
7328{
7329 //Apply instantly
7330 return RETURN_ERR;
7331}
7332
7333// set the authorization mode on this ap
7334// mode mapping as: 1: open, 2: shared, 4:auto
7335INT wifi_setApAuthMode(INT apIndex, INT mode)
7336{
7337 struct params params={0};
7338 char config_file[64] = {0};
7339 int ret;
7340
7341 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
7342
7343 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
7344 params.name = "auth_algs";
7345
developere5750452023-05-15 16:46:42 +08007346 if ((mode & 1 && mode & 2) || mode & 4)
developer72fb0bb2023-01-11 09:46:29 +08007347 params.value = "3";
7348 else if (mode & 2)
7349 params.value = "2";
7350 else if (mode & 1)
7351 params.value = "1";
7352 else
7353 params.value = "0";
7354
7355 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7356 wifi_hostapdWrite(config_file, &params, 1);
7357 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08007358 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007359 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
7360
7361 return RETURN_OK;
7362}
7363
7364// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7365INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7366{
7367 //save to wifi config, and wait for wifi restart to apply
7368 struct params params={'\0'};
7369 char config_file[MAX_BUF_SIZE] = {0};
7370 int ret;
7371
7372 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7373 if(authMode == NULL)
7374 return RETURN_ERR;
7375
7376 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
7377 params.name = "wpa_key_mgmt";
7378
7379 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
7380 params.value = "WPA-PSK";
7381 else if(strcmp(authMode,"EAPAuthentication") == 0)
7382 params.value = "WPA-EAP";
7383 else if (strcmp(authMode, "SAEAuthentication") == 0)
7384 params.value = "SAE";
7385 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
7386 params.value = "WPA-EAP-SUITE-B-192";
7387 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
7388 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
developer3086e2f2023-01-17 09:40:01 +08007389 else if (strcmp(authMode, "Enhanced_Open") == 0)
7390 params.value = "OWE";
developer72fb0bb2023-01-11 09:46:29 +08007391 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
7392 return RETURN_OK; //This is taken careof in beaconType
7393
7394 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7395 ret=wifi_hostapdWrite(config_file,&params,1);
7396 if(!ret)
7397 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
7398 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7399
7400 return ret;
7401}
7402
7403// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7404INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7405{
7406 //save to wifi config, and wait for wifi restart to apply
7407 char BeaconType[50] = {0};
7408 char config_file[MAX_BUF_SIZE] = {0};
7409
7410 *authMode = 0;
7411 wifi_getApBeaconType(apIndex,BeaconType);
7412 printf("%s____%s \n",__FUNCTION__,BeaconType);
7413
7414 if(strcmp(BeaconType,"None") == 0)
7415 strcpy(authMode,"None");
7416 else
7417 {
7418 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7419 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
7420 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
7421 if(strcmp(authMode,"WPA-PSK") == 0)
7422 strcpy(authMode,"SharedAuthentication");
7423 else if(strcmp(authMode,"WPA-EAP") == 0)
7424 strcpy(authMode,"EAPAuthentication");
7425 }
7426
7427 return RETURN_OK;
7428}
7429
7430// Outputs the number of stations associated per AP
7431INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
7432{
7433 char interface_name[16] = {0};
7434 char cmd[128]={0};
7435 char buf[128]={0};
7436 BOOL status = false;
7437
7438 if(apIndex > MAX_APS)
7439 return RETURN_ERR;
7440
7441 wifi_getApEnable(apIndex,&status);
7442 if (!status)
7443 return RETURN_OK;
7444
7445 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
7446 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7447 return RETURN_ERR;
7448 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name);
7449 _syscmd(cmd, buf, sizeof(buf));
7450 sscanf(buf,"%lu", output_ulong);
7451
7452 return RETURN_OK;
7453}
7454
7455// manually removes any active wi-fi association with the device specified on this ap
7456INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
7457{
developer7e4a2a62023-04-06 19:56:03 +08007458 char inf_name[16] = {0};
7459 char cmd[MAX_CMD_SIZE] = {0};
7460 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007461
developer7e4a2a62023-04-06 19:56:03 +08007462 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08007463 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007464
7465 snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
7466 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007467
7468 return RETURN_OK;
7469}
7470
7471// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
7472INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
7473{
developer7e4a2a62023-04-06 19:56:03 +08007474 int max_radio_num = 0;
7475
7476 if(NULL == output_int)
7477 return RETURN_ERR;
7478
7479 wifi_getMaxRadioNumber(&max_radio_num);
7480 *output_int = apIndex % max_radio_num;
7481
7482 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007483}
7484
7485// sets the radio index for the specific ap
7486INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
7487{
7488 //set to config only and wait for wifi reset to apply settings
7489 return RETURN_ERR;
7490}
7491
developer121a8e72023-05-22 09:19:39 +08007492
7493#define MAX_ACL_DUMP_LEN 4096
7494int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
7495{
7496 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7497 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
7498 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7499 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08007500 int err = 0;
developer121a8e72023-05-22 09:19:39 +08007501 unsigned short acl_result_len = 0;
7502 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08007503 if (!msg || !cb_data) {
developer2edaf012023-05-24 14:24:53 +08007504 wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data);
developer121a8e72023-05-22 09:19:39 +08007505 return NL_SKIP;
7506 }
developer121a8e72023-05-22 09:19:39 +08007507 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7508 genlmsg_attrlen(gnlh, 0), NULL);
7509 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08007510 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08007511 return NL_SKIP;
7512 }
developer121a8e72023-05-22 09:19:39 +08007513 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7514 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
7515 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7516 if (err < 0)
7517 return NL_SKIP;
7518 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
7519 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7520 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7521 if (acl_result_len > MAX_ACL_DUMP_LEN) {
7522 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
7523 return NL_SKIP;
7524 } else if (*(show_str + acl_result_len - 1) != '\0') {
7525 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
7526 *(show_str + acl_result_len - 1) = '\0';
7527 }
7528 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08007529
7530 if (cb_data->out_len >= acl_result_len) {
7531 memset(cb_data->out_buf, 0, cb_data->out_len);
7532 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
7533 memmove(cb_data->out_buf, show_str, acl_result_len);
7534 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
7535 } else {
7536 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08007537 }
developer121a8e72023-05-22 09:19:39 +08007538 } else
7539 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
7540 } else
7541 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
7542 return NL_OK;
7543}
developer72fb0bb2023-01-11 09:46:29 +08007544// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08007545INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08007546{
developer7e4a2a62023-04-06 19:56:03 +08007547 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08007548 struct mtk_nl80211_param params;
7549 unsigned int if_idx = 0;
7550 int ret = -1;
7551 struct unl unl_ins;
7552 struct nl_msg *msg = NULL;
7553 struct nlattr * msg_data = NULL;
7554 struct mtk_nl80211_param param;
7555 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08007556 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7557 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08007558 if_idx = if_nametoindex(inf_name);
7559 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08007560 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08007561 return RETURN_ERR;
7562 }
7563 /*init mtk nl80211 vendor cmd*/
7564 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7565 param.if_type = NL80211_ATTR_IFINDEX;
7566 param.if_idx = if_idx;
7567
7568 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7569 if (ret) {
7570 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7571 return RETURN_ERR;
7572 }
developer121a8e72023-05-22 09:19:39 +08007573 /*add mtk vendor cmd data*/
7574 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08007575 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08007576 nlmsg_free(msg);
7577 goto err;
7578 }
developer72fb0bb2023-01-11 09:46:29 +08007579
developer121a8e72023-05-22 09:19:39 +08007580 /*send mtk nl80211 vendor msg*/
7581 cb_data.out_buf = macArray;
7582 cb_data.out_len = buf_size;
7583
7584 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
7585 if (ret) {
7586 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7587 goto err;
7588 }
7589 /*deinit mtk nl80211 vendor msg*/
7590 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007591 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developer72fb0bb2023-01-11 09:46:29 +08007592 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08007593err:
7594 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007595 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08007596 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007597}
7598
developer2edaf012023-05-24 14:24:53 +08007599INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7600{
7601 char *mac_arry_buf = NULL;
7602
7603 mac_arry_buf = malloc(buf_size);
7604 if (!mac_arry_buf) {
7605 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
7606 return RETURN_ERR;
7607 }
7608 memset(mac_arry_buf, 0, buf_size);
7609 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
7610 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
7611 free(mac_arry_buf);
7612 mac_arry_buf = NULL;
7613 return RETURN_ERR;
7614 }
7615 /*
7616 mtk format to wifi hal format:
7617 "policy=1
7618 00:11:22:33:44:55
7619 00:11:22:33:44:66
7620 "
7621 -->
7622 "00:11:22:33:44:55
7623 00:11:22:33:44:66
7624 "
7625 */
7626 memset(macArray, 0, buf_size);
7627 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
7628 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
7629 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
7630 }
7631 free(mac_arry_buf);
7632 mac_arry_buf = NULL;
7633 return RETURN_OK;
7634}
7635
developer72fb0bb2023-01-11 09:46:29 +08007636INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7637{
developer72fb0bb2023-01-11 09:46:29 +08007638
developer7e4a2a62023-04-06 19:56:03 +08007639 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08007640
7641 return RETURN_OK;
7642}
7643
7644
7645// Get the list of stations associated per AP
7646INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
7647{
developer7e4a2a62023-04-06 19:56:03 +08007648 char interface_name[IF_NAME_SIZE] = {0};
7649 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08007650
developer7e4a2a62023-04-06 19:56:03 +08007651 if(apIndex > 3) //Currently supporting apIndex upto 3
7652 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007653
developer7e4a2a62023-04-06 19:56:03 +08007654 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7655 return RETURN_ERR;
7656
7657 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
7658 _syscmd(cmd, macArray, buf_size);
7659 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007660}
7661
developer8dd72532023-05-17 19:58:35 +08007662int hex2num(char c)
7663{
7664 if (c >= '0' && c <= '9')
7665 return c - '0';
7666 if (c >= 'a' && c <= 'f')
7667 return c - 'a' + 10;
7668 if (c >= 'A' && c <= 'F')
7669 return c - 'A' + 10;
7670 return -1;
7671}
7672
7673/**
7674 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
7675 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
7676 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
7677 * Returns: Characters used (> 0) on success, -1 on failure
7678 */
7679int hwaddr_aton2(const char *txt, unsigned char *addr)
7680{
7681 int i;
7682 const char *pos = txt;
7683
7684 for (i = 0; i < 6; i++) {
7685 int a, b;
7686
7687 while (*pos == ':' || *pos == '.' || *pos == '-')
7688 pos++;
7689
7690 a = hex2num(*pos++);
7691 if (a < 0)
7692 return -1;
7693 b = hex2num(*pos++);
7694 if (b < 0)
7695 return -1;
7696 *addr++ = (a << 4) | b;
7697 }
7698
7699 return pos - txt;
7700}
7701
developer72fb0bb2023-01-11 09:46:29 +08007702// adds the mac address to the filter list
7703//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7704INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7705{
developer7e4a2a62023-04-06 19:56:03 +08007706 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08007707 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08007708 struct nl_msg *msg = NULL;
7709 struct nlattr * msg_data = NULL;
7710 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08007711 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
7712 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08007713 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7714 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007715 if (!DeviceMacAddress)
7716 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08007717 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08007718 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08007719 return RETURN_ERR;
7720 }
developer8dd72532023-05-17 19:58:35 +08007721 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08007722 if (!if_idx) {
7723 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7724 return RETURN_ERR;
7725 }
developer49b17232023-05-19 16:35:19 +08007726 /*init mtk nl80211 vendor cmd*/
7727 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7728 param.if_type = NL80211_ATTR_IFINDEX;
7729 param.if_idx = if_idx;
7730 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7731 if (ret) {
7732 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007733 return RETURN_ERR;
7734 }
developer49b17232023-05-19 16:35:19 +08007735 /*add mtk vendor cmd data*/
7736 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08007737 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08007738 nlmsg_free(msg);
7739 goto err;
7740 }
developer49b17232023-05-19 16:35:19 +08007741 /*send mtk nl80211 vendor msg*/
7742 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7743 if (ret) {
7744 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007745 goto err;
7746 }
developer49b17232023-05-19 16:35:19 +08007747 /*deinit mtk nl80211 vendor msg*/
7748 mtk_nl80211_deint(&unl_ins);
7749 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08007750 return RETURN_OK;
7751err:
developer49b17232023-05-19 16:35:19 +08007752 mtk_nl80211_deint(&unl_ins);
7753 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08007754 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007755}
7756
7757// deletes the mac address from the filter list
7758//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7759INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7760{
developer2edaf012023-05-24 14:24:53 +08007761 struct unl unl_ins;
7762 int if_idx = 0, ret = 0;
7763 struct nl_msg *msg = NULL;
7764 struct nlattr * msg_data = NULL;
7765 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08007766 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007767 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007768
developer7e4a2a62023-04-06 19:56:03 +08007769 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7770 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007771
developer7e4a2a62023-04-06 19:56:03 +08007772 if (!DeviceMacAddress)
7773 return RETURN_ERR;
7774
developer2edaf012023-05-24 14:24:53 +08007775 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
7776 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
7777 return RETURN_ERR;
7778 }
developer72fb0bb2023-01-11 09:46:29 +08007779
developer2edaf012023-05-24 14:24:53 +08007780 if_idx = if_nametoindex(inf_name);
7781 if (!if_idx) {
7782 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7783 return RETURN_ERR;
7784 }
7785 /*init mtk nl80211 vendor cmd*/
7786 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7787 param.if_type = NL80211_ATTR_IFINDEX;
7788 param.if_idx = if_idx;
7789 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7790 if (ret) {
7791 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7792 return RETURN_ERR;
7793 }
7794 /*add mtk vendor cmd data*/
7795 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
7796 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7797 nlmsg_free(msg);
7798 goto err;
7799 }
7800 /*send mtk nl80211 vendor msg*/
7801 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7802 if (ret) {
7803 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7804 goto err;
7805 }
7806 /*deinit mtk nl80211 vendor msg*/
7807 mtk_nl80211_deint(&unl_ins);
7808 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
7809 return RETURN_OK;
7810err:
7811 mtk_nl80211_deint(&unl_ins);
7812 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7813 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007814}
7815
7816// outputs the number of devices in the filter list
7817INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
7818{
developer7e4a2a62023-04-06 19:56:03 +08007819 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007820 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
7821 UINT buf_size = 1024;
7822 UINT sta_num = 0;
7823 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007824 if(output_uint == NULL)
7825 return RETURN_ERR;
7826
developer2edaf012023-05-24 14:24:53 +08007827 mac_arry = (char *)malloc(buf_size);
7828 if (mac_arry == NULL) {
7829 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08007830 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007831 }
7832 memset(mac_arry, buf_size, 0);
7833 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
7834 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
7835 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
7836 return RETURN_ERR;
7837 }
7838 /*count the acl str nums:*/
7839 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08007840
developer2edaf012023-05-24 14:24:53 +08007841 /*mac addr string format:
7842 exp1: 00:11:22:33:44:55\0
7843 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
7844 */
7845 ptr = mac_arry;
7846 while (sscanf(ptr, "%17s", mac_str) == 1) {
7847 if (hwaddr_aton2(mac_str, mac) >= 0)
7848 sta_num++;
7849 ptr = strstr(ptr, mac_str) + strlen(mac_str);
7850 }
7851 *output_uint = sta_num;
7852 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
7853 free(mac_arry);
7854 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08007855 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007856err:
7857 free(mac_arry);
7858 mac_arry = NULL;
7859 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007860}
7861
7862INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
7863{
7864 char cmd[128]={'\0'};
7865 char buf[128]={'\0'};
7866
7867 if(strcmp(action,"DENY")==0)
7868 {
7869 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
7870 system(buf);
7871 return RETURN_OK;
7872 }
7873
7874 if(strcmp(action,"ALLOW")==0)
7875 {
7876 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
7877 system(buf);
7878 return RETURN_OK;
7879 }
7880
7881 return RETURN_ERR;
7882
7883}
7884
7885// enable kick for devices on acl black list
7886INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
7887{
developer47cc27a2023-05-17 23:09:58 +08007888 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
7889 char assocArray[MAX_BUF_SIZE] = {0}, *asso = NULL;
developer72fb0bb2023-01-11 09:46:29 +08007890
7891 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
7892 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
7893
developer7e4a2a62023-04-06 19:56:03 +08007894 /* if there are no devices connected there is nothing to do */
developer72fb0bb2023-01-11 09:46:29 +08007895 if (strlen(assocArray) < 17)
7896 return RETURN_OK;
7897
developer7e4a2a62023-04-06 19:56:03 +08007898 if (enable == TRUE) {
7899 /* kick off the MAC which is in ACL array (deny list) */
7900 acl = strtok(aclArray, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007901 while (acl != NULL) {
7902 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
7903 wifi_kickApAssociatedDevice(apIndex, acl);
7904
developer7e4a2a62023-04-06 19:56:03 +08007905 acl = strtok(NULL, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007906 }
7907 wifi_setApMacAddressControlMode(apIndex, 2);
developer7e4a2a62023-04-06 19:56:03 +08007908 } else
developer72fb0bb2023-01-11 09:46:29 +08007909 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08007910
developer72fb0bb2023-01-11 09:46:29 +08007911 return RETURN_OK;
7912}
7913
7914INT wifi_setPreferPrivateConnection(BOOL enable)
7915{
7916 return RETURN_OK;
7917}
7918
7919// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
7920INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
7921{
developer2edaf012023-05-24 14:24:53 +08007922 int if_idx = 0, ret = 0;
7923 struct unl unl_ins;
7924 struct nl_msg *msg = NULL;
7925 struct nlattr * msg_data = NULL;
7926 struct mtk_nl80211_param param;
7927 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08007928 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007929
developer7e4a2a62023-04-06 19:56:03 +08007930 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7931 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007932 if_idx = if_nametoindex(inf_name);
7933 if (!if_idx) {
7934 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7935 return RETURN_ERR;
7936 }
7937 /*init mtk nl80211 vendor cmd*/
7938 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7939 param.if_type = NL80211_ATTR_IFINDEX;
7940 param.if_idx = if_idx;
7941 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7942 if (ret) {
7943 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7944 return RETURN_ERR;
7945 }
7946 /*add mtk vendor cmd data*/
7947 if (filterMode == 0) {
7948 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
7949 } else if (filterMode == 1) {
7950 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
7951 } else if (filterMode == 2) {
7952 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
7953 } else {
7954 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
7955 nlmsg_free(msg);
7956 goto err;
7957 }
7958 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
7959 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7960 nlmsg_free(msg);
7961 goto err;
7962 }
7963 /*send mtk nl80211 vendor msg*/
7964 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7965 if (ret) {
7966 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7967 goto err;
7968 }
7969 /*deinit mtk nl80211 vendor msg*/
7970 mtk_nl80211_deint(&unl_ins);
7971 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08007972 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007973err:
7974 mtk_nl80211_deint(&unl_ins);
7975 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7976 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007977}
7978
7979// 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.
7980INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
7981{
7982 return RETURN_ERR;
7983}
7984
7985// gets the vlan ID for this ap from an internal enviornment variable
7986INT wifi_getApVlanID(INT apIndex, INT *output_int)
7987{
7988 if(apIndex==0)
7989 {
7990 *output_int=100;
7991 return RETURN_OK;
7992 }
7993
7994 return RETURN_ERR;
7995}
7996
7997// sets the vlan ID for this ap to an internal enviornment variable
7998INT wifi_setApVlanID(INT apIndex, INT vlanId)
7999{
8000 //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)
8001 return RETURN_ERR;
8002}
8003
8004// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
8005INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
8006{
8007 snprintf(bridgeName, 32, "brlan0");
8008 snprintf(IP, 32, "10.0.0.1");
8009 snprintf(subnet, 32, "255.255.255.0");
8010
8011 return RETURN_OK;
8012}
8013
8014//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
8015INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
8016{
8017 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
8018 return RETURN_ERR;
8019}
8020
8021// reset the vlan configuration for this ap
8022INT wifi_resetApVlanCfg(INT apIndex)
8023{
developera1255e42023-05-13 17:45:02 +08008024 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08008025 int if_idx, ret = 0;
8026 struct nl_msg *msg = NULL;
8027 struct nlattr * msg_data = NULL;
8028 struct mtk_nl80211_param param;
8029 struct unl unl_ins;
8030 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08008031
developer2202b332023-05-24 16:23:22 +08008032 if (apIndex > MAX_APS) {
8033 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8034 return RETURN_ERR;
8035 }
developer72fb0bb2023-01-11 09:46:29 +08008036
developer2202b332023-05-24 16:23:22 +08008037 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8038 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8039 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008040
developer2202b332023-05-24 16:23:22 +08008041 /*step 1. mwctl dev %s set vlan_tag 0*/
8042 if_idx = if_nametoindex(interface_name);
8043 /*init mtk nl80211 vendor cmd*/
8044 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
8045 param.if_type = NL80211_ATTR_IFINDEX;
8046 param.if_idx = if_idx;
8047 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08008048
developer2202b332023-05-24 16:23:22 +08008049 if (ret) {
8050 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8051 return RETURN_ERR;
8052 }
developer72fb0bb2023-01-11 09:46:29 +08008053
developer2202b332023-05-24 16:23:22 +08008054 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
8055 printf("Nla put attribute error\n");
8056 nlmsg_free(msg);
8057 goto err;
8058 }
developer72fb0bb2023-01-11 09:46:29 +08008059
developer2202b332023-05-24 16:23:22 +08008060 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8061 if (ret) {
8062 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8063 goto err;
8064 }
8065 mtk_nl80211_deint(&unl_ins);
8066 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08008067
developer2202b332023-05-24 16:23:22 +08008068 /*step 2. mwctl dev %s set vlan_priority 0*/
8069 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8070 if (ret) {
8071 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8072 return RETURN_ERR;
8073 }
developer72fb0bb2023-01-11 09:46:29 +08008074
developer2202b332023-05-24 16:23:22 +08008075 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
8076 printf("Nla put attribute error\n");
8077 nlmsg_free(msg);
8078 goto err;
8079 }
developer72fb0bb2023-01-11 09:46:29 +08008080
developer2202b332023-05-24 16:23:22 +08008081 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8082 if (ret) {
8083 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8084 goto err;
8085 }
8086 mtk_nl80211_deint(&unl_ins);
8087 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
8088
8089 /*step 3. mwctl dev %s set vlan_id 0*/
8090 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8091 if (ret) {
8092 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08008093 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08008094 }
developer72fb0bb2023-01-11 09:46:29 +08008095
developer2202b332023-05-24 16:23:22 +08008096 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
8097 printf("Nla put attribute error\n");
8098 nlmsg_free(msg);
8099 goto err;
8100 }
8101
8102 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8103 if (ret) {
8104 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8105 goto err;
8106 }
8107 mtk_nl80211_deint(&unl_ins);
8108 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
8109
8110 /*step 4. mwctl dev %s set vlan_en 0*/
8111 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8112 if (ret) {
8113 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8114 return RETURN_ERR;
8115 }
8116
8117 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
8118 printf("Nla put attribute error\n");
8119 nlmsg_free(msg);
8120 goto err;
8121 }
8122
8123 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8124 if (ret) {
8125 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8126 goto err;
8127 }
8128 mtk_nl80211_deint(&unl_ins);
8129 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
8130
8131 /*step 5. mwctl dev %s set vlan_policy 0:4*/
8132 vlan_param.direction = 0;
8133 vlan_param.policy = 4;
8134 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8135 if (ret) {
8136 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8137 return RETURN_ERR;
8138 }
8139 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
8140 printf("Nla put attribute error\n");
8141 nlmsg_free(msg);
8142 goto err;
8143 }
8144
8145 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8146 if (ret) {
8147 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8148 goto err;
8149 }
8150 mtk_nl80211_deint(&unl_ins);
8151 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
8152
8153 /*step 6. mwctl dev %s set vlan_policy 1:0*/
8154 vlan_param.direction = 1;
8155 vlan_param.policy = 0;
8156 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8157 if (ret) {
8158 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8159 return RETURN_ERR;
8160 }
8161
8162 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
8163 printf("Nla put attribute error\n");
8164 nlmsg_free(msg);
8165 goto err;
8166 }
8167
8168 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8169 if (ret) {
8170 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8171 goto err;
8172 }
8173 /*deinit mtk nl80211 vendor msg*/
8174 mtk_nl80211_deint(&unl_ins);
8175 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
8176
8177 /*TODO need to modify VLAN config in dat file*/
8178 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8179
8180 return RETURN_OK;
8181err:
8182 mtk_nl80211_deint(&unl_ins);
8183 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8184 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008185}
8186
8187// 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.
8188INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
8189{
8190 return RETURN_ERR;
8191}
8192
8193// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
8194INT wifi_startHostApd()
8195{
8196 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8197 system("systemctl start hostapd.service");
8198 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8199 return RETURN_OK;
8200 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
8201}
8202
8203// stops hostapd
developer69b61b02023-03-07 17:17:44 +08008204INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08008205{
8206 char cmd[128] = {0};
8207 char buf[128] = {0};
8208
8209 sprintf(cmd,"systemctl stop hostapd");
8210 _syscmd(cmd, buf, sizeof(buf));
8211
8212 return RETURN_OK;
8213}
8214
8215// restart hostapd dummy function
8216INT wifi_restartHostApd()
8217{
8218 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8219 system("systemctl restart hostapd-global");
8220 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8221
8222 return RETURN_OK;
8223}
8224
8225static int align_hostapd_config(int index)
8226{
8227 ULONG lval;
8228 wifi_getRadioChannel(index%2, &lval);
8229 wifi_setRadioChannel(index%2, lval);
8230 return RETURN_OK;
8231}
8232
8233// sets the AP enable status variable for the specified ap.
8234INT wifi_setApEnable(INT apIndex, BOOL enable)
8235{
developer7e4a2a62023-04-06 19:56:03 +08008236 char interface_name[16] = {0};
8237 char config_file[MAX_BUF_SIZE] = {0};
8238 char cmd[MAX_CMD_SIZE] = {0};
8239 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008240 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08008241 int max_radio_num = 0;
8242 int phyId = 0;
developer72fb0bb2023-01-11 09:46:29 +08008243
developer7e4a2a62023-04-06 19:56:03 +08008244 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08008245
developer7e4a2a62023-04-06 19:56:03 +08008246 wifi_getMaxRadioNumber(&max_radio_num);
8247 if (enable == status)
8248 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008249
developer7e4a2a62023-04-06 19:56:03 +08008250 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8251 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008252
developer7e4a2a62023-04-06 19:56:03 +08008253 if (enable == TRUE) {
8254 int radioIndex = apIndex % max_radio_num;
8255 phyId = radio_index_to_phy(radioIndex);
developerf3c7d292023-05-29 17:57:16 +08008256 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
8257 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08008258
developer7e4a2a62023-04-06 19:56:03 +08008259 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
8260 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
8261 _syscmd(cmd, buf, sizeof(buf));
8262 } else {
8263 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8264 _syscmd(cmd, buf, sizeof(buf));
developerf3c7d292023-05-29 17:57:16 +08008265 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
8266 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +08008267 }
8268 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
8269 interface_name, interface_name, enable, VAP_STATUS_FILE);
8270 _syscmd(cmd, buf, sizeof(buf));
8271 //Wait for wifi up/down to apply
8272 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008273}
8274
8275// Outputs the setting of the internal variable that is set by wifi_setApEnable().
8276INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
8277{
developer7e4a2a62023-04-06 19:56:03 +08008278 char interface_name[IF_NAME_SIZE] = {0};
8279 char cmd[MAX_CMD_SIZE] = {0};
8280 char buf[MAX_BUF_SIZE] = {0};
developere740c2a2023-05-23 18:34:32 +08008281 int ret;
developer72fb0bb2023-01-11 09:46:29 +08008282
developer7e4a2a62023-04-06 19:56:03 +08008283 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
8284 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008285
developer7e4a2a62023-04-06 19:56:03 +08008286 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08008287
developer7e4a2a62023-04-06 19:56:03 +08008288 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
8289 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8290 *output_bool = FALSE;
8291 return RETURN_OK;
8292 }
developere740c2a2023-05-23 18:34:32 +08008293 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status", interface_name);
8294 ret = system(cmd);
8295 if (ret == 0)
8296 *output_bool = 1;
developer7e4a2a62023-04-06 19:56:03 +08008297 }
developer72fb0bb2023-01-11 09:46:29 +08008298
developer7e4a2a62023-04-06 19:56:03 +08008299 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008300}
8301
developer69b61b02023-03-07 17:17:44 +08008302// Outputs the AP "Enabled" "Disabled" status from driver
8303INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08008304{
developer7e4a2a62023-04-06 19:56:03 +08008305 char cmd[128] = {0};
8306 char buf[128] = {0};
8307 BOOL output_bool;
developer72fb0bb2023-01-11 09:46:29 +08008308
developer7e4a2a62023-04-06 19:56:03 +08008309 if (!output_string) {
8310 printf("%s: null pointer!", __func__);
8311 return RETURN_ERR;
8312 }
developer72fb0bb2023-01-11 09:46:29 +08008313
developer7e4a2a62023-04-06 19:56:03 +08008314 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08008315
developer7e4a2a62023-04-06 19:56:03 +08008316 if(output_bool == 1)
8317 snprintf(output_string, 32, "Up");
8318 else
8319 snprintf(output_string, 32, "Disable");
8320
8321 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008322}
8323
8324//Indicates whether or not beacons include the SSID name.
8325// outputs a 1 if SSID on the AP is enabled, else outputs 0
8326INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
8327{
8328 //get the running status
8329 char config_file[MAX_BUF_SIZE] = {0};
8330 char buf[16] = {0};
8331
8332 if (!output)
8333 return RETURN_ERR;
8334
8335 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8336 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
8337 // default is enable
8338 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
8339 *output = TRUE;
8340
8341 return RETURN_OK;
8342}
8343
8344// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
8345INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
8346{
8347 //store the config, apply instantly
8348 char config_file[MAX_BUF_SIZE] = {0};
8349 struct params list;
8350
8351 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8352 list.name = "ignore_broadcast_ssid";
8353 list.value = enable?"0":"1";
8354
8355 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8356 wifi_hostapdWrite(config_file, &list, 1);
8357 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8358 //TODO: call hostapd_cli for dynamic_config_control
8359 wifi_reloadAp(apIndex);
8360 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8361
8362 return RETURN_OK;
8363}
8364
8365//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
8366INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
8367{
developer47cc27a2023-05-17 23:09:58 +08008368 /* get the running status */
8369 if(!output_uint)
8370 return RETURN_ERR;
8371
8372 *output_uint = 15;
8373 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008374}
8375
developer47cc27a2023-05-17 23:09:58 +08008376/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +08008377INT wifi_setApRetryLimit(INT apIndex, UINT number)
8378{
developer47cc27a2023-05-17 23:09:58 +08008379 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008380}
8381
developer95c045d2023-05-24 19:26:28 +08008382int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
8383{
8384 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8385 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
8386 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8387 unsigned char *status = (unsigned char * *)data;
8388 int err = 0;
8389 //u16 acl_result_len = 0;
8390
8391 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8392 genlmsg_attrlen(gnlh, 0), NULL);
8393 if (err < 0)
8394 return err;
8395
8396 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8397 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
8398 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8399 if (err < 0)
8400 return err;
8401
8402 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
8403 //acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
8404 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
8405 }
8406 }
8407
8408 return 0;
8409}
8410
developer72fb0bb2023-01-11 09:46:29 +08008411//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
8412INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
8413{
developer95c045d2023-05-24 19:26:28 +08008414 int if_idx, ret = 0;
developer8e6583c2023-05-23 13:36:06 +08008415 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08008416 unsigned char status = 0;
8417 struct nl_msg *msg = NULL;
8418 struct nlattr * msg_data = NULL;
8419 struct mtk_nl80211_param param;
8420 struct unl unl_ins;
8421 struct vlan_policy_param vlan_param;
developer8e6583c2023-05-23 13:36:06 +08008422
8423 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008424 if(!output)
8425 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008426
developer95c045d2023-05-24 19:26:28 +08008427 if (apIndex > MAX_APS) {
8428 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8429 return RETURN_ERR;
8430 }
8431
developer8e6583c2023-05-23 13:36:06 +08008432 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8433 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +08008434
8435 if_idx = if_nametoindex(interface_name);
8436 /*init mtk nl80211 vendor cmd*/
8437 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8438 param.if_type = NL80211_ATTR_IFINDEX;
8439 param.if_idx = if_idx;
8440 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8441
8442 if (ret) {
8443 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8444 return RETURN_ERR;
8445 }
8446
8447 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
8448 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8449 nlmsg_free(msg);
8450 goto err;
8451 }
8452
8453 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
8454 (void *)&status);
8455 if (ret) {
8456 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8457 goto err;
8458 }
8459 mtk_nl80211_deint(&unl_ins);
8460
8461 *output = status == 0 ? FALSE : TRUE;
8462 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +08008463
8464 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008465 return RETURN_OK;
developer95c045d2023-05-24 19:26:28 +08008466err:
8467 mtk_nl80211_deint(&unl_ins);
8468 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8469 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008470}
8471
8472//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
8473INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
8474{
8475 //get the running status from driver
8476 char cmd[128] = {0};
8477 char buf[128] = {0};
8478 int max_radio_num = 0, radioIndex = 0;
8479 int phyId = 0;
8480
8481 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8482
8483 wifi_getMaxRadioNumber(&max_radio_num);
8484 radioIndex = apIndex % max_radio_num;
8485 phyId = radio_index_to_phy(radioIndex);
8486 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
8487 _syscmd(cmd,buf, sizeof(buf));
8488
8489 if (strlen(buf) > 0)
8490 *output = true;
8491
8492 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8493
8494 return RETURN_OK;
8495}
8496
8497//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
8498INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
8499{
developer95c045d2023-05-24 19:26:28 +08008500 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +08008501}
8502
8503// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
8504INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
8505{
developer95c045d2023-05-24 19:26:28 +08008506 int if_idx, ret = 0;
8507 char interface_name[16] = {0};
8508 unsigned char status = 0;
8509 struct nl_msg *msg = NULL;
8510 struct nlattr * msg_data = NULL;
8511 struct mtk_nl80211_param param;
8512 struct unl unl_ins;
8513 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08008514
developer95c045d2023-05-24 19:26:28 +08008515 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008516
developer95c045d2023-05-24 19:26:28 +08008517 if (apIndex > MAX_APS) {
8518 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8519 return RETURN_ERR;
8520 }
developer72fb0bb2023-01-11 09:46:29 +08008521
developer95c045d2023-05-24 19:26:28 +08008522 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8523 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008524
developer95c045d2023-05-24 19:26:28 +08008525 if_idx = if_nametoindex(interface_name);
8526 /*init mtk nl80211 vendor cmd*/
8527 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8528 param.if_type = NL80211_ATTR_IFINDEX;
8529 param.if_idx = if_idx;
8530 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8531
8532 if (ret) {
8533 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8534 return RETURN_ERR;
8535 }
8536
8537 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
8538 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8539 nlmsg_free(msg);
8540 goto err;
8541 }
8542
8543 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8544 if (ret) {
8545 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8546 goto err;
8547 }
8548 mtk_nl80211_deint(&unl_ins);
8549
8550 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8551 return RETURN_OK;
8552err:
8553 mtk_nl80211_deint(&unl_ins);
8554 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8555 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008556}
8557
developer95c045d2023-05-24 19:26:28 +08008558
developer72fb0bb2023-01-11 09:46:29 +08008559//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.
8560INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
8561{
8562 //get the running status from driver
8563 if(!output)
8564 return RETURN_ERR;
8565
8566 char config_file[128] = {0};
8567 char buf[16] = {0};
8568
8569 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8570 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
8571 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
8572 *output = TRUE;
8573 else
8574 *output = FALSE;
8575
8576 return RETURN_OK;
8577}
8578
8579// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
8580INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
8581{
8582 //save config and apply instantly.
8583 char config_file[MAX_BUF_SIZE] = {0};
8584 struct params list;
8585
8586 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8587 list.name = "uapsd_advertisement_enabled";
8588 list.value = enable?"1":"0";
8589
8590 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8591 wifi_hostapdWrite(config_file, &list, 1);
8592 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developere82c0ca2023-05-10 16:25:35 +08008593 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008594 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8595
8596 return RETURN_OK;
8597}
8598
8599// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
8600INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
8601{
8602 char interface_name[16] = {0};
8603 // assume class 0->BE, 1->BK, 2->VI, 3->VO
8604 char cmd[128] = {0};
8605 char buf[128] = {0};
8606 char ack_filepath[128] = {0};
8607 uint16_t bitmap = 0;
8608 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
8609 FILE *f = NULL;
8610
8611 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
8612
8613 // Get current setting
8614 snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
8615 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
8616 _syscmd(cmd, buf, sizeof(buf));
8617 if (strlen(buf) > 0)
8618 bitmap = strtoul(buf, NULL, 10);
8619
8620 bitmap = strtoul(buf, NULL, 10);
8621
8622 if (ackPolicy == TRUE) { // True, unset this class
8623 bitmap &= ~class_map[class];
8624 } else { // False, set this class
8625 bitmap |= class_map[class];
8626 }
8627
8628 f = fopen(ack_filepath, "w");
8629 if (f == NULL) {
8630 fprintf(stderr, "%s: fopen failed\n", __func__);
8631 return RETURN_ERR;
8632 }
8633 fprintf(f, "%hu", bitmap);
8634 fclose(f);
8635
8636 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8637 return RETURN_ERR;
8638 snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
8639 _syscmd(cmd, buf, sizeof(buf));
8640
8641 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
8642 return RETURN_OK;
8643}
8644
8645//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.
8646INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
8647{
8648 //get the running status from driver
8649 if(!output_uint)
8650 return RETURN_ERR;
8651
8652 char output[16]={'\0'};
8653 char config_file[MAX_BUF_SIZE] = {0};
8654
8655 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8656 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
8657 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
8658 else {
8659 int device_num = atoi(output);
8660 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
8661 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
8662 return RETURN_ERR;
8663 }
8664 else {
8665 *output_uint = device_num;
8666 }
8667 }
8668
8669 return RETURN_OK;
8670}
8671
8672INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
8673{
8674 //store to wifi config, apply instantly
8675 char str[MAX_BUF_SIZE]={'\0'};
8676 char cmd[MAX_CMD_SIZE]={'\0'};
8677 struct params params;
8678 char config_file[MAX_BUF_SIZE] = {0};
8679
8680 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8681 if (number > MAX_ASSOCIATED_STA_NUM) {
8682 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
8683 return RETURN_ERR;
8684 }
8685 sprintf(str, "%d", number);
8686 params.name = "max_num_sta";
8687 params.value = str;
8688
8689 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
8690 int ret = wifi_hostapdWrite(config_file, &params, 1);
8691 if (ret) {
8692 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
8693 ,__func__, ret);
8694 }
8695
8696 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
8697 if (ret) {
8698 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
8699 ,__func__, ret);
8700 }
8701 wifi_reloadAp(apIndex);
8702 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8703
8704 return RETURN_OK;
8705}
8706
8707//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.
8708INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
8709{
8710 //get the current threshold
8711 if(!output_uint)
8712 return RETURN_ERR;
8713 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
8714 if (*output_uint == 0)
8715 *output_uint = 50;
8716 return RETURN_OK;
8717}
8718
8719INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
8720{
8721 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
8722 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
8723 return RETURN_OK;
8724 return RETURN_ERR;
8725}
8726
8727//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.
8728INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
8729{
8730 if(!output_uint)
8731 return RETURN_ERR;
8732 *output_uint = 3;
8733 return RETURN_OK;
8734}
8735
8736//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
8737INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
8738{
8739 if(!output_uint)
8740 return RETURN_ERR;
8741 *output_uint = 3;
8742 return RETURN_OK;
8743}
8744
8745//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.
8746INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
8747{
8748 if(!output_in_seconds)
8749 return RETURN_ERR;
8750 *output_in_seconds = 0;
8751 return RETURN_OK;
8752}
8753
8754//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
8755INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
8756{
8757 if(!output || apIndex>=MAX_APS)
8758 return RETURN_ERR;
8759 //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
8760 snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
8761 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008762}
developer72fb0bb2023-01-11 09:46:29 +08008763
8764//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
8765INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
8766{
8767 char config_file[128] = {0};
8768 char wpa[16] = {0};
8769 char key_mgmt[64] = {0};
8770 char buf[16] = {0};
8771 if (!output)
8772 return RETURN_ERR;
8773
8774 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8775 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
8776
8777 strcpy(output, "None");//Copying "None" to output string for default case
8778 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
8779 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
8780 if (!strcmp(wpa, "1"))
8781 snprintf(output, 32, "WPA-Personal");
8782 else if (!strcmp(wpa, "2"))
8783 snprintf(output, 32, "WPA2-Personal");
8784 else if (!strcmp(wpa, "3"))
8785 snprintf(output, 32, "WPA-WPA2-Personal");
8786
developere5750452023-05-15 16:46:42 +08008787 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
8788 snprintf(output, 32, "WPA3-Enterprise");
developer72fb0bb2023-01-11 09:46:29 +08008789 } else if (strstr(key_mgmt, "WPA-EAP")) {
8790 if (!strcmp(wpa, "1"))
8791 snprintf(output, 32, "WPA-Enterprise");
8792 else if (!strcmp(wpa, "2"))
8793 snprintf(output, 32, "WPA2-Enterprise");
8794 else if (!strcmp(wpa, "3"))
8795 snprintf(output, 32, "WPA-WPA2-Enterprise");
8796 } else if (strstr(key_mgmt, "SAE")) {
8797 if (strstr(key_mgmt, "WPA-PSK") == NULL)
8798 snprintf(output, 32, "WPA3-Personal");
8799 else
8800 snprintf(output, 32, "WPA3-Personal-Transition");
developer72fb0bb2023-01-11 09:46:29 +08008801 }
8802
8803 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8804 return RETURN_OK;
8805#if 0
8806 //TODO: need to revisit below implementation
8807 char securityType[32], authMode[32];
8808 int enterpriseMode=0;
8809
8810 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8811 if(!output)
8812 return RETURN_ERR;
8813
8814 wifi_getApBeaconType(apIndex, securityType);
8815 strcpy(output,"None");//By default, copying "None" to output string
8816 if (strncmp(securityType,"None", strlen("None")) == 0)
8817 return RETURN_OK;
8818
8819 wifi_getApBasicAuthenticationMode(apIndex, authMode);
8820 enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0;
8821
8822 if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0)
8823 snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal");
8824 else if (strncmp(securityType, "WPA", strlen("WPA")) == 0)
8825 snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal");
8826 else if (strncmp(securityType, "11i", strlen("11i")) == 0)
8827 snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal");
8828 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8829
8830 return RETURN_OK;
8831#endif
8832}
developer69b61b02023-03-07 17:17:44 +08008833
developer72fb0bb2023-01-11 09:46:29 +08008834INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
8835{
8836 char securityType[32];
8837 char authMode[32];
8838
8839 //store settings and wait for wifi up to apply
8840 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8841 if(!encMode)
8842 return RETURN_ERR;
8843
8844 if (strcmp(encMode, "None")==0)
8845 {
8846 strcpy(securityType,"None");
8847 strcpy(authMode,"None");
8848 }
8849 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
8850 {
8851 strcpy(securityType,"WPAand11i");
8852 strcpy(authMode,"PSKAuthentication");
8853 }
8854 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
8855 {
8856 strcpy(securityType,"WPAand11i");
8857 strcpy(authMode,"EAPAuthentication");
8858 }
8859 else if (strcmp(encMode, "WPA-Personal")==0)
8860 {
8861 strcpy(securityType,"WPA");
8862 strcpy(authMode,"PSKAuthentication");
8863 }
8864 else if (strcmp(encMode, "WPA-Enterprise")==0)
8865 {
8866 strcpy(securityType,"WPA");
8867 strcpy(authMode,"EAPAuthentication");
8868 }
8869 else if (strcmp(encMode, "WPA2-Personal")==0)
8870 {
8871 strcpy(securityType,"11i");
8872 strcpy(authMode,"PSKAuthentication");
8873 }
8874 else if (strcmp(encMode, "WPA2-Enterprise")==0)
8875 {
8876 strcpy(securityType,"11i");
8877 strcpy(authMode,"EAPAuthentication");
8878 }
8879 else if (strcmp(encMode, "WPA3-Personal") == 0)
8880 {
8881 strcpy(securityType,"11i");
8882 strcpy(authMode,"SAEAuthentication");
8883 }
8884 else if (strcmp(encMode, "WPA3-Personal-Transition") == 0)
8885 {
8886 strcpy(securityType, "11i");
8887 strcpy(authMode, "PSK-SAEAuthentication");
8888 }
8889 else if (strcmp(encMode, "WPA3-Enterprise") == 0)
8890 {
8891 strcpy(securityType,"11i");
8892 strcpy(authMode,"EAP_192-bit_Authentication");
8893 }
developer3086e2f2023-01-17 09:40:01 +08008894 else if (strcmp(encMode, "OWE") == 0)
8895 {
8896 strcpy(securityType,"11i");
8897 strcpy(authMode,"Enhanced_Open");
8898 }
developer72fb0bb2023-01-11 09:46:29 +08008899 else
8900 {
8901 strcpy(securityType,"None");
8902 strcpy(authMode,"None");
8903 }
8904 wifi_setApBeaconType(apIndex, securityType);
8905 wifi_setApBasicAuthenticationMode(apIndex, authMode);
8906 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8907
8908 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008909}
developer72fb0bb2023-01-11 09:46:29 +08008910
8911
8912//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
8913// output_string must be pre-allocated as 64 character string by caller
8914// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8915INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
8916{
8917 char buf[16] = {0};
8918 char config_file[MAX_BUF_SIZE] = {0};
8919
8920 if(output_string==NULL)
8921 return RETURN_ERR;
8922
8923 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8924 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8925
8926 if(strcmp(buf,"0")==0)
8927 {
8928 printf("wpa_mode is %s ......... \n",buf);
8929 return RETURN_ERR;
8930 }
8931
8932 wifi_dbg_printf("\nFunc=%s\n",__func__);
8933 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
developere5750452023-05-15 16:46:42 +08008934 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developer72fb0bb2023-01-11 09:46:29 +08008935 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8936
8937 return RETURN_OK;
8938}
8939
8940// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
8941// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8942INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
8943{
8944 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8945 struct params params={'\0'};
8946 int ret;
8947 char config_file[MAX_BUF_SIZE] = {0};
8948
8949 if(NULL == preSharedKey)
8950 return RETURN_ERR;
8951
developere5750452023-05-15 16:46:42 +08008952 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +08008953
developere5750452023-05-15 16:46:42 +08008954 if(strlen(preSharedKey) != 64)
developer72fb0bb2023-01-11 09:46:29 +08008955 {
developere5750452023-05-15 16:46:42 +08008956 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
developer72fb0bb2023-01-11 09:46:29 +08008957 return RETURN_ERR;
8958 }
8959 params.value = preSharedKey;
8960 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8961 ret = wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +08008962 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08008963 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008964 wifi_reloadAp(apIndex);
8965 }
developer72fb0bb2023-01-11 09:46:29 +08008966 return ret;
8967 //TODO: call hostapd_cli for dynamic_config_control
8968}
8969
8970//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
8971// outputs the passphrase, maximum 63 characters
8972INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
8973{
8974 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
8975
8976 wifi_dbg_printf("\nFunc=%s\n",__func__);
8977 if (NULL == output_string)
8978 return RETURN_ERR;
8979
8980 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8981 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8982 if(strcmp(buf,"0")==0)
8983 {
8984 printf("wpa_mode is %s ......... \n",buf);
8985 return RETURN_ERR;
8986 }
8987
8988 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
8989 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8990
8991 return RETURN_OK;
8992}
8993
8994// sets the passphrase enviornment variable, max 63 characters
8995INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
8996{
8997 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8998 struct params params={'\0'};
8999 char config_file[MAX_BUF_SIZE] = {0};
9000 int ret;
9001
9002 if(NULL == passPhrase)
9003 return RETURN_ERR;
9004
9005 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
9006 {
9007 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
9008 return RETURN_ERR;
9009 }
9010 params.name = "wpa_passphrase";
9011 params.value = passPhrase;
9012 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
9013 ret=wifi_hostapdWrite(config_file,&params,1);
developere5750452023-05-15 16:46:42 +08009014 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08009015 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08009016 wifi_reloadAp(apIndex);
9017 }
developer72fb0bb2023-01-11 09:46:29 +08009018
9019 return ret;
9020}
9021
9022//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.
9023INT wifi_setApSecurityReset(INT apIndex)
9024{
9025 char original_config_file[64] = {0};
9026 char current_config_file[64] = {0};
9027 char buf[64] = {0};
9028 char cmd[64] = {0};
9029 char wpa[4] = {0};
9030 char wpa_psk[64] = {0};
9031 char wpa_passphrase[64] = {0};
9032 char wpa_psk_file[128] = {0};
9033 char wpa_key_mgmt[64] = {0};
9034 char wpa_pairwise[32] = {0};
9035 wifi_band band;
9036 struct params list[6];
9037
9038 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9039
9040 band = wifi_index_to_band(apIndex);
9041 if (band == band_2_4)
9042 sprintf(original_config_file, "/etc/hostapd-2G.conf");
9043 else if (band == band_5)
9044 sprintf(original_config_file, "/etc/hostapd-5G.conf");
9045 else if (band == band_6)
9046 sprintf(original_config_file, "/etc/hostapd-6G.conf");
9047 else
9048 return RETURN_ERR;
9049
9050 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
9051 list[0].name = "wpa";
9052 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +08009053
developer72fb0bb2023-01-11 09:46:29 +08009054 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
9055 list[1].name = "wpa_psk";
9056 list[1].value = wpa_psk;
9057
9058 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
9059 list[2].name = "wpa_passphrase";
9060 list[2].value = wpa_passphrase;
9061
9062 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
9063
9064 if (strlen(wpa_psk_file) == 0)
9065 strcpy(wpa_psk_file, PSK_FILE);
9066
9067 if (access(wpa_psk_file, F_OK) != 0) {
9068 sprintf(cmd, "touch %s", wpa_psk_file);
9069 _syscmd(cmd, buf, sizeof(buf));
9070 }
9071 list[3].name = "wpa_psk_file";
9072 list[3].value = wpa_psk_file;
9073
9074 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
9075 list[4].name = "wpa_key_mgmt";
9076 list[4].value = wpa_key_mgmt;
9077
9078 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
9079 list[5].name = "wpa_pairwise";
9080 list[5].value = wpa_pairwise;
9081
9082 sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
9083 wifi_hostapdWrite(current_config_file, list, 6);
9084
9085 wifi_setApEnable(apIndex, FALSE);
9086 wifi_setApEnable(apIndex, TRUE);
9087
9088 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9089 return RETURN_OK;
9090}
9091
9092//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).
9093INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
9094{
9095 char config_file[64] = {0};
9096 char buf[64] = {0};
9097 char cmd[256] = {0};
9098
9099 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9100
9101 if(!IP_output || !Port_output || !RadiusSecret_output)
9102 return RETURN_ERR;
9103
9104 // Read the first matched config
9105 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9106 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9107 _syscmd(cmd, buf, sizeof(buf));
9108 strncpy(IP_output, buf, 64);
9109
9110 memset(buf, 0, sizeof(buf));
9111 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9112 _syscmd(cmd, buf, sizeof(buf));
9113 *Port_output = atoi(buf);
9114
9115 memset(buf, 0, sizeof(buf));
9116 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9117 _syscmd(cmd, buf, sizeof(buf));
9118 strncpy(RadiusSecret_output, buf, 64);
9119
9120 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9121 return RETURN_OK;
9122}
9123
9124INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
9125{
9126 char config_file[64] = {0};
9127 char port_str[8] = {0};
9128 char cmd[256] = {0};
9129 char buf[128] = {0};
9130
9131 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9132
developere5750452023-05-15 16:46:42 +08009133 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
9134 return RETURN_ERR;
9135
9136 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
9137 return RETURN_ERR;
9138
developer72fb0bb2023-01-11 09:46:29 +08009139 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9140
9141 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
9142 _syscmd(cmd, buf, sizeof(buf));
9143 memset(cmd, 0, sizeof(cmd));
9144
9145 snprintf(port_str, sizeof(port_str), "%d", port);
9146 if (strlen(buf) == 0)
9147 // Append
9148 snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
9149 "auth_server_addr=%s\\n"
9150 "auth_server_port=%s\\n"
9151 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
9152 else {
9153 // Delete the three lines setting after the "# radius 1" comment
9154 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
9155 _syscmd(cmd, buf, sizeof(buf));
9156 memset(cmd, 0, sizeof(cmd));
9157 // Use "# radius 1" comment to find the location to insert the radius setting
9158 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
9159 "# radius 1\\n"
9160 "auth_server_addr=%s\\n"
9161 "auth_server_port=%s\\n"
9162 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9163 }
9164 if(_syscmd(cmd, buf, sizeof(buf))) {
9165 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9166 return RETURN_ERR;
9167 }
9168
9169 wifi_reloadAp(apIndex);
9170 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9171 return RETURN_OK;
9172}
9173
9174INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
9175{
9176 char config_file[64] = {0};
9177 char buf[64] = {0};
9178 char cmd[256] = {0};
9179
9180 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9181
9182 if(!IP_output || !Port_output || !RadiusSecret_output)
9183 return RETURN_ERR;
9184
9185 // Read the second matched config
9186 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9187 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9188 _syscmd(cmd, buf, sizeof(buf));
9189 strncpy(IP_output, buf, 64);
9190
9191 memset(buf, 0, sizeof(buf));
9192 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9193 _syscmd(cmd, buf, sizeof(buf));
9194 *Port_output = atoi(buf);
9195
9196 memset(buf, 0, sizeof(buf));
9197 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9198 _syscmd(cmd, buf, sizeof(buf));
9199 strncpy(RadiusSecret_output, buf, 64);
9200
9201 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9202 return RETURN_OK;
9203}
9204
9205INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
9206{
9207 char config_file[64] = {0};
9208 char port_str[8] = {0};
9209 char cmd[256] = {0};
9210 char buf[128] = {0};
9211
9212 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9213
developere5750452023-05-15 16:46:42 +08009214 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
9215 return RETURN_ERR;
9216
9217 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
9218 return RETURN_ERR;
9219
developer72fb0bb2023-01-11 09:46:29 +08009220 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9221
9222 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
9223 _syscmd(cmd, buf, sizeof(buf));
9224 memset(cmd, 0, sizeof(cmd));
9225
9226 snprintf(port_str, sizeof(port_str), "%d", port);
9227 if (strlen(buf) == 0)
9228 // Append
9229 snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
9230 "auth_server_addr=%s\\n"
9231 "auth_server_port=%s\\n"
9232 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
9233 else {
9234 // Delete the three lines setting after the "# radius 2" comment
9235 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
9236 _syscmd(cmd, buf, sizeof(buf));
9237 memset(cmd, 0, sizeof(cmd));
9238 // Use "# radius 2" comment to find the location to insert the radius setting
9239 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
9240 "# radius 2\\n"
9241 "auth_server_addr=%s\\n"
9242 "auth_server_port=%s\\n"
9243 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9244 }
9245 if(_syscmd(cmd, buf, sizeof(buf))) {
9246 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9247 return RETURN_ERR;
9248 }
9249
9250 wifi_reloadAp(apIndex);
9251 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9252 return RETURN_OK;
9253}
9254
9255//RadiusSettings
9256INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
9257{
9258 if(!output)
9259 return RETURN_ERR;
9260
9261 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
developer69b61b02023-03-07 17:17:44 +08009262 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
9263 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
9264 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
9265 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 +08009266 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 +08009267 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
9268 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
9269 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 +08009270 //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.
9271
9272 return RETURN_OK;
9273}
9274
9275INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
9276{
9277 //store the paramters, and apply instantly
9278 return RETURN_ERR;
9279}
9280
9281//Device.WiFi.AccessPoint.{i}.WPS.Enable
9282//Enables or disables WPS functionality for this access point.
9283// outputs the WPS enable state of this ap in output_bool
9284INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
9285{
9286 char interface_name[16] = {0};
9287 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
9288 if(!output_bool)
9289 return RETURN_ERR;
9290 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9291 return RETURN_ERR;
9292 sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name);
9293 _syscmd(cmd, buf, sizeof(buf));
9294 if(strstr(buf, "configured"))
9295 *output_bool=TRUE;
9296 else
9297 *output_bool=FALSE;
9298
9299 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08009300}
developer72fb0bb2023-01-11 09:46:29 +08009301
9302//Device.WiFi.AccessPoint.{i}.WPS.Enable
9303// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
9304INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
9305{
9306 char config_file[MAX_BUF_SIZE] = {0};
developere5750452023-05-15 16:46:42 +08009307 char buf[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009308 struct params params;
9309
9310 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9311 //store the paramters, and wait for wifi up to apply
9312 params.name = "wps_state";
developere5750452023-05-15 16:46:42 +08009313 if (enable == TRUE) {
9314 wifi_getApBeaconType(apIndex, buf);
9315 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
9316 params.value = "1";
9317 else // If ap set encryption
9318 params.value = "2";
9319 } else {
9320 params.value = "0";
9321 }
developer72fb0bb2023-01-11 09:46:29 +08009322
9323 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9324 wifi_hostapdWrite(config_file, &params, 1);
9325 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9326 wifi_reloadAp(apIndex);
9327
9328 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9329 return RETURN_OK;
9330}
9331
9332//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
9333INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
9334{
9335 if(!output)
9336 return RETURN_ERR;
9337 snprintf(output, 128, "PushButton,PIN");
9338 return RETURN_OK;
9339}
9340
9341//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9342//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.
9343// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
9344INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
9345{
9346 if(!output)
9347 return RETURN_ERR;
9348 snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
9349
9350 return RETURN_OK;
9351}
9352
9353//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9354// 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
9355INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
9356{
9357 //apply instantly. No setting need to be stored.
9358 char methods[MAX_BUF_SIZE], *token, *next_token;
9359 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
9360 struct params params;
9361
9362 if(!methodString)
9363 return RETURN_ERR;
9364 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9365 //store the paramters, and wait for wifi up to apply
9366
9367 snprintf(methods, sizeof(methods), "%s", methodString);
9368 for(token=methods; *token; token=next_token)
9369 {
9370 strtok_r(token, ",", &next_token);
9371 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
9372 snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
9373 else if(*token=='E')
9374 {
9375 if(!strcmp(methods, "Ethernet"))
9376 snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
9377 else if(!strcmp(methods, "ExternalNFCToken"))
9378 snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
9379 else
9380 printf("%s: Unknown WpsConfigMethod\n", __func__);
9381 }
9382 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
9383 snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
9384 else if(*token=='N' && !strcmp(token, "NFCInterface"))
9385 snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
9386 else if(*token=='P' )
9387 {
9388 if(!strcmp(token, "PushButton"))
developere5750452023-05-15 16:46:42 +08009389 snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developer72fb0bb2023-01-11 09:46:29 +08009390 else if(!strcmp(token, "PIN"))
9391 snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
9392 else
9393 printf("%s: Unknown WpsConfigMethod\n", __func__);
9394 }
9395 else
9396 printf("%s: Unknown WpsConfigMethod\n", __func__);
9397 }
9398 params.name = "config_methods";
9399 params.value = config_methods;
9400 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9401 wifi_hostapdWrite(config_file, &params, 1);
9402 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9403 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9404
9405 return RETURN_OK;
9406}
9407
9408// outputs the pin value, ulong_pin must be allocated by the caller
9409INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
9410{
9411 char buf[MAX_BUF_SIZE] = {0};
9412 char cmd[MAX_CMD_SIZE] = {0};
9413
9414 if(!output_ulong)
9415 return RETURN_ERR;
9416 snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
9417 _syscmd(cmd, buf, sizeof(buf));
9418 if(strlen(buf) > 0)
9419 *output_ulong=strtoul(buf, NULL, 10);
9420
9421 return RETURN_OK;
9422}
9423
9424// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
9425INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
9426{
9427 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
9428 char ap_pin[16] = {0};
9429 char buf[MAX_BUF_SIZE] = {0};
9430 char config_file[MAX_BUF_SIZE] = {0};
9431 ULONG prev_pin = 0;
9432 struct params params;
9433
9434 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9435 snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
9436 params.name = "ap_pin";
9437 params.value = ap_pin;
9438 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9439 wifi_hostapdWrite(config_file, &params, 1);
9440 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9441 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9442
9443 return RETURN_OK;
9444}
9445
9446// Output string is either Not configured or Configured, max 32 characters
9447INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
9448{
9449 char interface_name[16] = {0};
9450 char cmd[MAX_CMD_SIZE];
9451 char buf[MAX_BUF_SIZE]={0};
9452
9453 if(!output_string)
9454 return RETURN_ERR;
9455 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9456 snprintf(output_string, 32, "Not configured");
9457 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9458 return RETURN_ERR;
9459 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
9460 _syscmd(cmd, buf, sizeof(buf));
9461
9462 if(!strncmp(buf, "configured", 10))
9463 snprintf(output_string, 32, "Configured");
9464 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9465
9466 return RETURN_OK;
9467}
9468
9469// sets the WPS pin for this AP
9470INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
9471{
9472 char interface_name[16] = {0};
9473 char cmd[MAX_CMD_SIZE];
9474 char buf[MAX_BUF_SIZE]={0};
9475 BOOL enable;
9476
9477 wifi_getApEnable(apIndex, &enable);
9478 if (!enable)
9479 return RETURN_ERR;
9480 wifi_getApWpsEnable(apIndex, &enable);
9481 if (!enable)
9482 return RETURN_ERR;
9483
9484 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9485 return RETURN_ERR;
9486 snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
9487 _syscmd(cmd, buf, sizeof(buf));
9488 if((strstr(buf, "OK"))!=NULL)
9489 return RETURN_OK;
9490
9491 return RETURN_ERR;
9492}
9493
9494// This function is called when the WPS push button has been pressed for this AP
9495INT wifi_setApWpsButtonPush(INT apIndex)
9496{
9497 char cmd[MAX_CMD_SIZE];
9498 char buf[MAX_BUF_SIZE]={0};
9499 char interface_name[16] = {0};
9500 BOOL enable=FALSE;
9501
9502 wifi_getApEnable(apIndex, &enable);
9503 if (!enable)
9504 return RETURN_ERR;
9505
9506 wifi_getApWpsEnable(apIndex, &enable);
9507 if (!enable)
9508 return RETURN_ERR;
9509
9510 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9511 return RETURN_ERR;
9512
9513 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
9514 _syscmd(cmd, buf, sizeof(buf));
9515
9516 if((strstr(buf, "OK"))!=NULL)
9517 return RETURN_OK;
9518 return RETURN_ERR;
9519}
9520
9521// cancels WPS mode for this AP
9522INT wifi_cancelApWPS(INT apIndex)
9523{
9524 char interface_name[16] = {0};
9525 char cmd[MAX_CMD_SIZE];
9526 char buf[MAX_BUF_SIZE]={0};
9527
9528 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9529 return RETURN_ERR;
9530 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
9531 _syscmd(cmd,buf, sizeof(buf));
9532
9533 if((strstr(buf, "OK"))!=NULL)
9534 return RETURN_OK;
9535 return RETURN_ERR;
9536}
9537
9538//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
9539//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
9540INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
9541{
9542 char interface_name[16] = {0};
9543 FILE *f = NULL;
9544 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
9545 char cmd[256] = {0}, buf[2048] = {0};
9546 char *param = NULL, *value = NULL, *line=NULL;
9547 size_t len = 0;
9548 ssize_t nread = 0;
9549 wifi_associated_dev_t *dev=NULL;
9550
9551 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9552 *associated_dev_array = NULL;
9553 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9554 return RETURN_ERR;
9555 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9556 _syscmd(cmd,buf,sizeof(buf));
9557 *output_array_size = atoi(buf);
9558
9559 if (*output_array_size <= 0)
9560 return RETURN_OK;
9561
9562 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
9563 *associated_dev_array = dev;
9564 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
9565 _syscmd(cmd,buf,sizeof(buf));
9566 f = fopen("/tmp/connected_devices.txt", "r");
9567 if (f==NULL)
9568 {
9569 *output_array_size=0;
9570 return RETURN_ERR;
9571 }
9572 while ((getline(&line, &len, f)) != -1)
9573 {
9574 param = strtok(line,"=");
9575 value = strtok(NULL,"=");
9576
9577 if( strcmp("flags",param) == 0 )
9578 {
9579 value[strlen(value)-1]='\0';
9580 if(strstr (value,"AUTHORIZED") != NULL )
9581 {
9582 dev[auth_temp].cli_AuthenticationState = 1;
9583 dev[auth_temp].cli_Active = 1;
9584 auth_temp++;
9585 read_flag=1;
9586 }
9587 }
9588 if(read_flag==1)
9589 {
9590 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
9591 {
9592 value[strlen(value)-1]='\0';
9593 sscanf(value, "%x:%x:%x:%x:%x:%x",
9594 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
9595 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
9596 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
9597 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
9598 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
9599 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
9600 mac_temp++;
9601 read_flag=0;
9602 }
9603 }
9604 }
9605 *output_array_size = auth_temp;
9606 auth_temp=0;
9607 mac_temp=0;
9608 free(line);
9609 fclose(f);
9610 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9611 return RETURN_OK;
9612}
9613
9614#define MACADDRESS_SIZE 6
9615
9616INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9617{
9618 FILE *fp = NULL;
9619 char str[MAX_BUF_SIZE] = {0};
9620 int wificlientindex = 0 ;
9621 int count = 0;
9622 int signalstrength = 0;
9623 int arr[MACADDRESS_SIZE] = {0};
9624 unsigned char mac[MACADDRESS_SIZE] = {0};
9625 UINT wifi_count = 0;
9626 char virtual_interface_name[MAX_BUF_SIZE] = {0};
9627 char pipeCmd[MAX_CMD_SIZE] = {0};
9628
9629 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9630 *output_array_size = 0;
9631 *associated_dev_array = NULL;
9632
9633 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
9634 fp = popen(pipeCmd, "r");
developer69b61b02023-03-07 17:17:44 +08009635 if (fp == NULL)
developer72fb0bb2023-01-11 09:46:29 +08009636 {
9637 printf("Failed to run command inside function %s\n",__FUNCTION__ );
9638 return RETURN_ERR;
9639 }
9640
9641 /* Read the output a line at a time - output it. */
9642 fgets(str, sizeof(str)-1, fp);
9643 wifi_count = (unsigned int) atoi ( str );
9644 *output_array_size = wifi_count;
9645 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
9646 pclose(fp);
9647
9648 if(wifi_count == 0)
9649 {
9650 return RETURN_OK;
9651 }
9652 else
9653 {
9654 wifi_associated_dev3_t* temp = NULL;
9655 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
9656 if(temp == NULL)
9657 {
9658 printf("Error Statement. Insufficient memory \n");
9659 return RETURN_ERR;
9660 }
9661
9662 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
9663 system(pipeCmd);
9664 memset(pipeCmd,0,sizeof(pipeCmd));
9665 if(apIndex == 0)
9666 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
9667 else if(apIndex == 1)
9668 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
9669 system(pipeCmd);
9670
9671 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
9672 if(fp == NULL)
9673 {
9674 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
9675 free(temp);
9676 return RETURN_ERR;
9677 }
9678 fclose(fp);
9679
9680 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
9681 fp = popen(pipeCmd, "r");
9682 if(fp)
9683 {
9684 for(count =0 ; count < wifi_count; count++)
9685 {
9686 fgets(str, MAX_BUF_SIZE, fp);
9687 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9688 {
9689 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9690 {
9691 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9692
9693 }
9694 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9695 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]);
9696 }
9697 temp[count].cli_AuthenticationState = 1; //TODO
9698 temp[count].cli_Active = 1; //TODO
9699 }
9700 pclose(fp);
9701 }
9702
9703 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
9704 fp = popen(pipeCmd, "r");
9705 if(fp)
developer69b61b02023-03-07 17:17:44 +08009706 {
developer72fb0bb2023-01-11 09:46:29 +08009707 pclose(fp);
9708 }
9709 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
9710 if(fp)
9711 {
9712 for(count =0 ; count < wifi_count ;count++)
9713 {
9714 fgets(str, MAX_BUF_SIZE, fp);
9715 signalstrength = atoi(str);
9716 temp[count].cli_SignalStrength = signalstrength;
9717 temp[count].cli_RSSI = signalstrength;
9718 temp[count].cli_SNR = signalstrength + 95;
9719 }
9720 pclose(fp);
9721 }
9722
9723
9724 if((apIndex == 0) || (apIndex == 4))
9725 {
9726 for(count =0 ; count < wifi_count ;count++)
developer69b61b02023-03-07 17:17:44 +08009727 {
developer72fb0bb2023-01-11 09:46:29 +08009728 strcpy(temp[count].cli_OperatingStandard,"g");
9729 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
9730 }
9731
9732 //BytesSent
9733 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
9734 fp = popen(pipeCmd, "r");
9735 if(fp)
developer69b61b02023-03-07 17:17:44 +08009736 {
developer72fb0bb2023-01-11 09:46:29 +08009737 pclose(fp);
9738 }
9739 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
9740 if(fp)
9741 {
9742 for (count = 0; count < wifi_count; count++)
9743 {
9744 fgets(str, MAX_BUF_SIZE, fp);
9745 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
9746 }
9747 pclose(fp);
9748 }
9749
9750 //BytesReceived
9751 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
9752 fp = popen(pipeCmd, "r");
9753 if (fp)
9754 {
9755 pclose(fp);
9756 }
9757 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
9758 if (fp)
9759 {
9760 for (count = 0; count < wifi_count; count++)
9761 {
9762 fgets(str, MAX_BUF_SIZE, fp);
9763 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
9764 }
9765 pclose(fp);
9766 }
9767
9768 //PacketsSent
9769 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
9770 fp = popen(pipeCmd, "r");
9771 if (fp)
9772 {
9773 pclose(fp);
9774 }
9775
9776 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
9777 if (fp)
9778 {
9779 for (count = 0; count < wifi_count; count++)
9780 {
9781 fgets(str, MAX_BUF_SIZE, fp);
9782 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
9783 }
9784 pclose(fp);
9785 }
9786
9787 //PacketsReceived
9788 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
9789 fp = popen(pipeCmd, "r");
9790 if (fp)
9791 {
9792 pclose(fp);
9793 }
9794 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
9795 if (fp)
9796 {
9797 for (count = 0; count < wifi_count; count++)
9798 {
9799 fgets(str, MAX_BUF_SIZE, fp);
9800 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
9801 }
9802 pclose(fp);
9803 }
9804
9805 //ErrorsSent
9806 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9807 fp = popen(pipeCmd, "r");
9808 if (fp)
9809 {
9810 pclose(fp);
9811 }
9812 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9813 if (fp)
9814 {
9815 for (count = 0; count < wifi_count; count++)
9816 {
9817 fgets(str, MAX_BUF_SIZE, fp);
9818 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9819 }
9820 pclose(fp);
9821 }
9822
9823 //ErrorsSent
9824 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9825 fp = popen(pipeCmd, "r");
9826 if (fp)
9827 {
9828 pclose(fp);
9829 }
9830 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9831 if (fp)
9832 {
9833 for (count = 0; count < wifi_count; count++)
9834 {
9835 fgets(str, MAX_BUF_SIZE, fp);
9836 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9837 }
9838 pclose(fp);
9839 }
9840
9841 //LastDataDownlinkRate
9842 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
9843 fp = popen(pipeCmd, "r");
9844 if (fp)
9845 {
9846 pclose(fp);
9847 }
9848 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
9849 if (fp)
9850 {
9851 for (count = 0; count < wifi_count; count++)
9852 {
9853 fgets(str, MAX_BUF_SIZE, fp);
9854 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
9855 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
9856 }
9857 pclose(fp);
9858 }
9859
9860 //LastDataUplinkRate
9861 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
9862 fp = popen(pipeCmd, "r");
9863 if (fp)
9864 {
9865 pclose(fp);
9866 }
9867 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
9868 if (fp)
9869 {
9870 for (count = 0; count < wifi_count; count++)
9871 {
9872 fgets(str, MAX_BUF_SIZE, fp);
9873 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
9874 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
9875 }
9876 pclose(fp);
9877 }
9878
9879 }
9880 else if ((apIndex == 1) || (apIndex == 5))
9881 {
9882 for (count = 0; count < wifi_count; count++)
9883 {
9884 strcpy(temp[count].cli_OperatingStandard, "a");
9885 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
9886 temp[count].cli_BytesSent = 0;
9887 temp[count].cli_BytesReceived = 0;
9888 temp[count].cli_LastDataUplinkRate = 0;
9889 temp[count].cli_LastDataDownlinkRate = 0;
9890 temp[count].cli_PacketsSent = 0;
9891 temp[count].cli_PacketsReceived = 0;
9892 temp[count].cli_ErrorsSent = 0;
9893 }
9894 }
9895
9896 for (count = 0; count < wifi_count; count++)
9897 {
9898 temp[count].cli_Retransmissions = 0;
9899 temp[count].cli_DataFramesSentAck = 0;
9900 temp[count].cli_DataFramesSentNoAck = 0;
9901 temp[count].cli_MinRSSI = 0;
9902 temp[count].cli_MaxRSSI = 0;
9903 strncpy(temp[count].cli_InterferenceSources, "", 64);
9904 memset(temp[count].cli_IPAddress, 0, 64);
9905 temp[count].cli_RetransCount = 0;
9906 temp[count].cli_FailedRetransCount = 0;
9907 temp[count].cli_RetryCount = 0;
9908 temp[count].cli_MultipleRetryCount = 0;
9909 }
9910 *associated_dev_array = temp;
9911 }
9912 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9913 return RETURN_OK;
9914}
9915
developer7e4a2a62023-04-06 19:56:03 +08009916int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +08009917{
developer7e4a2a62023-04-06 19:56:03 +08009918 char cmd[MAX_CMD_SIZE] = {0};
9919 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009920
developer7e4a2a62023-04-06 19:56:03 +08009921 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
9922
9923 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
9924 interface_name);
9925 _syscmd(cmd, buf, MAX_BUF_SIZE);
9926
9927 strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */
9928
9929 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009930 return RETURN_OK;
9931}
9932
9933/* #define HOSTAPD_STA_PARAM_ENTRIES 29
9934struct hostapd_sta_param {
9935 char key[50];
9936 char value[100];
9937}
9938
9939static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){
9940 int i = 0;
9941
9942 while(i<HOSTAPD_STA_PARAM_ENTRIES) {
9943 if (strncmp(params[i].key,key,50) == 0){
9944 return &params[i].value;
9945 }
9946 i++;
9947 }
9948 return NULL;
9949
9950} */
9951
9952static unsigned int count_occurences(const char *buf, const char *word)
9953{
9954 unsigned int n = 0;
9955 char *ptr = strstr(buf, word);
9956
9957 while (ptr++) {
9958 n++;
9959 ptr = strstr(ptr, word);
9960 }
9961
9962 wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word);
9963 return n;
9964}
9965
9966static const char *get_line_from_str_buf(const char *buf, char *line)
9967{
9968 int i;
9969 int n = strlen(buf);
9970
9971 for (i = 0; i < n; i++) {
9972 line[i] = buf[i];
9973 if (buf[i] == '\n') {
9974 line[i] = '\0';
9975 return &buf[i + 1];
9976 }
9977 }
9978
9979 return NULL;
9980}
9981
9982INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9983{
developer0d26f2c2023-05-25 19:46:36 +08009984 char interface_name[16] = {0};
9985 FILE *f = NULL;
9986 int auth_temp= -1;
9987 char cmd[256] = {0}, buf[2048] = {0};
9988 char *param = NULL, *value = NULL, *line=NULL;
9989 size_t len = 0;
9990 wifi_associated_dev3_t *dev=NULL;
developer72fb0bb2023-01-11 09:46:29 +08009991
9992 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer0d26f2c2023-05-25 19:46:36 +08009993 *associated_dev_array = NULL;
9994 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08009995 return RETURN_ERR;
developer0d26f2c2023-05-25 19:46:36 +08009996 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9997 _syscmd(cmd, buf, sizeof(buf));
9998 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +08009999
developer0d26f2c2023-05-25 19:46:36 +080010000 if (*output_array_size <= 0)
10001 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010002
developer0d26f2c2023-05-25 19:46:36 +080010003 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10004 *associated_dev_array = dev;
10005 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
10006 _syscmd(cmd,buf,sizeof(buf));
10007 f = fopen("/tmp/diagnostic3_devices.txt", "r");
10008 if (f == NULL)
10009 {
10010 *output_array_size=0;
developer72fb0bb2023-01-11 09:46:29 +080010011 return RETURN_ERR;
10012 }
developer0d26f2c2023-05-25 19:46:36 +080010013 while ((getline(&line, &len, f)) != -1)
10014 {
10015 param = strtok(line, "=");
10016 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +080010017
developer0d26f2c2023-05-25 19:46:36 +080010018 if( strcmp("flags",param) == 0 )
10019 {
10020 value[strlen(value)-1]='\0';
10021 if(strstr (value,"AUTHORIZED") != NULL )
10022 {
10023 auth_temp++;
10024 dev[auth_temp].cli_AuthenticationState = 1;
10025 dev[auth_temp].cli_Active = 1;
developer72fb0bb2023-01-11 09:46:29 +080010026 }
developer0d26f2c2023-05-25 19:46:36 +080010027 } else if (auth_temp < 0) {
10028 continue;
10029 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
10030 {
10031 value[strlen(value)-1]='\0';
10032 sscanf(value, "%x:%x:%x:%x:%x:%x",
10033 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
10034 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
10035 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
10036 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
10037 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
10038 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
10039 } else if (strcmp("signal", param) == 0) {
10040 value[strlen(value)-1]='\0';
10041 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
10042 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
developer72fb0bb2023-01-11 09:46:29 +080010043 }
developer0d26f2c2023-05-25 19:46:36 +080010044 }
10045 if (line)
10046 free(line);
10047 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080010048 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010049 return RETURN_OK;
10050}
10051
10052#if 0
10053//To-do
10054INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10055{
10056 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10057
10058 //Using different approach to get required WiFi Parameters from system available commands
developer69b61b02023-03-07 17:17:44 +080010059#if 0
developer72fb0bb2023-01-11 09:46:29 +080010060 FILE *f;
10061 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
10062 char cmd[256], buf[2048];
10063 char *param , *value, *line=NULL;
10064 size_t len = 0;
10065 ssize_t nread;
10066 wifi_associated_dev3_t *dev=NULL;
10067 *associated_dev_array = NULL;
10068 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
10069 _syscmd(cmd,buf,sizeof(buf));
10070 *output_array_size = atoi(buf);
10071
10072 if (*output_array_size <= 0)
10073 return RETURN_OK;
10074
10075 dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t));
10076 *associated_dev_array = dev;
10077 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name);
10078 _syscmd(cmd,buf,sizeof(buf));
10079 f = fopen("/tmp/connected_devices.txt", "r");
10080 if (f==NULL)
10081 {
10082 *output_array_size=0;
10083 return RETURN_ERR;
10084 }
10085 while ((nread = getline(&line, &len, f)) != -1)
10086 {
10087 param = strtok(line,"=");
10088 value = strtok(NULL,"=");
10089
10090 if( strcmp("flags",param) == 0 )
10091 {
10092 value[strlen(value)-1]='\0';
10093 if(strstr (value,"AUTHORIZED") != NULL )
10094 {
10095 dev[auth_temp].cli_AuthenticationState = 1;
10096 dev[auth_temp].cli_Active = 1;
10097 auth_temp++;
10098 read_flag=1;
10099 }
10100 }
10101 if(read_flag==1)
10102 {
10103 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
10104 {
10105 value[strlen(value)-1]='\0';
10106 sscanf(value, "%x:%x:%x:%x:%x:%x",
10107 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
10108 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
10109 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
10110 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
10111 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
10112 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
10113
10114 }
10115 else if( strcmp("rx_packets",param) == 0 )
10116 {
10117 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived));
10118 }
10119
10120 else if( strcmp("tx_packets",param) == 0 )
10121 {
developer69b61b02023-03-07 17:17:44 +080010122 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent));
developer72fb0bb2023-01-11 09:46:29 +080010123 }
10124
10125 else if( strcmp("rx_bytes",param) == 0 )
10126 {
10127 sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived));
10128 }
10129
10130 else if( strcmp("tx_bytes",param) == 0 )
10131 {
developer69b61b02023-03-07 17:17:44 +080010132 sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent));
developer72fb0bb2023-01-11 09:46:29 +080010133 mac_temp++;
10134 read_flag=0;
developer69b61b02023-03-07 17:17:44 +080010135 }
developer72fb0bb2023-01-11 09:46:29 +080010136 }
10137 }
10138
10139 *output_array_size = auth_temp;
10140 auth_temp=0;
10141 mac_temp=0;
10142 free(line);
10143 fclose(f);
10144#endif
10145 char interface_name[MAX_BUF_SIZE] = {0};
10146 char wifi_status[MAX_BUF_SIZE] = {0};
10147 char hostapdconf[MAX_BUF_SIZE] = {0};
10148
10149 wifi_associated_dev3_t *dev_array = NULL;
10150 ULONG wifi_count = 0;
10151
10152 *associated_dev_array = NULL;
10153 *output_array_size = 0;
10154
10155 printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex);
10156 //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI.
10157 {
10158 sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex);
10159
10160 wifi_GetInterfaceName(interface_name, hostapdconf);
10161
10162 if(strlen(interface_name) > 1)
10163 {
10164 wifihal_interfacestatus(wifi_status,interface_name);
10165 if(strcmp(wifi_status,"RUNNING") == 0)
10166 {
10167 wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count);
10168
10169 *associated_dev_array = dev_array;
developer69b61b02023-03-07 17:17:44 +080010170 *output_array_size = wifi_count;
developer72fb0bb2023-01-11 09:46:29 +080010171 }
10172 else
10173 {
10174 *associated_dev_array = NULL;
10175 }
10176 }
10177 }
10178
10179 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10180 return RETURN_OK;
10181}
10182#endif
10183
10184/* getIPAddress function */
10185/**
10186* @description Returning IpAddress of the Matched String
10187*
developer69b61b02023-03-07 17:17:44 +080010188* @param
developer72fb0bb2023-01-11 09:46:29 +080010189* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080010190* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080010191* @return The status of the operation
10192* @retval RETURN_OK if successful
10193* @retval RETURN_ERR if any error is detected
10194*
10195*/
10196
10197INT getIPAddress(char *str,char *ipaddr)
10198{
10199 FILE *fp = NULL;
10200 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
10201 int LeaseTime = 0,ret = 0;
10202 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
10203 {
10204 return RETURN_ERR;
10205 }
10206
10207 while ( fgets(buf, sizeof(buf), fp)!= NULL )
10208 {
10209 /*
10210 Sample:sss
10211 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
10212 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
10213 */
10214 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
10215 &(LeaseTime),
10216 phyAddr,
10217 ipAddr,
10218 hostName
10219 );
10220 if(ret != 4)
10221 continue;
10222 if(strcmp(str,phyAddr) == 0)
10223 strcpy(ipaddr,ipAddr);
10224 }
10225 fclose(fp);
10226 return RETURN_OK;
10227}
10228
10229/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
10230/**
10231* @description Returning Inactive wireless connected clients informations
10232*
developer69b61b02023-03-07 17:17:44 +080010233* @param
developer72fb0bb2023-01-11 09:46:29 +080010234* @filename Holding private_wifi 2g/5g content files
10235* @associated_dev_array Having inactiv wireless clients informations
10236* @output_array_size Returning Inactive wireless counts
10237* @return The status of the operation
10238* @retval RETURN_OK if successful
10239* @retval RETURN_ERR if any error is detected
10240*
10241*/
10242
10243INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10244{
10245 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10246 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
10247 FILE *fp = NULL;
10248 int arr[MACADDRESS_SIZE] = {0};
10249 unsigned char mac[MACADDRESS_SIZE] = {0};
10250 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
10251 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
10252 fp = popen(buf,"r");
10253 if(fp == NULL)
10254 return RETURN_ERR;
10255 else
10256 {
10257 fgets(path,sizeof(path),fp);
10258 maccount = atoi(path);
10259 }
10260 pclose(fp);
10261 *output_array_size = maccount;
10262 wifi_associated_dev3_t* temp = NULL;
10263 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10264 *associated_dev_array = temp;
10265 if(temp == NULL)
10266 {
10267 printf("Error Statement. Insufficient memory \n");
10268 return RETURN_ERR;
10269 }
10270 memset(buf,0,sizeof(buf));
10271 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
10272 fp = popen(buf,"r");
10273 if (fp == NULL) {
10274 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
10275 return RETURN_ERR;
10276 }
10277 for(count = 0; count < maccount ; count++)
10278 {
10279 fgets(path,sizeof(path),fp);
10280 for(i = 0; path[i]!='\n';i++)
10281 str[i]=path[i];
10282 str[i]='\0';
10283 getIPAddress(str,ipaddr);
10284 memset(buf,0,sizeof(buf));
10285 if(strlen(ipaddr) > 0)
10286 {
10287 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
10288 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
10289 {
10290 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10291 {
10292 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10293 {
10294 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
10295
10296 }
10297 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10298 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]);
10299 }
10300 temp[count].cli_AuthenticationState = 0; //TODO
developer69b61b02023-03-07 17:17:44 +080010301 temp[count].cli_Active = 0; //TODO
developer72fb0bb2023-01-11 09:46:29 +080010302 temp[count].cli_SignalStrength = 0;
10303 }
10304 else //Active wireless clients info
10305 {
10306 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10307 {
10308 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10309 {
10310 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
10311
10312 }
10313 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10314 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]);
10315 }
10316 temp[count].cli_Active = 1;
10317 }
10318 }
10319 memset(ipaddr,0,sizeof(ipaddr));
10320 }
10321 pclose(fp);
10322 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10323 return RETURN_OK;
10324}
10325//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
10326//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
10327//To get Band Steering Capability
10328INT wifi_getBandSteeringCapability(BOOL *support)
10329{
10330 *support = FALSE;
10331 return RETURN_OK;
10332}
10333
10334
10335//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
10336//To get Band Steering enable status
10337INT wifi_getBandSteeringEnable(BOOL *enable)
10338{
10339 *enable = FALSE;
10340 return RETURN_OK;
10341}
10342
10343//To turn on/off Band steering
10344INT wifi_setBandSteeringEnable(BOOL enable)
10345{
10346 return RETURN_OK;
10347}
10348
10349//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
10350//To get Band Steering AP group
10351INT wifi_getBandSteeringApGroup(char *output_ApGroup)
10352{
10353 if (NULL == output_ApGroup)
10354 return RETURN_ERR;
10355
10356 strcpy(output_ApGroup, "1,2");
10357 return RETURN_OK;
10358}
10359
10360//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
10361//to set and read the band steering BandUtilizationThreshold parameters
10362INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
10363{
10364 return RETURN_ERR;
10365}
10366
10367INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
10368{
10369 return RETURN_ERR;
10370}
10371
10372//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
10373//to set and read the band steering RSSIThreshold parameters
10374INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
10375{
10376 return RETURN_ERR;
10377}
10378
10379INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
10380{
10381 return RETURN_ERR;
10382}
10383
10384
10385//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
10386//to set and read the band steering physical modulation rate threshold parameters
10387INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
10388{
10389 //If chip is not support, return -1
10390 return RETURN_ERR;
10391}
10392
10393INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
10394{
10395 //If chip is not support, return -1
10396 return RETURN_ERR;
10397}
10398
10399//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
10400//to set and read the inactivity time (in seconds) for steering under overload condition
10401INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
10402{
10403 return RETURN_ERR;
10404}
10405
10406INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
10407{
10408 return RETURN_ERR;
10409}
10410
10411//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
10412//to set and read the inactivity time (in seconds) for steering under Idle condition
10413INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
10414{
10415 return RETURN_ERR;
10416}
10417
10418INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
10419{
10420 return RETURN_ERR;
10421}
10422
10423//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
10424//pClientMAC[64]
10425//pSourceSSIDIndex[64]
10426//pDestSSIDIndex[64]
10427//pSteeringReason[256]
10428INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
10429{
10430 //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
10431 *pSteeringTime=time(NULL);
10432 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
10433 return RETURN_OK;
10434}
10435
10436INT wifi_ifConfigDown(INT apIndex)
10437{
10438 INT status = RETURN_OK;
10439 char cmd[64];
10440
10441 snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
10442 printf("%s: %s\n", __func__, cmd);
10443 system(cmd);
10444
10445 return status;
10446}
10447
10448INT wifi_ifConfigUp(INT apIndex)
10449{
10450 char interface_name[16] = {0};
10451 char cmd[128];
10452 char buf[1024];
10453
10454 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10455 return RETURN_ERR;
10456 snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
10457 _syscmd(cmd, buf, sizeof(buf));
10458 return 0;
10459}
10460
10461//>> Deprecated. Replace with wifi_applyRadioSettings
10462INT wifi_pushBridgeInfo(INT apIndex)
10463{
developerb2977562023-05-24 17:54:12 +080010464 char ip[32] = {0};
10465 char subnet[32] = {0};
10466 char bridge[32] = {0};
10467 char cmd[128] = {0};
10468 char buf[1024] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010469
developerb2977562023-05-24 17:54:12 +080010470 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080010471
developerb2977562023-05-24 17:54:12 +080010472 snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
10473 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010474
developerb2977562023-05-24 17:54:12 +080010475 return 0;
developer72fb0bb2023-01-11 09:46:29 +080010476}
10477
10478INT wifi_pushChannel(INT radioIndex, UINT channel)
10479{
10480 char interface_name[16] = {0};
10481 char cmd[128];
10482 char buf[1024];
10483 int apIndex;
10484
developer69b61b02023-03-07 17:17:44 +080010485 apIndex=(radioIndex==0)?0:1;
developer72fb0bb2023-01-11 09:46:29 +080010486 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10487 return RETURN_ERR;
10488 snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
10489 _syscmd(cmd,buf, sizeof(buf));
10490
10491 return 0;
10492}
10493
10494INT wifi_pushChannelMode(INT radioIndex)
10495{
10496 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
10497 return RETURN_ERR;
10498}
10499
10500INT wifi_pushDefaultValues(INT radioIndex)
10501{
10502 //Apply Comcast specified default radio settings instantly
10503 //AMPDU=1
10504 //AMPDUFrames=32
10505 //AMPDULim=50000
10506 //txqueuelen=1000
10507
10508 return RETURN_ERR;
10509}
10510
10511INT wifi_pushTxChainMask(INT radioIndex)
10512{
10513 //Apply default TxChainMask instantly
10514 return RETURN_ERR;
10515}
10516
10517INT wifi_pushRxChainMask(INT radioIndex)
10518{
10519 //Apply default RxChainMask instantly
10520 return RETURN_ERR;
10521}
10522
10523INT wifi_pushSSID(INT apIndex, CHAR *ssid)
10524{
developer7e4a2a62023-04-06 19:56:03 +080010525 INT status;
developer72fb0bb2023-01-11 09:46:29 +080010526
developer7e4a2a62023-04-06 19:56:03 +080010527 status = wifi_setSSIDName(apIndex, ssid);
10528 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010529
developer7e4a2a62023-04-06 19:56:03 +080010530 return status;
developer72fb0bb2023-01-11 09:46:29 +080010531}
10532
10533INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
10534{
10535 //Apply default Ssid Advertisement instantly
10536 return RETURN_ERR;
10537}
10538
10539INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
10540{
developere82c0ca2023-05-10 16:25:35 +080010541 time_t now;
10542
10543 time(&now);
10544 if (now > radio_up_time[radioIndex])
10545 *output = now - radio_up_time[radioIndex];
10546 else {
10547 *output = 0;
10548 return RETURN_ERR;
10549 }
10550
10551 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010552}
10553
10554INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
10555{
10556 return RETURN_OK;
10557}
10558
10559INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
10560{
10561 return RETURN_OK;
10562}
10563
10564//To-do
10565INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
10566{
10567 char output[16]={'\0'};
10568 char config_file[MAX_BUF_SIZE] = {0};
10569
10570 if (!output_string)
10571 return RETURN_ERR;
10572
10573 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10574 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
10575
10576 if (strlen(output) == 0)
10577 snprintf(output_string, 64, "Disabled");
10578 else if (strncmp(output, "0", 1) == 0)
10579 snprintf(output_string, 64, "Disabled");
10580 else if (strncmp(output, "1", 1) == 0)
10581 snprintf(output_string, 64, "Optional");
10582 else if (strncmp(output, "2", 1) == 0)
10583 snprintf(output_string, 64, "Required");
10584 else {
10585 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
10586 return RETURN_ERR;
10587 }
10588
10589 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
10590 return RETURN_OK;
10591}
10592INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
10593{
10594 char str[MAX_BUF_SIZE]={'\0'};
10595 char cmd[MAX_CMD_SIZE]={'\0'};
10596 struct params params;
10597 char config_file[MAX_BUF_SIZE] = {0};
10598
10599 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10600 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
10601 return RETURN_ERR;
10602
10603 params.name = "ieee80211w";
10604 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
10605 params.value = "0";
10606 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
10607 params.value = "1";
10608 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
10609 params.value = "2";
10610 else{
10611 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
10612 return RETURN_ERR;
10613 }
10614 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10615 wifi_hostapdWrite(config_file, &params, 1);
10616 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10617 return RETURN_OK;
10618}
10619INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
10620{
10621 char output[16]={'\0'};
10622 char config_file[MAX_BUF_SIZE] = {0};
10623
10624 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerc0772e62023-05-18 15:10:48 +080010625 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
developer262f4cb2023-05-24 12:22:04 +080010626 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080010627
developer262f4cb2023-05-24 12:22:04 +080010628 if (output == NULL)
10629 *output_bool = FALSE;
10630 else if (strncmp(output, "1", 1) == 0)
10631 *output_bool = TRUE;
10632 else if (strncmp(output, "2", 1) == 0)
10633 *output_bool = TRUE;
10634 else if (strncmp(output, "3", 1) == 0)
10635 *output_bool = TRUE;
10636 else
10637 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010638 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
10639
10640 return RETURN_OK;
10641}
10642
10643INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
10644{
10645 return RETURN_OK;
10646}
10647
10648INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
10649{
10650 return RETURN_OK;
10651}
10652
10653INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
10654{
10655 return RETURN_OK;
10656}
10657
10658INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10659{
10660 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10661 char config_file[MAX_BUF_SIZE] = {0};
10662
10663 if (NULL == output)
10664 return RETURN_ERR;
10665 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10666 wifi_hostapdRead(config_file,"hw_mode",output,64);
10667
10668 if(strcmp(output,"b")==0)
10669 sprintf(output, "%s", "1,2,5.5,11");
10670 else if (strcmp(output,"a")==0)
10671 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
10672 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
10673 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
10674
10675 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10676 return RETURN_OK;
10677}
10678
10679INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10680{
10681 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10682 char *temp;
10683 char temp_output[128];
10684 char temp_TransmitRates[128];
10685 char config_file[MAX_BUF_SIZE] = {0};
10686
10687 if (NULL == output)
10688 return RETURN_ERR;
10689
10690 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10691 wifi_hostapdRead(config_file,"supported_rates",output,64);
10692
10693 if (strlen(output) == 0) {
10694 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
10695 return RETURN_OK;
10696 }
10697 strcpy(temp_TransmitRates,output);
10698 strcpy(temp_output,"");
10699 temp = strtok(temp_TransmitRates," ");
10700 while(temp!=NULL)
10701 {
10702 temp[strlen(temp)-1]=0;
10703 if((temp[0]=='5') && (temp[1]=='\0'))
10704 {
10705 temp="5.5";
10706 }
10707 strcat(temp_output,temp);
10708 temp = strtok(NULL," ");
10709 if(temp!=NULL)
10710 {
10711 strcat(temp_output,",");
10712 }
10713 }
10714 strcpy(output,temp_output);
10715 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10716
10717 return RETURN_OK;
10718}
10719
10720INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10721{
10722 return RETURN_OK;
10723}
10724
10725
10726INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10727{
10728 int i=0;
10729 char *temp;
10730 char temp1[128] = {0};
10731 char temp_output[128] = {0};
10732 char temp_TransmitRates[128] = {0};
10733 struct params params={'\0'};
10734 char config_file[MAX_BUF_SIZE] = {0};
10735 wifi_band band = wifi_index_to_band(wlanIndex);
10736
10737 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10738 if(NULL == output)
10739 return RETURN_ERR;
10740 strcpy(temp_TransmitRates,output);
10741
10742 for(i=0;i<strlen(temp_TransmitRates);i++)
10743 {
10744 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
10745 {
10746 continue;
10747 }
10748 else
10749 {
10750 return RETURN_ERR;
10751 }
10752 }
10753 strcpy(temp_output,"");
10754 temp = strtok(temp_TransmitRates,",");
10755 while(temp!=NULL)
10756 {
10757 strcpy(temp1,temp);
10758 if(band == band_5)
10759 {
10760 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
10761 {
10762 return RETURN_ERR;
10763 }
10764 }
10765
10766 if(strcmp(temp,"5.5")==0)
10767 {
10768 strcpy(temp1,"55");
10769 }
10770 else
10771 {
10772 strcat(temp1,"0");
10773 }
10774 strcat(temp_output,temp1);
10775 temp = strtok(NULL,",");
10776 if(temp!=NULL)
10777 {
10778 strcat(temp_output," ");
10779 }
10780 }
10781 strcpy(output,temp_output);
10782
10783 params.name = "supported_rates";
10784 params.value = output;
10785
10786 wifi_dbg_printf("\n%s:",__func__);
10787 wifi_dbg_printf("params.value=%s\n",params.value);
10788 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10789 wifi_hostapdWrite(config_file,&params,1);
10790 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10791
10792 return RETURN_OK;
10793}
10794
10795
10796static char *sncopy(char *dst, int dst_sz, const char *src)
10797{
10798 if (src && dst && dst_sz > 0) {
10799 strncpy(dst, src, dst_sz);
10800 dst[dst_sz - 1] = '\0';
10801 }
10802 return dst;
10803}
10804
10805static int util_get_sec_chan_offset(int channel, const char* ht_mode)
10806{
10807 if (0 == strcmp(ht_mode, "HT40") ||
10808 0 == strcmp(ht_mode, "HT80") ||
10809 0 == strcmp(ht_mode, "HT160")) {
10810 switch (channel) {
10811 case 1 ... 7:
10812 case 36:
10813 case 44:
10814 case 52:
10815 case 60:
10816 case 100:
10817 case 108:
10818 case 116:
10819 case 124:
10820 case 132:
10821 case 140:
10822 case 149:
10823 case 157:
10824 return 1;
10825 case 8 ... 13:
10826 case 40:
10827 case 48:
10828 case 56:
10829 case 64:
10830 case 104:
10831 case 112:
10832 case 120:
10833 case 128:
10834 case 136:
10835 case 144:
10836 case 153:
10837 case 161:
10838 return -1;
10839 default:
10840 return -EINVAL;
10841 }
10842 }
10843
10844 return -EINVAL;
10845}
10846
10847static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
10848{
10849 int idx = channel%8;
10850 if (0 == strcmp(ht_mode, "HT40") ||
10851 0 == strcmp(ht_mode, "HT80") ||
10852 0 == strcmp(ht_mode, "HT160")) {
10853 switch (idx) {
10854 case 1:
10855 return 1;
10856 case 5:
10857 return -1;
10858 default:
10859 return -EINVAL;
10860 }
10861 }
10862
10863 return -EINVAL;
10864}
10865static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
10866{
10867 if (NULL == hw_mode) return;
10868
10869 if (0 == strcmp(hw_mode, "ac"))
10870 sncopy(bw_mode, bw_mode_len, "ht vht");
10871
10872 if (0 == strcmp(hw_mode, "n"))
10873 sncopy(bw_mode, bw_mode_len, "ht");
10874
10875 return;
10876}
10877
10878static int util_chan_to_freq(int chan)
10879{
10880 if (chan == 14)
10881 return 2484;
10882 else if (chan < 14)
10883 return 2407 + chan * 5;
10884 else if (chan >= 182 && chan <= 196)
10885 return 4000 + chan * 5;
10886 else
10887 return 5000 + chan * 5;
10888 return 0;
10889}
10890
10891static int util_6G_chan_to_freq(int chan)
10892{
10893 if (chan)
10894 return 5950 + chan * 5;
10895 else
10896 return 0;
developer69b61b02023-03-07 17:17:44 +080010897
developer72fb0bb2023-01-11 09:46:29 +080010898}
10899const int *util_unii_5g_chan2list(int chan, int width)
10900{
10901 static const int lists[] = {
10902 // <width>, <chan1>, <chan2>..., 0,
10903 20, 36, 0,
10904 20, 40, 0,
10905 20, 44, 0,
10906 20, 48, 0,
10907 20, 52, 0,
10908 20, 56, 0,
10909 20, 60, 0,
10910 20, 64, 0,
10911 20, 100, 0,
10912 20, 104, 0,
10913 20, 108, 0,
10914 20, 112, 0,
10915 20, 116, 0,
10916 20, 120, 0,
10917 20, 124, 0,
10918 20, 128, 0,
10919 20, 132, 0,
10920 20, 136, 0,
10921 20, 140, 0,
10922 20, 144, 0,
10923 20, 149, 0,
10924 20, 153, 0,
10925 20, 157, 0,
10926 20, 161, 0,
10927 20, 165, 0,
10928 40, 36, 40, 0,
10929 40, 44, 48, 0,
10930 40, 52, 56, 0,
10931 40, 60, 64, 0,
10932 40, 100, 104, 0,
10933 40, 108, 112, 0,
10934 40, 116, 120, 0,
10935 40, 124, 128, 0,
10936 40, 132, 136, 0,
10937 40, 140, 144, 0,
10938 40, 149, 153, 0,
10939 40, 157, 161, 0,
10940 80, 36, 40, 44, 48, 0,
10941 80, 52, 56, 60, 64, 0,
10942 80, 100, 104, 108, 112, 0,
10943 80, 116, 120, 124, 128, 0,
10944 80, 132, 136, 140, 144, 0,
10945 80, 149, 153, 157, 161, 0,
10946 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
10947 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
10948 -1 // final delimiter
10949 };
10950 const int *start;
10951 const int *p;
10952
10953 for (p = lists; *p != -1; p++) {
10954 if (*p == width) {
10955 for (start = ++p; *p != 0; p++) {
10956 if (*p == chan)
10957 return start;
10958 }
10959 }
10960 // move to the end of channel list of given width
10961 while (*p != 0) {
10962 p++;
10963 }
10964 }
10965
10966 return NULL;
10967}
10968
10969static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
10970{
10971 if (NULL == ht_mode)
10972 return 0;
10973
10974 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
10975 const int *chans = util_unii_5g_chan2list(channel, width);
10976 int sum = 0;
10977 int cnt = 0;
10978
10979 if (NULL == chans)
10980 return 0;
10981
10982 while (*chans) {
10983 sum += *chans;
10984 cnt++;
10985 chans++;
10986 }
10987 if (cnt == 0)
10988 return 0;
10989 return sum / cnt;
10990}
10991
10992static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
10993{
10994 if (NULL == ht_mode)
10995 return 0;
10996
10997 int width = strtol((ht_mode + 2), NULL, 10);
10998
10999 int idx = 0 ;
11000 int centerchan = 0;
11001 int chan_ofs = 1;
11002
11003 if (width == 40){
11004 idx = ((channel/4) + chan_ofs)%2;
11005 switch (idx) {
11006 case 0:
11007 centerchan = (channel - 2);
11008 break;
11009 case 1:
11010 centerchan = (channel + 2);
developer69b61b02023-03-07 17:17:44 +080011011 break;
developer72fb0bb2023-01-11 09:46:29 +080011012 default:
11013 return -EINVAL;
11014 }
11015 }else if (width == 80){
developer69b61b02023-03-07 17:17:44 +080011016 idx = ((channel/4) + chan_ofs)%4;
developer72fb0bb2023-01-11 09:46:29 +080011017 switch (idx) {
11018 case 0:
11019 centerchan = (channel - 6);
11020 break;
11021 case 1:
11022 centerchan = (channel + 6);
11023 break;
11024 case 2:
11025 centerchan = (channel + 2);
11026 break;
11027 case 3:
11028 centerchan = (channel - 2);
11029 break;
11030 default:
11031 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080011032 }
developer72fb0bb2023-01-11 09:46:29 +080011033 }else if (width == 160){
11034 switch (channel) {
11035 case 1 ... 29:
11036 centerchan = 15;
11037 break;
11038 case 33 ... 61:
11039 centerchan = 47;
11040 break;
11041 case 65 ... 93:
11042 centerchan = 79;
11043 break;
11044 case 97 ... 125:
11045 centerchan = 111;
11046 break;
11047 case 129 ... 157:
11048 centerchan = 143;
11049 break;
11050 case 161 ... 189:
11051 centerchan = 175;
11052 break;
11053 case 193 ... 221:
11054 centerchan = 207;
11055 break;
11056 default:
11057 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080011058 }
developer72fb0bb2023-01-11 09:46:29 +080011059 }
11060 return centerchan;
11061}
11062static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
11063{
11064 BOOL onlyG, onlyN, onlyA;
11065 CHAR tmp[64];
11066 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
11067 if (ret == RETURN_OK) {
11068 sncopy(hw_mode, hw_mode_size, tmp);
11069 }
11070 return ret;
11071}
11072
11073INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
11074{
11075 // Sample commands:
11076 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
11077 // hostapd_cli -i wifi0 chan_switch 30 2437
developer72fb0bb2023-01-11 09:46:29 +080011078 int freq = 0, ret = 0;
11079 char center_freq1_str[32] = ""; // center_freq1=%d
11080 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
11081 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
11082 char hw_mode[16] = ""; // n|ac
11083 char bw_mode[16] = ""; // ht|ht vht
11084 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
11085 char interface_name[16] = {0};
11086 int sec_chan_offset;
11087 int width;
11088 char config_file[64] = {0};
11089 BOOL stbcEnable = FALSE;
11090 char *ext_str = "None";
11091 wifi_band band = band_invalid;
11092 int center_chan = 0;
11093 int center_freq1 = 0;
11094
11095 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
11096
11097 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
11098 return RETURN_ERR;
11099
11100 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11101
11102 band = wifi_index_to_band(radioIndex);
11103
11104 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
11105
11106 // Get radio mode HT20|HT40|HT80 etc.
11107 if (channel){
11108 if (band == band_6){
11109 freq = util_6G_chan_to_freq(channel);
11110 }else{
11111 freq = util_chan_to_freq(channel);
11112 }
11113 snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
11114
11115 // Provide bandwith if specified
11116 if (channel_width_MHz > 20) {
11117 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
11118 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
11119 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
11120
11121 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
11122 }else if (channel_width_MHz == 20){
11123 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
11124 }
11125
11126
11127 if (channel_width_MHz > 20) {
11128 if (band == band_6){
11129 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
11130 if(center_chan){
11131 center_freq1 = util_6G_chan_to_freq(center_chan);
11132 }
11133 }else{
11134 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
11135 if(center_chan){
11136 center_freq1 = util_chan_to_freq(center_chan);
11137 }
11138 }
developer69b61b02023-03-07 17:17:44 +080011139
developer72fb0bb2023-01-11 09:46:29 +080011140 if (center_freq1)
11141 snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080011142
developer72fb0bb2023-01-11 09:46:29 +080011143 }
11144
11145 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
11146 if (band == band_6){
11147 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
11148 }else{
11149 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
11150 }
11151 if (sec_chan_offset != -EINVAL)
11152 snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
11153
11154 // Only the first AP, other are hanging on the same radio
developerfead3972023-05-25 20:15:02 +080011155 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
developerd1824452023-05-18 12:30:04 +080011156 if (ret != RETURN_OK) {
developerfead3972023-05-25 20:15:02 +080011157 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
developerd1824452023-05-18 12:30:04 +080011158 return RETURN_ERR;
11159 }
11160 /* wifi_dbg_printf("execute: '%s'\n", cmd);
developerf6a87542023-05-16 15:47:28 +080011161 ret = _syscmd(cmd, buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +080011162 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080011163
11164 ret = wifi_setRadioChannel(radioIndex, channel);
11165 if (ret != RETURN_OK) {
11166 fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__);
11167 return RETURN_ERR;
11168 }
11169
developer262f4cb2023-05-24 12:22:04 +080011170 if (sec_chan_offset == 1)
11171 ext_str = "Above";
11172 else if (sec_chan_offset == -1)
11173 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080011174
developerd1824452023-05-18 12:30:04 +080011175 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080011176
11177 } else {
11178 if (channel_width_MHz > 20)
11179 ext_str = "Above";
11180 }
11181
11182 wifi_setRadioExtChannel(radioIndex, ext_str);
11183
11184 char mhz_str[16];
11185 snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
11186 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
11187
11188 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11189
11190 return RETURN_OK;
11191}
11192
11193INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
11194{
11195 int index = -1;
11196 wifi_neighbor_ap2_t *scan_array = NULL;
11197 char cmd[256]={0};
11198 char buf[128]={0};
11199 char file_name[32] = {0};
11200 char filter_SSID[32] = {0};
11201 char line[256] = {0};
11202 char interface_name[16] = {0};
11203 char *ret = NULL;
11204 int freq=0;
11205 FILE *f = NULL;
11206 size_t len=0;
11207 int channels_num = 0;
11208 int vht_channel_width = 0;
11209 int get_noise_ret = RETURN_ERR;
11210 bool filter_enable = false;
11211 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
11212 int phyId = 0;
11213
11214 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
11215
11216 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
11217 f = fopen(file_name, "r");
11218 if (f != NULL) {
11219 fgets(filter_SSID, sizeof(file_name), f);
11220 if (strlen(filter_SSID) != 0)
11221 filter_enable = true;
11222 fclose(f);
11223 }
11224
11225 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
11226 return RETURN_ERR;
11227
11228 phyId = radio_index_to_phy(radio_index);
11229
11230 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
11231 _syscmd(cmd, buf, sizeof(buf));
11232 channels_num = strtol(buf, NULL, 10);
11233
11234 sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
11235 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
11236 fprintf(stderr, "cmd: %s\n", cmd);
11237 if ((f = popen(cmd, "r")) == NULL) {
11238 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11239 return RETURN_ERR;
11240 }
developer69b61b02023-03-07 17:17:44 +080011241
developer72fb0bb2023-01-11 09:46:29 +080011242 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
11243 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +080011244
developer72fb0bb2023-01-11 09:46:29 +080011245 ret = fgets(line, sizeof(line), f);
11246 while (ret != NULL) {
11247 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +080011248 // 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 +080011249 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
11250 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
11251
11252 if (!filter_BSS) {
11253 index++;
11254 wifi_neighbor_ap2_t *tmp;
11255 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
11256 if (tmp == NULL) { // no more memory to use
11257 index--;
11258 wifi_dbg_printf("%s: realloc failed\n", __func__);
11259 break;
11260 }
11261 scan_array = tmp;
11262 }
11263 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
11264
11265 filter_BSS = false;
11266 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
11267 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
11268 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
11269 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
11270 } else if (strstr(line, "freq") != NULL) {
11271 sscanf(line," freq: %d", &freq);
11272 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
11273
11274 if (freq >= 2412 && freq <= 2484) {
11275 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
11276 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
11277 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
11278 }
11279 else if (freq >= 5160 && freq <= 5805) {
11280 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
11281 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
11282 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
11283 }
11284
11285 scan_array[index].ap_Noise = 0;
11286 if (get_noise_ret == RETURN_OK) {
11287 for (int i = 0; i < channels_num; i++) {
11288 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
11289 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
11290 break;
11291 }
11292 }
11293 }
11294 } else if (strstr(line, "beacon interval") != NULL) {
11295 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
11296 } else if (strstr(line, "signal") != NULL) {
11297 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
11298 } else if (strstr(line,"SSID") != NULL) {
11299 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
11300 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
11301 filter_BSS = true;
11302 }
11303 } else if (strstr(line, "Supported rates") != NULL) {
11304 char SRate[80] = {0}, *tmp = NULL;
11305 memset(buf, 0, sizeof(buf));
11306 strcpy(SRate, line);
11307 tmp = strtok(SRate, ":");
11308 tmp = strtok(NULL, ":");
11309 strcpy(buf, tmp);
11310 memset(SRate, 0, sizeof(SRate));
11311
11312 tmp = strtok(buf, " \n");
11313 while (tmp != NULL) {
11314 strcat(SRate, tmp);
11315 if (SRate[strlen(SRate) - 1] == '*') {
11316 SRate[strlen(SRate) - 1] = '\0';
11317 }
11318 strcat(SRate, ",");
11319
11320 tmp = strtok(NULL, " \n");
11321 }
11322 SRate[strlen(SRate) - 1] = '\0';
11323 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
11324 } else if (strstr(line, "DTIM") != NULL) {
11325 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
11326 } else if (strstr(line, "VHT capabilities") != NULL) {
11327 strcat(scan_array[index].ap_SupportedStandards, ",ac");
11328 strcpy(scan_array[index].ap_OperatingStandards, "ac");
11329 } else if (strstr(line, "HT capabilities") != NULL) {
11330 strcat(scan_array[index].ap_SupportedStandards, ",n");
11331 strcpy(scan_array[index].ap_OperatingStandards, "n");
11332 } else if (strstr(line, "VHT operation") != NULL) {
11333 ret = fgets(line, sizeof(line), f);
11334 sscanf(line," * channel width: %d", &vht_channel_width);
11335 if(vht_channel_width == 1) {
11336 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
11337 } else {
11338 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
11339 }
11340 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11341 continue;
11342 } else if (strstr(line, "HT operation") != NULL) {
11343 ret = fgets(line, sizeof(line), f);
11344 sscanf(line," * secondary channel offset: %s", &buf);
11345 if (!strcmp(buf, "above")) {
11346 //40Mhz +
11347 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
11348 }
11349 else if (!strcmp(buf, "below")) {
11350 //40Mhz -
11351 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
11352 } else {
11353 //20Mhz
11354 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
11355 }
11356 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11357 continue;
11358 } else if (strstr(line, "HE capabilities") != NULL) {
11359 strcat(scan_array[index].ap_SupportedStandards, ",ax");
11360 strcpy(scan_array[index].ap_OperatingStandards, "ax");
11361 ret = fgets(line, sizeof(line), f);
11362 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
11363 if (strstr(line, "HE40/2.4GHz") != NULL)
11364 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
11365 else
11366 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
11367 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
11368 if (strstr(line, "HE80/5GHz") != NULL) {
11369 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
11370 ret = fgets(line, sizeof(line), f);
11371 } else
11372 continue;
11373 if (strstr(line, "HE160/5GHz") != NULL)
11374 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
11375 }
11376 continue;
11377 } else if (strstr(line, "WPA") != NULL) {
11378 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
11379 } else if (strstr(line, "RSN") != NULL) {
11380 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
11381 } else if (strstr(line, "Group cipher") != NULL) {
11382 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
11383 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
11384 strcpy(scan_array[index].ap_EncryptionMode, "AES");
11385 }
11386 }
11387 ret = fgets(line, sizeof(line), f);
11388 }
11389
11390 if (!filter_BSS) {
11391 *output_array_size = index + 1;
11392 } else {
11393 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
11394 *output_array_size = index;
11395 }
11396 *neighbor_ap_array = scan_array;
11397 pclose(f);
11398 free(channels_noise_arr);
11399 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11400 return RETURN_OK;
11401}
11402
11403INT wifi_getApAssociatedDeviceStats(
11404 INT apIndex,
11405 mac_address_t *clientMacAddress,
11406 wifi_associated_dev_stats_t *associated_dev_stats,
11407 u64 *handle)
11408{
11409 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
11410 char interface_name[50] = {0};
11411 char cmd[1024] = {0};
11412 char mac_str[18] = {0};
11413 char *key = NULL;
11414 char *val = NULL;
11415 FILE *f = NULL;
11416 char *line = NULL;
11417 size_t len = 0;
11418
11419 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11420 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11421 return RETURN_ERR;
11422 }
11423
11424 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
11425 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
11426 if((f = popen(cmd, "r")) == NULL) {
11427 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11428 return RETURN_ERR;
11429 }
11430
11431 while ((getline(&line, &len, f)) != -1) {
11432 key = strtok(line,":");
11433 val = strtok(NULL,":");
11434
11435 if(!strncmp(key,"rx bytes",8))
11436 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
11437 if(!strncmp(key,"tx bytes",8))
11438 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
11439 if(!strncmp(key,"rx packets",10))
11440 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11441 if(!strncmp(key,"tx packets",10))
11442 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11443 if(!strncmp(key,"tx retries",10))
11444 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
11445 if(!strncmp(key,"tx failed",9))
11446 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
11447 if(!strncmp(key,"rx drop misc",13))
11448 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
11449 if(!strncmp(key,"rx bitrate",10)) {
11450 val = strtok(val, " ");
11451 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
11452 }
11453 if(!strncmp(key,"tx bitrate",10)) {
11454 val = strtok(val, " ");
11455 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
11456 }
11457 }
11458 free(line);
11459 pclose(f);
11460 return RETURN_OK;
11461}
11462
11463INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
11464{
developer7e4a2a62023-04-06 19:56:03 +080011465 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011466 char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0};
11467
developer7e4a2a62023-04-06 19:56:03 +080011468 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11469
developer72fb0bb2023-01-11 09:46:29 +080011470 if (NULL == output_string)
11471 return RETURN_ERR;
11472
11473 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11474 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080011475
11476 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 +080011477 _syscmd(cmd, buf, sizeof(buf));
11478
11479 //size of SSID name restricted to value less than 32 bytes
11480 snprintf(output_string, 32, "%s", buf);
developer7e4a2a62023-04-06 19:56:03 +080011481 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011482
11483 return RETURN_OK;
11484}
11485
11486INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
11487{
developer2edaf012023-05-24 14:24:53 +080011488 char *mac_arry_buf = NULL;
11489 INT policy = -1;
11490 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080011491
developer2edaf012023-05-24 14:24:53 +080011492 mac_arry_buf = malloc(buf_size);
11493 if (!mac_arry_buf) {
11494 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080011495 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011496 }
11497 memset(mac_arry_buf, 0, buf_size);
11498 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
11499 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
11500 goto err;
11501 }
11502 /*
11503 mtk format to get policy:
11504 "policy=1
11505 00:11:22:33:44:55
11506 00:11:22:33:44:66
11507 "
11508 */
11509 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
11510 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
11511 goto err;
11512 }
11513 if (!(policy >=0 && policy <= 2)){
11514 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
11515 goto err;
11516 }
11517 *output_filterMode = policy;
11518 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
11519 free(mac_arry_buf);
11520 mac_arry_buf = NULL;
11521 return RETURN_OK;
11522err:
11523 free(mac_arry_buf);
11524 mac_arry_buf = NULL;
11525 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
11526 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011527}
11528
developer2edaf012023-05-24 14:24:53 +080011529
developer72fb0bb2023-01-11 09:46:29 +080011530INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
11531{
11532 FILE *fp = NULL;
11533 char str[MAX_BUF_SIZE] = {0};
11534 int wificlientindex = 0 ;
11535 int count = 0;
11536 int signalstrength = 0;
11537 int arr[MACADDRESS_SIZE] = {0};
11538 unsigned char mac[MACADDRESS_SIZE] = {0};
11539 UINT wifi_count = 0;
11540 char virtual_interface_name[MAX_BUF_SIZE] = {0};
11541 char pipeCmd[MAX_CMD_SIZE] = {0};
11542
11543 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11544 *output_array_size = 0;
11545 *associated_dev_array = NULL;
11546 char interface_name[50] = {0};
11547
11548 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11549 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11550 return RETURN_ERR;
11551 }
11552
11553 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
11554 fp = popen(pipeCmd, "r");
11555 if (fp == NULL)
11556 {
11557 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11558 return RETURN_ERR;
11559 }
11560
11561 /* Read the output a line at a time - output it. */
11562 fgets(str, sizeof(str)-1, fp);
11563 wifi_count = (unsigned int) atoi ( str );
11564 *output_array_size = wifi_count;
11565 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11566 pclose(fp);
11567
11568 if(wifi_count == 0)
11569 {
11570 return RETURN_OK;
11571 }
11572 else
11573 {
11574 wifi_associated_dev2_t* temp = NULL;
11575 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
11576 *associated_dev_array = temp;
11577 if(temp == NULL)
11578 {
11579 printf("Error Statement. Insufficient memory \n");
11580 return RETURN_ERR;
11581 }
11582
11583 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11584 system(pipeCmd);
11585
11586 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11587 if(fp == NULL)
11588 {
11589 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11590 return RETURN_ERR;
11591 }
11592 fclose(fp);
11593
11594 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11595 fp = popen(pipeCmd, "r");
11596 if(fp)
11597 {
11598 for(count =0 ; count < wifi_count; count++)
11599 {
11600 fgets(str, MAX_BUF_SIZE, fp);
11601 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11602 {
11603 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11604 {
11605 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
11606
11607 }
11608 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11609 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]);
11610 }
11611 temp[count].cli_AuthenticationState = 1; //TODO
11612 temp[count].cli_Active = 1; //TODO
11613 }
11614 pclose(fp);
11615 }
11616
11617 //Updating RSSI per client
11618 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11619 fp = popen(pipeCmd, "r");
11620 if(fp)
11621 {
11622 pclose(fp);
11623 }
11624 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11625 if(fp)
11626 {
11627 for(count =0 ; count < wifi_count ;count++)
11628 {
11629 fgets(str, MAX_BUF_SIZE, fp);
11630 signalstrength = atoi(str);
11631 temp[count].cli_RSSI = signalstrength;
11632 }
11633 pclose(fp);
11634 }
11635
11636
11637 //LastDataDownlinkRate
11638 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
11639 fp = popen(pipeCmd, "r");
11640 if (fp)
11641 {
11642 pclose(fp);
11643 }
11644 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
11645 if (fp)
11646 {
11647 for (count = 0; count < wifi_count; count++)
11648 {
11649 fgets(str, MAX_BUF_SIZE, fp);
11650 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
11651 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
11652 }
11653 pclose(fp);
11654 }
11655
11656 //LastDataUplinkRate
11657 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
11658 fp = popen(pipeCmd, "r");
11659 if (fp)
11660 {
11661 pclose(fp);
11662 }
11663 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
11664 if (fp)
11665 {
11666 for (count = 0; count < wifi_count; count++)
11667 {
11668 fgets(str, MAX_BUF_SIZE, fp);
11669 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
11670 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
11671 }
11672 pclose(fp);
11673 }
11674 }
11675 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11676 return RETURN_OK;
11677
11678}
11679
11680INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
11681{
11682#if 0
11683 /*char buf[1024] = {0};
11684 sprintf(cmd, "ifconfig %s ", interface_name);
11685 _syscmd(cmd, buf, sizeof(buf));*/
11686
11687 output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters.
11688 output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters.
11689 output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface.
11690 output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface.
11691
11692 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.
11693 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].
11694 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].
11695 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].
11696 output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012].
11697 output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac.
11698
11699 output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors.
11700 output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11701 output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11702 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.
11703 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.
11704 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.
11705 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.
11706 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.
11707 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.
11708 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.
11709 output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol.
11710#endif
11711
11712 FILE *fp = NULL;
11713 char interface_name[50] = {0};
11714 char pipeCmd[128] = {0};
11715 char str[256] = {0};
11716 wifi_ssidTrafficStats2_t *out = output_struct;
11717
11718 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11719 if (!output_struct)
11720 return RETURN_ERR;
11721
11722 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
11723 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
11724 return RETURN_ERR;
11725 sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name);
11726
11727 fp = popen(pipeCmd, "r");
11728 if (fp == NULL) {
11729 fprintf(stderr, "%s: popen failed\n", __func__);
11730 return RETURN_ERR;
11731 }
11732 fgets(str, sizeof(str), fp);
11733 pclose(fp);
11734
11735 if (strlen(str) == 0) // interface not exist
11736 return RETURN_OK;
11737
11738 sscanf(str, "%*[^:]: %lu %lu %lu %lu %* %* %* %* %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
11739 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
11740
11741 memset(str, 0, sizeof(str));
11742 sprintf(pipeCmd, "tail -n1 /proc/net/netstat");
11743 fp = popen(pipeCmd, "r");
11744 if (fp == NULL) {
11745 fprintf(stderr, "%s: popen failed\n", __func__);
11746 return RETURN_ERR;
11747 }
11748 fgets(str, sizeof(str), fp);
11749
11750 sscanf(str, "%*[^:]: %* %* %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
11751 &out->ssid_BroadcastPacketsSent);
11752 pclose(fp);
11753
11754 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
11755 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
11756
11757 // Not supported
11758 output_struct->ssid_RetransCount = 0;
11759 output_struct->ssid_FailedRetransCount = 0;
11760 output_struct->ssid_RetryCount = 0;
11761 output_struct->ssid_MultipleRetryCount = 0;
11762 output_struct->ssid_ACKFailureCount = 0;
11763 output_struct->ssid_AggregatedPacketCount = 0;
11764
11765 return RETURN_OK;
11766}
11767
11768//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).
11769INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
11770{
11771 char output_val[16]={'\0'};
11772 char config_file[MAX_BUF_SIZE] = {0};
11773
11774 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11775 if (!output)
11776 return RETURN_ERR;
11777 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11778 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
11779
11780 if( strcmp(output_val,"1") == 0 )
11781 *output = TRUE;
11782 else
11783 *output = FALSE;
11784 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11785
11786 return RETURN_OK;
11787}
11788
11789INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
11790{
11791 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11792 char str[MAX_BUF_SIZE]={'\0'};
11793 char string[MAX_BUF_SIZE]={'\0'};
11794 char cmd[MAX_CMD_SIZE]={'\0'};
11795 char *ch;
11796 char config_file[MAX_BUF_SIZE] = {0};
11797 struct params params;
11798
11799 if(enable == TRUE)
11800 strcpy(string,"1");
11801 else
11802 strcpy(string,"0");
11803
11804 params.name = "ap_isolate";
11805 params.value = string;
11806
11807 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11808 wifi_hostapdWrite(config_file,&params,1);
11809 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11810
11811 return RETURN_OK;
11812}
11813
11814INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
11815{
developera1255e42023-05-13 17:45:02 +080011816 char mgmtpwr_file[32] = {0};
11817 char cmd[64] = {0};
11818 char buf[32]={0};
11819
developer72fb0bb2023-01-11 09:46:29 +080011820 if (NULL == output_dBm)
11821 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080011822 snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
11823 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
11824 _syscmd(cmd, buf, sizeof(buf));
11825 if (strlen(buf) > 0)
11826 *output_dBm = strtol(buf, NULL, 10);
11827 else
11828 *output_dBm = 23;
developer72fb0bb2023-01-11 09:46:29 +080011829 return RETURN_OK;
11830}
11831
11832INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
11833{
developera1255e42023-05-13 17:45:02 +080011834 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080011835 char mgmt_pwr_file[128]={0};
11836 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080011837 int if_idx, ret = 0;
11838 struct nl_msg *msg = NULL;
11839 struct nlattr * msg_data = NULL;
11840 struct mtk_nl80211_param param;
11841 struct unl unl_ins;
11842 char power[16] = {0};
developera1255e42023-05-13 17:45:02 +080011843
11844 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11845
11846 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
11847 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080011848
11849 if_idx = if_nametoindex(interface_name);
11850 /*init mtk nl80211 vendor cmd*/
11851 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
11852 param.if_type = NL80211_ATTR_IFINDEX;
11853 param.if_idx = if_idx;
11854
11855 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11856 if (ret) {
11857 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11858 return RETURN_ERR;
11859 }
11860
11861 /*add mtk vendor cmd data*/
11862 snprintf(power, sizeof(power), "%d", dBm);
11863 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
11864 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11865 nlmsg_free(msg);
11866 goto err;
11867 }
11868
11869 /*send mtk nl80211 vendor msg*/
11870 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11871 if (ret) {
11872 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
11873 goto err;
11874 }
11875
11876 /*deinit mtk nl80211 vendor msg*/
11877 mtk_nl80211_deint(&unl_ins);
11878 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
11879
developera1255e42023-05-13 17:45:02 +080011880 snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
11881 f = fopen(mgmt_pwr_file, "w");
11882 if (f == NULL) {
11883 fprintf(stderr, "%s: fopen failed\n", __func__);
11884 return RETURN_ERR;
11885 }
11886 fprintf(f, "%d", dBm);
11887 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080011888 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080011889err:
11890 mtk_nl80211_deint(&unl_ins);
11891 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11892 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011893}
11894INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
11895{
11896 return RETURN_OK;
11897}
11898INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
11899{
11900 return RETURN_OK;
11901}
11902INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
11903{
11904 return RETURN_OK;
11905}
11906INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
11907{
11908 return RETURN_OK;
11909}
11910INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
11911{
11912 char config_file[MAX_BUF_SIZE] = {0};
11913 struct params list;
11914
11915 list.name = "bss_transition";
11916 list.value = activate?"1":"0";
11917 snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
11918 wifi_hostapdWrite(config_file, &list, 1);
11919
11920 return RETURN_OK;
11921}
11922wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
11923
11924void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
11925{
11926 return;
11927}
11928
11929INT wifi_setApCsaDeauth(INT apIndex, INT mode)
11930{
11931 // TODO Implement me!
11932 return RETURN_OK;
11933}
11934
11935INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
11936{
11937 char file_name[128] = {0};
11938 char buf[128] = {0};
11939 FILE *f = NULL;
11940 int max_num_radios = 0;
11941
11942 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11943
11944 wifi_getMaxRadioNumber(&max_num_radios);
11945 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
11946 for (int index = 0; index < max_num_radios; index++) {
11947 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
11948 f = fopen(file_name, "w");
11949 if (f == NULL)
11950 return RETURN_ERR;
11951 // For mode == 0 is to disable filter, just don't write to the file.
11952 if (mode)
11953 fprintf(f, "%s", essid);
11954
11955 fclose(f);
11956 }
11957 } else { // special case, need to set AP's SSID as filter for each radio.
11958 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
11959 f = fopen(file_name, "w");
11960 if (f == NULL)
11961 return RETURN_ERR;
11962
11963 // For mode == 0 is to disable filter, just don't write to the file.
11964 if (mode)
11965 fprintf(f, "%s", essid);
11966
11967 fclose(f);
11968 }
11969
11970 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11971 return RETURN_OK;
11972}
11973
11974INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
11975{
11976 // TODO Implement me!
11977 //Apply wifi_pushRadioChannel() instantly
11978 return RETURN_ERR;
11979}
11980
11981INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
11982{
11983 // TODO Implement me!
11984 return RETURN_OK;
11985}
11986
11987#ifdef HAL_NETLINK_IMPL
11988static int tidStats_callback(struct nl_msg *msg, void *arg) {
11989 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11990 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11991 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
11992 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
11993 int rem , tid_index = 0;
11994
11995 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
11996 wifi_associated_dev_tid_entry_t *stats_entry;
11997
11998 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
11999 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
12000 };
12001 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
12002 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
12003 };
12004
12005 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
12006 genlmsg_attrlen(gnlh, 0), NULL);
12007
12008
12009 if (!tb[NL80211_ATTR_STA_INFO]) {
12010 fprintf(stderr, "station stats missing!\n");
12011 return NL_SKIP;
12012 }
12013
12014 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
12015 tb[NL80211_ATTR_STA_INFO],
12016 stats_policy)) {
12017 fprintf(stderr, "failed to parse nested attributes!\n");
12018 return NL_SKIP;
12019 }
12020
developer386281b2023-05-20 15:43:13 +080012021 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
12022 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
12023 {
12024 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080012025
developer386281b2023-05-20 15:43:13 +080012026 stats_entry->tid = tid_index;
12027 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080012028
developer386281b2023-05-20 15:43:13 +080012029 if(sinfo[NL80211_STA_INFO_TID_STATS])
12030 {
12031 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
12032 printf("failed to parse nested stats attributes!");
12033 return NL_SKIP;
12034 }
developer72fb0bb2023-01-11 09:46:29 +080012035 }
developer386281b2023-05-20 15:43:13 +080012036 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12037 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080012038
developer386281b2023-05-20 15:43:13 +080012039 if(tid_index < (PS_MAX_TID - 1))
12040 tid_index++;
12041 }
developer72fb0bb2023-01-11 09:46:29 +080012042 }
12043 //ToDo: sum_time_ms, ewma_time_ms
12044 return NL_SKIP;
12045}
12046#endif
12047
12048INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
12049{
12050#ifdef HAL_NETLINK_IMPL
12051 Netlink nl;
12052 char if_name[10];
12053 char interface_name[16] = {0};
12054
12055 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12056 return RETURN_ERR;
12057
12058 snprintf(if_name, sizeof(if_name), "%s", interface_name);
12059
12060 nl.id = initSock80211(&nl);
12061
12062 if (nl.id < 0) {
12063 fprintf(stderr, "Error initializing netlink \n");
12064 return -1;
12065 }
12066
12067 struct nl_msg* msg = nlmsg_alloc();
12068
12069 if (!msg) {
12070 fprintf(stderr, "Failed to allocate netlink message.\n");
12071 nlfree(&nl);
12072 return -2;
12073 }
12074
12075 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012076 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012077 NL_AUTO_SEQ,
12078 nl.id,
12079 0,
12080 0,
12081 NL80211_CMD_GET_STATION,
12082 0);
12083
12084 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12085 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12086 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
developer8dd72532023-05-17 19:58:35 +080012087 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012088 nl_recvmsgs(nl.socket, nl.cb);
12089 nlmsg_free(msg);
12090 nlfree(&nl);
12091 return RETURN_OK;
12092#else
12093//iw implementation
12094#define TID_STATS_FILE "/tmp/tid_stats_file.txt"
12095#define TOTAL_MAX_LINES 50
12096
12097 char buf[256] = {'\0'}; /* or other suitable maximum line size */
12098 char if_name[32] = {0};
12099 FILE *fp=NULL;
12100 char pipeCmd[1024]= {'\0'};
12101 int lines,tid_index=0;
12102 char mac_addr[20] = {'\0'};
12103
12104 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12105 return RETURN_ERR;
12106
12107 wifi_associated_dev_tid_entry_t *stats_entry;
12108
12109 strcpy(mac_addr,clientMacAddress);
12110
12111 snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name);
12112 fp= popen(pipeCmd,"r");
12113 if(fp == NULL)
12114 {
12115 perror("popen for station dump failed\n");
12116 return RETURN_ERR;
12117 }
12118 pclose(fp);
12119
12120 snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1");
12121 fp=popen(pipeCmd,"r");
12122 if(fp == NULL)
12123 {
12124 perror("popen for grep station failed\n");
12125 return RETURN_ERR;
12126 }
12127 else if(fgets(buf,sizeof(buf),fp) != NULL)
12128 lines=atoi(buf);
12129 else
12130 {
12131 pclose(fp);
12132 fprintf(stderr,"No devices are connected \n");
12133 return RETURN_ERR;
12134 }
12135 pclose(fp);
12136
12137 if(lines == 1)
12138 lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output
12139
12140 for(tid_index=0; tid_index<PS_MAX_TID; tid_index++)
12141 {
12142 stats_entry = &tid_stats->tid_array[tid_index];
12143 stats_entry->tid = tid_index;
12144
12145 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);
12146
12147 fp=popen(pipeCmd,"r");
12148 if(fp ==NULL)
12149 {
12150 perror("Failed to read from tid file \n");
12151 return RETURN_ERR;
12152 }
12153 else if(fgets(buf,sizeof(buf),fp) != NULL)
12154 stats_entry->num_msdus = atol(buf);
12155
12156 pclose(fp);
12157 stats_entry->ac = _tid_ac_index_get[tid_index];
12158// TODO:
12159// ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus
12160// ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval
12161 }
12162 return RETURN_OK;
12163#endif
12164}
12165
12166
12167INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
12168{
12169 char interface_name[16] = {0};
12170 char cmd[128]={0};
12171 char buf[128]={0};
12172 int freq = 0;
12173
12174 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12175
12176 // full mode is used to scan all channels.
12177 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
12178 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
12179 ieee80211_channel_to_frequency(chan_list[0], &freq);
12180
12181 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12182 return RETURN_ERR;
12183
12184 if (freq)
12185 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
12186 else
12187 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
12188
12189 _syscmd(cmd, buf, sizeof(buf));
12190 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12191
12192 return RETURN_OK;
12193}
12194
12195
12196INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
12197{
12198 // TODO Implement me!
12199 return RETURN_ERR;
12200}
12201
12202INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
12203{
12204 // TODO Implement me!
12205 return RETURN_ERR;
12206}
12207
12208INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
12209{
12210 // TODO Implement me!
12211 return RETURN_ERR;
12212}
12213
12214INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
12215{
12216 // TODO Implement me!
12217 return RETURN_ERR;
12218}
12219
12220INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
12221{
12222 // TODO Implement me!
12223 return RETURN_ERR;
12224}
12225
12226INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
12227{
12228 // TODO Implement me!
12229 return RETURN_ERR;
12230}
12231
12232INT wifi_steering_eventUnregister(void)
12233{
12234 // TODO Implement me!
12235 return RETURN_ERR;
12236}
12237
12238INT wifi_delApAclDevices(INT apIndex)
12239{
developer7e4a2a62023-04-06 19:56:03 +080012240 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080012241 struct unl unl_ins;
12242 int if_idx = 0, ret = 0;
12243 struct nl_msg *msg = NULL;
12244 struct nlattr * msg_data = NULL;
12245 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080012246
developer7e4a2a62023-04-06 19:56:03 +080012247 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
12248 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080012249 if_idx = if_nametoindex(inf_name);
12250 if (!if_idx) {
12251 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
12252 return RETURN_ERR;
12253 }
12254 /*init mtk nl80211 vendor cmd*/
12255 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
12256 param.if_type = NL80211_ATTR_IFINDEX;
12257 param.if_idx = if_idx;
12258 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
12259 if (ret) {
12260 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
12261 return RETURN_ERR;
12262 }
12263 /*add mtk vendor cmd data*/
12264 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
12265 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
12266 nlmsg_free(msg);
12267 goto err;
12268 }
12269 /*send mtk nl80211 vendor msg*/
12270 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
12271 if (ret) {
12272 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
12273 goto err;
12274 }
12275 /*deinit mtk nl80211 vendor msg*/
12276 mtk_nl80211_deint(&unl_ins);
12277 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
12278 return RETURN_OK;
12279err:
12280 mtk_nl80211_deint(&unl_ins);
12281 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12282 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012283
12284 return RETURN_OK;
12285}
12286
12287#ifdef HAL_NETLINK_IMPL
12288static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
12289 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12290 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12291 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12292 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12293 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12294 char mac_addr[20],dev[20];
12295
12296 nla_parse(tb,
12297 NL80211_ATTR_MAX,
12298 genlmsg_attrdata(gnlh, 0),
12299 genlmsg_attrlen(gnlh, 0),
12300 NULL);
12301
12302 if(!tb[NL80211_ATTR_STA_INFO]) {
12303 fprintf(stderr, "sta stats missing!\n");
12304 return NL_SKIP;
12305 }
12306
12307 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12308 fprintf(stderr, "failed to parse nested attributes!\n");
12309 return NL_SKIP;
12310 }
12311 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
12312
12313 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12314
developer386281b2023-05-20 15:43:13 +080012315 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12316 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
12317 fprintf(stderr, "failed to parse nested rate attributes!");
12318 return NL_SKIP;
12319 }
developer72fb0bb2023-01-11 09:46:29 +080012320 }
12321
12322 if(sinfo[NL80211_STA_INFO_TID_STATS])
12323 {
12324 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12325 printf("failed to parse nested stats attributes!");
12326 return NL_SKIP;
12327 }
12328 }
developer5a1194f2023-05-24 16:00:03 +080012329 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080012330
developereb1ea832023-05-24 14:46:27 +080012331 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
12332 {
12333 printf("Type is VHT\n");
12334 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12335 ((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 +080012336
developereb1ea832023-05-24 14:46:27 +080012337 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12338 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
12339 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12340 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12341 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12342 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12343 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12344 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12345 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
12346 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12347 }
12348 else
12349 {
12350 printf(" OFDM or CCK \n");
12351 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12352 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
12353 }
12354 }
developer72fb0bb2023-01-11 09:46:29 +080012355
developereff896f2023-05-29 14:52:55 +080012356 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12357 if(rinfo[NL80211_RATE_INFO_MCS])
12358 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12359 }
12360 if(sinfo[NL80211_STA_INFO_RX_BYTES64])
12361 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
12362 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
12363 ((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 +080012364
developereff896f2023-05-29 14:52:55 +080012365 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12366 if(stats_info[NL80211_TID_STATS_RX_MSDU])
12367 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
12368 }
developer72fb0bb2023-01-11 09:46:29 +080012369
developereff896f2023-05-29 14:52:55 +080012370 if (sinfo[NL80211_STA_INFO_SIGNAL])
12371 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
12372 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
12373 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
12374 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
12375 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
12376 //rssi_array need to be filled
12377 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080012378}
12379#endif
12380
12381INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12382{
12383#ifdef HAL_NETLINK_IMPL
12384 Netlink nl;
12385 char if_name[32];
12386 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12387 return RETURN_ERR;
12388
12389 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
12390
12391 if (*output_array_size <= 0)
12392 return RETURN_OK;
12393
12394 nl.id = initSock80211(&nl);
12395
12396 if (nl.id < 0) {
12397 fprintf(stderr, "Error initializing netlink \n");
12398 return 0;
12399 }
12400
12401 struct nl_msg* msg = nlmsg_alloc();
12402
12403 if (!msg) {
12404 fprintf(stderr, "Failed to allocate netlink message.\n");
12405 nlfree(&nl);
12406 return 0;
12407 }
12408
12409 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012410 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012411 NL_AUTO_SEQ,
12412 nl.id,
12413 0,
12414 0,
12415 NL80211_CMD_GET_STATION,
12416 0);
12417
12418 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
12419 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12420 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012421 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012422 nl_recvmsgs(nl.socket, nl.cb);
12423 nlmsg_free(msg);
12424 nlfree(&nl);
12425 return RETURN_OK;
12426#else
12427 //TODO Implement me
12428 return RETURN_OK;
12429#endif
12430}
12431
12432#ifdef HAL_NETLINK_IMPL
12433static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
12434 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12435 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12436 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12437 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12438 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12439 char mac_addr[20],dev[20];
12440
12441 nla_parse(tb,
12442 NL80211_ATTR_MAX,
12443 genlmsg_attrdata(gnlh, 0),
12444 genlmsg_attrlen(gnlh, 0),
12445 NULL);
12446
12447 if(!tb[NL80211_ATTR_STA_INFO]) {
12448 fprintf(stderr, "sta stats missing!\n");
12449 return NL_SKIP;
12450 }
12451
12452 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12453 fprintf(stderr, "failed to parse nested attributes!\n");
12454 return NL_SKIP;
12455 }
12456
12457 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
12458
12459 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12460
developer386281b2023-05-20 15:43:13 +080012461 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12462 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
12463 fprintf(stderr, "failed to parse nested rate attributes!");
12464 return NL_SKIP;
12465 }
developer72fb0bb2023-01-11 09:46:29 +080012466 }
12467
12468 if(sinfo[NL80211_STA_INFO_TID_STATS])
12469 {
12470 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12471 printf("failed to parse nested stats attributes!");
12472 return NL_SKIP;
12473 }
12474 }
developera6beea42023-05-24 16:44:05 +080012475 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developereb1ea832023-05-24 14:46:27 +080012476 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
12477 {
12478 printf("Type is VHT\n");
12479 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12480 ((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 +080012481
developereb1ea832023-05-24 14:46:27 +080012482 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12483 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
12484 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12485 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12486 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12487 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12488 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12489 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12490 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
12491 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
12492 }
12493 else
12494 {
12495 printf(" OFDM or CCK \n");
developer72fb0bb2023-01-11 09:46:29 +080012496 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
developereb1ea832023-05-24 14:46:27 +080012497 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
12498 }
developer72fb0bb2023-01-11 09:46:29 +080012499 }
12500
12501 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12502 if(rinfo[NL80211_RATE_INFO_MCS])
12503 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12504 }
12505
12506 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
12507 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
12508 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
12509 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
12510
12511 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
developereff896f2023-05-29 14:52:55 +080012512 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
12513 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080012514
developereff896f2023-05-29 14:52:55 +080012515 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12516 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12517 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
12518 }
developer72fb0bb2023-01-11 09:46:29 +080012519
12520 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
12521 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
12522
developereff896f2023-05-29 14:52:55 +080012523 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
12524 ((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 +080012525
12526 return NL_SKIP;
12527}
12528#endif
12529
12530INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12531{
12532#ifdef HAL_NETLINK_IMPL
12533 Netlink nl;
12534 char if_name[10];
12535 char interface_name[16] = {0};
12536 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12537 return RETURN_ERR;
12538
12539 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
12540
12541 if (*output_array_size <= 0)
12542 return RETURN_OK;
12543
12544 snprintf(if_name, sizeof(if_name), "%s", interface_name);
12545
12546 nl.id = initSock80211(&nl);
12547
12548 if(nl.id < 0) {
12549 fprintf(stderr, "Error initializing netlink \n");
12550 return 0;
12551 }
12552
12553 struct nl_msg* msg = nlmsg_alloc();
12554
12555 if(!msg) {
12556 fprintf(stderr, "Failed to allocate netlink message.\n");
12557 nlfree(&nl);
12558 return 0;
12559 }
12560
12561 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012562 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012563 NL_AUTO_SEQ,
12564 nl.id,
12565 0,
12566 0,
12567 NL80211_CMD_GET_STATION,
12568 0);
12569
12570 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12571 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12572 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012573 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012574 nl_recvmsgs(nl.socket, nl.cb);
12575 nlmsg_free(msg);
12576 nlfree(&nl);
12577 return RETURN_OK;
12578#else
12579 //TODO Implement me
12580 return RETURN_OK;
12581#endif
12582}
12583
12584INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
12585{
12586 // TODO Implement me!
12587 char buf[MAX_BUF_SIZE] = {0};
12588 char config_file[MAX_BUF_SIZE] = {0};
12589
12590 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12591 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
12592 *activate = (strncmp("1",buf,1) == 0);
12593
12594 return RETURN_OK;
12595}
12596
12597INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
12598{
12599 char config_file[MAX_BUF_SIZE] = {0};
12600 struct params list;
12601
12602 list.name = "rrm_neighbor_report";
12603 list.value = activate?"1":"0";
12604 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12605 wifi_hostapdWrite(config_file, &list, 1);
12606
12607 return RETURN_OK;
12608}
12609
12610INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
12611{
12612 char buf[32] = {0};
12613 char config_file[MAX_BUF_SIZE] = {0};
12614
12615 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12616 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
12617 *activate = (strncmp("1",buf,1) == 0);
12618
12619 return RETURN_OK;
12620}
12621#undef HAL_NETLINK_IMPL
12622#ifdef HAL_NETLINK_IMPL
12623static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
12624 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12625 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12626 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
12627 char dev[20];
12628 int freq =0 ;
12629 static int i=0;
12630
12631 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
12632
12633 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
12634 };
12635
12636 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
12637
12638 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12639
12640 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
12641 fprintf(stderr, "survey data missing!\n");
12642 return NL_SKIP;
12643 }
12644
12645 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
12646 {
12647 fprintf(stderr, "failed to parse nested attributes!\n");
12648 return NL_SKIP;
12649 }
12650
12651
12652 if(out[0].array_size == 1 )
12653 {
12654 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
12655 {
12656 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12657 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12658 out[0].ch_number = ieee80211_frequency_to_channel(freq);
12659
12660 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12661 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12662 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12663 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12664 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12665 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12666 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12667 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12668 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12669 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12670 if (sinfo[NL80211_SURVEY_INFO_TIME])
12671 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12672 return NL_STOP;
12673 }
12674 }
12675 else
12676 {
12677 if ( i <= out[0].array_size )
12678 {
12679 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12680 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12681 out[i].ch_number = ieee80211_frequency_to_channel(freq);
12682
12683 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12684 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12685 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12686 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12687 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12688 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12689 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12690 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12691 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12692 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12693 if (sinfo[NL80211_SURVEY_INFO_TIME])
12694 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12695 }
12696 }
12697
12698 i++;
12699 return NL_SKIP;
12700}
12701#endif
12702
12703static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
12704{
12705 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
12706 FILE *fp;
12707
12708 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
12709 {
12710 printf("Creating Frequency-Channel Map\n");
12711 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
12712 }
12713 snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
12714 if((fp = popen(command, "r")))
12715 {
12716 fgets(output, sizeof(output), fp);
12717 *freqMHz = atoi(output);
12718 pclose(fp);
12719 }
12720
12721 return 0;
12722}
12723
12724static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz)
12725{
12726 int freqMHz = -1;
12727 char cmd[MAX_CMD_SIZE] = {'\0'};
12728 char interface_name[16] = {0};
12729
12730 ieee80211_channel_to_frequency(channel, &freqMHz);
12731 if (freqMHz == -1) {
12732 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
12733 return -1;
12734 }
12735
12736 wifi_GetInterfaceName(radioIndex, interface_name);
12737 if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) {
12738 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
12739 radioIndex, freqMHz);
12740 return -1;
12741 }
12742
12743 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
12744 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
12745 return -1;
12746 }
12747
12748 return 0;
12749}
12750
12751static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
12752{
12753 const char *ptr = buf;
12754 char *key = NULL;
12755 char *val = NULL;
12756 char line[256] = { '\0' };
12757
12758 while (ptr = get_line_from_str_buf(ptr, line)) {
12759 if (strstr(line, "Frequency")) continue;
12760
12761 key = strtok(line, ":");
12762 val = strtok(NULL, " ");
12763 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
12764
12765 if (!strcmp(key, "noise")) {
12766 sscanf(val, "%d", &stats->ch_noise);
12767 if (stats->ch_noise == 0) {
12768 // Workaround for missing noise information.
12769 // Assume -95 for 2.4G and -103 for 5G
12770 if (radioIndex == 0) stats->ch_noise = -95;
12771 if (radioIndex == 1) stats->ch_noise = -103;
12772 }
12773 }
12774 else if (!strcmp(key, "channel active time")) {
12775 sscanf(val, "%llu", &stats->ch_utilization_total);
12776 }
12777 else if (!strcmp(key, "channel busy time")) {
12778 sscanf(val, "%llu", &stats->ch_utilization_busy);
12779 }
12780 else if (!strcmp(key, "channel receive time")) {
12781 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
12782 }
12783 else if (!strcmp(key, "channel transmit time")) {
12784 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
12785 }
12786 };
12787
12788 return 0;
12789}
12790
12791INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
12792{
12793 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12794#ifdef HAL_NETLINK_IMPL
12795 Netlink nl;
12796 wifi_channelStats_t_loc local[array_size];
12797 char if_name[32];
12798
12799 local[0].array_size = array_size;
12800
12801 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12802 return RETURN_ERR;
12803
12804 nl.id = initSock80211(&nl);
12805
12806 if (nl.id < 0) {
12807 fprintf(stderr, "Error initializing netlink \n");
12808 return -1;
12809 }
12810
12811 struct nl_msg* msg = nlmsg_alloc();
12812
12813 if (!msg) {
12814 fprintf(stderr, "Failed to allocate netlink message.\n");
12815 nlfree(&nl);
12816 return -2;
12817 }
12818
12819 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012820 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012821 NL_AUTO_SEQ,
12822 nl.id,
12823 0,
12824 NLM_F_DUMP,
12825 NL80211_CMD_GET_SURVEY,
12826 0);
12827
12828 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +080012829 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012830 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
12831 nl_recvmsgs(nl.socket, nl.cb);
12832 nlmsg_free(msg);
12833 nlfree(&nl);
12834 //Copying the Values
12835 for(int i=0;i<array_size;i++)
12836 {
12837 input_output_channelStats_array[i].ch_number = local[i].ch_number;
12838 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
12839 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
12840 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
12841 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
12842 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
12843 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
12844 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
12845 }
12846#else
12847 ULONG channel = 0;
12848 int i;
12849 int number_of_channels = array_size;
12850 char buf[512];
12851 INT ret;
12852 wifi_channelStats_t tmp_stats;
12853
12854 if (number_of_channels == 0) {
12855 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
12856 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
12857 return RETURN_ERR;
12858 }
12859 number_of_channels = 1;
12860 input_output_channelStats_array[0].ch_number = channel;
12861 }
12862
12863 for (i = 0; i < number_of_channels; i++) {
12864
12865 input_output_channelStats_array[i].ch_noise = 0;
12866 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
12867 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
12868 input_output_channelStats_array[i].ch_utilization_busy = 0;
12869 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
12870 input_output_channelStats_array[i].ch_utilization_total = 0;
12871
12872 memset(buf, 0, sizeof(buf));
12873 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
12874 return RETURN_ERR;
12875 }
12876 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
12877 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
12878 return RETURN_ERR;
12879 }
12880
12881 // XXX: fake missing 'self' counter which is not available in iw survey output
12882 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
12883 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
12884
12885 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
12886 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
12887 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
12888 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
12889 input_output_channelStats_array[i].ch_utilization_total *= 1000;
12890
12891 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",
12892 __func__,
12893 input_output_channelStats_array[i].ch_number,
12894 input_output_channelStats_array[i].ch_noise,
12895 input_output_channelStats_array[i].ch_utilization_total,
12896 input_output_channelStats_array[i].ch_utilization_busy,
12897 input_output_channelStats_array[i].ch_utilization_busy_rx,
12898 input_output_channelStats_array[i].ch_utilization_busy_tx,
12899 input_output_channelStats_array[i].ch_utilization_busy_self,
12900 input_output_channelStats_array[i].ch_utilization_busy_ext);
12901 }
12902#endif
12903 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12904 return RETURN_OK;
12905}
12906#define HAL_NETLINK_IMPL
12907
12908/* Hostapd events */
12909
12910#ifndef container_of
12911#define offset_of(st, m) ((size_t)&(((st *)0)->m))
12912#define container_of(ptr, type, member) \
12913 ((type *)((char *)ptr - offset_of(type, member)))
12914#endif /* container_of */
12915
12916struct ctrl {
12917 char sockpath[128];
12918 char sockdir[128];
12919 char bss[IFNAMSIZ];
12920 char reply[4096];
12921 int ssid_index;
12922 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
12923 void (*overrun)(struct ctrl *ctrl);
12924 struct wpa_ctrl *wpa;
12925 unsigned int ovfl;
12926 size_t reply_len;
12927 int initialized;
12928 ev_timer retry;
12929 ev_timer watchdog;
12930 ev_stat stat;
12931 ev_io io;
12932};
12933static wifi_newApAssociatedDevice_callback clients_connect_cb;
12934static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
12935static struct ctrl wpa_ctrl[MAX_APS];
12936static int initialized;
12937
12938static unsigned int ctrl_get_drops(struct ctrl *ctrl)
12939{
12940 char cbuf[256] = {};
12941 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
12942 struct cmsghdr *cmsg;
12943 unsigned int ovfl = ctrl->ovfl;
12944 unsigned int drop;
12945
12946 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
12947 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
12948 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
12949 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
12950
12951 drop = ovfl - ctrl->ovfl;
12952 ctrl->ovfl = ovfl;
12953
12954 return drop;
12955}
12956
12957static void ctrl_close(struct ctrl *ctrl)
12958{
12959 if (ctrl->io.cb)
12960 ev_io_stop(EV_DEFAULT_ &ctrl->io);
12961 if (ctrl->retry.cb)
12962 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
12963 if (!ctrl->wpa)
12964 return;
12965
12966 wpa_ctrl_detach(ctrl->wpa);
12967 wpa_ctrl_close(ctrl->wpa);
12968 ctrl->wpa = NULL;
12969 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
12970}
12971
12972static void ctrl_process(struct ctrl *ctrl)
12973{
12974 const char *str;
12975 int drops;
12976 int level;
12977 int err;
12978
12979 /* Example events:
12980 *
12981 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
12982 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
12983 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
12984 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
12985 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
12986 */
12987 if (!(str = index(ctrl->reply, '>')))
12988 return;
12989 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
12990 return;
12991
12992 str++;
12993
12994 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
12995 if (!(str = index(ctrl->reply, ' ')))
12996 return;
12997 wifi_associated_dev_t sta;
12998 memset(&sta, 0, sizeof(sta));
12999
13000 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
13001 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
13002 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
13003
13004 sta.cli_Active=true;
13005
13006 (clients_connect_cb)(ctrl->ssid_index, &sta);
13007 goto handled;
13008 }
13009
13010 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
13011 if (!(str = index(ctrl->reply, ' ')))
13012 return;
13013
13014 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
13015 goto handled;
13016 }
13017
13018 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
13019 printf("CTRL_WPA: handle TERMINATING event\n");
13020 goto retry;
13021 }
13022
13023 if (strncmp("AP-DISABLED", str, 11) == 0) {
13024 printf("CTRL_WPA: handle AP-DISABLED\n");
13025 goto retry;
13026 }
13027
13028 printf("Event not supported!!\n");
13029
13030handled:
13031
13032 if ((drops = ctrl_get_drops(ctrl))) {
13033 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
13034 if (ctrl->overrun)
13035 ctrl->overrun(ctrl);
13036 }
13037
13038 return;
13039
13040retry:
13041 printf("WPA_CTRL: closing\n");
13042 ctrl_close(ctrl);
13043 printf("WPA_CTRL: retrying from ctrl prcoess\n");
13044 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
13045}
13046
13047static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
13048{
13049 struct ctrl *ctrl = container_of(io, struct ctrl, io);
13050 int err;
13051
13052 memset(ctrl->reply, 0, sizeof(ctrl->reply));
13053 ctrl->reply_len = sizeof(ctrl->reply) - 1;
13054 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
13055 ctrl->reply[ctrl->reply_len] = 0;
13056 if (err < 0) {
13057 if (errno == EAGAIN || errno == EWOULDBLOCK)
13058 return;
13059 ctrl_close(ctrl);
13060 ev_timer_again(EV_A_ &ctrl->retry);
13061 return;
13062 }
13063
13064 ctrl_process(ctrl);
13065}
13066
13067static int ctrl_open(struct ctrl *ctrl)
13068{
13069 int fd;
13070
13071 if (ctrl->wpa)
13072 return 0;
13073
13074 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
13075 if (!ctrl->wpa)
13076 goto err;
13077
13078 if (wpa_ctrl_attach(ctrl->wpa) < 0)
13079 goto err_close;
13080
13081 fd = wpa_ctrl_get_fd(ctrl->wpa);
13082 if (fd < 0)
13083 goto err_detach;
13084
13085 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
13086 goto err_detach;
13087
13088 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
13089 ev_io_start(EV_DEFAULT_ &ctrl->io);
13090
13091 return 0;
13092
13093err_detach:
13094 wpa_ctrl_detach(ctrl->wpa);
13095err_close:
13096 wpa_ctrl_close(ctrl->wpa);
13097err:
13098 ctrl->wpa = NULL;
13099 return -1;
13100}
13101
13102static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
13103{
13104 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
13105
13106 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
13107 ctrl_open(ctrl);
13108}
13109
13110static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
13111{
13112 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
13113
13114 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
13115 if (ctrl_open(ctrl) == 0) {
13116 printf("WPA_CTRL: retry successful\n");
13117 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
13118 }
13119}
13120
13121int ctrl_enable(struct ctrl *ctrl)
13122{
13123 if (ctrl->wpa)
13124 return 0;
13125
13126 if (!ctrl->stat.cb) {
13127 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
13128 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
13129 }
13130
13131 if (!ctrl->retry.cb) {
13132 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
13133 }
13134
13135 return ctrl_open(ctrl);
13136}
13137
13138static void
13139ctrl_msg_cb(char *buf, size_t len)
13140{
13141 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
13142
13143 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
13144 ctrl_process(ctrl);
13145}
13146
13147static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
13148{
13149 int err;
13150
13151 if (!ctrl->wpa)
13152 return -1;
13153 if (*reply_len < 2)
13154 return -1;
13155
13156 (*reply_len)--;
13157 ctrl->reply_len = sizeof(ctrl->reply);
13158 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
13159 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
13160 if (err < 0)
13161 return err;
13162
13163 if (ctrl->reply_len > *reply_len)
13164 ctrl->reply_len = *reply_len;
13165
13166 *reply_len = ctrl->reply_len;
13167 memcpy(reply, ctrl->reply, *reply_len);
13168 reply[*reply_len - 1] = 0;
13169 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
13170 return 0;
13171}
13172
13173static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
13174{
13175 const char *pong = "PONG";
13176 const char *ping = "PING";
13177 char reply[1024];
13178 size_t len = sizeof(reply);
13179 int err;
13180 ULONG s, snum;
13181 INT ret;
13182 BOOL status;
13183
13184 printf("WPA_CTRL: watchdog cb\n");
13185
13186 ret = wifi_getSSIDNumberOfEntries(&snum);
13187 if (ret != RETURN_OK) {
13188 printf("%s: failed to get SSID count", __func__);
13189 return;
13190 }
13191
13192 if (snum > MAX_APS) {
13193 printf("more ssid than supported! %lu\n", snum);
13194 return;
13195 }
13196
13197 for (s = 0; s < snum; s++) {
13198 if (wifi_getApEnable(s, &status) != RETURN_OK) {
13199 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
13200 continue;
13201 }
13202 if (status == false) continue;
13203
13204 memset(reply, 0, sizeof(reply));
13205 len = sizeof(reply);
13206 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
13207 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
13208 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
13209 continue;
13210
13211 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
13212 ctrl_close(&wpa_ctrl[s]);
13213 printf("WPA_CTRL: ev_timer_again %lu\n", s);
13214 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
13215 }
13216}
13217
13218static int init_wpa()
13219{
13220 int ret = 0, i = 0;
13221 ULONG s, snum;
13222
13223 ret = wifi_getSSIDNumberOfEntries(&snum);
13224 if (ret != RETURN_OK) {
13225 printf("%s: failed to get SSID count", __func__);
13226 return RETURN_ERR;
13227 }
13228
13229 if (snum > MAX_APS) {
13230 printf("more ssid than supported! %lu\n", snum);
13231 return RETURN_ERR;
13232 }
13233
13234 for (s = 0; s < snum; s++) {
13235 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
13236 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
13237 wpa_ctrl[s].ssid_index = s;
13238 ctrl_enable(&wpa_ctrl[s]);
13239 }
13240
13241 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
13242 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
13243
13244 initialized = 1;
13245 printf("WPA_CTRL: initialized\n");
13246
13247 return RETURN_OK;
13248}
13249
13250void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
13251{
13252 clients_connect_cb = callback_proc;
13253 if (!initialized)
13254 init_wpa();
13255}
13256
13257void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
13258{
13259 clients_disconnect_cb = callback_proc;
13260 if (!initialized)
13261 init_wpa();
13262}
13263
13264INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
13265{
13266 // TODO Implement me!
13267 return RETURN_ERR;
13268}
13269
13270INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
13271{
13272 // TODO Implement me!
13273 return RETURN_ERR;
13274}
13275
13276INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
13277{
13278 int i;
developerd1824452023-05-18 12:30:04 +080013279 int phyId = -1;
13280 char cmd[256] = {0};
13281 char channel_numbers_buf[256] = {0};
13282 char dfs_state_buf[256] = {0};
13283 char line[256] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013284 const char *ptr;
developerd1824452023-05-18 12:30:04 +080013285 BOOL dfs_enable = false;
developer72fb0bb2023-01-11 09:46:29 +080013286
developerd1824452023-05-18 12:30:04 +080013287 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080013288
developerd1824452023-05-18 12:30:04 +080013289 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
13290 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013291
developerd1824452023-05-18 12:30:04 +080013292 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 +080013293
developerd1824452023-05-18 12:30:04 +080013294 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
13295 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13296 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013297 }
13298
developerd1824452023-05-18 12:30:04 +080013299 ptr = channel_numbers_buf;
13300 i = 0;
13301 while (ptr = get_line_from_str_buf(ptr, line)) {
13302 if (i >= outputMapSize) {
13303 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
13304 return RETURN_ERR;
13305 }
13306 sscanf(line, "%d", &outputMap[i].ch_number);
13307
13308 memset(cmd, 0, sizeof(cmd));
13309 // Below command should fetch string for DFS state (usable, available or unavailable)
13310 // Example line: "DFS state: usable (for 78930 sec)"
13311 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) {
13312 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
developer72fb0bb2023-01-11 09:46:29 +080013313 return RETURN_ERR;
13314 }
13315
developerd1824452023-05-18 12:30:04 +080013316 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
13317 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
developer72fb0bb2023-01-11 09:46:29 +080013318 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13319 return RETURN_ERR;
13320 }
13321
developerd1824452023-05-18 12:30:04 +080013322 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080013323
developerd1824452023-05-18 12:30:04 +080013324 if (!strcmp(dfs_state_buf, "usable")) {
13325 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
13326 } else if (!strcmp(dfs_state_buf, "available")) {
13327 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
13328 } else if (!strcmp(dfs_state_buf, "unavailable")) {
13329 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
13330 } else {
13331 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
developer72fb0bb2023-01-11 09:46:29 +080013332 }
developerd1824452023-05-18 12:30:04 +080013333 i++;
developer59fda4f2023-05-16 15:47:38 +080013334 }
developer40ba1762023-05-13 11:03:49 +080013335
developerd1824452023-05-18 12:30:04 +080013336 return RETURN_OK;
13337
developer72fb0bb2023-01-11 09:46:29 +080013338 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
13339 return RETURN_ERR;
13340}
13341
13342INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
13343{
13344 // TODO Implement me!
13345 return RETURN_ERR;
13346}
13347
13348INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
13349{
13350 return RETURN_OK;
13351}
13352
13353INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
13354{
13355 // TODO Implement me!
13356 return RETURN_ERR;
13357}
13358
13359INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
13360{
13361 // TODO API refrence Implementaion is present on RPI hal
13362 return RETURN_ERR;
13363}
13364
13365INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
13366{
developera1255e42023-05-13 17:45:02 +080013367/*
developer72fb0bb2023-01-11 09:46:29 +080013368 char interface_name[16] = {0};
13369 char cmd[128]={'\0'};
13370 char buf[128]={'\0'};
13371 char *support;
13372 int maximum_tx = 0, current_tx = 0;
developera1255e42023-05-13 17:45:02 +080013373*/ ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080013374
13375 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13376 if(txpwr_pcntg == NULL)
13377 return RETURN_ERR;
13378
developera1255e42023-05-13 17:45:02 +080013379 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
13380 *txpwr_pcntg = pwr_percentage;
13381/* if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +080013382 return RETURN_ERR;
13383
13384 // Get the maximum tx power of the device
13385 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
13386 _syscmd(cmd, buf, sizeof(buf));
13387 maximum_tx = strtol(buf, NULL, 10);
13388
13389 // Get the current tx power
13390 memset(cmd, 0, sizeof(cmd));
13391 memset(buf, 0, sizeof(buf));
13392 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
13393 _syscmd(cmd, buf, sizeof(buf));
13394 current_tx = strtol(buf, NULL, 10);
13395
13396 // Get the power supported list and find the current power percentage in supported list
13397 memset(buf, 0, sizeof(buf));
13398 wifi_getRadioTransmitPowerSupported(apIndex, buf);
13399 support = strtok(buf, ",");
13400 while(true)
13401 {
13402 if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal.
13403 *txpwr_pcntg = 100;
13404 wifi_dbg_printf("current power is not in supported list\n");
13405 return RETURN_OK;
13406 }
13407 int tmp = maximum_tx*strtol(support, NULL, 10)/100;
13408 if (tmp == current_tx) {
13409 *txpwr_pcntg = strtol(support, NULL, 10);
13410 break;
13411 }
13412 support = strtok(NULL, ",");
13413 }
developera1255e42023-05-13 17:45:02 +080013414*/
developer72fb0bb2023-01-11 09:46:29 +080013415 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13416 return RETURN_OK;
13417}
13418
13419INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
13420{
13421 // TODO precac feature.
developerd1824452023-05-18 12:30:04 +080013422 struct params params[2] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013423 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080013424 BOOL dfs_enable = false;
13425 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080013426
13427 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerd1824452023-05-18 12:30:04 +080013428 band = wifi_index_to_band(radioIndex);
13429 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080013430
developerd1824452023-05-18 12:30:04 +080013431 if (dfs_enable == false) {
13432 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
13433 return RETURN_ERR;
13434 }
13435 params[0].name = "DfsZeroWaitDefault";
13436 params[0].value = enable?"1":"0";
13437 params[1].name = "DfsDedicatedZeroWait";
13438 params[1].value = enable?"1":"0";
13439 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13440 wifi_datfileWrite(config_file, params, 2);
developerc0772e62023-05-18 15:10:48 +080013441 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013442 /* TODO precac feature */
13443
13444 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13445 return RETURN_OK;
13446}
13447
13448INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
13449{
13450 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080013451 char buf1[32] = {0};
13452 char buf2[32] = {0};
13453 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080013454
13455 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13456 if (NULL == enable || NULL == precac)
13457 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +080013458 band = wifi_index_to_band(radioIndex);
13459 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13460 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
13461 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
13462 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
developer72fb0bb2023-01-11 09:46:29 +080013463 *enable = true;
13464 else
13465 *enable = false;
13466
13467 /* TODO precac feature */
13468
13469 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13470 return RETURN_OK;
13471}
13472
13473INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
13474{
13475 *supported = TRUE;
13476 return RETURN_OK;
13477}
13478
13479INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
13480{
developera1255e42023-05-13 17:45:02 +080013481 UCHAR dat_file[64] = {0};
13482 wifi_band band = band_invalid;
13483 char cmd[128] = {0};
13484 char buf[256] = {0};
13485 char ofdmabuf[32] = {'\0'};
13486 char mimobuf[32] = {'\0'};
13487 char new_ofdmabuf[32] = {'\0'};
13488 char new_mimobuf[32] = {'\0'};
13489 struct params params[2];
13490 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13491 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13492 UCHAR bss_cnt = 0;
13493 UCHAR val_cnt = 0;
13494 char *token = NULL;
developer72fb0bb2023-01-11 09:46:29 +080013495
developera1255e42023-05-13 17:45:02 +080013496 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13497 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
13498 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
13499 printf("%s:mu_type input Error", __func__);
13500 return RETURN_ERR;
13501 }
13502 band = wifi_index_to_band(radio_index);
13503 if (band == band_invalid) {
13504 printf("%s:Band Error\n", __func__);
13505 return RETURN_ERR;
13506 }
13507 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13508 /*get current value in dat file*/
13509 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13510 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
13511 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13512 get_bssnum_byindex(radio_index, &bss_cnt);
13513 val_cnt = 2*bss_cnt - 1;
13514 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
13515 if ((val_cnt >= sizeof(new_ofdmabuf))
13516 || (val_cnt >= sizeof(new_mimobuf))) {
13517 printf("%s:bss cnt Error", __func__, bss_cnt);
13518 return RETURN_ERR;
13519 }
13520 /*translate set value*/
13521 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
13522 strncpy(new_ofdmabuf, str_zero, val_cnt);
13523 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013524 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080013525 strncpy(new_ofdmabuf, str_one, val_cnt);
13526 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013527 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080013528 strncpy(new_ofdmabuf, str_zero, val_cnt);
13529 strncpy(new_mimobuf, str_one, val_cnt);
13530 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
13531 strncpy(new_ofdmabuf, str_one, val_cnt);
13532 strncpy(new_mimobuf, str_one, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013533 }
developera1255e42023-05-13 17:45:02 +080013534 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13535 /*same value, not operation*/
13536 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13537 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13538 printf("%s:Reduntant value\n", __func__);
13539 return RETURN_OK;
13540 }
13541 /*modify dat file to new file*/
13542 params[0].name="MuOfdmaDlEnable";
13543 params[0].value=new_ofdmabuf;
13544 params[1].name="MuMimoDlEnable";
13545 params[1].value=new_mimobuf;
13546 wifi_datfileWrite(dat_file, params, 2);
13547 /*hostapd control restarp ap to take effect on these new value*/
13548 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013549 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13550 return RETURN_OK;
13551}
13552
13553INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
13554{
13555 struct params params={0};
13556 char config_file[64] = {0};
13557 char buf[64] = {0};
13558 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080013559 UCHAR dat_file[64] = {0};
13560 wifi_band band = band_invalid;
13561 char ofdmabuf[32] = {'\0'};
13562 char mimobuf[32] = {'\0'};
13563 char *token = NULL;
13564 UCHAR ofdma = 0;
13565 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013566
13567 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13568
13569 if (mu_type == NULL)
13570 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013571 band = wifi_index_to_band(radio_index);
13572 if (band == band_invalid) {
13573 printf("%s:Band Error\n", __func__);
13574 return RETURN_ERR;
13575 }
13576 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13577 /*get current value in dat file*/
13578 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13579 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013580
developera1255e42023-05-13 17:45:02 +080013581 token = strtok(ofdmabuf, ";");
13582 ofdma = strtol(token, NULL, 10);
13583 token = strtok(mimobuf, ";");
13584 mimo = strtol(token, NULL, 10);
13585 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
13586 if ((ofdma == 1) && (mimo == 1))
13587 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
13588 else if ((ofdma == 0) && (mimo == 1))
13589 *mu_type = WIFI_DL_MU_TYPE_MIMO;
13590 else if ((ofdma == 1) && (mimo == 0))
13591 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
13592 else
13593 *mu_type = WIFI_DL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013594 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13595 return RETURN_OK;
13596}
13597
13598INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
13599{
13600 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developera1255e42023-05-13 17:45:02 +080013601 UCHAR dat_file[64] = {0};
13602 wifi_band band = band_invalid;
13603 char cmd[128] = {0};
13604 char buf[256] = {0};
13605 char ofdmabuf[32] = {'\0'};
13606 char mimobuf[32] = {'\0'};
13607 char new_ofdmabuf[32] = {'\0'};
13608 char new_mimobuf[32] = {'\0'};
13609 struct params params[2];
13610 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13611 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13612 UCHAR bss_cnt = 0;
13613 UCHAR val_cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013614
developera1255e42023-05-13 17:45:02 +080013615 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13616 band = wifi_index_to_band(radio_index);
13617 if (band == band_invalid) {
13618 printf("%s:Band Error\n", __func__);
13619 return RETURN_ERR;
13620 }
13621 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
13622 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
13623 printf("%s:mu_type input Error\n", __func__);
13624 return RETURN_ERR;
13625 }
13626 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13627 /*get current value in dat file*/
13628 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13629 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
13630 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13631 get_bssnum_byindex(radio_index, &bss_cnt);
13632 val_cnt = 2*bss_cnt - 1;
13633 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
13634 if ((val_cnt >= sizeof(new_ofdmabuf))
13635 || (val_cnt >= sizeof(new_mimobuf))) {
13636 printf("%s:bss cnt Error\n", __func__, val_cnt);
13637 return RETURN_ERR;
13638 }
13639 /*translate set value*/
13640 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
13641 strncpy(new_ofdmabuf, str_zero, val_cnt);
13642 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013643 }
developera1255e42023-05-13 17:45:02 +080013644 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
13645 strncpy(new_ofdmabuf, str_one, val_cnt);
13646 strncpy(new_mimobuf, str_zero, val_cnt);
13647 }
13648 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13649 /*same value, not operation*/
13650 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13651 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13652 printf("%s:Reduntant value\n", __func__);
13653 return RETURN_OK;
13654 }
13655 /*modify dat file to new file*/
13656 params[0].name="MuOfdmaUlEnable";
13657 params[0].value=new_ofdmabuf;
13658 params[1].name="MuMimoUlEnable";
13659 params[1].value=new_mimobuf;
13660 wifi_datfileWrite(dat_file, params, 2);
13661 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013662 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13663 return RETURN_OK;
13664}
13665
13666INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
13667{
13668 struct params params={0};
13669 char config_file[64] = {0};
13670 char buf[64] = {0};
13671 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080013672 UCHAR dat_file[64] = {0};
13673 wifi_band band = band_invalid;
13674 char ofdmabuf[32] = {'\0'};
13675 char mimobuf[32] = {'\0'};
13676 char *token = NULL;
13677 UCHAR ofdma = 0;
13678 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013679
13680 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13681
13682 if (mu_type == NULL)
13683 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013684 band = wifi_index_to_band(radio_index);
13685 if (band == band_invalid) {
13686 printf("%s:Band Error", __func__);
13687 return RETURN_ERR;
13688 }
13689 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13690 /*get current value in dat file*/
13691 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13692 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013693
developera1255e42023-05-13 17:45:02 +080013694 token = strtok(ofdmabuf, ";");
13695 ofdma = strtol(token, NULL, 10);
13696 token = strtok(mimobuf, ";");
13697 mimo = strtol(token, NULL, 10);
13698 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
13699 if ((ofdma == 1) && (mimo == 0))
13700 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
13701 else
13702 *mu_type = WIFI_UL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013703 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13704 return RETURN_OK;
13705}
13706
13707
13708INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
13709{
13710 char cmd[128] = {0};
13711 char buf[256] = {0};
13712 char config_file[64] = {0};
13713 char GI[8] = {0};
13714 int mode_map = 0;
13715 FILE *f = NULL;
13716 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080013717 char dat_file[64] = {'\0'};
13718 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080013719
13720 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13721
13722 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
13723 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
13724 return RETURN_ERR;
13725 }
developera1255e42023-05-13 17:45:02 +080013726 /*sanity check*/
13727 if (((guard_interval == wifi_guard_interval_1600)
13728 || (guard_interval == wifi_guard_interval_3200))
13729 && (mode_map & (WIFI_MODE_BE | WIFI_MODE_AX) == 0)) {
13730 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
13731 return RETURN_ERR;
13732 }
developer72fb0bb2023-01-11 09:46:29 +080013733 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
13734 band = wifi_index_to_band(radio_index);
13735
13736 // Hostapd are not supported HE mode GI 1600, 3200 ns.
13737 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
13738 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
13739 _syscmd(cmd, buf, sizeof(buf));
13740 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
13741 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
13742 if (strstr(buf, "[SHORT-GI-") == NULL) {
13743 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
13744 _syscmd(cmd, buf, sizeof(buf));
13745 }
13746 if (band == band_5) {
13747 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
13748 if (strstr(buf, "[SHORT-GI-") == NULL) {
13749 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
13750 _syscmd(cmd, buf, sizeof(buf));
13751 }
13752 }
13753 }
developera1255e42023-05-13 17:45:02 +080013754 /*wifi_reloadAp(radio_index);
13755 caller "wifi_setRadioOperatingParameters" have done this step.
13756 */
13757 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13758 if (guard_interval == wifi_guard_interval_400) {
13759 params[0].name = "HT_GI";
13760 params[0].value = "1";
13761 params[1].name = "VHT_SGI";
13762 params[1].value = "1";
13763 wifi_datfileWrite(dat_file, params, 2);
developer72fb0bb2023-01-11 09:46:29 +080013764 strcpy(GI, "0.4");
developera1255e42023-05-13 17:45:02 +080013765 } else {
13766 params[0].name = "HT_GI";
13767 params[0].value = "0";
13768 params[1].name = "VHT_SGI";
13769 params[1].value = "0";
13770 /*should enable FIXED_HE_GI_SUPPORT in driver*/
13771 params[2].name = "FgiFltf";
13772 if (guard_interval == wifi_guard_interval_800) {
13773 params[2].value = "800";
13774 strcpy(GI, "0.8");
13775 } else if (guard_interval == wifi_guard_interval_1600) {
13776 params[2].value = "1600";
13777 strcpy(GI, "1.6");
13778 } else if (guard_interval == wifi_guard_interval_3200) {
13779 params[2].value = "3200";
13780 strcpy(GI, "3.2");
13781 } else if (guard_interval == wifi_guard_interval_auto) {
13782 params[2].value = "0";
13783 strcpy(GI, "auto");
13784 }
13785 wifi_datfileWrite(dat_file, params, 3);
13786 }
developer72fb0bb2023-01-11 09:46:29 +080013787 // Record GI for get GI function
13788 snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
13789 f = fopen(buf, "w");
13790 if (f == NULL)
13791 return RETURN_ERR;
13792 fprintf(f, "%s", GI);
13793 fclose(f);
13794 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13795 return RETURN_OK;
13796}
13797
13798INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
13799{
13800 char buf[32] = {0};
13801 char cmd[64] = {0};
13802
13803 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13804
13805 if (guard_interval == NULL)
13806 return RETURN_ERR;
13807
developera1255e42023-05-13 17:45:02 +080013808 snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013809 _syscmd(cmd, buf, sizeof(buf));
13810
13811 if (strncmp(buf, "0.4", 3) == 0)
13812 *guard_interval = wifi_guard_interval_400;
13813 else if (strncmp(buf, "0.8", 3) == 0)
13814 *guard_interval = wifi_guard_interval_800;
13815 else if (strncmp(buf, "1.6", 3) == 0)
13816 *guard_interval = wifi_guard_interval_1600;
13817 else if (strncmp(buf, "3.2", 3) == 0)
13818 *guard_interval = wifi_guard_interval_3200;
13819 else
13820 *guard_interval = wifi_guard_interval_auto;
13821
13822 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13823 return RETURN_OK;
13824}
13825
13826INT wifi_setBSSColor(INT radio_index, UCHAR color)
13827{
13828 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13829 struct params params = {0};
13830 char config_file[128] = {0};
13831 char bss_color[4] ={0};
13832
developera1255e42023-05-13 17:45:02 +080013833 if (color < 1 || color > 63) {
13834 wifi_dbg_printf("color value is err:%d.\n", color);
13835 return RETURN_ERR;
13836 }
developer72fb0bb2023-01-11 09:46:29 +080013837 params.name = "he_bss_color";
13838 snprintf(bss_color, sizeof(bss_color), "%hhu", color);
13839 params.value = bss_color;
13840 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13841 wifi_hostapdWrite(config_file, &params, 1);
developera1255e42023-05-13 17:45:02 +080013842 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
13843 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080013844
developer72fb0bb2023-01-11 09:46:29 +080013845 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13846 return RETURN_OK;
13847}
13848
13849INT wifi_getBSSColor(INT radio_index, UCHAR *color)
13850{
13851 char config_file[128] = {0};
13852 char buf[64] = {0};
13853 char temp_output[128] = {'\0'};
13854
13855 wifi_dbg_printf("\nFunc=%s\n", __func__);
13856 if (NULL == color)
13857 return RETURN_ERR;
13858
13859 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13860 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
13861
13862 if(strlen(buf) > 0) {
13863 snprintf(temp_output, sizeof(temp_output), "%s", buf);
13864 } else {
13865 snprintf(temp_output, sizeof(temp_output), "1"); // default value
13866 }
13867
13868 *color = (UCHAR)strtoul(temp_output, NULL, 10);
13869 wifi_dbg_printf("\noutput_string=%s\n", color);
13870
13871 return RETURN_OK;
13872}
13873
13874/* multi-psk support */
13875INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
13876{
13877 char cmd[256];
13878 char interface_name[16] = {0};
13879
13880 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13881 return RETURN_ERR;
13882
13883 sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
13884 interface_name,
13885 mac[0],
13886 mac[1],
13887 mac[2],
13888 mac[3],
13889 mac[4],
13890 mac[5]
13891 );
13892 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
13893 _syscmd(cmd, key->wifi_keyId, 64);
13894
13895
13896 return RETURN_OK;
13897}
13898
13899INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13900{
13901 char interface_name[16] = {0};
13902 FILE *fd = NULL;
13903 char fname[100];
13904 char cmd[128] = {0};
13905 char out[64] = {0};
13906 wifi_key_multi_psk_t * key = NULL;
13907 if(keysNumber < 0)
13908 return RETURN_ERR;
13909
13910 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13911 fd = fopen(fname, "w");
13912 if (!fd) {
13913 return RETURN_ERR;
13914 }
13915 key= (wifi_key_multi_psk_t *) keys;
13916 for(int i=0; i<keysNumber; ++i, key++) {
13917 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
13918 }
13919 fclose(fd);
13920
13921 //reload file
13922 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13923 return RETURN_ERR;
13924 sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
13925 _syscmd(cmd, out, 64);
13926 return RETURN_OK;
13927}
13928
13929INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13930{
13931 FILE *fd = NULL;
13932 char fname[100];
13933 char * line = NULL;
13934 char * pos = NULL;
13935 size_t len = 0;
13936 ssize_t read = 0;
13937 INT ret = RETURN_OK;
13938 wifi_key_multi_psk_t *keys_it = NULL;
13939
13940 if (keysNumber < 1) {
13941 return RETURN_ERR;
13942 }
13943
13944 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13945 fd = fopen(fname, "r");
13946 if (!fd) {
13947 return RETURN_ERR;
13948 }
13949
13950 if (keys == NULL) {
13951 ret = RETURN_ERR;
13952 goto close;
13953 }
13954
13955 keys_it = keys;
13956 while ((read = getline(&line, &len, fd)) != -1) {
13957 //Strip trailing new line if present
13958 if (read > 0 && line[read-1] == '\n') {
13959 line[read-1] = '\0';
13960 }
13961
13962 if(strcmp(line,"keyid=")) {
13963 sscanf(line, "keyid=%s", &(keys_it->wifi_keyId));
13964 if (!(pos = index(line, ' '))) {
13965 ret = RETURN_ERR;
13966 goto close;
13967 }
13968 pos++;
13969 //Here should be 00:00:00:00:00:00
13970 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
13971 printf("Not supported MAC: %s\n", pos);
13972 }
13973 if (!(pos = index(pos, ' '))) {
13974 ret = RETURN_ERR;
13975 goto close;
13976 }
13977 pos++;
13978
13979 //The rest is PSK
13980 snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
13981 keys_it++;
13982
13983 if(--keysNumber <= 0)
13984 break;
13985 }
13986 }
13987
13988close:
13989 free(line);
13990 fclose(fd);
13991 return ret;
13992}
13993/* end of multi-psk support */
13994
13995INT wifi_setNeighborReports(UINT apIndex,
13996 UINT numNeighborReports,
13997 wifi_NeighborReport_t *neighborReports)
13998{
13999 char cmd[256] = { 0 };
14000 char hex_bssid[13] = { 0 };
14001 char bssid[18] = { 0 };
14002 char nr[256] = { 0 };
14003 char ssid[256];
14004 char hex_ssid[256];
14005 char interface_name[16] = {0};
14006 INT ret;
14007
14008 /*rmeove all neighbors*/
14009 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
14010 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14011 return RETURN_ERR;
14012 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);
14013 system(cmd);
14014
14015 for(unsigned int i = 0; i < numNeighborReports; i++)
14016 {
14017 memset(ssid, 0, sizeof(ssid));
14018 ret = wifi_getSSIDName(apIndex, ssid);
14019 if (ret != RETURN_OK)
14020 return RETURN_ERR;
14021
14022 memset(hex_ssid, 0, sizeof(hex_ssid));
14023 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
14024 sprintf(hex_ssid + k,"%02x", ssid[j]);
14025
14026 snprintf(hex_bssid, sizeof(hex_bssid),
14027 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
14028 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
14029 snprintf(bssid, sizeof(bssid),
14030 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
14031 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
14032
14033 snprintf(nr, sizeof(nr),
14034 "%s" // bssid
14035 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
14036 "%02hhx" // operclass
14037 "%02hhx" // channel
14038 "%02hhx", // phy_mode
14039 hex_bssid,
14040 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
14041 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
14042 neighborReports[i].opClass,
14043 neighborReports[i].channel,
14044 neighborReports[i].phyTable);
14045
14046 snprintf(cmd, sizeof(cmd),
14047 "hostapd_cli set_neighbor "
14048 "%s " // bssid
14049 "ssid=%s " // ssid
14050 "nr=%s " // nr
14051 "-i %s",
14052 bssid,hex_ssid,nr, interface_name);
14053
14054 if (WEXITSTATUS(system(cmd)) != 0)
14055 {
14056 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
14057 }
14058 }
14059
14060 return RETURN_OK;
14061}
14062
14063INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
14064{
14065 return RETURN_OK;
14066}
14067
14068#ifdef _WIFI_HAL_TEST_
14069int main(int argc,char **argv)
14070{
14071 int index;
14072 INT ret=0;
14073 char buf[1024]="";
14074
14075 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14076 if(argc<3)
14077 {
14078 if(argc==2)
14079 {
14080 if(!strcmp(argv[1], "init"))
14081 return wifi_init();
14082 if(!strcmp(argv[1], "reset"))
14083 return wifi_reset();
14084 if(!strcmp(argv[1], "wifi_getHalVersion"))
14085 {
14086 char buffer[64];
14087 if(wifi_getHalVersion(buffer)==RETURN_OK)
14088 printf("Version: %s\n", buffer);
14089 else
14090 printf("Error in wifi_getHalVersion\n");
14091 return RETURN_OK;
14092 }
14093 }
14094 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
14095 exit(-1);
14096 }
14097
14098 index = atoi(argv[2]);
14099 if(strstr(argv[1], "wifi_getApName")!=NULL)
14100 {
14101 wifi_getApName(index,buf);
14102 printf("Ap name is %s \n",buf);
14103 return 0;
14104 }
developerfead3972023-05-25 20:15:02 +080014105 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
14106 {
14107 UINT pureMode = atoi(argv[3]);
14108
14109 wifi_setRadioMode(index, NULL, pureMode);
14110 printf("Ap SET Radio mode 0x%x\n", pureMode);
14111 return 0;
14112 }
14113 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
14114 {
14115 ULONG TransmitPower = atoi(argv[3]);
14116
14117 wifi_setRadioTransmitPower(index, TransmitPower);
14118 printf("Ap SET TransmitPower %lu\n", TransmitPower);
14119 return 0;
14120 }
14121 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
14122 {
14123 INT TransmitPower = atoi(argv[3]);
14124
14125 wifi_setApManagementFramePowerControl(index, TransmitPower);
14126 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
14127 return 0;
14128 }
14129 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
14130 {
14131 CHAR *bandwith = argv[3];
14132
14133 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
14134 printf("Ap SET bw %s\n", bandwith);
14135 return 0;
14136 }
14137 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
14138 {
14139 wifi_factoryResetRadio(index);
14140 printf("wifi_factoryResetRadio ok!\n");
14141 return 0;
14142 }
14143 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
14144 {
14145 ULONG rst_cnt;
14146 wifi_getRadioResetCount(index, &rst_cnt);
14147 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
14148 return 0;
14149 }
developer2edaf012023-05-24 14:24:53 +080014150 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080014151 if(argc <= 3 )
14152 {
developer2edaf012023-05-24 14:24:53 +080014153 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
developer49b17232023-05-19 16:35:19 +080014154 exit(-1);
14155 }
14156 wifi_addApAclDevice(index, argv[3]);
14157 return 0;
14158 }
developer2edaf012023-05-24 14:24:53 +080014159 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
14160 wifi_getApAclDevices(index, buf, 1024);
14161 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080014162 return 0;
14163 }
developer2edaf012023-05-24 14:24:53 +080014164 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
14165 if(argc <= 3 )
14166 {
14167 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14168 exit(-1);
14169 }
14170 wifi_delApAclDevice(index, argv[3]);
14171 return 0;
14172 }
14173 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
14174 wifi_delApAclDevices(index);
14175 return 0;
14176 }
14177 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
14178 int acl_num = 0;
14179 wifi_getApAclDeviceNum(index, &acl_num);
14180 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
14181 return 0;
14182 }
14183 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
14184 wifi_getApDenyAclDevices(index, buf, 1024);
14185 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
14186 return 0;
14187 }
14188 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
14189 int filter_mode = 0;
14190 if(argc <= 3 )
14191 {
14192 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14193 exit(-1);
14194 }
14195 filter_mode = atoi(argv[3]);
14196 wifi_setApMacAddressControlMode(index,filter_mode);
14197 return 0;
14198 }
developer5cd4c862023-05-26 09:34:42 +080014199 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
14200 BOOL output_bool = 0;
14201 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
14202 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
14203 return 0;
14204 }
14205 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
14206 BOOL output_bool = 0;
14207 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
14208 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
14209 return 0;
14210 }
14211
14212 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14213 int filter_mode = 0;
14214 wifi_getApMacAddressControlMode(index, &filter_mode);
14215 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14216 return 0;
14217 }
14218 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
14219 int enable = 0;
14220 if(argc <= 3 )
14221 {
14222 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14223 exit(-1);
14224 }
14225 enable = (BOOL)atoi(argv[3]);
14226 wifi_setRadioIGMPSnoopingEnable(index, enable);
14227 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
14228 return 0;
14229 }
14230
14231 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
14232 BOOL out_status = 0;
14233 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
14234 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
14235 return 0;
14236 }
developer121a8e72023-05-22 09:19:39 +080014237
developer95c045d2023-05-24 19:26:28 +080014238 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
14239 int enable = 0;
14240 if(argc <= 3)
14241 {
14242 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14243 exit(-1);
14244 }
14245 enable = atoi(argv[3]);
14246 wifi_setApWmmEnable(index,enable);
14247 return 0;
14248 }
14249
14250 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
14251 BOOL enable = 0;
14252
14253 wifi_getApWMMCapability(index, &enable);
14254 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
14255 return 0;
14256 }
14257
14258 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
14259 BOOL enable = 0;
14260
14261 wifi_getApWmmEnable(index, &enable);
14262 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
14263 return 0;
14264 }
14265
developer2edaf012023-05-24 14:24:53 +080014266 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14267 int filter_mode = 0;
14268 wifi_getApMacAddressControlMode(index, &filter_mode);
14269 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14270 return 0;
14271 }
developer0f10c772023-05-16 21:43:39 +080014272 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
14273 {
14274 int mode = 0;
14275
14276 wifi_getRadioMode(index, buf, &mode);
14277 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
14278 return 0;
14279 }
developer72fb0bb2023-01-11 09:46:29 +080014280 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
14281 {
14282 BOOL b = FALSE;
14283 BOOL *output_bool = &b;
14284 wifi_getRadioAutoChannelEnable(index,output_bool);
14285 printf("Channel enabled = %d \n",b);
14286 return 0;
14287 }
14288 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
14289 {
14290 wifi_getApWpaEncryptionMode(index,buf);
14291 printf("encryption enabled = %s\n",buf);
14292 return 0;
14293 }
14294 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
14295 {
14296 BOOL b = FALSE;
14297 BOOL *output_bool = &b;
14298 wifi_getApSsidAdvertisementEnable(index,output_bool);
14299 printf("advertisment enabled = %d\n",b);
14300 return 0;
14301 }
14302 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
14303 {
14304 if(argc <= 3 )
14305 {
14306 printf("Insufficient arguments \n");
14307 exit(-1);
14308 }
14309
14310 char sta[20] = {'\0'};
14311 ULLONG handle= 0;
14312 strcpy(sta,argv[3]);
14313 mac_address_t st;
14314 mac_addr_aton(st,sta);
14315
14316 wifi_associated_dev_tid_stats_t tid_stats;
14317 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
14318 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
14319 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);
14320 }
14321
14322 if(strstr(argv[1], "getApEnable")!=NULL) {
14323 BOOL enable;
14324 ret=wifi_getApEnable(index, &enable);
14325 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14326 }
14327 else if(strstr(argv[1], "setApEnable")!=NULL) {
14328 BOOL enable = atoi(argv[3]);
14329 ret=wifi_setApEnable(index, enable);
14330 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14331 }
14332 else if(strstr(argv[1], "getApStatus")!=NULL) {
developer69b61b02023-03-07 17:17:44 +080014333 char status[64];
developer72fb0bb2023-01-11 09:46:29 +080014334 ret=wifi_getApStatus(index, status);
14335 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
14336 }
14337 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
14338 {
14339 wifi_getSSIDNameStatus(index,buf);
14340 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
14341 return 0;
developer2202b332023-05-24 16:23:22 +080014342 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
14343 wifi_resetApVlanCfg(index);
14344 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
14345 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014346 }
14347 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
14348 wifi_ssidTrafficStats2_t stats={0};
14349 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
14350 printf("%s %d: returns %d\n", argv[1], index, ret);
14351 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
14352 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
14353 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
14354 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
14355 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
14356 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
14357 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
14358 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
14359 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
14360 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
14361 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
14362 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
14363 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
14364 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
14365 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
14366 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
14367 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
14368 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
14369 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
14370 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
14371 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
14372 }
14373 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
14374 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
14375 UINT array_size=0;
14376 UINT i=0;
14377 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
14378 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080014379 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080014380 printf(" neighbor %d:\n", i);
14381 printf(" ap_SSID =%s\n", pt->ap_SSID);
14382 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
14383 printf(" ap_Mode =%s\n", pt->ap_Mode);
14384 printf(" ap_Channel =%d\n", pt->ap_Channel);
14385 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
14386 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14387 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
14388 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
14389 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
14390 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
14391 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14392 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
14393 printf(" ap_Noise =%d\n", pt->ap_Noise);
14394 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
14395 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
14396 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
developer69b61b02023-03-07 17:17:44 +080014397 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
developer72fb0bb2023-01-11 09:46:29 +080014398 }
14399 if(neighbor_ap_array)
14400 free(neighbor_ap_array); //make sure to free the list
14401 }
14402 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
14403 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
14404 UINT array_size=0;
14405 UINT i=0;
14406 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
14407 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080014408 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080014409 printf(" associated_dev %d:\n", i);
14410 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
14411 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
14412 printf(" cli_SNR =%d\n", pt->cli_SNR);
14413 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
14414 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
14415 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
14416 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
14417 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
14418 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
14419 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
14420 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
14421 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
14422 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
14423 }
14424 if(associated_dev_array)
14425 free(associated_dev_array); //make sure to free the list
14426 }
14427
14428 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
14429 {
14430#define MAX_ARRAY_SIZE 64
14431 int i, array_size;
14432 char *p, *ch_str;
14433 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
14434
14435 if(argc != 5)
14436 {
14437 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
14438 exit(-1);
14439 }
14440 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
14441
14442 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
14443 {
14444 strtok_r(ch_str, ",", &p);
14445 input_output_channelStats_array[i].ch_number = atoi(ch_str);
14446 }
14447 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
14448 if(!array_size)
14449 array_size=1;//Need to print current channel statistics
14450 for(i=0; i<array_size; i++)
14451 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
14452 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
14453 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
14454 input_output_channelStats_array[i].ch_number,\
14455 input_output_channelStats_array[i].ch_noise,\
14456 input_output_channelStats_array[i].ch_utilization_busy_rx,\
14457 input_output_channelStats_array[i].ch_utilization_busy_tx,\
14458 input_output_channelStats_array[i].ch_utilization_busy,\
14459 input_output_channelStats_array[i].ch_utilization_busy_ext,\
14460 input_output_channelStats_array[i].ch_utilization_total);
14461 }
14462
14463 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
14464 {
14465 if(argc <= 3 )
14466 {
14467 printf("Insufficient arguments \n");
14468 exit(-1);
14469 }
14470 char mac_addr[20] = {'\0'};
14471 wifi_device_t output_struct;
14472 int dev_index = atoi(argv[3]);
14473
14474 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
14475 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
14476 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);
14477 }
14478
14479 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
14480 {
14481 if (argc <= 3)
14482 {
14483 printf("Insufficient arguments\n");
14484 exit(-1);
14485 }
14486 char args[256];
14487 wifi_NeighborReport_t *neighborReports;
14488
14489 neighborReports = calloc(argc - 2, sizeof(neighborReports));
14490 if (!neighborReports)
14491 {
14492 printf("Failed to allocate memory");
14493 exit(-1);
14494 }
14495
14496 for (int i = 3; i < argc; ++i)
14497 {
14498 char *val;
14499 int j = 0;
14500 memset(args, 0, sizeof(args));
14501 strncpy(args, argv[i], sizeof(args));
14502 val = strtok(args, ";");
14503 while (val != NULL)
14504 {
14505 if (j == 0)
14506 {
14507 mac_addr_aton(neighborReports[i - 3].bssid, val);
14508 } else if (j == 1)
14509 {
14510 neighborReports[i - 3].info = strtol(val, NULL, 16);
14511 } else if (j == 2)
14512 {
14513 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
14514 } else if (j == 3)
14515 {
14516 neighborReports[i - 3].channel = strtol(val, NULL, 16);
14517 } else if (j == 4)
14518 {
14519 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
14520 } else {
14521 printf("Insufficient arguments]n\n");
14522 exit(-1);
14523 }
14524 val = strtok(NULL, ";");
14525 j++;
14526 }
14527 }
14528
14529 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
14530 if (ret != RETURN_OK)
14531 {
14532 printf("wifi_setNeighborReports ret = %d", ret);
14533 exit(-1);
14534 }
14535 }
14536 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
14537 {
14538 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
14539 printf("%s.\n", buf);
14540 else
14541 printf("Error returned\n");
14542 }
14543 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
14544 {
14545 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
14546 printf("%s.\n", buf);
14547 else
14548 printf("Error returned\n");
14549 }
14550 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
14551 {
14552 if (argc <= 2)
14553 {
14554 printf("Insufficient arguments\n");
14555 exit(-1);
14556 }
14557 char buf[64]= {'\0'};
14558 wifi_getRadioOperatingChannelBandwidth(index,buf);
14559 printf("Current bandwidth is %s \n",buf);
14560 return 0;
14561 }
14562 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
14563 {
14564 if (argc <= 5)
14565 {
14566 printf("Insufficient arguments\n");
14567 exit(-1);
14568 }
14569 UINT channel = atoi(argv[3]);
14570 UINT width = atoi(argv[4]);
14571 UINT beacon = atoi(argv[5]);
14572 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
14573 printf("Result = %d", ret);
14574 }
14575
14576 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14577 return 0;
14578}
14579
14580#endif
14581
14582#ifdef WIFI_HAL_VERSION_3
14583
14584INT BitMapToTransmitRates(UINT bitMap, char *BasicRate)
14585{
14586 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14587 if (bitMap & WIFI_BITRATE_1MBPS)
14588 strcat(BasicRate, "1,");
14589 if (bitMap & WIFI_BITRATE_2MBPS)
14590 strcat(BasicRate, "2,");
14591 if (bitMap & WIFI_BITRATE_5_5MBPS)
14592 strcat(BasicRate, "5.5,");
14593 if (bitMap & WIFI_BITRATE_6MBPS)
14594 strcat(BasicRate, "6,");
14595 if (bitMap & WIFI_BITRATE_9MBPS)
14596 strcat(BasicRate, "9,");
14597 if (bitMap & WIFI_BITRATE_11MBPS)
14598 strcat(BasicRate, "11,");
14599 if (bitMap & WIFI_BITRATE_12MBPS)
14600 strcat(BasicRate, "12,");
14601 if (bitMap & WIFI_BITRATE_18MBPS)
14602 strcat(BasicRate, "18,");
14603 if (bitMap & WIFI_BITRATE_24MBPS)
14604 strcat(BasicRate, "24,");
14605 if (bitMap & WIFI_BITRATE_36MBPS)
14606 strcat(BasicRate, "36,");
14607 if (bitMap & WIFI_BITRATE_48MBPS)
14608 strcat(BasicRate, "48,");
14609 if (bitMap & WIFI_BITRATE_54MBPS)
14610 strcat(BasicRate, "54,");
14611 if (strlen(BasicRate) != 0) // remove last comma
14612 BasicRate[strlen(BasicRate) - 1] = '\0';
14613 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14614 return RETURN_OK;
14615}
14616
14617INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
14618{
14619 UINT BitMap = 0;
14620 char *rate;
14621
14622 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14623 rate = strtok(BasicRatesList, ",");
14624 while(rate != NULL)
14625 {
14626 if (strcmp(rate, "1") == 0)
14627 BitMap |= WIFI_BITRATE_1MBPS;
14628 else if (strcmp(rate, "2") == 0)
14629 BitMap |= WIFI_BITRATE_2MBPS;
14630 else if (strcmp(rate, "5.5") == 0)
14631 BitMap |= WIFI_BITRATE_5_5MBPS;
14632 else if (strcmp(rate, "6") == 0)
14633 BitMap |= WIFI_BITRATE_6MBPS;
14634 else if (strcmp(rate, "9") == 0)
14635 BitMap |= WIFI_BITRATE_9MBPS;
14636 else if (strcmp(rate, "11") == 0)
14637 BitMap |= WIFI_BITRATE_11MBPS;
14638 else if (strcmp(rate, "12") == 0)
14639 BitMap |= WIFI_BITRATE_12MBPS;
14640 else if (strcmp(rate, "18") == 0)
14641 BitMap |= WIFI_BITRATE_18MBPS;
14642 else if (strcmp(rate, "24") == 0)
14643 BitMap |= WIFI_BITRATE_24MBPS;
14644 else if (strcmp(rate, "36") == 0)
14645 BitMap |= WIFI_BITRATE_36MBPS;
14646 else if (strcmp(rate, "48") == 0)
14647 BitMap |= WIFI_BITRATE_48MBPS;
14648 else if (strcmp(rate, "54") == 0)
14649 BitMap |= WIFI_BITRATE_54MBPS;
14650 rate = strtok(NULL, ",");
14651 }
14652 *basicRateBitMap = BitMap;
14653 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14654 return RETURN_OK;
14655}
14656
14657// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
14658INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14659{
14660 char buf[128] = {0};
14661 char cmd[128] = {0};
14662 char config_file[64] = {0};
14663 int bandwidth;
14664 int set_mode = 0;
14665 wifi_radio_operationParam_t current_param;
14666
14667 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14668
14669 multiple_set = TRUE;
14670 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
14671 fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__);
14672 return RETURN_ERR;
14673 }
14674 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
14675 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
14676 fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__);
14677 return RETURN_ERR;
14678 }
14679 }
14680
14681 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
14682 bandwidth = 20;
14683 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
14684 bandwidth = 40;
14685 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
14686 bandwidth = 80;
14687 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
14688 bandwidth = 160;
14689 if (operationParam->autoChannelEnabled){
14690 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14691 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14692 return RETURN_ERR;
14693 }
developer69b61b02023-03-07 17:17:44 +080014694 }else{
developer72fb0bb2023-01-11 09:46:29 +080014695 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14696 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14697 return RETURN_ERR;
14698 }
14699 }
14700
14701 if (current_param.variant != operationParam->variant) {
14702 // Two different definition bit map, so need to check every bit.
14703 if (operationParam->variant & WIFI_80211_VARIANT_A)
14704 set_mode |= WIFI_MODE_A;
14705 if (operationParam->variant & WIFI_80211_VARIANT_B)
14706 set_mode |= WIFI_MODE_B;
14707 if (operationParam->variant & WIFI_80211_VARIANT_G)
14708 set_mode |= WIFI_MODE_G;
14709 if (operationParam->variant & WIFI_80211_VARIANT_N)
14710 set_mode |= WIFI_MODE_N;
14711 if (operationParam->variant & WIFI_80211_VARIANT_AC)
14712 set_mode |= WIFI_MODE_AC;
14713 if (operationParam->variant & WIFI_80211_VARIANT_AX)
14714 set_mode |= WIFI_MODE_AX;
14715 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
14716 memset(buf, 0, sizeof(buf));
developer0f10c772023-05-16 21:43:39 +080014717 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014718 fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__);
14719 return RETURN_ERR;
14720 }
14721 }
14722 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
14723 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
14724 fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__);
14725 return RETURN_ERR;
14726 }
14727 }
14728 if (current_param.beaconInterval != operationParam->beaconInterval) {
14729 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
14730 fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__);
14731 return RETURN_ERR;
14732 }
14733 }
14734 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
14735 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf);
14736 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14737 fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__);
14738 return RETURN_ERR;
14739 }
14740 }
14741 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
14742 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
14743 fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__);
14744 return RETURN_ERR;
14745 }
14746 }
14747 if (current_param.guardInterval != operationParam->guardInterval) {
14748 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
14749 fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__);
14750 return RETURN_ERR;
14751 }
14752 }
14753 if (current_param.transmitPower != operationParam->transmitPower) {
14754 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
14755 fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__);
14756 return RETURN_ERR;
14757 }
14758 }
14759 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
14760 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
14761 fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__);
14762 return RETURN_ERR;
14763 }
14764 }
14765 if (current_param.obssCoex != operationParam->obssCoex) {
14766 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
14767 fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__);
14768 return RETURN_ERR;
14769 }
14770 }
14771 if (current_param.stbcEnable != operationParam->stbcEnable) {
14772 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
14773 fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__);
14774 return RETURN_ERR;
14775 }
14776 }
14777 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
14778 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
14779 fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__);
14780 return RETURN_ERR;
14781 }
14782 }
14783
14784 // if enable is true, then restart the radio
14785 wifi_setRadioEnable(index, FALSE);
14786 if (operationParam->enable == TRUE)
14787 wifi_setRadioEnable(index, TRUE);
14788 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14789
14790 return RETURN_OK;
14791}
14792
14793INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14794{
14795 char band[64] = {0};
14796 char buf[256] = {0};
14797 char config_file[64] = {0};
14798 char cmd[128] = {0};
14799 int ret = RETURN_ERR;
14800 int mode = 0;
14801 ULONG channel = 0;
14802 BOOL enabled = FALSE;
14803
14804 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14805 printf("Entering %s index = %d\n", __func__, (int)index);
14806
14807 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
14808 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
14809 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
14810 {
14811 fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__);
14812 return RETURN_ERR;
14813 }
14814 operationParam->enable = enabled;
14815
14816 memset(band, 0, sizeof(band));
14817 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
14818 {
14819 fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__);
14820 return RETURN_ERR;
14821 }
14822
14823 if (!strcmp(band, "2.4GHz"))
14824 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
14825 else if (!strcmp(band, "5GHz"))
14826 operationParam->band = WIFI_FREQUENCY_5_BAND;
14827 else if (!strcmp(band, "6GHz"))
14828 operationParam->band = WIFI_FREQUENCY_6_BAND;
14829 else
14830 {
14831 fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
14832 band);
14833 }
14834
14835 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
14836 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
14837 operationParam->channel = 0;
14838 operationParam->autoChannelEnabled = TRUE;
14839 } else {
14840 operationParam->channel = strtol(buf, NULL, 10);
14841 operationParam->autoChannelEnabled = FALSE;
14842 }
14843
14844 memset(buf, 0, sizeof(buf));
14845 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
14846 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__);
14847 return RETURN_ERR;
14848 }
14849 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
14850 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
14851 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
14852 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
14853 else
14854 {
14855 fprintf(stderr, "Unknown channel bandwidth: %s\n", buf);
14856 return false;
14857 }
14858
14859 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
14860 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
14861 return RETURN_ERR;
14862 }
14863 // Two different definition bit map, so need to check every bit.
14864 if (mode & WIFI_MODE_A)
14865 operationParam->variant |= WIFI_80211_VARIANT_A;
14866 if (mode & WIFI_MODE_B)
14867 operationParam->variant |= WIFI_80211_VARIANT_B;
14868 if (mode & WIFI_MODE_G)
14869 operationParam->variant |= WIFI_80211_VARIANT_G;
14870 if (mode & WIFI_MODE_N)
14871 operationParam->variant |= WIFI_80211_VARIANT_N;
14872 if (mode & WIFI_MODE_AC)
14873 operationParam->variant |= WIFI_80211_VARIANT_AC;
14874 if (mode & WIFI_MODE_AX)
14875 operationParam->variant |= WIFI_80211_VARIANT_AX;
14876 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
14877 fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__);
14878 return RETURN_ERR;
14879 }
14880 if (wifi_getApDTIMInterval(index, &operationParam->dtimPeriod) != RETURN_OK) {
14881 fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__);
14882 return RETURN_ERR;
14883 }
14884 if (wifi_getRadioBeaconPeriod(index, &operationParam->dtimPeriod) != RETURN_OK) {
14885 fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__);
14886 return RETURN_ERR;
14887 }
14888
14889 memset(buf, 0, sizeof(buf));
14890 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
14891 fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__);
14892 return RETURN_ERR;
14893 }
14894 TransmitRatesToBitMap(buf, &operationParam->basicDataTransmitRates);
14895
14896 memset(buf, 0, sizeof(buf));
14897 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14898 fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__);
14899 return RETURN_ERR;
14900 }
14901 TransmitRatesToBitMap(buf, &operationParam->operationalDataTransmitRates);
14902
14903 memset(buf, 0, sizeof(buf));
14904 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
14905 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
14906
14907 if (wifi_getGuardInterval(index, &operationParam->guardInterval) != RETURN_OK) {
14908 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
14909 return RETURN_ERR;
14910 }
developera1255e42023-05-13 17:45:02 +080014911 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&operationParam->transmitPower) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014912 fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__);
14913 return RETURN_ERR;
14914 }
14915
14916 memset(buf, 0, sizeof(buf));
14917 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
14918 if (strcmp(buf, "-1") == 0) {
14919 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
14920 operationParam->ctsProtection = FALSE;
14921 } else {
14922 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
14923 operationParam->ctsProtection = TRUE;
14924 }
14925
14926 memset(buf, 0, sizeof(buf));
14927 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
14928 if (strcmp(buf, "0") == 0)
14929 operationParam->obssCoex = FALSE;
14930 else
14931 operationParam->obssCoex = TRUE;
14932
14933 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
14934 _syscmd(cmd, buf, sizeof(buf));
14935 if (strlen(buf) != 0)
14936 operationParam->stbcEnable = TRUE;
14937 else
14938 operationParam->stbcEnable = FALSE;
14939
14940 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
14941 fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__);
14942 return RETURN_ERR;
14943 }
14944
14945 // Below value is hardcoded
14946
14947 operationParam->numSecondaryChannels = 0;
14948 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
14949 operationParam->channelSecondary[i] = 0;
14950 }
14951 operationParam->csa_beacon_count = 15;
14952 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
14953
14954 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14955 return RETURN_OK;
14956}
14957
14958static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
14959{
14960 int max_radio_num = 0;
14961
14962 wifi_getMaxRadioNumber(&max_radio_num);
14963 if (radioIndex >= max_radio_num) {
14964 fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex);
14965 return RETURN_ERR;
14966 }
14967
14968 return (arrayIndex * max_radio_num) + radioIndex;
14969}
14970
developer96b38512023-02-22 11:17:45 +080014971static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
14972{
14973 int max_radio_num = 0;
14974
14975 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
14976 return -1;
14977
14978 wifi_getMaxRadioNumber(&max_radio_num);
14979
14980 (*radioIndex) = vapIndex % max_radio_num;
14981 (*arrayIndex) = vapIndex / max_radio_num;
14982
14983 return 0;
14984}
14985
14986
developer72fb0bb2023-01-11 09:46:29 +080014987wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
14988 if (strncmp(beaconRate, "1Mbps", 5) == 0)
14989 return WIFI_BITRATE_1MBPS;
14990 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
14991 return WIFI_BITRATE_2MBPS;
14992 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
14993 return WIFI_BITRATE_5_5MBPS;
14994 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
14995 return WIFI_BITRATE_6MBPS;
14996 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
14997 return WIFI_BITRATE_9MBPS;
14998 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
14999 return WIFI_BITRATE_11MBPS;
15000 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
15001 return WIFI_BITRATE_12MBPS;
15002 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
15003 return WIFI_BITRATE_18MBPS;
15004 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
15005 return WIFI_BITRATE_24MBPS;
15006 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
15007 return WIFI_BITRATE_36MBPS;
15008 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
15009 return WIFI_BITRATE_48MBPS;
15010 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
15011 return WIFI_BITRATE_54MBPS;
15012 return WIFI_BITRATE_DEFAULT;
15013}
15014
15015INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str)
15016{
15017 if (beacon == WIFI_BITRATE_1MBPS)
15018 strcpy(beacon_str, "1Mbps");
15019 else if (beacon == WIFI_BITRATE_2MBPS)
15020 strcpy(beacon_str, "2Mbps");
15021 else if (beacon == WIFI_BITRATE_5_5MBPS)
15022 strcpy(beacon_str, "5.5Mbps");
15023 else if (beacon == WIFI_BITRATE_6MBPS)
15024 strcpy(beacon_str, "6Mbps");
15025 else if (beacon == WIFI_BITRATE_9MBPS)
15026 strcpy(beacon_str, "9Mbps");
15027 else if (beacon == WIFI_BITRATE_11MBPS)
15028 strcpy(beacon_str, "11Mbps");
15029 else if (beacon == WIFI_BITRATE_12MBPS)
15030 strcpy(beacon_str, "12Mbps");
15031 else if (beacon == WIFI_BITRATE_18MBPS)
15032 strcpy(beacon_str, "18Mbps");
15033 else if (beacon == WIFI_BITRATE_24MBPS)
15034 strcpy(beacon_str, "24Mbps");
15035 else if (beacon == WIFI_BITRATE_36MBPS)
15036 strcpy(beacon_str, "36Mbps");
15037 else if (beacon == WIFI_BITRATE_48MBPS)
15038 strcpy(beacon_str, "48Mbps");
15039 else if (beacon == WIFI_BITRATE_54MBPS)
15040 strcpy(beacon_str, "54Mbps");
15041 return RETURN_OK;
15042}
15043
15044INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15045{
15046 INT mode = 0;
15047 INT ret = -1;
15048 INT output = 0;
15049 int i = 0;
15050 int vap_index = 0;
15051 BOOL enabled = FALSE;
15052 char buf[256] = {0};
15053 wifi_vap_security_t security = {0};
developer72fb0bb2023-01-11 09:46:29 +080015054
15055 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15056 printf("Entering %s index = %d\n", __func__, (int)index);
15057
developerfde01262023-05-22 15:15:24 +080015058 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
15059 if (ret != 0) {
15060 fprintf(stderr, "%s: wifi_BandProfileRead BssidNum failed\n", __func__);
15061 return RETURN_ERR;
15062 }
15063
15064 map->num_vaps = atoi(buf);
15065 if (map->num_vaps <= 0) {
15066 fprintf(stderr, "%s: invalid BssidNum %s\n", __func__, buf);
15067 return RETURN_ERR;
15068 }
15069
15070 for (i = 0; i < map->num_vaps; i++)
developer72fb0bb2023-01-11 09:46:29 +080015071 {
15072 map->vap_array[i].radio_index = index;
15073
15074 vap_index = array_index_to_vap_index(index, i);
15075 if (vap_index < 0)
15076 return RETURN_ERR;
15077
15078 strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME);
15079
15080 map->vap_array[i].vap_index = vap_index;
15081
15082 memset(buf, 0, sizeof(buf));
15083 ret = wifi_getApName(vap_index, buf);
15084 if (ret != RETURN_OK) {
15085 printf("%s: wifi_getApName return error\n", __func__);
15086 return RETURN_ERR;
15087 }
15088 snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
15089
15090 memset(buf, 0, sizeof(buf));
15091 ret = wifi_getSSIDName(vap_index, buf);
15092 if (ret != RETURN_OK) {
15093 printf("%s: wifi_getSSIDName return error\n", __func__);
15094 return RETURN_ERR;
15095 }
15096 snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
15097
developere740c2a2023-05-23 18:34:32 +080015098#if 0
developer72fb0bb2023-01-11 09:46:29 +080015099 ret = wifi_getSSIDEnable(vap_index, &enabled);
15100 if (ret != RETURN_OK) {
15101 printf("%s: wifi_getSSIDEnable return error\n", __func__);
15102 return RETURN_ERR;
15103 }
developere740c2a2023-05-23 18:34:32 +080015104#endif
15105 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080015106
15107 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
15108 if (ret != RETURN_OK) {
15109 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
15110 return RETURN_ERR;
15111 }
15112 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080015113
developer72fb0bb2023-01-11 09:46:29 +080015114 ret = wifi_getApIsolationEnable(vap_index, &enabled);
15115 if (ret != RETURN_OK) {
15116 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
15117 return RETURN_ERR;
15118 }
15119 map->vap_array[i].u.bss_info.isolation = enabled;
15120
15121 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
15122 if (ret != RETURN_OK) {
15123 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
15124 return RETURN_ERR;
15125 }
15126 map->vap_array[i].u.bss_info.bssMaxSta = output;
15127
15128 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
15129 if (ret != RETURN_OK) {
15130 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
15131 return RETURN_ERR;
15132 }
15133 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
15134
15135 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
15136 if (ret != RETURN_OK) {
15137 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
15138 return RETURN_ERR;
15139 }
15140 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
15141
15142 ret = wifi_getApSecurity(vap_index, &security);
15143 if (ret != RETURN_OK) {
15144 printf("%s: wifi_getApSecurity return error\n", __func__);
15145 return RETURN_ERR;
15146 }
15147 map->vap_array[i].u.bss_info.security = security;
15148
15149 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
15150 if (ret != RETURN_OK) {
15151 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
15152 return RETURN_ERR;
15153 }
developer69b61b02023-03-07 17:17:44 +080015154 if (mode == 0)
developer72fb0bb2023-01-11 09:46:29 +080015155 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
developer69b61b02023-03-07 17:17:44 +080015156 else
developer72fb0bb2023-01-11 09:46:29 +080015157 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
developer69b61b02023-03-07 17:17:44 +080015158 if (mode == 1)
developer72fb0bb2023-01-11 09:46:29 +080015159 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
developer69b61b02023-03-07 17:17:44 +080015160 else if (mode == 2)
developer72fb0bb2023-01-11 09:46:29 +080015161 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
15162
15163 ret = wifi_getApWmmEnable(vap_index, &enabled);
15164 if (ret != RETURN_OK) {
15165 printf("%s: wifi_getApWmmEnable return error\n", __func__);
15166 return RETURN_ERR;
15167 }
15168 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
15169
15170 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
15171 if (ret != RETURN_OK) {
15172 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
15173 return RETURN_ERR;
15174 }
15175 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
15176
15177 memset(buf, 0, sizeof(buf));
15178 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
15179 if (ret != RETURN_OK) {
15180 printf("%s: wifi_getApBeaconRate return error\n", __func__);
15181 return RETURN_ERR;
15182 }
15183 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
15184
15185 memset(buf, 0, sizeof(buf));
15186 ret = wifi_getBaseBSSID(vap_index, buf);
15187 if (ret != RETURN_OK) {
15188 printf("%s: wifi_getBaseBSSID return error\n", __func__);
15189 return RETURN_ERR;
15190 }
developer5b2f10c2023-05-25 17:02:21 +080015191 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
15192 printf("%s: hwaddr_aton2 fail\n", __func__);
15193 return RETURN_ERR;
15194 }
developer72fb0bb2023-01-11 09:46:29 +080015195
15196 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
15197 if (ret != RETURN_OK) {
15198 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
15199 return RETURN_ERR;
15200 }
15201 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
15202
15203 // TODO: wps, noack
15204 }
15205 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15206 return RETURN_OK;
15207}
15208
developer47cc27a2023-05-17 23:09:58 +080015209void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080015210{
15211 char if_name[16] = {0};
15212 char cmd[128] = {0};
15213 char buf[128] = {0};
15214
15215 *enable = FALSE;
15216 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
15217 return;
15218
15219 snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
15220 _syscmd(cmd, buf, sizeof(buf));
15221 if (strlen(buf) > 0)
15222 *enable = TRUE;
15223 return;
15224}
15225
15226static int prepareInterface(UINT apIndex, char *new_interface)
15227{
15228 char cur_interface[16] = {0};
15229 char config_file[128] = {0};
developer8a3bbbf2023-03-15 17:47:23 +080015230 char cmd[MAX_CMD_SIZE] = {0};
15231 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015232 int max_radio_num = 0;
15233 int radioIndex = -1;
15234 int phyIndex = -1;
developer8a3bbbf2023-03-15 17:47:23 +080015235 struct params params;
developer72fb0bb2023-01-11 09:46:29 +080015236
15237 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15238 wifi_hostapdRead(config_file, "interface", cur_interface, sizeof(cur_interface));
15239
15240 if (strncmp(cur_interface, new_interface, sizeof(cur_interface)) != 0) {
developer8a3bbbf2023-03-15 17:47:23 +080015241 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +080015242 radioIndex = apIndex % max_radio_num;
15243 phyIndex = radio_index_to_phy(radioIndex);
15244 // disable and del old interface, then add new interface
15245 wifi_setApEnable(apIndex, FALSE);
developer8a3bbbf2023-03-15 17:47:23 +080015246
15247 params.name = "interface";
15248 params.value = new_interface;
15249 wifi_hostapdWrite(config_file, &params, 1);
15250
15251 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyIndex, config_file);
15252 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015253 }
developer8a3bbbf2023-03-15 17:47:23 +080015254
developer72fb0bb2023-01-11 09:46:29 +080015255 // update the vap status file
15256 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=1' %s", cur_interface, new_interface, VAP_STATUS_FILE);
15257 _syscmd(cmd, buf, sizeof(buf));
15258 return RETURN_OK;
15259}
15260
15261INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15262{
15263 char interface_name[16] = {0};
15264 unsigned int i;
15265 wifi_vap_info_t *vap_info = NULL;
15266 int acl_mode;
15267 int ret = 0;
15268 char *sec_str = NULL;
15269 char buf[256] = {0};
15270 char cmd[128] = {0};
15271 char config_file[64] = {0};
15272 char bssid[32] = {0};
15273 char psk_file[64] = {0};
developer47cc27a2023-05-17 23:09:58 +080015274 BOOL enable = FALSE;
developere740c2a2023-05-23 18:34:32 +080015275 int band_idx;
15276
developer72fb0bb2023-01-11 09:46:29 +080015277
15278 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15279 printf("Entering %s index = %d\n", __func__, (int)index);
15280 for (i = 0; i < map->num_vaps; i++)
15281 {
15282 multiple_set = TRUE;
15283 vap_info = &map->vap_array[i];
15284
15285 // Check vap status file to enable multiple ap if the system boot.
15286 checkVapStatus(vap_info->vap_index, &enable);
15287 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
15288 continue;
15289
15290 fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
15291
developere740c2a2023-05-23 18:34:32 +080015292 band_idx = radio_index_to_band(index);
15293 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
15294 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
15295 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015296
developere740c2a2023-05-23 18:34:32 +080015297 struct params params[4];
developer72fb0bb2023-01-11 09:46:29 +080015298 params[0].name = "interface";
15299 params[0].value = vap_info->vap_name;
15300 mac_addr_ntoa(bssid, vap_info->u.bss_info.bssid);
15301 params[1].name = "bssid";
15302 params[1].value = bssid;
15303 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
15304 params[2].name = "wpa_psk_file";
15305 params[2].value = psk_file;
developere740c2a2023-05-23 18:34:32 +080015306 params[3].name = "ssid";
15307 params[3].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080015308
15309 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
developere740c2a2023-05-23 18:34:32 +080015310 wifi_hostapdWrite(config_file, params, 4);
developer72fb0bb2023-01-11 09:46:29 +080015311
15312 snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
15313 _syscmd(cmd, buf, sizeof(buf));
15314
15315 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
15316 if (ret != RETURN_OK) {
15317 fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__);
15318 return RETURN_ERR;
15319 }
15320
15321 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
15322 if (ret != RETURN_OK) {
15323 fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__);
15324 return RETURN_ERR;
15325 }
15326
15327 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
15328 if (ret != RETURN_OK) {
15329 fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__);
15330 return RETURN_ERR;
15331 }
15332
15333 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
15334 if (ret != RETURN_OK) {
15335 fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__);
15336 return RETURN_ERR;
15337 }
15338
15339 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
15340 if (ret != RETURN_OK) {
15341 fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__);
15342 return RETURN_ERR;
15343 }
15344
15345 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
15346 if (ret != RETURN_OK) {
15347 fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__);
15348 return RETURN_ERR;
15349 }
15350
15351 if (vap_info->u.bss_info.mac_filter_enable == false){
15352 acl_mode = 0;
15353 }else {
15354 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
15355 acl_mode = 2;
15356 snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
15357 _syscmd(cmd, buf, sizeof(buf));
15358 }else{
15359 acl_mode = 1;
15360 }
15361 }
15362
15363 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
15364 if (ret != RETURN_OK) {
15365 fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__);
15366 return RETURN_ERR;
15367 }
15368
15369 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
15370 if (ret != RETURN_OK) {
15371 fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__);
15372 return RETURN_ERR;
15373 }
15374
developer0f10c772023-05-16 21:43:39 +080015375 memset(buf, 0, sizeof(buf));
15376 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf);
15377 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
15378 if (ret != RETURN_OK) {
15379 fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__);
15380 return RETURN_ERR;
15381 }
developer72fb0bb2023-01-11 09:46:29 +080015382
15383 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
15384 if (ret != RETURN_OK) {
15385 fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__);
15386 return RETURN_ERR;
15387 }
15388
developer72fb0bb2023-01-11 09:46:29 +080015389 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
15390 if (ret != RETURN_OK) {
15391 fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__);
15392 return RETURN_ERR;
15393 }
15394
developer23e71282023-01-18 10:25:19 +080015395 wifi_setApEnable(vap_info->vap_index, FALSE);
15396 wifi_setApEnable(vap_info->vap_index, TRUE);
15397 multiple_set = FALSE;
15398
15399 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
developer72fb0bb2023-01-11 09:46:29 +080015400 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
15401 if (ret != RETURN_OK) {
15402 fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__);
15403 return RETURN_ERR;
15404 }
15405
15406 // TODO mgmtPowerControl, interworking, wps
15407 }
15408 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15409 return RETURN_OK;
15410}
15411
15412int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
15413{
15414 char *token, *next;
15415 const char s[2] = ",";
15416 int count =0;
15417
15418 /* get the first token */
15419 token = strtok_r(pchannels, s, &next);
15420
15421 /* walk through other tokens */
15422 while( token != NULL && count < MAX_CHANNELS) {
15423 chlistptr->channels_list[count++] = atoi(token);
15424 token = strtok_r(NULL, s, &next);
15425 }
15426
15427 return count;
15428}
15429
15430static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
15431{
15432 INT status;
15433 wifi_channels_list_t *chlistp;
15434 CHAR output_string[64];
15435 CHAR pchannels[128];
15436 CHAR interface_name[16] = {0};
15437 wifi_band band;
15438
15439 if(rcap == NULL)
15440 {
15441 return RETURN_ERR;
15442 }
15443
15444 rcap->numSupportedFreqBand = 1;
15445 band = wifi_index_to_band(radioIndex);
15446
15447 if (band == band_2_4)
15448 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
15449 else if (band == band_5)
15450 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
15451 else if (band == band_6)
15452 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
15453
15454 chlistp = &(rcap->channel_list[0]);
15455 memset(pchannels, 0, sizeof(pchannels));
15456
15457 /* possible number of radio channels */
15458 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
15459 {
15460 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
15461 }
15462 /* Number of channels and list*/
15463 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
15464
15465 /* autoChannelSupported */
15466 /* always ON with wifi_getRadioAutoChannelSupported */
15467 rcap->autoChannelSupported = TRUE;
15468
15469 /* DCSSupported */
15470 /* always ON with wifi_getRadioDCSSupported */
15471 rcap->DCSSupported = TRUE;
15472
15473 /* zeroDFSSupported - TBD */
15474 rcap->zeroDFSSupported = FALSE;
15475
15476 /* Supported Country List*/
15477 memset(output_string, 0, sizeof(output_string));
15478 status = wifi_getRadioCountryCode(radioIndex, output_string);
15479 if( status != 0 ) {
15480 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
15481 return RETURN_ERR;
15482 } else {
15483 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
15484 }
15485 if(!strcmp(output_string,"US")){
15486 rcap->countrySupported[0] = wifi_countrycode_US;
15487 rcap->countrySupported[1] = wifi_countrycode_CA;
15488 } else if (!strcmp(output_string,"CA")) {
15489 rcap->countrySupported[0] = wifi_countrycode_CA;
15490 rcap->countrySupported[1] = wifi_countrycode_US;
15491 } else {
15492 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
15493 }
15494
15495 rcap->numcountrySupported = 2;
15496
15497 /* csi */
15498 rcap->csi.maxDevices = 8;
15499 rcap->csi.soudingFrameSupported = TRUE;
15500
15501 wifi_GetInterfaceName(radioIndex, interface_name);
15502 snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
15503
15504 /* channelWidth - all supported bandwidths */
15505 int i=0;
15506 rcap->channelWidth[i] = 0;
15507 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
15508 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
15509 WIFI_CHANNELBANDWIDTH_40MHZ);
15510
15511 }
15512 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
15513 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
15514 WIFI_CHANNELBANDWIDTH_40MHZ |
15515 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
15516 }
15517
15518
15519 /* mode - all supported variants */
15520 // rcap->mode[i] = WIFI_80211_VARIANT_H;
15521 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
15522 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
15523 }
15524 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
15525 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
15526 }
15527 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
15528 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
15529 }
15530 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
15531 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
15532
15533 /* supportedBitRate - all supported bitrates */
15534 rcap->supportedBitRate[i] = 0;
15535 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
15536 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
15537 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
15538 }
15539 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) | rcap->band[i] & (WIFI_FREQUENCY_6_BAND )) {
15540 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
15541 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
15542 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
15543 }
15544
15545
15546 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
15547 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
15548 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
15549 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
15550 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
15551 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
15552 rcap->cipherSupported = 0;
15553 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
15554 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
15555
15556 return RETURN_OK;
15557}
15558
15559INT wifi_getHalCapability(wifi_hal_capability_t *cap)
15560{
15561 INT status = 0, radioIndex = 0;
15562 char cmd[MAX_BUF_SIZE] = {0}, output[MAX_BUF_SIZE] = {0};
15563 int iter = 0;
15564 unsigned int j = 0;
15565 int max_num_radios;
15566 wifi_interface_name_idex_map_t *iface_info = NULL;
15567
15568 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15569
15570 memset(cap, 0, sizeof(wifi_hal_capability_t));
15571
15572 /* version */
15573 cap->version.major = WIFI_HAL_MAJOR_VERSION;
15574 cap->version.minor = WIFI_HAL_MINOR_VERSION;
15575
15576 /* number of radios platform property */
15577 wifi_getMaxRadioNumber(&max_num_radios);
15578 cap->wifi_prop.numRadios = max_num_radios;
15579
15580 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
15581 {
15582 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
15583 if (status != 0) {
15584 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
15585 return RETURN_ERR;
15586 }
15587
15588 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
15589 {
15590 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
15591 {
15592 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
15593 return RETURN_ERR;
15594 }
15595 iface_info = &cap->wifi_prop.interface_map[iter];
15596 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
15597 iface_info->rdk_radio_index = radioIndex;
15598 memset(output, 0, sizeof(output));
15599 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
15600 {
15601 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
15602 }
15603 // TODO: bridge name
15604 // TODO: vlan id
15605 // TODO: primary
15606 iface_info->index = array_index_to_vap_index(radioIndex, j);
15607 memset(output, 0, sizeof(output));
15608 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
15609 {
15610 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
15611 }
15612 iter++;
15613 }
15614 }
15615
15616 cap->BandSteeringSupported = FALSE;
15617 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15618 return RETURN_OK;
15619}
15620
15621INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
15622{
15623 struct params h_config={0};
15624 char config_file[64] = {0};
15625
15626 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15627
15628 h_config.name = "okc";
15629 h_config.value = okc_enable?"1":"0";
15630
15631 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15632 wifi_hostapdWrite(config_file, &h_config, 1);
15633 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15634
15635 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15636 return RETURN_OK;
15637}
15638
15639INT wifi_setSAEMFP(int ap_index, BOOL enable)
15640{
15641 struct params h_config={0};
15642 char config_file[64] = {0};
15643 char buf[128] = {0};
15644
15645 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15646
15647 h_config.name = "sae_require_mfp";
15648 h_config.value = enable?"1":"0";
15649
15650 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15651 wifi_hostapdWrite(config_file, &h_config, 1);
15652 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15653
15654 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15655 return RETURN_OK;
15656}
15657
15658INT wifi_setSAEpwe(int ap_index, int sae_pwe)
15659{
15660 struct params h_config={0};
15661 char config_file[64] = {0};
15662 char buf[128] = {0};
15663
15664 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15665
15666 h_config.name = "sae_pwe";
15667 snprintf(buf, sizeof(buf), "%d", sae_pwe);
15668 h_config.value = buf;
15669
15670 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15671 wifi_hostapdWrite(config_file, &h_config, 1);
15672 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15673
15674 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15675 return RETURN_OK;
15676}
15677
15678INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
15679{
15680 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
15681 struct params h_config={0};
15682 char config_file[64] = {0};
15683
15684 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15685
15686 h_config.name = "wpa_disable_eapol_key_retries";
15687 h_config.value = disable_EAPOL_retries?"1":"0";
15688
15689 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15690 wifi_hostapdWrite(config_file, &h_config, 1);
15691 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15692
15693 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15694 return RETURN_OK;
15695}
15696
15697INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
15698{
15699 char buf[128] = {0};
15700 char config_file[128] = {0};
developere5750452023-05-15 16:46:42 +080015701 char cmd[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015702 char password[64] = {0};
15703 char mfp[32] = {0};
15704 char wpa_mode[32] = {0};
15705 BOOL okc_enable = FALSE;
15706 BOOL sae_MFP = FALSE;
15707 BOOL disable_EAPOL_retries = TRUE;
15708 int sae_pwe = 0;
15709 struct params params = {0};
15710 wifi_band band = band_invalid;
15711
15712 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15713
15714 multiple_set = TRUE;
15715 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15716 if (security->mode == wifi_security_mode_none) {
15717 strcpy(wpa_mode, "None");
15718 } else if (security->mode == wifi_security_mode_wpa_personal)
15719 strcpy(wpa_mode, "WPA-Personal");
15720 else if (security->mode == wifi_security_mode_wpa2_personal)
15721 strcpy(wpa_mode, "WPA2-Personal");
15722 else if (security->mode == wifi_security_mode_wpa_wpa2_personal)
15723 strcpy(wpa_mode, "WPA-WPA2-Personal");
15724 else if (security->mode == wifi_security_mode_wpa_enterprise)
15725 strcpy(wpa_mode, "WPA-Enterprise");
15726 else if (security->mode == wifi_security_mode_wpa2_enterprise)
15727 strcpy(wpa_mode, "WPA2-Enterprise");
15728 else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise)
15729 strcpy(wpa_mode, "WPA-WPA2-Enterprise");
15730 else if (security->mode == wifi_security_mode_wpa3_personal) {
15731 strcpy(wpa_mode, "WPA3-Personal");
15732 okc_enable = TRUE;
15733 sae_MFP = TRUE;
15734 sae_pwe = 2;
15735 disable_EAPOL_retries = FALSE;
15736 } else if (security->mode == wifi_security_mode_wpa3_transition) {
15737 strcpy(wpa_mode, "WPA3-Personal-Transition");
15738 okc_enable = TRUE;
15739 sae_MFP = TRUE;
15740 sae_pwe = 2;
15741 disable_EAPOL_retries = FALSE;
15742 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
15743 strcpy(wpa_mode, "WPA3-Enterprise");
15744 sae_MFP = TRUE;
15745 sae_pwe = 2;
15746 disable_EAPOL_retries = FALSE;
developerd01e3e82023-04-26 19:10:38 +080015747 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer3086e2f2023-01-17 09:40:01 +080015748 strcpy(wpa_mode, "OWE");
15749 sae_MFP = TRUE;
15750 sae_pwe = 2;
15751 disable_EAPOL_retries = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015752 }
15753
15754 band = wifi_index_to_band(ap_index);
15755 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
15756 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
15757 return RETURN_ERR;
15758 }
15759
15760 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
15761 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
15762 wifi_setSAEMFP(ap_index, sae_MFP);
15763 wifi_setSAEpwe(ap_index, sae_pwe);
15764 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
15765
developerd01e3e82023-04-26 19:10:38 +080015766 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
developere5750452023-05-15 16:46:42 +080015767 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) {
15768 int key_len = strlen(security->u.key.key);
15769 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
15770 if (key_len == 64) { // set wpa_psk
15771 strncpy(password, security->u.key.key, 64); // 64 characters
15772 password[64] = '\0';
15773 wifi_setApSecurityPreSharedKey(ap_index, password);
15774 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
15775 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
15776 strncpy(password, security->u.key.key, 63);
15777 password[63] = '\0';
15778 wifi_setApSecurityKeyPassphrase(ap_index, password);
15779 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
15780 } else
15781 return RETURN_ERR;
15782 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015783 }
15784 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
15785 params.name = "sae_password";
15786 params.value = security->u.key.key;
15787 wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +080015788 } else { // remove sae_password
15789 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
15790 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015791 }
15792 }
15793
15794 if (security->mode != wifi_security_mode_none) {
15795 memset(&params, 0, sizeof(params));
15796 params.name = "wpa_pairwise";
15797 if (security->encr == wifi_encryption_tkip)
15798 params.value = "TKIP";
15799 else if (security->encr == wifi_encryption_aes)
15800 params.value = "CCMP";
15801 else if (security->encr == wifi_encryption_aes_tkip)
15802 params.value = "TKIP CCMP";
15803 wifi_hostapdWrite(config_file, &params, 1);
15804 }
15805
15806 if (security->mfp == wifi_mfp_cfg_disabled)
15807 strcpy(mfp, "Disabled");
15808 else if (security->mfp == wifi_mfp_cfg_optional)
15809 strcpy(mfp, "Optional");
15810 else if (security->mfp == wifi_mfp_cfg_required)
15811 strcpy(mfp, "Required");
15812 wifi_setApSecurityMFPConfig(ap_index, mfp);
15813
15814 memset(&params, 0, sizeof(params));
15815 params.name = "transition_disable";
15816 if (security->wpa3_transition_disable == TRUE)
15817 params.value = "0x01";
15818 else
15819 params.value = "0x00";
15820 wifi_hostapdWrite(config_file, &params, 1);
15821
15822 memset(&params, 0, sizeof(params));
15823 params.name = "wpa_group_rekey";
15824 snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
15825 params.value = buf;
15826 wifi_hostapdWrite(config_file, &params, 1);
15827
15828 memset(&params, 0, sizeof(params));
15829 params.name = "wpa_strict_rekey";
15830 params.value = security->strict_rekey?"1":"0";
15831 wifi_hostapdWrite(config_file, &params, 1);
15832
15833 memset(&params, 0, sizeof(params));
15834 params.name = "wpa_pairwise_update_count";
developere5750452023-05-15 16:46:42 +080015835 if (security->eapol_key_retries == 0)
15836 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developer72fb0bb2023-01-11 09:46:29 +080015837 snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
15838 params.value = buf;
15839 wifi_hostapdWrite(config_file, &params, 1);
15840
15841 memset(&params, 0, sizeof(params));
15842 params.name = "disable_pmksa_caching";
15843 params.value = security->disable_pmksa_caching?"1":"0";
15844 wifi_hostapdWrite(config_file, &params, 1);
15845
developer23e71282023-01-18 10:25:19 +080015846 if (multiple_set == FALSE) {
15847 wifi_setApEnable(ap_index, FALSE);
15848 wifi_setApEnable(ap_index, TRUE);
15849 }
developer72fb0bb2023-01-11 09:46:29 +080015850
15851 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15852
15853 return RETURN_OK;
15854}
15855
15856INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
15857{
15858 char buf[256] = {0};
15859 char config_file[128] = {0};
15860 int disable = 0;
developere5750452023-05-15 16:46:42 +080015861 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015862
15863 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15864 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15865 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
15866 security->mode = wifi_security_mode_none;
15867 if (strlen(buf) != 0) {
15868 if (!strcmp(buf, "WPA-Personal"))
15869 security->mode = wifi_security_mode_wpa_personal;
15870 else if (!strcmp(buf, "WPA2-Personal"))
15871 security->mode = wifi_security_mode_wpa2_personal;
15872 else if (!strcmp(buf, "WPA-WPA2-Personal"))
15873 security->mode = wifi_security_mode_wpa_wpa2_personal;
15874 else if (!strcmp(buf, "WPA-Enterprise"))
15875 security->mode = wifi_security_mode_wpa_enterprise;
15876 else if (!strcmp(buf, "WPA2-Enterprise"))
15877 security->mode = wifi_security_mode_wpa2_enterprise;
15878 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
15879 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
15880 else if (!strcmp(buf, "WPA3-Personal"))
15881 security->mode = wifi_security_mode_wpa3_personal;
15882 else if (!strcmp(buf, "WPA3-Personal-Transition"))
15883 security->mode = wifi_security_mode_wpa3_transition;
15884 else if (!strcmp(buf, "WPA3-Enterprise"))
15885 security->mode = wifi_security_mode_wpa3_enterprise;
developer3086e2f2023-01-17 09:40:01 +080015886 else if (!strcmp(buf, "OWE"))
developerd01e3e82023-04-26 19:10:38 +080015887 security->mode = wifi_security_mode_enhanced_open;
developer72fb0bb2023-01-11 09:46:29 +080015888 }
15889
15890 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
15891 if (security->mode == wifi_security_mode_none)
15892 security->encr = wifi_encryption_none;
15893 else {
15894 if (strcmp(buf, "TKIP") == 0)
15895 security->encr = wifi_encryption_tkip;
15896 else if (strcmp(buf, "CCMP") == 0)
15897 security->encr = wifi_encryption_aes;
15898 else
15899 security->encr = wifi_encryption_aes_tkip;
15900 }
15901
15902 if (security->mode != wifi_encryption_none) {
15903 memset(buf, 0, sizeof(buf));
15904 // wpa3 can use one or both configs as password, so we check sae_password first.
15905 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
developere5750452023-05-15 16:46:42 +080015906 if (strlen(buf) != 0) {
15907 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
15908 security->u.key.type = wifi_security_key_type_sae;
15909 set_sae = TRUE;
15910 strncpy(security->u.key.key, buf, sizeof(buf));
15911 }
15912 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
15913 if (strlen(buf) != 0){
15914 if (set_sae == TRUE)
15915 security->u.key.type = wifi_security_key_type_psk_sae;
15916 else if (strlen(buf) == 64)
15917 security->u.key.type = wifi_security_key_type_psk;
15918 else
15919 security->u.key.type = wifi_security_key_type_pass;
15920 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
developer72fb0bb2023-01-11 09:46:29 +080015921 }
developer72fb0bb2023-01-11 09:46:29 +080015922 security->u.key.key[255] = '\0';
15923 }
15924
15925 memset(buf, 0, sizeof(buf));
15926 wifi_getApSecurityMFPConfig(ap_index, buf);
15927 if (strcmp(buf, "Disabled") == 0)
15928 security->mfp = wifi_mfp_cfg_disabled;
15929 else if (strcmp(buf, "Optional") == 0)
15930 security->mfp = wifi_mfp_cfg_optional;
15931 else if (strcmp(buf, "Required") == 0)
15932 security->mfp = wifi_mfp_cfg_required;
15933
15934 memset(buf, 0, sizeof(buf));
15935 security->wpa3_transition_disable = FALSE;
15936 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
15937 disable = strtol(buf, NULL, 16);
15938 if (disable != 0)
15939 security->wpa3_transition_disable = TRUE;
15940
15941 memset(buf, 0, sizeof(buf));
15942 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
15943 if (strlen(buf) == 0)
15944 security->rekey_interval = 86400;
15945 else
15946 security->rekey_interval = strtol(buf, NULL, 10);
15947
15948 memset(buf, 0, sizeof(buf));
15949 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
15950 if (strlen(buf) == 0)
15951 security->strict_rekey = 1;
15952 else
15953 security->strict_rekey = strtol(buf, NULL, 10);
15954
15955 memset(buf, 0, sizeof(buf));
15956 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
15957 if (strlen(buf) == 0)
15958 security->eapol_key_retries = 4;
15959 else
15960 security->eapol_key_retries = strtol(buf, NULL, 10);
15961
15962 memset(buf, 0, sizeof(buf));
15963 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
15964 if (strlen(buf) == 0)
15965 security->disable_pmksa_caching = FALSE;
15966 else
15967 security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE;
15968
15969 /* TODO
15970 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
15971 */
15972 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
15973 security->eap_identity_req_timeout = 0;
15974 security->eap_identity_req_retries = 0;
15975 security->eap_req_timeout = 0;
15976 security->eap_req_retries = 0;
15977 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15978 return RETURN_OK;
15979}
15980
15981#endif /* WIFI_HAL_VERSION_3 */
15982
15983#ifdef WIFI_HAL_VERSION_3_PHASE2
15984INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
15985{
15986 char interface_name[16] = {0};
15987 char cmd[128] = {0};
15988 char buf[128] = {0};
15989 char *mac_addr = NULL;
15990 BOOL status = FALSE;
15991 size_t len = 0;
15992
15993 if(ap_index > MAX_APS)
15994 return RETURN_ERR;
15995
15996 *output_numDevices = 0;
15997 wifi_getApEnable(ap_index, &status);
15998 if (status == FALSE)
15999 return RETURN_OK;
16000
16001 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
16002 return RETURN_ERR;
16003 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
16004 _syscmd(cmd, buf, sizeof(buf));
16005
16006 mac_addr = strtok(buf, "\n");
16007 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
16008 *output_numDevices = i + 1;
16009 fprintf(stderr, "mac_addr: %s\n", mac_addr);
16010 addr_ptr = output_deviceMacAddressArray[i];
16011 mac_addr_aton(addr_ptr, mac_addr);
16012 mac_addr = strtok(NULL, "\n");
16013 }
16014
16015 return RETURN_OK;
16016}
16017#else
16018INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
16019{
16020 char interface_name[16] = {0};
16021 char cmd[128];
16022 BOOL status = false;
16023
16024 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
16025 return RETURN_ERR;
16026
16027 output_buf[0] = '\0';
16028
16029 wifi_getApEnable(ap_index,&status);
16030 if (!status)
16031 return RETURN_OK;
16032
16033 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
16034 return RETURN_ERR;
16035 sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
16036 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080016037
developer72fb0bb2023-01-11 09:46:29 +080016038 return RETURN_OK;
16039}
16040#endif
16041
16042INT wifi_getProxyArp(INT apIndex, BOOL *enable)
16043{
16044 char output[16]={'\0'};
16045 char config_file[MAX_BUF_SIZE] = {0};
16046
16047 if (!enable)
16048 return RETURN_ERR;
16049
16050 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
16051 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
16052
16053 if (strlen(output) == 0)
16054 *enable = FALSE;
16055 else if (strncmp(output, "1", 1) == 0)
16056 *enable = TRUE;
16057 else
16058 *enable = FALSE;
16059
16060 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
16061 return RETURN_OK;
16062}
16063
16064INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
16065{
16066 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
16067 return RETURN_ERR;
16068 *output_enable=TRUE;
16069 return RETURN_OK;
16070}
16071
16072INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
16073{
16074 char cmd[128] = {0};
16075 char buf[128] = {0};
16076 char line[128] = {0};
16077 size_t len = 0;
16078 FILE *f = NULL;
16079 int index = 0;
16080 int exp = 0;
16081 int mantissa = 0;
16082 int duration = 0;
16083 int radio_index = 0;
16084 int max_radio_num = 0;
16085 uint twt_wake_interval = 0;
16086 int phyId = 0;
16087 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16088
16089 wifi_getMaxRadioNumber(&max_radio_num);
16090
16091 radio_index = ap_index % max_radio_num;
16092
16093 phyId = radio_index_to_phy(radio_index);
16094 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
16095 _syscmd(cmd, buf, sizeof(buf));
16096 *numSessionReturned = strtol(buf, NULL, 10) - 1;
16097 if (*numSessionReturned > maxNumberSessions)
16098 *numSessionReturned = maxNumberSessions;
16099 else if (*numSessionReturned < 1) {
16100 *numSessionReturned = 0;
16101 return RETURN_OK;
16102 }
16103
16104 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
16105 if ((f = popen(cmd, "r")) == NULL) {
16106 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
16107 return RETURN_ERR;
16108 }
16109
16110 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
16111 while((fgets(line, sizeof(line), f)) != NULL) {
16112 char *tmp = NULL;
16113 strcpy(buf, line);
16114 tmp = strtok(buf, " ");
16115 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
16116 tmp = strtok(NULL, " ");
16117 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
16118 tmp = strtok(NULL, " ");
16119 if (strstr(tmp, "t")) {
16120 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
16121 }
16122 if (strstr(tmp, "a")) {
16123 twtSessions[index].twtParameters.operation.announced = TRUE;
16124 }
16125 tmp = strtok(NULL, " ");
16126 exp = strtol(tmp, NULL, 10);
16127 tmp = strtok(NULL, " ");
16128 mantissa = strtol(tmp, NULL, 10);
16129 tmp = strtok(NULL, " ");
16130 duration = strtol(tmp, NULL, 10);
16131
16132 // only implicit supported
16133 twtSessions[index].twtParameters.operation.implicit = TRUE;
16134 // only individual agreement supported
16135 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
16136
16137 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
16138 twt_wake_interval = mantissa * (1 << exp);
16139 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
16140 // Overflow handling
16141 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
16142 } else {
16143 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
16144 }
16145 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
16146 index++;
16147 }
16148
16149 pclose(f);
16150 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16151 return RETURN_OK;
16152}