blob: 786d75134c601a7e0c875237449ff14c814b0446 [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{
developer56fbedb2023-05-30 16:47:05 +08002348 char interface_name[16] = {0};
2349 char buf[128] = {0}, cmd[128] = {0};
2350 int apIndex;
2351 int max_radio_num = 0;
developer3a85ab82023-05-25 11:59:38 +08002352
developer56fbedb2023-05-30 16:47:05 +08002353 if (NULL == output_bool)
2354 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002355
developer56fbedb2023-05-30 16:47:05 +08002356 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08002357
developer56fbedb2023-05-30 16:47:05 +08002358 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +08002359
developer56fbedb2023-05-30 16:47:05 +08002360 if (radioIndex >= max_radio_num)
2361 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08002362
developer56fbedb2023-05-30 16:47:05 +08002363 /* loop all interface in radio, if any is enable, reture true, else return false */
2364 for(apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num)
2365 {
2366 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2367 continue;
2368 memset(cmd, 0, sizeof(cmd));
2369 sprintf(cmd, "ifconfig %s 2> /dev/null | grep UP", interface_name);
2370 *output_bool = _syscmd(cmd, buf, sizeof(buf)) ? FALSE : TRUE;
2371 if (*output_bool == TRUE)
2372 break;
2373 }
2374
2375 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08002376}
2377
developere82c0ca2023-05-10 16:25:35 +08002378typedef long time_t;
2379static time_t radio_up_time[MAX_NUM_RADIOS];
2380
developer72fb0bb2023-01-11 09:46:29 +08002381INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
2382{
2383 char interface_name[16] = {0};
2384 char cmd[MAX_CMD_SIZE] = {0};
developer8a3bbbf2023-03-15 17:47:23 +08002385 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08002386 int apIndex, ret;
developer69b61b02023-03-07 17:17:44 +08002387 int max_radio_num = 0;
developer72fb0bb2023-01-11 09:46:29 +08002388 int phyId = 0;
2389
2390 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2391
2392 phyId = radio_index_to_phy(radioIndex);
2393
2394 wifi_getMaxRadioNumber(&max_radio_num);
2395
developer8a3bbbf2023-03-15 17:47:23 +08002396 if(enable == FALSE) {
developer47cc27a2023-05-17 23:09:58 +08002397
2398 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
2399 return RETURN_ERR;
2400
2401 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002402 _syscmd(cmd, buf, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +08002403 memset(cmd, 0, sizeof(cmd));
2404 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
2405 _syscmd(cmd, buf, sizeof(buf));
developere82c0ca2023-05-10 16:25:35 +08002406 if(strncmp(buf, "OK", 2))
2407 fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name);
developer8a3bbbf2023-03-15 17:47:23 +08002408 } else {
developere82c0ca2023-05-10 16:25:35 +08002409 for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) {
developer72fb0bb2023-01-11 09:46:29 +08002410 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
2411 return RETURN_ERR;
2412
developer8a3bbbf2023-03-15 17:47:23 +08002413 memset(cmd, 0, MAX_CMD_SIZE);
2414 memset(buf, 0, MAX_BUF_SIZE);
2415
developer72fb0bb2023-01-11 09:46:29 +08002416 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
2417 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002418
2419 if(*buf == '1') {
developer56fbedb2023-05-30 16:47:05 +08002420 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
2421 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002422
2423 memset(cmd, 0, MAX_CMD_SIZE);
2424 memset(buf, 0, MAX_BUF_SIZE);
2425
developer72fb0bb2023-01-11 09:46:29 +08002426 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
2427 phyId, apIndex);
2428 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08002429
developer72fb0bb2023-01-11 09:46:29 +08002430 }
2431 }
developere82c0ca2023-05-10 16:25:35 +08002432 time(&radio_up_time[radioIndex]);
developer72fb0bb2023-01-11 09:46:29 +08002433 }
2434
2435 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2436 return RETURN_OK;
2437}
2438
2439//Get the Radio enable status
2440INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
2441{
2442 if (NULL == output_bool)
2443 return RETURN_ERR;
2444
2445 return wifi_getRadioEnable(radioIndex, output_bool);
2446}
2447
2448//Get the Radio Interface name from platform, eg "wlan0"
2449INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
2450{
2451 if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0)
2452 return RETURN_ERR;
2453 return wifi_GetInterfaceName(radioIndex, output_string);
2454}
2455
2456//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
2457//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.
2458INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2459{
2460 // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
2461 // For max bit rate, we should always choose the best MCS
2462 char mode[64] = {0};
2463 char channel_bandwidth_str[64] = {0};
2464 char *tmp = NULL;
2465 UINT mode_map = 0;
2466 UINT num_subcarrier = 0;
2467 UINT code_bits = 0;
2468 float code_rate = 0; // use max code rate
2469 int NSS = 0;
2470 UINT Symbol_duration = 0;
developer69b61b02023-03-07 17:17:44 +08002471 UINT GI_duration = 0;
developer72fb0bb2023-01-11 09:46:29 +08002472 wifi_band band = band_invalid;
2473 wifi_guard_interval_t gi = wifi_guard_interval_auto;
2474 BOOL enable = FALSE;
2475 float bit_rate = 0;
developera1255e42023-05-13 17:45:02 +08002476 int ant_bitmap = 0;
developer72fb0bb2023-01-11 09:46:29 +08002477
2478 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2479 if (NULL == output_string)
2480 return RETURN_ERR;
2481
2482 wifi_getRadioEnable(radioIndex, &enable);
2483 if (enable == FALSE) {
2484 snprintf(output_string, 64, "0 Mb/s");
2485 return RETURN_OK;
2486 }
2487
2488 if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
2489 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
2490 return RETURN_ERR;
2491 }
2492
2493 if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
2494 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
2495 return RETURN_ERR;
2496 }
2497
2498 if (gi == wifi_guard_interval_3200)
2499 GI_duration = 32;
2500 else if (gi == wifi_guard_interval_1600)
2501 GI_duration = 16;
2502 else if (gi == wifi_guard_interval_800)
2503 GI_duration = 8;
2504 else // auto, 400
2505 GI_duration = 4;
2506
2507 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
2508 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__);
2509 return RETURN_ERR;
2510 }
2511
2512 if (strstr(channel_bandwidth_str, "80+80") != NULL)
2513 strcpy(channel_bandwidth_str, "160");
2514
2515 if (mode_map & WIFI_MODE_AX) {
2516 if (strstr(channel_bandwidth_str, "160") != NULL)
2517 num_subcarrier = 1960;
2518 else if (strstr(channel_bandwidth_str, "80") != NULL)
2519 num_subcarrier = 980;
2520 else if (strstr(channel_bandwidth_str, "40") != NULL)
2521 num_subcarrier = 468;
2522 else if (strstr(channel_bandwidth_str, "20") != NULL)
2523 num_subcarrier = 234;
2524 code_bits = 10;
2525 code_rate = (float)5/6;
2526 Symbol_duration = 128;
developera1255e42023-05-13 17:45:02 +08002527 GI_duration = 8;/*HE no GI 400ns*/
developer72fb0bb2023-01-11 09:46:29 +08002528 } else if (mode_map & WIFI_MODE_AC) {
2529 if (strstr(channel_bandwidth_str, "160") != NULL)
2530 num_subcarrier = 468;
2531 else if (strstr(channel_bandwidth_str, "80") != NULL)
2532 num_subcarrier = 234;
2533 else if (strstr(channel_bandwidth_str, "40") != NULL)
2534 num_subcarrier = 108;
2535 else if (strstr(channel_bandwidth_str, "20") != NULL)
2536 num_subcarrier = 52;
2537 code_bits = 8;
2538 code_rate = (float)5/6;
2539 Symbol_duration = 32;
2540 } else if (mode_map & WIFI_MODE_N) {
2541 if (strstr(channel_bandwidth_str, "160") != NULL)
2542 num_subcarrier = 468;
2543 else if (strstr(channel_bandwidth_str, "80") != NULL)
2544 num_subcarrier = 234;
2545 else if (strstr(channel_bandwidth_str, "40") != NULL)
2546 num_subcarrier = 108;
2547 else if (strstr(channel_bandwidth_str, "20") != NULL)
2548 num_subcarrier = 52;
2549 code_bits = 6;
2550 code_rate = (float)3/4;
2551 Symbol_duration = 32;
2552 } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
2553 // mode b must run with mode g, so we output mode g bitrate in 2.4 G.
2554 snprintf(output_string, 64, "65 Mb/s");
2555 return RETURN_OK;
2556 } else {
2557 snprintf(output_string, 64, "0 Mb/s");
2558 return RETURN_OK;
2559 }
2560
2561 // Spatial streams
developera1255e42023-05-13 17:45:02 +08002562 if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +08002563 fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__);
2564 return RETURN_ERR;
2565 }
developera1255e42023-05-13 17:45:02 +08002566 for (; ant_bitmap > 0; ant_bitmap >>= 1)
2567 NSS += ant_bitmap & 1;
developer72fb0bb2023-01-11 09:46:29 +08002568
2569 // multiple 10 is to align duration unit (0.1 us)
2570 bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
2571 snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
developera1255e42023-05-13 17:45:02 +08002572 WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
2573 __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
developer72fb0bb2023-01-11 09:46:29 +08002574 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2575
2576 return RETURN_OK;
2577}
2578#if 0
2579INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
2580{
2581 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2582 char cmd[64];
2583 char buf[1024];
2584 int apIndex;
2585
developer69b61b02023-03-07 17:17:44 +08002586 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002587 return RETURN_ERR;
2588
2589 apIndex=(radioIndex==0)?0:1;
2590
2591 snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name);
2592 _syscmd(cmd,buf, sizeof(buf));
2593
2594 snprintf(output_string, 64, "%s", buf);
2595 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2596 return RETURN_OK;
2597}
2598#endif
2599
2600
2601//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
2602//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.
2603INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
2604{
2605 wifi_band band = band_invalid;
2606
2607 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2608 if (NULL == output_string)
2609 return RETURN_ERR;
2610
2611 band = wifi_index_to_band(radioIndex);
2612
2613 memset(output_string, 0, 10);
2614 if (band == band_2_4)
2615 strcpy(output_string, "2.4GHz");
2616 else if (band == band_5)
2617 strcpy(output_string, "5GHz");
2618 else if (band == band_6)
2619 strcpy(output_string, "6GHz");
2620 else
2621 return RETURN_ERR;
2622 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2623
2624 return RETURN_OK;
2625#if 0
2626 char buf[MAX_BUF_SIZE]={'\0'};
2627 char str[MAX_BUF_SIZE]={'\0'};
2628 char cmd[MAX_CMD_SIZE]={'\0'};
2629 char *ch=NULL;
2630 char *ch2=NULL;
2631
2632 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2633 if (NULL == output_string)
2634 return RETURN_ERR;
2635
2636
2637 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2638
2639 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2640 {
2641 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2642 return RETURN_ERR;
2643 }
2644 ch=strchr(buf,'\n');
2645 *ch='\0';
2646 ch=strchr(buf,'=');
2647 if(ch==NULL)
2648 return RETURN_ERR;
2649
2650
2651 ch++;
2652
2653 /* prepend 0 for channel with single digit. for ex, 6 would be 06 */
2654 strcpy(buf,"0");
2655 if(strlen(ch) == 1)
2656 ch=strcat(buf,ch);
2657
2658
2659 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2660
2661 if(_syscmd(cmd,str,64) == RETURN_ERR)
2662 {
2663 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2664 return RETURN_ERR;
2665 }
2666
2667
2668 ch2=strchr(str,'\n');
2669 //replace \n with \0
2670 *ch2='\0';
2671 ch2=strchr(str,'=');
2672 if(ch2==NULL)
2673 {
2674 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2675 return RETURN_ERR;
2676 }
2677 else
2678 wifi_dbg_printf("%s",ch2+1);
2679
2680
2681 ch2++;
2682
2683
2684 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch);
2685
2686 memset(buf,'\0',sizeof(buf));
2687 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2688 {
2689 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2690 return RETURN_ERR;
2691 }
2692 if (strstr(buf,"2.4") != NULL )
2693 strcpy(output_string,"2.4GHz");
2694 else if(strstr(buf,"5.") != NULL )
2695 strcpy(output_string,"5GHz");
2696 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2697
2698 return RETURN_OK;
2699#endif
2700}
2701
2702//Get the frequency band at which the radio is operating, eg: "2.4GHz"
2703//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.
2704INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
2705{
2706 wifi_band band = band_invalid;
2707 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2708 if (NULL == output_string)
2709 return RETURN_ERR;
2710 band = wifi_index_to_band(radioIndex);
2711
developer69b61b02023-03-07 17:17:44 +08002712 if (band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08002713 snprintf(output_string, 64, "2.4GHz");
2714 else if (band == band_5)
developer69b61b02023-03-07 17:17:44 +08002715 snprintf(output_string, 64, "5GHz");
developer72fb0bb2023-01-11 09:46:29 +08002716 else if (band == band_6)
2717 snprintf(output_string, 64, "6GHz");
2718
2719 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2720
2721 return RETURN_OK;
2722#if 0
2723 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2724 char buf[MAX_BUF_SIZE]={'\0'};
2725 char str[MAX_BUF_SIZE]={'\0'};
2726 char cmd[MAX_CMD_SIZE]={'\0'};
2727 char *ch=NULL;
2728 char *ch2=NULL;
2729 char ch1[5]="0";
2730
2731 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2732
2733 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
2734 {
2735 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2736 return RETURN_ERR;
2737 }
2738
2739 ch=strchr(buf,'\n');
2740 *ch='\0';
2741 ch=strchr(buf,'=');
2742 if(ch==NULL)
2743 return RETURN_ERR;
2744 ch++;
2745
2746 if(strlen(ch)==1)
2747 {
2748 strcat(ch1,ch);
2749
2750 }
2751 else
2752 {
2753 strcpy(ch1,ch);
2754 }
2755
2756
2757
2758 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
2759 if(_syscmd(cmd,str,64) == RETURN_ERR)
2760 {
2761 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2762 return RETURN_ERR;
2763 }
2764
2765
2766 ch2=strchr(str,'\n');
2767 //replace \n with \0
2768 *ch2='\0';
2769 ch2=strchr(str,'=');
2770 if(ch2==NULL)
2771 {
2772 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2773 return RETURN_ERR;
2774 }
2775 else
2776 wifi_dbg_printf("%s",ch2+1);
2777 ch2++;
2778
2779
2780 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1);
2781 memset(buf,'\0',sizeof(buf));
2782 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
2783 {
2784 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
2785 return RETURN_ERR;
2786 }
2787
2788
2789 if(strstr(buf,"2.4")!=NULL)
2790 {
2791 strcpy(output_string,"2.4GHz");
2792 }
2793 if(strstr(buf,"5.")!=NULL)
2794 {
2795 strcpy(output_string,"5GHz");
2796 }
2797 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2798 return RETURN_OK;
2799#endif
2800}
2801
2802//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
2803//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.
2804INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
2805{
2806 char cmd[128]={0};
2807 char buf[128]={0};
2808 char temp_output[128] = {0};
2809 wifi_band band;
2810 int phyId = 0;
2811
2812 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08002813 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08002814 return RETURN_ERR;
2815
2816 band = wifi_index_to_band(radioIndex);
2817 if (band == band_2_4) {
2818 strcat(temp_output, "b,g,");
2819 } else if (band == band_5) {
2820 strcat(temp_output, "a,");
2821 }
2822 phyId = radio_index_to_phy(radioIndex);
2823 // ht capabilities
2824 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);
2825 _syscmd(cmd, buf, sizeof(buf));
2826 if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
2827 strcat(temp_output, "n,");
2828 }
2829
2830 // vht capabilities
2831 if (band == band_5) {
2832 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
2833 _syscmd(cmd, buf, sizeof(buf));
2834 if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
2835 strcat(temp_output, "ac,");
2836 }
2837 }
2838
2839 // he capabilities
2840 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);
2841 _syscmd(cmd, buf, sizeof(buf));
2842 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2843 strcat(temp_output, "ax,");
2844 }
2845
developere82c0ca2023-05-10 16:25:35 +08002846 // eht capabilities
2847 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);
2848 _syscmd(cmd, buf, sizeof(buf));
2849 if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
2850 strcat(temp_output, "be,");
2851 }
2852
developer72fb0bb2023-01-11 09:46:29 +08002853 // Remove the last comma
2854 if (strlen(temp_output) != 0)
2855 temp_output[strlen(temp_output)-1] = '\0';
2856 strncpy(output_string, temp_output, strlen(temp_output));
2857 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2858 return RETURN_OK;
2859}
2860
2861//Get the radio operating mode, and pure mode flag. eg: "ac"
2862//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.
2863INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
2864{
2865 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2866 if (NULL == output_string)
2867 return RETURN_ERR;
2868
2869 if (radioIndex == 0) {
2870 snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
2871 *gOnly = FALSE;
2872 *nOnly = TRUE;
2873 *acOnly = FALSE;
2874 } else {
2875 snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
2876 *gOnly = FALSE;
2877 *nOnly = FALSE;
2878 *acOnly = FALSE;
2879 }
2880 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2881
2882 return RETURN_OK;
2883#if 0
2884 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2885 char buf[64] = {0};
2886 char config_file[MAX_BUF_SIZE] = {0};
2887
developer69b61b02023-03-07 17:17:44 +08002888 if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly))
developer72fb0bb2023-01-11 09:46:29 +08002889 return RETURN_ERR;
2890
2891 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
2892 wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf));
2893
2894 wifi_dbg_printf("\nhw_mode=%s\n",buf);
developer69b61b02023-03-07 17:17:44 +08002895 if (strlen(buf) == 0)
developer72fb0bb2023-01-11 09:46:29 +08002896 {
2897 wifi_dbg_printf("\nwifi_hostapdRead returned none\n");
2898 return RETURN_ERR;
2899 }
2900 if(strcmp(buf,"g")==0)
2901 {
2902 wifi_dbg_printf("\nG\n");
2903 *gOnly=TRUE;
2904 *nOnly=FALSE;
2905 *acOnly=FALSE;
2906 }
2907 else if(strcmp(buf,"n")==0)
2908 {
2909 wifi_dbg_printf("\nN\n");
2910 *gOnly=FALSE;
2911 *nOnly=TRUE;
2912 *acOnly=FALSE;
2913 }
2914 else if(strcmp(buf,"ac")==0)
2915 {
2916 wifi_dbg_printf("\nac\n");
2917 *gOnly=FALSE;
2918 *nOnly=FALSE;
2919 *acOnly=TRUE;
2920 }
2921 /* hostapd-5G.conf has "a" as hw_mode */
2922 else if(strcmp(buf,"a")==0)
2923 {
2924 wifi_dbg_printf("\na\n");
2925 *gOnly=FALSE;
2926 *nOnly=FALSE;
2927 *acOnly=FALSE;
2928 }
2929 else
2930 wifi_dbg_printf("\nInvalid Mode %s\n", buf);
2931
2932 //for a,n mode
2933 if(radioIndex == 1)
2934 {
2935 wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf));
2936 if(strcmp(buf,"1")==0)
2937 {
2938 strncpy(output_string, "n", 1);
2939 *nOnly=FALSE;
2940 }
2941 }
2942
2943 wifi_dbg_printf("\nReturning from getRadioStandard\n");
2944 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2945 return RETURN_OK;
2946#endif
2947}
2948
developer0f10c772023-05-16 21:43:39 +08002949enum WIFI_MODE {
2950 WMODE_INVALID = 0,
2951 WMODE_A = 1 << 0,
2952 WMODE_B = 1 << 1,
2953 WMODE_G = 1 << 2,
2954 WMODE_GN = 1 << 3,
2955 WMODE_AN = 1 << 4,
2956 WMODE_AC = 1 << 5,
2957 WMODE_AX_24G = 1 << 6,
2958 WMODE_AX_5G = 1 << 7,
2959 WMODE_AX_6G = 1 << 8,
2960 WMODE_BE_24G = 1 << 9,
2961 WMODE_BE_5G = 1 << 10,
2962 WMODE_BE_6G = 1 << 11,
2963 /*
2964 * total types of supported wireless mode,
2965 * add this value once yow add new type
2966 */
2967 WMODE_COMP = 12,
2968};
2969
2970#define RADIO_MODE_LEN 32
developerfead3972023-05-25 20:15:02 +08002971
2972int get_radio_mode_handler(struct nl_msg *msg, void *cb)
developer72fb0bb2023-01-11 09:46:29 +08002973{
developerfead3972023-05-25 20:15:02 +08002974 struct nlattr *tb[NL80211_ATTR_MAX + 1];
2975 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
2976 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
2977 unsigned int *phymode;
2978 int err = 0;
2979 struct mtk_nl80211_cb_data *cb_data = cb;
developer72fb0bb2023-01-11 09:46:29 +08002980
developerfead3972023-05-25 20:15:02 +08002981 if (!msg || !cb_data) {
2982 wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data);
2983 return NL_SKIP;
2984 }
developer72fb0bb2023-01-11 09:46:29 +08002985
developerfead3972023-05-25 20:15:02 +08002986 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
2987 genlmsg_attrlen(gnlh, 0), NULL);
2988 if (err < 0) {
2989 wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
2990 return NL_SKIP;
2991 }
developer0f10c772023-05-16 21:43:39 +08002992
developerfead3972023-05-25 20:15:02 +08002993 if (tb[NL80211_ATTR_VENDOR_DATA]) {
2994 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
2995 tb[NL80211_ATTR_VENDOR_DATA], NULL);
2996 if (err < 0)
2997 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +08002998
developerfead3972023-05-25 20:15:02 +08002999 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
3000 phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
3001
3002 memset(cb_data->out_buf, 0, cb_data->out_len);
3003 memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
3004 }
3005 } else
3006 wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
3007
3008 return NL_OK;
3009}
developer0f10c772023-05-16 21:43:39 +08003010
developerfead3972023-05-25 20:15:02 +08003011void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
3012{
3013 wifi_band band;
3014 unsigned char radio_mode_tem_len;
3015
3016 band = wifi_index_to_band(radioIndex);
developer0f10c772023-05-16 21:43:39 +08003017 // puremode is a bit map
developer72fb0bb2023-01-11 09:46:29 +08003018 *pureMode = 0;
developer0f10c772023-05-16 21:43:39 +08003019 memset(output_string, 0, RADIO_MODE_LEN);
3020
3021 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3022
3023 switch (band) {
3024 case band_2_4:
3025 if (phymode & WMODE_B) {
3026 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
3027 *pureMode |= WIFI_MODE_B;
3028 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3029 }
3030 if (phymode & WMODE_G) {
3031 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
3032 *pureMode |= WIFI_MODE_G;
3033 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3034 }
3035 if (phymode & WMODE_GN) {
3036 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3037 *pureMode |= WIFI_MODE_N;
3038 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3039 }
3040 if (phymode & WMODE_AX_24G) {
3041 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3042 *pureMode |= WIFI_MODE_AX;
3043 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3044 }
3045 if (phymode & WMODE_BE_24G) {
3046 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3047 *pureMode |= WIFI_MODE_BE;
3048 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3049 }
3050 break;
3051 case band_5:
3052 if (phymode & WMODE_A) {
3053 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
3054 *pureMode |= WIFI_MODE_A;
3055 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3056 }
3057 if (phymode & WMODE_AN) {
3058 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
3059 *pureMode |= WIFI_MODE_N;
3060 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3061 }
3062 if (phymode & WMODE_AC) {
3063 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
3064 *pureMode |= WIFI_MODE_AC;
3065 }
3066 if (phymode & WMODE_AX_5G) {
3067 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3068 *pureMode |= WIFI_MODE_AX;
3069 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3070 }
3071 if (phymode & WMODE_BE_5G) {
3072 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3073 *pureMode |= WIFI_MODE_BE;
3074 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3075 }
3076 break;
3077 case band_6:
3078 if (phymode & WMODE_AX_6G) {
3079 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
3080 *pureMode |= WIFI_MODE_AX;
3081 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3082 }
3083 if (phymode & WMODE_BE_6G) {
3084 snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
3085 *pureMode |= WIFI_MODE_BE;
3086 radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
3087 }
3088 break;
3089 default:
3090 fprintf(stderr, "%s band_idx invalid\n", __func__);
3091 break;
3092 }
3093
3094 /* Remove the last comma */
3095 if (strlen(output_string) != 0)
3096 output_string[strlen(output_string)-1] = '\0';
developer72fb0bb2023-01-11 09:46:29 +08003097
developerfead3972023-05-25 20:15:02 +08003098}
3099
3100INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
3101{
3102 unsigned int phymode;
3103 char interface_name[IF_NAME_SIZE] = {0};
3104 struct mtk_nl80211_param params;
3105 int ret = -1;
3106 unsigned int if_idx = 0;
3107 struct unl unl_ins;
3108 struct nl_msg *msg = NULL;
3109 struct nlattr * msg_data = NULL;
3110 struct mtk_nl80211_param param;
3111 struct mtk_nl80211_cb_data cb_data;
3112
3113 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3114 if(NULL == output_string || NULL == pureMode)
3115 return RETURN_ERR;
3116
3117 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3118 return RETURN_ERR;
3119
3120 if_idx = if_nametoindex(interface_name);
3121 if (!if_idx) {
3122 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
3123 return RETURN_ERR;
3124 }
3125 /*init mtk nl80211 vendor cmd*/
3126 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
3127 param.if_type = NL80211_ATTR_IFINDEX;
3128 param.if_idx = if_idx;
3129
3130 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3131 if (ret) {
3132 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3133 return RETURN_ERR;
3134 }
3135
3136 /*add mtk vendor cmd data*/
3137 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
3138 wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
3139 nlmsg_free(msg);
3140 goto err;
3141 }
3142
3143 /*send mtk nl80211 vendor msg*/
3144 cb_data.out_buf = (char *)&phymode;
3145 cb_data.out_len = sizeof(unsigned int);
3146
3147 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
3148
3149 if (ret) {
3150 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3151 goto err;
3152 }
3153 /*deinit mtk nl80211 vendor msg*/
3154 mtk_nl80211_deint(&unl_ins);
3155
3156 phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
3157 wifi_debug(DEBUG_NOTICE,"send cmd success\n");
3158
developer72fb0bb2023-01-11 09:46:29 +08003159 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3160 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003161err:
3162 mtk_nl80211_deint(&unl_ins);
3163 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
3164 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08003165}
3166
3167// Set the radio operating mode, and pure mode flag.
3168INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
3169{
developer69b61b02023-03-07 17:17:44 +08003170 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003171 if (strcmp (channelMode,"11A") == 0)
3172 {
3173 writeBandWidth(radioIndex,"20MHz");
3174 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3175 printf("\nChannel Mode is 802.11a (5GHz)\n");
3176 }
3177 else if (strcmp (channelMode,"11NAHT20") == 0)
3178 {
3179 writeBandWidth(radioIndex,"20MHz");
3180 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3181 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
3182 }
3183 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
3184 {
3185 writeBandWidth(radioIndex,"40MHz");
3186 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3187 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3188 }
3189 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
3190 {
3191 writeBandWidth(radioIndex,"40MHz");
3192 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3193 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
3194 }
3195 else if (strcmp (channelMode,"11ACVHT20") == 0)
3196 {
3197 writeBandWidth(radioIndex,"20MHz");
3198 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3199 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
3200 }
3201 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
3202 {
3203 writeBandWidth(radioIndex,"40MHz");
3204 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3205 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3206 }
3207 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
3208 {
3209 writeBandWidth(radioIndex,"40MHz");
3210 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3211 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
3212 }
3213 else if (strcmp (channelMode,"11ACVHT80") == 0)
3214 {
3215 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
3216 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
3217 }
3218 else if (strcmp (channelMode,"11ACVHT160") == 0)
3219 {
3220 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
3221 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
developer69b61b02023-03-07 17:17:44 +08003222 }
developer72fb0bb2023-01-11 09:46:29 +08003223 else if (strcmp (channelMode,"11B") == 0)
3224 {
3225 writeBandWidth(radioIndex,"20MHz");
3226 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3227 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
3228 }
3229 else if (strcmp (channelMode,"11G") == 0)
3230 {
3231 writeBandWidth(radioIndex,"20MHz");
3232 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3233 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
3234 }
3235 else if (strcmp (channelMode,"11NGHT20") == 0)
3236 {
3237 writeBandWidth(radioIndex,"20MHz");
3238 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
3239 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
3240 }
3241 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
3242 {
3243 writeBandWidth(radioIndex,"40MHz");
3244 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3245 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3246 }
3247 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
3248 {
3249 writeBandWidth(radioIndex,"40MHz");
3250 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
3251 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
3252 }
developer69b61b02023-03-07 17:17:44 +08003253 else
developer72fb0bb2023-01-11 09:46:29 +08003254 {
3255 return RETURN_ERR;
3256 }
3257 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3258
3259 return RETURN_OK;
3260}
3261
developer0f10c772023-05-16 21:43:39 +08003262typedef enum _RT_802_11_PHY_MODE {
3263 PHY_11BG_MIXED = 0,
3264 PHY_11B = 1,
3265 PHY_11A = 2,
3266 PHY_11ABG_MIXED = 3,
3267 PHY_11G = 4,
3268 PHY_11ABGN_MIXED = 5, /* both band 5 */
3269 PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */
3270 PHY_11GN_MIXED = 7, /* 2.4G band 7 */
3271 PHY_11AN_MIXED = 8, /* 5G band 8 */
3272 PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */
3273 PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */
3274 PHY_11N_5G = 11, /* 11n-only with 5G band 11 */
3275 PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
3276 PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */
3277 PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
3278 PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
3279 PHY_11AX_24G = 16,
3280 PHY_11AX_5G = 17,
3281 PHY_11AX_6G = 18,
3282 PHY_11AX_24G_6G = 19,
3283 PHY_11AX_5G_6G = 20,
3284 PHY_11AX_24G_5G_6G = 21,
3285 PHY_11BE_24G = 22,
3286 PHY_11BE_5G = 23,
3287 PHY_11BE_6G = 24,
3288 PHY_11BE_24G_6G = 25,
3289 PHY_11BE_5G_6G = 26,
3290 PHY_11BE_24G_5G_6G = 27,
3291 PHY_MODE_MAX,
3292} RT_802_11_PHY_MODE;
3293
3294unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
3295{
3296 int band_idx = 0;
developerfead3972023-05-25 20:15:02 +08003297 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003298
3299 band_idx = radio_index_to_band(radioIndex);
3300
3301 switch (band_idx) {
3302 case band_2_4:
3303 if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
3304 wireless_mode = PHY_11GN_MIXED;
3305 if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
3306 wireless_mode = PHY_11BGN_MIXED;
3307 if (pureMode & WIFI_MODE_AX)
3308 wireless_mode = PHY_11AX_24G;
3309 if (pureMode & WIFI_MODE_BE)
3310 wireless_mode = PHY_11BE_24G;
3311 break;
3312 case band_5:
3313 if (pureMode == WIFI_MODE_N)
3314 wireless_mode = PHY_11N_5G;
3315 if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
3316 wireless_mode = PHY_11VHT_N_MIXED;
3317 if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
3318 wireless_mode = PHY_11VHT_N_A_MIXED;
3319 if (pureMode & WIFI_MODE_AX)
3320 wireless_mode = PHY_11AX_5G;
3321 if (pureMode & WIFI_MODE_BE)
3322 wireless_mode = PHY_11BE_5G;
3323 break;
3324 case band_6:
3325 if (pureMode & WIFI_MODE_AX)
3326 wireless_mode = PHY_11AX_6G;
3327 if (pureMode & WIFI_MODE_BE)
3328 wireless_mode = PHY_11BE_6G;
3329 break;
3330 default:
3331 fprintf(stderr, "%s band_idx invalid\n", __func__);
3332 break;
3333 }
3334
3335 return wireless_mode;
3336}
3337
developer72fb0bb2023-01-11 09:46:29 +08003338// Set the radio operating mode, and pure mode flag.
3339INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
3340{
developerfead3972023-05-25 20:15:02 +08003341 unsigned char wireless_mode = PHY_MODE_MAX;
developer69b61b02023-03-07 17:17:44 +08003342
developer0f10c772023-05-16 21:43:39 +08003343 char interface_name[IF_NAME_SIZE] = {0};
developerfead3972023-05-25 20:15:02 +08003344 int ret = -1;
3345 unsigned int if_idx = 0;
3346 struct unl unl_ins;
3347 struct nl_msg *msg = NULL;
3348 struct nlattr * msg_data = NULL;
3349 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +08003350
developer0f10c772023-05-16 21:43:39 +08003351 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08003352
developer0f10c772023-05-16 21:43:39 +08003353 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
developer72fb0bb2023-01-11 09:46:29 +08003354
developer0f10c772023-05-16 21:43:39 +08003355 if (wireless_mode == PHY_MODE_MAX) {
3356 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3357 return RETURN_ERR;
3358 }
developer72fb0bb2023-01-11 09:46:29 +08003359
developer0f10c772023-05-16 21:43:39 +08003360 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3361 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08003362
3363 if_idx = if_nametoindex(interface_name);
3364 if (!if_idx) {
3365 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
3366 return RETURN_ERR;
3367 }
3368 /*init mtk nl80211 vendor cmd*/
3369 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
3370 param.if_type = NL80211_ATTR_IFINDEX;
3371 param.if_idx = if_idx;
3372
3373 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
3374 if (ret) {
3375 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
3376 return RETURN_ERR;
3377 }
3378
3379 /*add mtk vendor cmd data*/
3380 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) {
3381 wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
3382 nlmsg_free(msg);
3383 goto err;
3384 }
3385 /*send mtk nl80211 vendor msg*/
3386 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
3387 if (ret) {
3388 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
3389 goto err;
3390 }
3391 /*deinit mtk nl80211 vendor msg*/
3392 mtk_nl80211_deint(&unl_ins);
3393 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08003394
developer0f10c772023-05-16 21:43:39 +08003395 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3396
3397 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08003398err:
3399 mtk_nl80211_deint(&unl_ins);
3400 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
3401 return RETURN_ERR;
developer0f10c772023-05-16 21:43:39 +08003402}
3403
3404INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode)
3405{
developerfead3972023-05-25 20:15:02 +08003406 unsigned char wireless_mode = PHY_MODE_MAX;
developer0f10c772023-05-16 21:43:39 +08003407 char interface_name[IF_NAME_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003408 char buf[MAX_BUF_SIZE] = {0};
developer0f10c772023-05-16 21:43:39 +08003409 char dat_file[MAX_BUF_SIZE] = {0};
3410 struct params params={0};
3411
3412 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__);
3413
3414 wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
3415
3416 if (wireless_mode == PHY_MODE_MAX) {
3417 fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode);
3418 return RETURN_ERR;
3419 }
3420
3421 params.name = "WirelessMode";
3422 snprintf(buf, sizeof(buf), "%d", wireless_mode);
3423 params.value = buf;
3424
3425 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
3426 wifi_datfileWrite(dat_file, &params, 1);
3427
developer72fb0bb2023-01-11 09:46:29 +08003428 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3429
3430 return RETURN_OK;
3431}
3432
3433INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
3434
3435 char config_file[64] = {0};
3436 char buf[64] = {0};
3437 struct params params = {0};
3438 wifi_band band = band_invalid;
3439
3440 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3441
3442 band = wifi_index_to_band(radioIndex);
3443
3444 if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
3445 return RETURN_ERR;
3446 else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
3447 return RETURN_ERR;
3448 else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
3449 return RETURN_ERR;
3450
3451 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3452 params.name = "hw_mode";
3453 params.value = hw_mode;
3454 wifi_hostapdWrite(config_file, &params, 1);
3455 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3456
3457 if (band == band_2_4) {
3458 if (strncmp(hw_mode, "b", 1) == 0) {
3459 wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
3460 snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
3461 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3462 snprintf(buf, sizeof(buf), "%s", "1,2");
3463 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3464 } else {
3465 // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
3466
3467 snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
3468 wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
3469 snprintf(buf, sizeof(buf), "%s", "6,12,24");
3470 wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
3471 }
3472 }
3473
3474 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3475 return RETURN_OK;
3476}
3477
3478INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
3479{
3480 char config_file[64] = {0};
3481 struct params params = {0};
3482 wifi_band band = band_invalid;
3483
3484 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3485
3486 band = wifi_index_to_band(radioIndex);
3487 if (band != band_2_4)
3488 return RETURN_OK;
3489
3490 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
3491 params.name = "noscan";
3492 params.value = noscan;
3493 wifi_hostapdWrite(config_file, &params, 1);
3494 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
3495
3496 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3497 return RETURN_OK;
3498}
3499
3500//Get the list of supported channel. eg: "1-11"
3501//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.
3502INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
3503{
3504 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer69b61b02023-03-07 17:17:44 +08003505 if (NULL == output_string)
developer72fb0bb2023-01-11 09:46:29 +08003506 return RETURN_ERR;
3507 char cmd[256] = {0};
3508 char buf[128] = {0};
3509 BOOL dfs_enable = false;
3510 int phyId = 0;
3511
3512 // Parse possible channel number and separate them with commas.
3513 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
3514 phyId = radio_index_to_phy(radioIndex);
3515 // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
3516 if (dfs_enable)
3517 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 +08003518 else
developer72fb0bb2023-01-11 09:46:29 +08003519 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);
3520
3521 _syscmd(cmd,buf,sizeof(buf));
3522 strncpy(output_string, buf, sizeof(buf));
3523
3524 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3525 return RETURN_OK;
3526}
developerd1824452023-05-18 12:30:04 +08003527//Getting current radio extension channel
3528INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
3529{
3530 CHAR buf[150] = {0};
3531 CHAR cmd[150] = {0};
3532
3533 wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
developer262f4cb2023-05-24 12:22:04 +08003534 if (strncmp(buf, "Below", 5) == 0) //below
developerd1824452023-05-18 12:30:04 +08003535 strcpy(Value,"BelowControlChannel");
developer262f4cb2023-05-24 12:22:04 +08003536 if(strncmp(buf, "Above", 5) == 0) //above
developerd1824452023-05-18 12:30:04 +08003537 strcpy(Value,"AboveControlChannel");
3538 return RETURN_OK;
3539}
developerf6a87542023-05-16 15:47:28 +08003540
developer72fb0bb2023-01-11 09:46:29 +08003541//Get the list for used channel. eg: "1,6,9,11"
3542//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.
3543INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
3544{
3545 char interface_name[16] = {0};
3546 char cmd[128] = {0};
3547 char buf[128] = {0};
3548 char config_file[64] = {0};
3549 int channel = 0;
3550 int freq = 0;
3551 int bandwidth = 0;
3552 int center_freq = 0;
3553 int center_channel = 0;
3554 int channel_delta = 0;
3555 wifi_band band = band_invalid;
3556
3557 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
3558
3559 if (NULL == output_string)
3560 return RETURN_ERR;
3561
3562 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
3563 return RETURN_ERR;
3564 sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name);
3565 _syscmd(cmd, buf, sizeof(buf));
3566 if (strlen(buf) == 0) {
3567 fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__);
3568 return RETURN_ERR;
3569 }
3570 sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, &center_freq);
3571
3572 if (bandwidth == 20) {
3573 snprintf(output_string, 256, "%d", channel);
3574 return RETURN_OK;
3575 }
3576
3577 center_channel = ieee80211_frequency_to_channel(center_freq);
3578
3579 band = wifi_index_to_band(radioIndex);
3580 if (band == band_2_4 && bandwidth == 40) {
developerd1824452023-05-18 12:30:04 +08003581 sprintf(config_file, "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08003582 memset(buf, 0, sizeof(buf));
3583 wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or -
3584
3585 if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) {
3586 snprintf(output_string, 256, "%d,%d", channel, channel+4);
3587 } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) {
3588 snprintf(output_string, 256, "%d,%d", channel-4, channel);
3589 } else {
3590 fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf);
3591 return RETURN_ERR;
3592 }
3593 } else if (band == band_5 || band == band_6){
3594 // 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 +08003595 // 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 +08003596 channel_delta = (bandwidth-20)/10;
developerd1824452023-05-18 12:30:04 +08003597 memset(output_string, 0, 256);
3598 for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) {
3599 // If i is not the last channel, we add a comma.
3600 snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":",");
3601 strncat(output_string, buf, strlen(buf));
3602 }
developer72fb0bb2023-01-11 09:46:29 +08003603 } else
3604 return RETURN_ERR;
3605
3606 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3607 return RETURN_OK;
3608}
3609
developer69b61b02023-03-07 17:17:44 +08003610//Get the running channel number
developerd1824452023-05-18 12:30:04 +08003611INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB
developer72fb0bb2023-01-11 09:46:29 +08003612{
3613 char channel_str[16] = {0};
3614 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +08003615 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08003616
3617 if (output_ulong == NULL)
3618 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08003619 band = wifi_index_to_band(radioIndex);
3620 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
3621 wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
developer72fb0bb2023-01-11 09:46:29 +08003622
3623 *output_ulong = strtoul(channel_str, NULL, 10);
3624
3625 return RETURN_OK;
3626}
3627
3628
3629INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
3630{
3631 char cmd[1024] = {0}, buf[5] = {0};
3632 char interface_name[16] = {0};
3633
3634 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3635 if (NULL == output_ulong)
3636 return RETURN_ERR;
3637
3638 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name);
3639 if (wifi_getApName(apIndex,interface_name) != RETURN_OK)
3640 return RETURN_ERR;
3641 _syscmd(cmd,buf,sizeof(buf));
3642 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
3643 if (*output_ulong == 0) {
3644 return RETURN_ERR;
3645 }
3646
3647 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3648 return RETURN_OK;
3649}
3650
3651//Storing the previous channel value
3652INT wifi_storeprevchanval(INT radioIndex)
3653{
3654 char buf[256] = {0};
3655 char output[4]={'\0'};
3656 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08003657 wifi_band band = band_invalid;
3658
3659 band = wifi_index_to_band(radioIndex);
3660 if (band == band_invalid) {
3661 return RETURN_ERR;
3662 wifi_dbg_printf("[%s]: Invalid radio index", __func__);
3663 }
3664 snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
3665 wifi_datfileRead(config_file, "Channel", output, sizeof(output));
3666
3667 if(band == band_2_4)
developer72fb0bb2023-01-11 09:46:29 +08003668 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003669 else if(band == band_5)
developer72fb0bb2023-01-11 09:46:29 +08003670 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
developerd1824452023-05-18 12:30:04 +08003671 else
3672 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable");
developer72fb0bb2023-01-11 09:46:29 +08003673 system(buf);
3674 Radio_flag = FALSE;
3675 return RETURN_OK;
3676}
3677
3678//Set the running channel number
3679INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
3680{
3681 // We only write hostapd config here
3682 char str_channel[8]={0};
3683 char *list_channel;
3684 char config_file[128] = {0};
3685 char possible_channels[256] = {0};
developerd1824452023-05-18 12:30:04 +08003686 char config_file_dat[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08003687 int max_radio_num = 0;
3688 struct params list = {0};
developerd1824452023-05-18 12:30:04 +08003689 struct params dat = {0};
3690 struct params acs = {0};
3691 wifi_band band = band_invalid;
3692 bool acs_channel = false;
developer72fb0bb2023-01-11 09:46:29 +08003693
3694 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3695
developerd1824452023-05-18 12:30:04 +08003696 if (channel == 0)
3697 acs_channel = true;
developer72fb0bb2023-01-11 09:46:29 +08003698 // Check valid
3699 sprintf(str_channel, "%lu", channel);
3700
developerd1824452023-05-18 12:30:04 +08003701
developer72fb0bb2023-01-11 09:46:29 +08003702 wifi_getRadioPossibleChannels(radioIndex, possible_channels);
3703 list_channel = strtok(possible_channels, ",");
3704 while(true)
3705 {
3706 if(list_channel == NULL) { // input not in the list
3707 fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel);
3708 return RETURN_ERR;
3709 }
3710 if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
3711 break;
3712 list_channel = strtok(NULL, ",");
3713 }
developerd1824452023-05-18 12:30:04 +08003714 /*
developer72fb0bb2023-01-11 09:46:29 +08003715 list.name = "channel";
3716 list.value = str_channel;
3717 wifi_getMaxRadioNumber(&max_radio_num);
3718 for(int i=0; i<=MAX_APS/max_radio_num;i++)
3719 {
3720 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
3721 wifi_hostapdWrite(config_file, &list, 1);
3722 }
developerd1824452023-05-18 12:30:04 +08003723 */
3724 dat.name = "Channel";
3725 dat.value = str_channel;
3726 band = wifi_index_to_band(radioIndex);
3727 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
3728 wifi_datfileWrite(config_file_dat, &dat, 1);
3729 if (acs_channel == true) {
3730 acs.name = "AutoChannelSelect";
3731 acs.value = "3";
3732 } else {
3733 acs.name = "AutoChannelSelect";
3734 acs.value = "0";
3735 }
3736 wifi_datfileWrite(config_file_dat, &acs, 1);
developerc0772e62023-05-18 15:10:48 +08003737 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08003738 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
3739 return RETURN_OK;
3740}
3741
3742INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
3743{
3744 struct params list[2];
3745 char str_idx[16];
3746 char config_file[64];
3747 int max_num_radios = 0;
3748 wifi_band band = band_invalid;
3749
3750 band = wifi_index_to_band(radioIndex);
3751 if (band == band_2_4)
3752 return RETURN_OK;
3753
3754 snprintf(str_idx, sizeof(str_idx), "%lu", channel);
3755 list[0].name = "vht_oper_centr_freq_seg0_idx";
3756 list[0].value = str_idx;
3757 list[1].name = "he_oper_centr_freq_seg0_idx";
3758 list[1].value = str_idx;
3759
3760 wifi_getMaxRadioNumber(&max_num_radios);
3761 for(int i=0; i<=MAX_APS/max_num_radios; i++)
3762 {
3763 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i));
3764 if (band == band_6)
3765 wifi_hostapdWrite(config_file, &list[1], 1);
3766 else
3767 wifi_hostapdWrite(config_file, list, 2);
3768 }
3769
3770 return RETURN_OK;
3771}
3772
3773//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
3774//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
3775INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
3776{
3777 //Set to wifi config only. Wait for wifi reset to apply.
3778 char buf[256] = {0};
3779 char str_channel[256] = {0};
3780 int count = 0;
3781 ULONG Value = 0;
3782 FILE *fp = NULL;
3783 if(enable == TRUE)
3784 {
3785 wifi_setRadioChannel(radioIndex,Value);
3786 }
3787 return RETURN_OK;
3788}
3789
3790INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
3791{
3792 if (output_bool == NULL)
3793 return RETURN_ERR;
3794
3795 *output_bool = TRUE;
3796
3797 return RETURN_OK;
3798}
3799
3800INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
3801{
developer69b61b02023-03-07 17:17:44 +08003802 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003803 return RETURN_ERR;
3804 *output_bool=FALSE;
3805 return RETURN_OK;
3806}
3807
3808INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
3809{
developer69b61b02023-03-07 17:17:44 +08003810 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003811 return RETURN_ERR;
3812 *output_bool=FALSE;
3813 return RETURN_OK;
3814}
3815
3816INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
3817{
3818 //Set to wifi config only. Wait for wifi reset to apply.
3819 return RETURN_OK;
3820}
3821
3822INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
3823{
3824 return RETURN_OK;
3825}
3826
3827INT wifi_factoryResetAP(int apIndex)
3828{
developer47cc27a2023-05-17 23:09:58 +08003829 char ap_config_file[MAX_CMD_SIZE] = {0};
3830 char cmd[MAX_CMD_SIZE] = {0};
3831 char ret_buf[MAX_BUF_SIZE] = {0};
3832 int radio_idx = 0;
3833 int bss_idx = 0;
3834 char ssid[32] = {0};
3835 char interface[IF_NAME_SIZE] = {0};
3836 char psk_file[MAX_CMD_SIZE] = {0};
3837 struct params params[3] = {0};
3838 char *band_str[3] = {"2G", "5G", "6G"};
developer72fb0bb2023-01-11 09:46:29 +08003839
3840 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3841
developer47cc27a2023-05-17 23:09:58 +08003842 /*del old config file*/
3843 snprintf(ap_config_file, MAX_CMD_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
3844 snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file);
3845 _syscmd(cmd, ret_buf, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003846
developer47cc27a2023-05-17 23:09:58 +08003847 memset(cmd, 0, sizeof(cmd));
3848 memset(ret_buf, 0, sizeof(ret_buf));
developer72fb0bb2023-01-11 09:46:29 +08003849
developer47cc27a2023-05-17 23:09:58 +08003850 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
3851
3852 /*prepare new config file*/
developere740c2a2023-05-23 18:34:32 +08003853 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
developer47cc27a2023-05-17 23:09:58 +08003854 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3855
3856 if (radio_idx == band_2_4) {
3857 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
3858 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
3859 } else if (radio_idx == band_5) {
3860 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
3861 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
3862 } else if (radio_idx == band_6) {
3863 snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
3864 snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
3865 }
3866
3867 /* fix wpa_psk_file path */
3868 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex);
3869
3870 params[0].name = "ssid";
3871 params[0].value = ssid;
3872 params[1].name = "interface";
3873 params[1].value = interface;
3874 params[2].name = "wpa_psk_file";
3875 params[2].value = psk_file;
3876
3877 wifi_hostapdWrite(ap_config_file, params, 3);
3878
3879 /*clear psk file*/
3880 memset(cmd, 0, sizeof(cmd));
3881 memset(ret_buf, 0, sizeof(ret_buf));
3882
3883 snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
3884
3885 if (access(psk_file, F_OK) != 0) {
3886 snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file);
3887 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3888 } else {
3889 snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file);
3890 _syscmd(cmd, ret_buf, sizeof(ret_buf));
3891 }
3892
3893 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3894
3895 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08003896}
3897
3898//To set Band Steering AP group
3899//To-do
3900INT wifi_setBandSteeringApGroup(char *ApGroup)
3901{
3902 return RETURN_OK;
3903}
3904
3905INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
3906{
3907 char config_file[128] = {'\0'};
3908 char buf[128] = {'\0'};
3909
3910 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3911 if (dtimInterval == NULL)
3912 return RETURN_ERR;
3913
3914 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer885b56c2023-05-22 15:02:46 +08003915 wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08003916
3917 if (strlen(buf) == 0) {
3918 *dtimInterval = 2;
3919 } else {
3920 *dtimInterval = strtoul(buf, NULL, 10);
3921 }
3922
3923 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3924 return RETURN_OK;
3925}
3926
3927INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
3928{
3929 struct params params={0};
3930 char config_file[MAX_BUF_SIZE] = {'\0'};
3931 char buf[MAX_BUF_SIZE] = {'\0'};
3932
3933 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3934 if (dtimInterval < 1 || dtimInterval > 255) {
3935 WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
3936 return RETURN_ERR;
3937 }
developer69b61b02023-03-07 17:17:44 +08003938
developer72fb0bb2023-01-11 09:46:29 +08003939 params.name = "dtim_period";
3940 snprintf(buf, sizeof(buf), "%d", dtimInterval);
3941 params.value = buf;
3942
3943 sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex);
3944 wifi_hostapdWrite(config_file, &params, 1);
3945 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3946
3947 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3948 return RETURN_OK;
3949}
3950
3951//Check if the driver support the Dfs
3952INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
3953{
3954 wifi_band band = band_invalid;
developer69b61b02023-03-07 17:17:44 +08003955 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08003956 return RETURN_ERR;
3957 *output_bool=FALSE;
3958
3959 band = wifi_index_to_band(radioIndex);
3960 if (band == band_5)
3961 *output_bool = TRUE;
3962 return RETURN_OK;
3963}
3964
3965//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.
3966//The value of this parameter is a comma seperated list of channel number
3967INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
3968{
developer69b61b02023-03-07 17:17:44 +08003969 if (NULL == output_pool)
developer72fb0bb2023-01-11 09:46:29 +08003970 return RETURN_ERR;
3971 if (radioIndex==1)
developer69b61b02023-03-07 17:17:44 +08003972 return RETURN_OK;//TODO need to handle for 5GHz band, i think
developer72fb0bb2023-01-11 09:46:29 +08003973 snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
3974
3975 return RETURN_OK;
3976}
3977
3978INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
3979{
3980 //Set to wifi config. And apply instantly.
3981 return RETURN_OK;
3982}
3983
3984INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
3985{
developer69b61b02023-03-07 17:17:44 +08003986 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
developer72fb0bb2023-01-11 09:46:29 +08003987 return RETURN_ERR;
3988 *output_interval_seconds=1800;
3989 *output_dwell_milliseconds=40;
3990
3991 return RETURN_OK;
3992}
3993
3994INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
3995{
3996 //Set to wifi config. And apply instantly.
3997 return RETURN_OK;
3998}
3999
4000INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181
4001{
4002 if (output_bool == NULL)
4003 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08004004 *output_bool = true;
4005 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08004006}
4007
4008INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181
4009{
4010 return RETURN_OK;
4011}
4012
4013//Get the Dfs enable status
4014INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
4015{
4016 char buf[16] = {0};
4017 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08004018 char config_file_dat[128] = {0};
developerd1824452023-05-18 12:30:04 +08004019 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004020
4021 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4022
4023 if (output_bool == NULL)
4024 return RETURN_ERR;
developerf6a87542023-05-16 15:47:28 +08004025 *output_bool = TRUE; // default
developerd1824452023-05-18 12:30:04 +08004026 band = wifi_index_to_band(radioIndex);
4027 snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
4028
developer262f4cb2023-05-24 12:22:04 +08004029 wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +08004030
4031 if (strncmp(buf, "0", 1) == 0)
4032 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08004033 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4034 return RETURN_OK;
4035}
4036
4037//Set the Dfs enable status
4038INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
4039{
4040 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +08004041 char config_dat_file[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004042 FILE *f = NULL;
developerd1824452023-05-18 12:30:04 +08004043 struct params dat = {0};
4044 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004045
4046 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4047
4048 f = fopen(DFS_ENABLE_FILE, "w");
4049 if (f == NULL)
4050 return RETURN_ERR;
4051 fprintf(f, "%d", enable);
4052 fclose(f);
4053
developer72fb0bb2023-01-11 09:46:29 +08004054 wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
4055
developerd1824452023-05-18 12:30:04 +08004056 dat.name = "DfsEnable";
developer262f4cb2023-05-24 12:22:04 +08004057 dat.value = enable?"1":"0";
developerd1824452023-05-18 12:30:04 +08004058 band = wifi_index_to_band(radioIndex);
4059 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4060 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08004061 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4062 return RETURN_OK;
4063}
4064
4065//Check if the driver support the AutoChannelRefreshPeriod
4066INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
4067{
developer69b61b02023-03-07 17:17:44 +08004068 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08004069 return RETURN_ERR;
4070 *output_bool=FALSE; //not support
4071
4072 return RETURN_OK;
4073}
4074
4075//Get the ACS refresh period in seconds
4076INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
4077{
developer69b61b02023-03-07 17:17:44 +08004078 if (NULL == output_ulong)
developer72fb0bb2023-01-11 09:46:29 +08004079 return RETURN_ERR;
4080 *output_ulong=300;
4081
4082 return RETURN_OK;
4083}
4084
4085//Set the ACS refresh period in seconds
4086INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
4087{
4088 return RETURN_ERR;
4089}
4090
4091//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
4092//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.
4093INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
4094{
developer8666b312023-03-24 14:05:31 +08004095 char cmd[MAX_CMD_SIZE] = {0}, buf[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004096 char extchannel[128] = {0};
developer8666b312023-03-24 14:05:31 +08004097 char interface_name[64] = {0};
4098 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08004099 BOOL radio_enable = FALSE;
4100 wifi_band band;
4101
4102 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4103
developerd1824452023-05-18 12:30:04 +08004104 if (NULL == output_string) {
4105 WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004106 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004107 }
4108 if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
4109 WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004110 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004111 }
4112 if (radio_enable != TRUE) {
4113 WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08004114 return RETURN_OK;
developerd1824452023-05-18 12:30:04 +08004115 }
developer8666b312023-03-24 14:05:31 +08004116 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4117 return RETURN_ERR;
4118 /*IW command get BW320 to do*/
developerd1824452023-05-18 12:30:04 +08004119
developer8666b312023-03-24 14:05:31 +08004120 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
4121 ret = _syscmd(cmd, buf, sizeof(buf));
4122 len = strlen(buf);
4123 if((ret != 0) || (len == 0))
4124 {
4125 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4126 return RETURN_ERR;
4127 }
4128
developer72fb0bb2023-01-11 09:46:29 +08004129 band = wifi_index_to_band(radioIndex);
developer8666b312023-03-24 14:05:31 +08004130 if (band == band_2_4 && strncmp(buf, "20", 2) == 0) {
developer72fb0bb2023-01-11 09:46:29 +08004131 wifi_getRadioExtChannel(radioIndex, extchannel);
developer8666b312023-03-24 14:05:31 +08004132 if (strncmp(extchannel, "Auto", 4) != 0) // not auto means we have set HT40+/-
4133 snprintf(buf, sizeof(buf), "40");
developer72fb0bb2023-01-11 09:46:29 +08004134 }
developer8666b312023-03-24 14:05:31 +08004135 snprintf(output_string, 64, "%sMHz", buf);
developer72fb0bb2023-01-11 09:46:29 +08004136 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4137
4138 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004139}
4140
4141enum mwctl_chan_width {
4142 MWCTL_CHAN_WIDTH_20,
4143 MWCTL_CHAN_WIDTH_40,
4144 MWCTL_CHAN_WIDTH_80,
4145 MWCTL_CHAN_WIDTH_160,
4146 MWCTL_CHAN_WIDTH_320,
4147};
4148
4149struct bw_option {
4150 unsigned int bandwith;
4151 enum mwctl_chan_width mode;
4152};
4153
4154struct bw_option bw_opt[] = {
4155 {20, MWCTL_CHAN_WIDTH_20},
4156 {40, MWCTL_CHAN_WIDTH_40},
4157 {80, MWCTL_CHAN_WIDTH_80},
4158 {160, MWCTL_CHAN_WIDTH_160},
4159 {320, MWCTL_CHAN_WIDTH_320},
4160};
4161
4162INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth)
4163{
4164 int ret = -1;
4165 int i;
4166 struct unl unl_ins;
4167 struct nl_msg *msg = NULL;
4168 struct nlattr * msg_data = NULL;
4169 struct mtk_nl80211_param param;
4170 bool b_match = FALSE;
4171
4172 /*init mtk nl80211 vendor cmd*/
4173 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
4174 param.if_type = NL80211_ATTR_WIPHY;
4175 param.if_idx = radio_index_to_phy(radioIndex);
4176
4177 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4178 if (ret) {
4179 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4180 return RETURN_ERR;
4181 }
4182
4183 /*add mtk vendor cmd data*/
4184 if (channel != NULL)
4185 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
4186 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
4187 nlmsg_free(msg);
4188 goto err;
4189 }
4190
4191 if (bandwidth != NULL) {
4192 for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
4193 if (bw_opt[i].bandwith == *bandwidth) {
4194 b_match = true;
4195 if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
4196 wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
4197 nlmsg_free(msg);
4198 goto err;
4199 }
4200 break;
4201 }
4202 }
4203
4204 if (!b_match) {
4205 wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
4206 nlmsg_free(msg);
4207 goto err;
4208 }
4209 }
4210
4211 /*send mtk nl80211 vendor msg*/
4212 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4213 if (ret) {
4214 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4215 goto err;
4216 }
4217 /*deinit mtk nl80211 vendor msg*/
4218 mtk_nl80211_deint(&unl_ins);
4219 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
4220 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4221
4222 return RETURN_OK;
4223err:
4224 mtk_nl80211_deint(&unl_ins);
4225 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4226 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004227}
developerfead3972023-05-25 20:15:02 +08004228
developer72fb0bb2023-01-11 09:46:29 +08004229//Set the Operating Channel Bandwidth.
4230INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only
4231{
4232 char config_file[128];
developerd1824452023-05-18 12:30:04 +08004233 char ht_value[16];
4234 char vht_value[16];
4235 char eht_value[16];
4236 struct params dat[3];
4237 wifi_band band = band_invalid;
developerfead3972023-05-25 20:15:02 +08004238 unsigned int bw = 20;
4239 int ret = 0;
developer72fb0bb2023-01-11 09:46:29 +08004240
4241 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4242
4243 if(NULL == bandwidth)
4244 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004245 band = wifi_index_to_band(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08004246
developerd1824452023-05-18 12:30:04 +08004247 if(strstr(bandwidth,"320") != NULL) {
4248 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4249 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4250 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
developer262f4cb2023-05-24 12:22:04 +08004251 bw = 320;
developerd1824452023-05-18 12:30:04 +08004252 } else if(strstr(bandwidth,"160") != NULL) {
4253 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4254 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
4255 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
developer262f4cb2023-05-24 12:22:04 +08004256 bw = 160;
developerd1824452023-05-18 12:30:04 +08004257 } else if(strstr(bandwidth,"80") != NULL) {
4258 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4259 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
4260 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
developer262f4cb2023-05-24 12:22:04 +08004261 bw = 80;
developerd1824452023-05-18 12:30:04 +08004262 } else if(strstr(bandwidth,"40") != NULL) {
4263 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
4264 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4265 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
developerfead3972023-05-25 20:15:02 +08004266 bw = 40;
developerd1824452023-05-18 12:30:04 +08004267 } else if(strstr(bandwidth,"20") != NULL) {
4268 snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
4269 snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
4270 snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
developer262f4cb2023-05-24 12:22:04 +08004271 bw = 20;
developerd1824452023-05-18 12:30:04 +08004272 } else {
developer72fb0bb2023-01-11 09:46:29 +08004273 fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth);
4274 return RETURN_ERR;
4275 }
4276
developerd1824452023-05-18 12:30:04 +08004277 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4278 dat[0].name = "HT_BW";
4279 dat[0].value = ht_value;
4280 dat[1].name = "VHT_BW";
4281 dat[1].value = vht_value;
4282 dat[2].name = "EHT_ApBw";
4283 dat[2].value = eht_value;
4284 wifi_datfileWrite(config_file, dat, 3);
developerfead3972023-05-25 20:15:02 +08004285 ret = wifi_setChannel_netlink(radioIndex, NULL, &bw);
4286 if (ret != RETURN_OK) {
4287 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
4288 return RETURN_ERR;
4289 }
developer72fb0bb2023-01-11 09:46:29 +08004290
4291 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4292 return RETURN_OK;
4293}
4294
developer72fb0bb2023-01-11 09:46:29 +08004295//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
4296//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.
4297INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
4298{
4299 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004300 char config_dat_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004301 char mode_str[16] = {0};
4302 char buf[64] = {0};
developerd1824452023-05-18 12:30:04 +08004303 char cmd[MAX_CMD_SIZE] = {0};
4304 char interface_name[64] = {0};
4305 int ret = 0, len=0;
developer72fb0bb2023-01-11 09:46:29 +08004306 wifi_band band;
developerd1824452023-05-18 12:30:04 +08004307 ULONG channel = 0;
4308 int centr_channel = 0;
developer72fb0bb2023-01-11 09:46:29 +08004309 UINT mode_map = 0;
developerd1824452023-05-18 12:30:04 +08004310 int freq=0;
developer72fb0bb2023-01-11 09:46:29 +08004311
4312 if (output_string == NULL)
4313 return RETURN_ERR;
4314
4315 wifi_getRadioMode(radioIndex, mode_str, &mode_map);
4316
4317 band = wifi_index_to_band(radioIndex);
4318 if (band == band_invalid)
4319 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +08004320 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4321 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004322
4323 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4324
4325 snprintf(output_string, 64, "Auto");
developer23e71282023-01-18 10:25:19 +08004326 if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) {
developerd1824452023-05-18 12:30:04 +08004327 // 2G band or ac and ax mode is disable, we will check HT_EXTCHA
4328 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4329 wifi_halgetRadioExtChannel(config_dat_file, output_string);
developer23e71282023-01-18 10:25:19 +08004330 if (!(mode_map&WIFI_MODE_N))
developer72fb0bb2023-01-11 09:46:29 +08004331 snprintf(output_string, 64, "Auto");
4332 } else {
4333 // 5G and 6G band with ac or ax mode.
4334 wifi_getRadioChannel(radioIndex, &channel);
developerd1824452023-05-18 12:30:04 +08004335 snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name);
4336
4337 ret = _syscmd(cmd, buf, sizeof(buf));
4338 len = strlen(buf);
4339 if((ret != 0) || (len == 0))
4340 {
4341 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
4342 return RETURN_ERR;
4343 }
4344 sscanf(buf, "%d", &freq);
4345 centr_channel = ieee80211_frequency_to_channel(freq);
4346 if (centr_channel > (int)channel)
developer72fb0bb2023-01-11 09:46:29 +08004347 snprintf(output_string, 64, "AboveControlChannel");
4348 else
4349 snprintf(output_string, 64, "BelowControlChannel");
4350 }
4351
4352 return RETURN_OK;
4353}
4354
4355//Set the extension channel.
4356INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
developer69b61b02023-03-07 17:17:44 +08004357{
developer72fb0bb2023-01-11 09:46:29 +08004358 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4359 struct params params={0};
4360 char config_file[64] = {0};
developerd1824452023-05-18 12:30:04 +08004361 char config_dat_file[64] = {0};
4362 char ext_channel[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004363 char buf[128] = {0};
4364 char cmd[128] = {0};
4365 int max_radio_num =0, ret = 0, bandwidth = 0;
4366 unsigned long channel = 0, centr_channel = 0;
4367 bool stbcEnable = FALSE;
4368 params.name = "ht_capab";
4369 wifi_band band;
4370
4371 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4372 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
4373 _syscmd(cmd, buf, sizeof(buf));
4374 if (strlen(buf) != 0)
4375 stbcEnable = TRUE;
4376 if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
4377 return RETURN_ERR;
4378 bandwidth = strtol(buf, NULL, 10);
4379 // TDK expected to get error with 20MHz
developer262f4cb2023-05-24 12:22:04 +08004380 // we handle 20MHz in function wifi_RemoveRadioExtChannel().
developer72fb0bb2023-01-11 09:46:29 +08004381 if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
4382 return RETURN_ERR;
4383
4384 band = wifi_index_to_band(radioIndex);
4385 if (band == band_invalid)
4386 return RETURN_ERR;
4387
4388 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
4389 return RETURN_ERR;
4390
developer262f4cb2023-05-24 12:22:04 +08004391 snprintf(buf, sizeof(buf), "HT%d", bandwidth);
4392 ret = util_get_sec_chan_offset(channel, buf);
4393 if (ret == -EINVAL)
4394 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004395
4396 if(NULL!= strstr(string,"Above")) {
developer262f4cb2023-05-24 12:22:04 +08004397 if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
4398 return RETURN_OK;
4399 strcpy(ext_channel, "Above");
developer72fb0bb2023-01-11 09:46:29 +08004400 } else if(NULL!= strstr(string,"Below")) {
developer262f4cb2023-05-24 12:22:04 +08004401 if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
4402 return RETURN_OK;
4403 strcpy(ext_channel, "Below");
4404 } else {
developerd1824452023-05-18 12:30:04 +08004405 printf("%s: invalid EXT_CHA:%s\n", __func__, string);
developer262f4cb2023-05-24 12:22:04 +08004406 return RETURN_ERR;
4407 }
developerd1824452023-05-18 12:30:04 +08004408 params.name = "HT_EXTCHA";
developer72fb0bb2023-01-11 09:46:29 +08004409 params.value = ext_channel;
4410
developerd1824452023-05-18 12:30:04 +08004411 snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
4412 wifi_datfileWrite(config_dat_file, &params, 1);
4413
developer72fb0bb2023-01-11 09:46:29 +08004414 wifi_getMaxRadioNumber(&max_radio_num);
4415 for(int i=0; i<=MAX_APS/max_radio_num; i++)
4416 {
4417 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i));
developer72fb0bb2023-01-11 09:46:29 +08004418 wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable);
4419 }
4420
4421 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
4422 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4423 return RETURN_OK;
4424}
4425
4426//Get the guard interval value. eg "400nsec" or "800nsec"
4427//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.
4428INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
4429{
4430 wifi_guard_interval_t GI;
4431
4432 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4433
4434 if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
4435 return RETURN_ERR;
4436
4437 if (GI == wifi_guard_interval_400)
4438 strcpy(output_string, "400nsec");
4439 else if (GI == wifi_guard_interval_800)
4440 strcpy(output_string, "800nsec");
4441 else if (GI == wifi_guard_interval_1600)
4442 strcpy(output_string, "1600nsec");
4443 else if (GI == wifi_guard_interval_3200)
4444 strcpy(output_string, "3200nsec");
4445 else
4446 strcpy(output_string, "Auto");
4447
4448 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4449 return RETURN_OK;
4450}
4451
4452//Set the guard interval value.
4453INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
4454{
4455 wifi_guard_interval_t GI;
4456 int ret = 0;
4457
4458 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4459
4460 if (strcmp(string, "400nsec") == 0)
4461 GI = wifi_guard_interval_400;
4462 else if (strcmp(string , "800nsec") == 0)
4463 GI = wifi_guard_interval_800;
4464 else if (strcmp(string , "1600nsec") == 0)
4465 GI = wifi_guard_interval_1600;
4466 else if (strcmp(string , "3200nsec") == 0)
4467 GI = wifi_guard_interval_3200;
4468 else
4469 GI = wifi_guard_interval_auto;
4470
4471 ret = wifi_setGuardInterval(radioIndex, GI);
4472
4473 if (ret == RETURN_ERR) {
4474 wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__);
4475 return RETURN_ERR;
4476 }
4477
4478 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4479 return RETURN_OK;
4480}
4481
4482//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
4483INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
4484{
4485 char buf[32]={0};
4486 char mcs_file[64] = {0};
4487 char cmd[64] = {0};
4488 int mode_bitmap = 0;
4489
4490 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4491 if(output_int == NULL)
4492 return RETURN_ERR;
4493 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4494
4495 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file);
4496 _syscmd(cmd, buf, sizeof(buf));
4497 if (strlen(buf) > 0)
4498 *output_int = strtol(buf, NULL, 10);
4499 else {
4500 // output the max MCS for the current radio mode
4501 if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
4502 wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__);
4503 return RETURN_ERR;
4504 }
4505 if (mode_bitmap & WIFI_MODE_AX) {
4506 *output_int = 11;
4507 } else if (mode_bitmap & WIFI_MODE_AC) {
4508 *output_int = 9;
4509 } else if (mode_bitmap & WIFI_MODE_N) {
4510 *output_int = 7;
4511 }
4512 }
4513 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4514
4515 return RETURN_OK;
4516}
4517
4518//Set the Modulation Coding Scheme index
4519INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
4520{
developera1255e42023-05-13 17:45:02 +08004521 /*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
4522 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 +08004523 char config_file[64] = {0};
4524 char set_value[16] = {0};
4525 char mcs_file[32] = {0};
developer72fb0bb2023-01-11 09:46:29 +08004526 struct params set_config = {0};
4527 FILE *f = NULL;
developera1255e42023-05-13 17:45:02 +08004528 INT nss = 0;
4529 int ant_bitmap = 0;
4530 unsigned short cal_value = 0;
4531 UCHAR tval = 0, i = 0;
developer72fb0bb2023-01-11 09:46:29 +08004532
4533 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4534
4535 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4536
4537 // -1 means auto
4538 if (MCS > 15 || MCS < -1) {
4539 fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS);
4540 return RETURN_ERR;
4541 }
developera1255e42023-05-13 17:45:02 +08004542 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
4543 for(; ant_bitmap > 0; ant_bitmap >>= 1)
4544 nss += 1;
4545 //printf("%s:nss = %d\n", __func__, nss);
4546 /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
4547 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
developer72fb0bb2023-01-11 09:46:29 +08004548 if (MCS > 9 || MCS == -1)
developera1255e42023-05-13 17:45:02 +08004549 tval = 2;/*one stream value*/
developer72fb0bb2023-01-11 09:46:29 +08004550 else if (MCS > 7)
developera1255e42023-05-13 17:45:02 +08004551 tval = 1;
developer72fb0bb2023-01-11 09:46:29 +08004552 else
developera1255e42023-05-13 17:45:02 +08004553 tval = 0;
4554 for (i = 0; i < nss; i++)
4555 cal_value |= (tval << (2*i));
4556 snprintf(set_value, sizeof(set_value), "%x", cal_value);
4557 WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
4558 set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
developer72fb0bb2023-01-11 09:46:29 +08004559 set_config.value = set_value;
4560
4561 wifi_hostapdWrite(config_file, &set_config, 1);
4562 wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
4563
4564 // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
4565 snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
4566 f = fopen(mcs_file, "w");
4567 if (f == NULL) {
4568 fprintf(stderr, "%s: fopen failed\n", __func__);
4569 return RETURN_ERR;
4570 }
4571 fprintf(f, "%d", MCS);
4572 fclose(f);
4573
4574 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4575 return RETURN_OK;
4576}
4577
4578//Get supported Transmit Power list, eg : "0,25,50,75,100"
4579//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.
4580INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
4581{
4582 if (NULL == output_list)
4583 return RETURN_ERR;
4584 snprintf(output_list, 64,"0,25,50,75,100");
4585 return RETURN_OK;
4586}
4587
4588//Get current Transmit Power in dBm units.
4589//The transmite power level is in units of full power for this radio.
4590INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
4591{
4592 char interface_name[16] = {0};
4593 char cmd[128]={0};
4594 char buf[16]={0};
developera1255e42023-05-13 17:45:02 +08004595 char pwr_file[128]={0};
4596
developer72fb0bb2023-01-11 09:46:29 +08004597 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4598
4599 if(output_ulong == NULL)
4600 return RETURN_ERR;
4601
4602 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4603 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004604/*
developer72fb0bb2023-01-11 09:46:29 +08004605 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
4606 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004607 *output_ulong = strtol(buf, NULL, 10);
developera1255e42023-05-13 17:45:02 +08004608*/
4609 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4610 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file);
4611 _syscmd(cmd, buf, sizeof(buf));
4612 if (strlen(buf) > 0)
4613 *output_ulong = strtol(buf, NULL, 10);
4614 else
4615 *output_ulong = 100;
developer72fb0bb2023-01-11 09:46:29 +08004616 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4617 return RETURN_OK;
4618}
4619
4620//Set Transmit Power
4621//The transmite power level is in units of full power for this radio.
4622INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
4623{
4624 char interface_name[16] = {0};
4625 char *support;
developer72fb0bb2023-01-11 09:46:29 +08004626 char buf[128]={0};
4627 char txpower_str[64] = {0};
developera1255e42023-05-13 17:45:02 +08004628 char pwr_file[128]={0};
4629 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +08004630 int if_idx, ret = 0;
4631 struct nl_msg *msg = NULL;
4632 struct nlattr * msg_data = NULL;
4633 struct mtk_nl80211_param param;
4634 struct unl unl_ins;
developer72fb0bb2023-01-11 09:46:29 +08004635
4636 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4637
4638 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4639 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +08004640 // Get the Tx power supported list and check that is the input in the list
4641 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4642 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4643 support = strtok(buf, ",");
4644 while(true)
4645 {
4646 if(support == NULL) { // input not in the list
4647 wifi_dbg_printf("Input value is invalid.\n");
4648 return RETURN_ERR;
4649 }
4650 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4651 break;
4652 }
4653 support = strtok(NULL, ",");
4654 }
developerfead3972023-05-25 20:15:02 +08004655
4656 if_idx = if_nametoindex(interface_name);
4657 /*init mtk nl80211 vendor cmd*/
4658 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
4659 param.if_type = NL80211_ATTR_IFINDEX;
4660 param.if_idx = if_idx;
4661 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
4662 if (ret) {
4663 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
4664 return RETURN_ERR;
4665 }
4666 /*add mtk vendor cmd data*/
4667 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
4668 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4669 nlmsg_free(msg);
4670 goto err;
4671 }
4672
4673 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
4674 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
4675 nlmsg_free(msg);
4676 goto err;
4677 }
4678
4679 /*send mtk nl80211 vendor msg*/
4680 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
4681 if (ret) {
4682 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
4683 goto err;
4684 }
4685 /*deinit mtk nl80211 vendor msg*/
4686 mtk_nl80211_deint(&unl_ins);
4687 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
4688
developera1255e42023-05-13 17:45:02 +08004689 snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex);
4690 f = fopen(pwr_file, "w");
4691 if (f == NULL) {
4692 fprintf(stderr, "%s: fopen failed\n", __func__);
4693 return RETURN_ERR;
4694 }
4695 fprintf(f, "%d", TransmitPower);
4696 fclose(f);
4697/* 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 +08004698 _syscmd(cmd, buf, sizeof(buf));
4699 maximum_tx = strtol(buf, NULL, 10);
4700
4701 // Get the Tx power supported list and check that is the input in the list
4702 snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
4703 wifi_getRadioTransmitPowerSupported(radioIndex, buf);
4704 support = strtok(buf, ",");
4705 while(true)
4706 {
4707 if(support == NULL) { // input not in the list
4708 wifi_dbg_printf("Input value is invalid.\n");
4709 return RETURN_ERR;
4710 }
4711 if (strncmp(txpower_str, support, strlen(support)) == 0) {
4712 break;
4713 }
4714 support = strtok(NULL, ",");
4715 }
4716 txpower = TransmitPower*maximum_tx/100;
4717 phyId = radio_index_to_phy(radioIndex);
4718 snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower);
4719 _syscmd(cmd, buf, sizeof(buf));
4720 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developera1255e42023-05-13 17:45:02 +08004721*/
4722 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +08004723err:
4724 mtk_nl80211_deint(&unl_ins);
4725 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
4726 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08004727}
4728
4729//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
4730INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
4731{
developer69b61b02023-03-07 17:17:44 +08004732 if (NULL == Supported)
developer72fb0bb2023-01-11 09:46:29 +08004733 return RETURN_ERR;
4734 *Supported = TRUE;
4735
4736 return RETURN_OK;
4737}
4738
4739//Get 80211h feature enable
4740INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
4741{
4742 char buf[64]={'\0'};
4743 char config_file[64] = {'\0'};
4744
4745 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4746 if(enable == NULL)
4747 return RETURN_ERR;
4748
4749 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
developerd1824452023-05-18 12:30:04 +08004750 /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
4751 wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08004752
4753 if (strncmp(buf, "1", 1) == 0)
4754 *enable = TRUE;
4755 else
4756 *enable = FALSE;
4757
4758 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4759 return RETURN_OK;
4760}
4761
4762//Set 80211h feature enable
4763INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
4764{
4765 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4766 struct params params={'\0'};
developerd1824452023-05-18 12:30:04 +08004767 struct params dat={0};
developer72fb0bb2023-01-11 09:46:29 +08004768 char config_file[MAX_BUF_SIZE] = {0};
developerd1824452023-05-18 12:30:04 +08004769 char config_dat_file[MAX_BUF_SIZE] = {0};
4770 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08004771
4772 params.name = "ieee80211h";
4773
4774 if (enable) {
4775 params.value = "1";
4776 } else {
4777 params.value = "0";
4778 }
4779
developerd1824452023-05-18 12:30:04 +08004780 dat.name = "IEEE80211H";
4781 dat.value = params.value;
4782
4783 band = wifi_index_to_band(radioIndex);
4784 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
4785 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer69b61b02023-03-07 17:17:44 +08004786
developerd1824452023-05-18 12:30:04 +08004787 wifi_hostapdWrite(config_file, &params, 1);
4788 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08004789 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4790 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4791 return RETURN_OK;
4792}
4793
4794//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.
4795INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
4796{
4797 if (NULL == output)
4798 return RETURN_ERR;
4799 *output=100;
4800
4801 return RETURN_OK;
4802}
4803
4804//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.
4805INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
4806{
4807 if (NULL == output)
4808 return RETURN_ERR;
4809 *output = -99;
4810
4811 return RETURN_OK;
4812}
4813
4814INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
4815{
4816 return RETURN_ERR;
4817}
4818
4819
4820//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
4821INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
4822{
4823 char interface_name[16] = {0};
4824 char cmd[MAX_BUF_SIZE]={'\0'};
4825 char buf[MAX_CMD_SIZE]={'\0'};
4826
4827 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4828 if(output == NULL)
4829 return RETURN_ERR;
4830
4831 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
4832 return RETURN_ERR;
4833 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
4834 _syscmd(cmd, buf, sizeof(buf));
4835 *output = atoi(buf);
4836
4837 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4838 return RETURN_OK;
4839}
developer69b61b02023-03-07 17:17:44 +08004840
developer72fb0bb2023-01-11 09:46:29 +08004841INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
4842{
4843 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4844 struct params params={'\0'};
4845 char buf[MAX_BUF_SIZE] = {'\0'};
4846 char config_file[MAX_BUF_SIZE] = {'\0'};
4847
4848 if (BeaconPeriod < 15 || BeaconPeriod > 65535)
4849 return RETURN_ERR;
4850
4851 params.name = "beacon_int";
4852 snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
4853 params.value = buf;
4854
4855 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
4856 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08004857
developer72fb0bb2023-01-11 09:46:29 +08004858 wifi_hostapdProcessUpdate(radioIndex, &params, 1);
4859 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4860 return RETURN_OK;
4861}
4862
4863//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.
4864INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
4865{
4866 //TODO: need to revisit below implementation
4867 char *temp;
4868 char temp_output[128] = {0};
4869 char temp_TransmitRates[64] = {0};
4870 char config_file[64] = {0};
4871
4872 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4873 if (NULL == output)
4874 return RETURN_ERR;
4875 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
4876 wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
developer69b61b02023-03-07 17:17:44 +08004877
developer72fb0bb2023-01-11 09:46:29 +08004878 if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate
4879 wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
4880 } else {
4881 temp = strtok(temp_TransmitRates," ");
4882 while(temp!=NULL)
4883 {
4884 // Convert 100 kbps to Mbps
4885 temp[strlen(temp)-1]=0;
4886 if((temp[0]=='5') && (temp[1]=='\0'))
4887 {
4888 temp="5.5";
4889 }
4890 strcat(temp_output,temp);
4891 temp = strtok(NULL," ");
4892 if(temp!=NULL)
4893 {
4894 strcat(temp_output,",");
4895 }
4896 }
4897 strcpy(output,temp_output);
4898 }
4899 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4900 return RETURN_OK;
4901}
4902
4903INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
4904{
4905 char *temp;
4906 char temp1[128];
4907 char temp_output[128];
4908 char temp_TransmitRates[128];
4909 char set[128];
4910 char sub_set[128];
4911 int set_count=0,subset_count=0;
4912 int set_index=0,subset_index=0;
4913 char *token;
4914 int flag=0, i=0;
4915 struct params params={'\0'};
4916 char config_file[MAX_BUF_SIZE] = {0};
4917 wifi_band band = wifi_index_to_band(radioIndex);
4918
4919 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4920 if(NULL == TransmitRates)
4921 return RETURN_ERR;
4922 strcpy(sub_set,TransmitRates);
4923
4924 //Allow only supported Data transmit rate to be set
4925 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
4926 token = strtok(sub_set,",");
4927 while( token != NULL ) /* split the basic rate to be set, by comma */
4928 {
4929 sub_set[subset_count]=atoi(token);
4930 subset_count++;
4931 token=strtok(NULL,",");
4932 }
4933 token=strtok(set,",");
4934 while(token!=NULL) /* split the supported rate by comma */
4935 {
4936 set[set_count]=atoi(token);
4937 set_count++;
4938 token=strtok(NULL,",");
4939 }
4940 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
4941 {
4942 for(set_index=0;set_index < set_count;set_index++)
4943 {
4944 flag=0;
4945 if(sub_set[subset_index]==set[set_index])
4946 break;
4947 else
4948 flag=1; /* No match found */
4949 }
4950 if(flag==1)
4951 return RETURN_ERR; //If value not found return Error
4952 }
4953 strcpy(temp_TransmitRates,TransmitRates);
4954
4955 for(i=0;i<strlen(temp_TransmitRates);i++)
4956 {
4957 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
4958 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
4959 {
4960 continue;
4961 }
4962 else
4963 {
4964 return RETURN_ERR;
4965 }
4966 }
4967 strcpy(temp_output,"");
4968 temp = strtok(temp_TransmitRates,",");
4969 while(temp!=NULL)
4970 {
4971 strcpy(temp1,temp);
4972 if(band == band_5)
4973 {
4974 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
4975 {
4976 return RETURN_ERR;
4977 }
4978 }
4979
4980 if(strcmp(temp,"5.5")==0)
4981 {
4982 strcpy(temp1,"55");
4983 }
4984 else
4985 {
4986 strcat(temp1,"0");
4987 }
4988 strcat(temp_output,temp1);
4989 temp = strtok(NULL,",");
4990 if(temp!=NULL)
4991 {
4992 strcat(temp_output," ");
4993 }
4994 }
4995 strcpy(TransmitRates,temp_output);
4996
4997 params.name= "basic_rates";
4998 params.value =TransmitRates;
4999
5000 wifi_dbg_printf("\n%s:",__func__);
5001 wifi_dbg_printf("\nparams.value=%s\n",params.value);
5002 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
5003 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
5004 wifi_hostapdWrite(config_file,&params,1);
5005 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5006 return RETURN_OK;
5007}
5008
5009//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
5010INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
5011{
5012 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5013 FILE *fp = NULL;
5014 char path[256] = {0}, output_string[256] = {0};
5015 int count = 0;
5016 char *interface = NULL;
5017
5018 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
5019 if (fp == NULL)
5020 {
5021 printf("Failed to run command in Function %s\n", __FUNCTION__);
5022 return RETURN_ERR;
5023 }
5024 if (fgets(path, sizeof(path) - 1, fp) != NULL)
5025 {
5026 interface = strchr(path, '=');
5027
5028 if (interface != NULL)
5029 {
5030 strcpy(output_string, interface + 1);
5031 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
5032 interface_name[count] = output_string[count];
5033
5034 interface_name[count] = '\0';
5035 }
5036 }
5037 pclose(fp);
5038 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5039 return RETURN_OK;
5040}
5041
5042INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
5043{
5044 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5045 output_struct->radio_BytesSent = 0;
5046 output_struct->radio_BytesReceived = 0;
5047 output_struct->radio_PacketsSent = 0;
5048 output_struct->radio_PacketsReceived = 0;
5049 output_struct->radio_ErrorsSent = 0;
5050 output_struct->radio_ErrorsReceived = 0;
5051 output_struct->radio_DiscardPacketsSent = 0;
5052 output_struct->radio_DiscardPacketsReceived = 0;
5053 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5054 return RETURN_OK;
5055}
5056
5057
5058INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
5059{
5060 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5061 CHAR buf[MAX_CMD_SIZE] = {0};
5062 CHAR Value[MAX_BUF_SIZE] = {0};
5063 FILE *fp = NULL;
5064
5065 if (ifname == NULL || strlen(ifname) <= 1)
5066 return RETURN_OK;
5067
5068 snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
5069 system(buf);
5070
5071 fp = fopen("/tmp/Radio_Stats.txt", "r");
5072 if(fp == NULL)
5073 {
5074 printf("/tmp/Radio_Stats.txt not exists \n");
5075 return RETURN_ERR;
5076 }
5077 fclose(fp);
5078
5079 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5080 File_Reading(buf, Value);
5081 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
5082
5083 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5084 File_Reading(buf, Value);
5085 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
5086
5087 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5088 File_Reading(buf, Value);
5089 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
5090
5091 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5092 File_Reading(buf, Value);
5093 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
5094
5095 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5096 File_Reading(buf, Value);
5097 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
5098
5099 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5100 File_Reading(buf, Value);
5101 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
5102
5103 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5104 File_Reading(buf, Value);
5105 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
5106
5107 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5108 File_Reading(buf, Value);
5109 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
5110
5111 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5112 return RETURN_OK;
5113}
5114
5115INT GetIfacestatus(CHAR *interface_name, CHAR *status)
5116{
developer7e4a2a62023-04-06 19:56:03 +08005117 CHAR buf[MAX_CMD_SIZE] = {0};
5118 INT count = 0;
developer72fb0bb2023-01-11 09:46:29 +08005119
developer7e4a2a62023-04-06 19:56:03 +08005120 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5121
5122 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
5123 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
5124 File_Reading(buf, status);
5125 }
5126
5127 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5128 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005129}
5130
5131//Get detail radio traffic static info
5132INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
5133{
5134
developer69b61b02023-03-07 17:17:44 +08005135#if 0
5136 //ifconfig radio_x
developer72fb0bb2023-01-11 09:46:29 +08005137 output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters.
5138 output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters.
5139 output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface.
5140 output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface.
5141
5142 output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors.
5143 output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
5144 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.
5145 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.
5146
developer69b61b02023-03-07 17:17:44 +08005147 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 +08005148 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].
5149 output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error.
5150 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.
5151 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
5152 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
5153 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
5154 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
5155 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
5156
5157 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
5158 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
5159 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
5160 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.
5161
5162 return RETURN_OK;
5163#endif
5164
5165 CHAR interface_name[64] = {0};
5166 BOOL iface_status = FALSE;
5167 wifi_radioTrafficStats2_t radioTrafficStats = {0};
5168
5169 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
5170 if (NULL == output_struct)
5171 return RETURN_ERR;
5172
5173 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5174 return RETURN_ERR;
5175
5176 wifi_getApEnable(radioIndex, &iface_status);
5177
5178 if (iface_status == TRUE)
5179 wifi_halGetIfStats(interface_name, &radioTrafficStats);
5180 else
5181 wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0
5182
5183 output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent;
5184 output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived;
5185 output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent;
5186 output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived;
5187 output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent;
5188 output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived;
5189 output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent;
5190 output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived;
5191
5192 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
5193 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].
5194 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
5195 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.
5196 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
5197 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
5198 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
5199 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
5200 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
5201
5202 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
5203 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
5204 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
5205 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.
5206
5207 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
5208
5209 return RETURN_OK;
5210}
5211
5212//Set radio traffic static Measureing rules
5213INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
5214{
5215 //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
5216 // Else, save the MeasuringRate and MeasuringInterval for future usage
5217
5218 return RETURN_OK;
5219}
5220
5221//To start or stop RadioTrafficStats
5222INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
5223{
5224 //zqiu: If the RadioTrafficStats process running
5225 // if(enable)
5226 // return RETURN_OK.
5227 // else
5228 // Stop RadioTrafficStats process
developer69b61b02023-03-07 17:17:44 +08005229 // Else
developer72fb0bb2023-01-11 09:46:29 +08005230 // if(enable)
5231 // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds
5232 // else
5233 // return RETURN_OK.
5234
5235 return RETURN_OK;
5236}
5237
5238//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
5239INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
5240{
5241 //zqiu: Please ignor signalIndex.
developer69b61b02023-03-07 17:17:44 +08005242 if (NULL == SignalLevel)
developer72fb0bb2023-01-11 09:46:29 +08005243 return RETURN_ERR;
developer47cc27a2023-05-17 23:09:58 +08005244
developer72fb0bb2023-01-11 09:46:29 +08005245 *SignalLevel=(radioIndex==0)?-19:-19;
5246
5247 return RETURN_OK;
5248}
5249
5250//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5251INT wifi_applyRadioSettings(INT radioIndex)
5252{
5253 return RETURN_OK;
5254}
5255
5256//Get the radio index assocated with this SSID entry
5257INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
5258{
5259 if(NULL == radioIndex)
5260 return RETURN_ERR;
5261 int max_radio_num = 0;
5262 wifi_getMaxRadioNumber(&max_radio_num);
5263 *radioIndex = ssidIndex%max_radio_num;
5264 return RETURN_OK;
5265}
5266
5267//Device.WiFi.SSID.{i}.Enable
5268//Get SSID enable configuration parameters (not the SSID enable status)
5269INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
5270{
developer69b61b02023-03-07 17:17:44 +08005271 if (NULL == output_bool)
developer72fb0bb2023-01-11 09:46:29 +08005272 return RETURN_ERR;
5273
5274 return wifi_getApEnable(ssidIndex, output_bool);
5275}
5276
5277//Device.WiFi.SSID.{i}.Enable
5278//Set SSID enable configuration parameters
5279INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
5280{
5281 return wifi_setApEnable(ssidIndex, enable);
5282}
5283
5284//Device.WiFi.SSID.{i}.Status
5285//Get the SSID enable status
5286INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
5287{
5288 char cmd[MAX_CMD_SIZE]={0};
5289 char buf[MAX_BUF_SIZE]={0};
5290 BOOL output_bool;
5291
5292 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5293 if (NULL == output_string)
5294 return RETURN_ERR;
developer69b61b02023-03-07 17:17:44 +08005295
developer72fb0bb2023-01-11 09:46:29 +08005296 wifi_getApEnable(ssidIndex,&output_bool);
5297 snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
5298
5299 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5300 return RETURN_OK;
5301}
5302
5303// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
5304INT wifi_getSSIDName(INT apIndex, CHAR *output)
5305{
5306 char config_file[MAX_BUF_SIZE] = {0};
5307
developer69b61b02023-03-07 17:17:44 +08005308 if (NULL == output)
developer72fb0bb2023-01-11 09:46:29 +08005309 return RETURN_ERR;
5310
5311 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5312 wifi_hostapdRead(config_file,"ssid",output,32);
5313
5314 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
5315 return RETURN_OK;
5316}
5317
developer69b61b02023-03-07 17:17:44 +08005318// Set a max 32 byte string and sets an internal variable to the SSID name
developer72fb0bb2023-01-11 09:46:29 +08005319INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
5320{
5321 char str[MAX_BUF_SIZE]={'\0'};
5322 char cmd[MAX_CMD_SIZE]={'\0'};
5323 struct params params;
5324 char config_file[MAX_BUF_SIZE] = {0};
5325
5326 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5327 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
5328 return RETURN_ERR;
5329
5330 params.name = "ssid";
5331 params.value = ssid_string;
5332 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5333 wifi_hostapdWrite(config_file, &params, 1);
5334 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5335 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5336
5337 return RETURN_OK;
5338}
5339
5340//Get the BSSID
5341INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
5342{
developer7e4a2a62023-04-06 19:56:03 +08005343 char cmd[MAX_CMD_SIZE] = {0};
5344 char inf_name[IF_NAME_SIZE] = {0};
5345 char conf_file[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08005346
developer7e4a2a62023-04-06 19:56:03 +08005347 if (!output_string)
developer72fb0bb2023-01-11 09:46:29 +08005348 return RETURN_ERR;
5349
developer47cc27a2023-05-17 23:09:58 +08005350 if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
5351 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08005352
developer5b2f10c2023-05-25 17:02:21 +08005353 if (ssidIndex < 0 || ssidIndex > MAX_APS) {
5354 wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
5355 strncpy(output_string, "\0", 1);
5356 return RETURN_ERR;
5357 }
5358 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
5359 _syscmd(cmd, output_string, 64);
developer7e4a2a62023-04-06 19:56:03 +08005360
developer5b2f10c2023-05-25 17:02:21 +08005361 /* if hostapd does not control interface even if this interface has been brought up,
5362 * try to get its mac address by iw command.
5363 */
5364 if(strlen(output_string) == 0) {
5365 memset(cmd, 0, sizeof(cmd));
5366 snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
5367 _syscmd(cmd, output_string, 64);
5368 }
developer72fb0bb2023-01-11 09:46:29 +08005369
developer5b2f10c2023-05-25 17:02:21 +08005370 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08005371}
5372
5373//Get the MAC address associated with this Wifi SSID
5374INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
5375{
5376 wifi_getBaseBSSID(ssidIndex,output_string);
5377 return RETURN_OK;
5378}
5379
5380//Get the basic SSID traffic static info
5381//Apply SSID and AP (in the case of Acess Point devices) to the hardware
5382//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
5383INT wifi_applySSIDSettings(INT ssidIndex)
5384{
5385 char interface_name[16] = {0};
5386 BOOL status = false;
5387 char cmd[MAX_CMD_SIZE] = {0};
5388 char buf[MAX_CMD_SIZE] = {0};
5389 int apIndex, ret;
5390 int max_radio_num = 0;
5391 int radioIndex = 0;
5392
5393 wifi_getMaxRadioNumber(&max_radio_num);
5394
5395 radioIndex = ssidIndex % max_radio_num;
5396
5397 wifi_getApEnable(ssidIndex,&status);
5398 // Do not apply when ssid index is disabled
5399 if (status == false)
5400 return RETURN_OK;
5401
5402 /* Doing full remove and add for ssid Index
5403 * Not all hostapd options are supported with reload
5404 * for example macaddr_acl
5405 */
5406 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
5407 return RETURN_ERR;
5408
5409 ret = wifi_setApEnable(ssidIndex,true);
5410
5411 /* Workaround for hostapd issue with multiple bss definitions
5412 * when first created interface will be removed
5413 * then all vaps other vaps on same phy are removed
5414 * after calling setApEnable to false readd all enabled vaps */
5415 for(int i=0; i < MAX_APS/max_radio_num; i++) {
5416 apIndex = max_radio_num*i+radioIndex;
5417 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5418 return RETURN_ERR;
5419 snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
5420 _syscmd(cmd, buf, sizeof(buf));
5421 if(*buf == '1')
5422 wifi_setApEnable(apIndex, true);
5423 }
5424
5425 return ret;
5426}
5427
5428struct channels_noise {
5429 int channel;
5430 int noise;
5431};
5432
5433// Return noise array for each channel
5434int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
5435{
5436 char interface_name[16] = {0};
5437 FILE *f = NULL;
5438 char cmd[128] = {0};
5439 char line[256] = {0};
5440 size_t len = 0;
5441 ssize_t read = 0;
5442 int tmp = 0, arr_index = -1;
5443
5444 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5445 return RETURN_ERR;
5446 sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
5447
5448 if ((f = popen(cmd, "r")) == NULL) {
5449 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5450 return RETURN_ERR;
5451 }
developer69b61b02023-03-07 17:17:44 +08005452
developer72fb0bb2023-01-11 09:46:29 +08005453 while(fgets(line, sizeof(line), f) != NULL) {
5454 if(arr_index < channels_num){
5455 sscanf(line, "%d", &tmp);
5456 if (tmp > 0) { // channel frequency, the first line must be frequency
5457 arr_index++;
5458 channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
5459 } else { // noise
5460 channels_noise_arr[arr_index].noise = tmp;
5461 }
5462 }else{
5463 break;
5464 }
5465 }
5466 pclose(f);
5467 return RETURN_OK;
5468}
5469
5470//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
5471//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
developer69b61b02023-03-07 17:17:44 +08005472INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
developer72fb0bb2023-01-11 09:46:29 +08005473{
5474 int index = -1;
5475 wifi_neighbor_ap2_t *scan_array = NULL;
5476 char cmd[256]={0};
5477 char buf[128]={0};
5478 char file_name[32] = {0};
5479 char filter_SSID[32] = {0};
5480 char line[256] = {0};
5481 char interface_name[16] = {0};
5482 char *ret = NULL;
5483 int freq=0;
5484 FILE *f = NULL;
5485 size_t len=0;
5486 int channels_num = 0;
5487 int vht_channel_width = 0;
5488 int get_noise_ret = RETURN_ERR;
5489 bool filter_enable = false;
5490 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
5491 int phyId = 0;
5492
5493 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
5494
5495 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
5496 return RETURN_ERR;
5497
5498 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex);
5499 f = fopen(file_name, "r");
5500 if (f != NULL) {
5501 fgets(filter_SSID, sizeof(file_name), f);
5502 if (strlen(filter_SSID) != 0)
5503 filter_enable = true;
5504 fclose(f);
5505 }
5506
5507 phyId = radio_index_to_phy(radioIndex);
5508 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
5509 _syscmd(cmd, buf, sizeof(buf));
5510 channels_num = strtol(buf, NULL, 10);
5511
5512
5513
5514 sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
5515 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
5516 fprintf(stderr, "cmd: %s\n", cmd);
5517 if ((f = popen(cmd, "r")) == NULL) {
5518 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
5519 return RETURN_ERR;
5520 }
developer69b61b02023-03-07 17:17:44 +08005521
developer72fb0bb2023-01-11 09:46:29 +08005522 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
5523 get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +08005524
developer72fb0bb2023-01-11 09:46:29 +08005525 ret = fgets(line, sizeof(line), f);
5526 while (ret != NULL) {
5527 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +08005528 // 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 +08005529 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
5530 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
5531
5532 if (!filter_BSS) {
5533 index++;
5534 wifi_neighbor_ap2_t *tmp;
5535 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
5536 if (tmp == NULL) { // no more memory to use
5537 index--;
5538 wifi_dbg_printf("%s: realloc failed\n", __func__);
5539 break;
5540 }
5541 scan_array = tmp;
5542 }
5543 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5544
5545 filter_BSS = false;
5546 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
5547 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
5548 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
5549 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
5550 } else if (strstr(line, "freq") != NULL) {
5551 sscanf(line," freq: %d", &freq);
5552 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
5553
5554 if (freq >= 2412 && freq <= 2484) {
5555 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
5556 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
5557 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
5558 }
5559 else if (freq >= 5160 && freq <= 5805) {
5560 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
5561 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
5562 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
5563 }
5564
5565 scan_array[index].ap_Noise = 0;
5566 if (get_noise_ret == RETURN_OK) {
5567 for (int i = 0; i < channels_num; i++) {
5568 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
5569 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
5570 break;
5571 }
5572 }
5573 }
5574 } else if (strstr(line, "beacon interval") != NULL) {
5575 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
5576 } else if (strstr(line, "signal") != NULL) {
5577 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
5578 } else if (strstr(line,"SSID") != NULL) {
5579 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
5580 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
5581 filter_BSS = true;
5582 }
5583 } else if (strstr(line, "Supported rates") != NULL) {
5584 char SRate[80] = {0}, *tmp = NULL;
5585 memset(buf, 0, sizeof(buf));
5586 strcpy(SRate, line);
5587 tmp = strtok(SRate, ":");
5588 tmp = strtok(NULL, ":");
5589 strcpy(buf, tmp);
5590 memset(SRate, 0, sizeof(SRate));
5591
5592 tmp = strtok(buf, " \n");
5593 while (tmp != NULL) {
5594 strcat(SRate, tmp);
5595 if (SRate[strlen(SRate) - 1] == '*') {
5596 SRate[strlen(SRate) - 1] = '\0';
5597 }
5598 strcat(SRate, ",");
5599
5600 tmp = strtok(NULL, " \n");
5601 }
5602 SRate[strlen(SRate) - 1] = '\0';
5603 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
5604 } else if (strstr(line, "DTIM") != NULL) {
5605 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
5606 } else if (strstr(line, "VHT capabilities") != NULL) {
5607 strcat(scan_array[index].ap_SupportedStandards, ",ac");
5608 strcpy(scan_array[index].ap_OperatingStandards, "ac");
5609 } else if (strstr(line, "HT capabilities") != NULL) {
5610 strcat(scan_array[index].ap_SupportedStandards, ",n");
5611 strcpy(scan_array[index].ap_OperatingStandards, "n");
5612 } else if (strstr(line, "VHT operation") != NULL) {
5613 ret = fgets(line, sizeof(line), f);
5614 sscanf(line," * channel width: %d", &vht_channel_width);
5615 if(vht_channel_width == 1) {
5616 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
5617 } else {
5618 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
5619 }
5620 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5621 continue;
5622 } else if (strstr(line, "HT operation") != NULL) {
5623 ret = fgets(line, sizeof(line), f);
5624 sscanf(line," * secondary channel offset: %s", &buf);
5625 if (!strcmp(buf, "above")) {
5626 //40Mhz +
5627 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
5628 }
5629 else if (!strcmp(buf, "below")) {
5630 //40Mhz -
5631 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
5632 } else {
5633 //20Mhz
5634 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
5635 }
5636 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
5637 continue;
5638 } else if (strstr(line, "HE capabilities") != NULL) {
5639 strcat(scan_array[index].ap_SupportedStandards, ",ax");
5640 strcpy(scan_array[index].ap_OperatingStandards, "ax");
5641 ret = fgets(line, sizeof(line), f);
5642 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
5643 if (strstr(line, "HE40/2.4GHz") != NULL)
5644 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
5645 else
5646 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
5647 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
5648 if (strstr(line, "HE80/5GHz") != NULL) {
5649 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
5650 ret = fgets(line, sizeof(line), f);
5651 } else
5652 continue;
5653 if (strstr(line, "HE160/5GHz") != NULL)
5654 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
5655 }
5656 continue;
5657 } else if (strstr(line, "WPA") != NULL) {
5658 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
5659 } else if (strstr(line, "RSN") != NULL) {
5660 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
5661 } else if (strstr(line, "Group cipher") != NULL) {
5662 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
5663 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
5664 strcpy(scan_array[index].ap_EncryptionMode, "AES");
5665 }
5666 }
5667 ret = fgets(line, sizeof(line), f);
5668 }
5669
5670 if (!filter_BSS) {
5671 *output_array_size = index + 1;
5672 } else {
5673 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
5674 *output_array_size = index;
5675 }
5676 *neighbor_ap_array = scan_array;
5677 pclose(f);
5678 free(channels_noise_arr);
5679 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5680 return RETURN_OK;
5681}
5682
5683//>> Deprecated: used for old RDKB code.
5684INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
5685{
5686 INT status = RETURN_ERR;
5687
5688 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5689 output_struct->wifi_PLCPErrorCount = 0;
5690 output_struct->wifi_FCSErrorCount = 0;
5691 output_struct->wifi_InvalidMACCount = 0;
5692 output_struct->wifi_PacketsOtherReceived = 0;
5693 output_struct->wifi_Noise = 0;
5694 status = RETURN_OK;
5695 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5696 return status;
5697}
5698
5699INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
5700{
5701 char interface_name[16] = {0};
5702 char cmd[128] = {0};
5703 char buf[1280] = {0};
5704 char *pos = NULL;
5705
5706 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5707 if (NULL == output_struct)
5708 return RETURN_ERR;
5709
5710 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
5711 return RETURN_ERR;
5712
5713 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5714
5715 snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name);
5716 _syscmd(cmd, buf, sizeof(buf));
5717
5718 pos = buf;
5719 if ((pos = strstr(pos, "RX packets:")) == NULL)
5720 return RETURN_ERR;
5721 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
5722
5723 if ((pos = strstr(pos, "TX packets:")) == NULL)
5724 return RETURN_ERR;
5725 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
5726
5727 if ((pos = strstr(pos, "RX bytes:")) == NULL)
5728 return RETURN_ERR;
5729 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
5730
5731 if ((pos = strstr(pos, "TX bytes:")) == NULL)
5732 return RETURN_ERR;
5733 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
5734
5735 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name);
5736 _syscmd(cmd, buf, sizeof(buf));
5737 sscanf(buf, "%lu", &output_struct->wifi_Associations);
5738
5739#if 0
5740 //TODO: need to revisit below implementation
5741 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5742 char interface_name[MAX_BUF_SIZE] = {0};
5743 char interface_status[MAX_BUF_SIZE] = {0};
5744 char Value[MAX_BUF_SIZE] = {0};
5745 char buf[MAX_CMD_SIZE] = {0};
5746 char cmd[MAX_CMD_SIZE] = {0};
5747 FILE *fp = NULL;
5748
5749 if (NULL == output_struct) {
5750 return RETURN_ERR;
5751 }
5752
5753 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
5754
5755 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
5756 {
5757 if(apIndex == 0) //private_wifi for 2.4G
5758 {
5759 wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
5760 }
5761 else if(apIndex == 1) //private_wifi for 5G
5762 {
5763 wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
5764 }
5765 else if(apIndex == 4) //public_wifi for 2.4G
5766 {
5767 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
5768 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
5769 {
5770 return RETURN_ERR;
5771 }
5772 if(buf[0] == '#')//tp-link
5773 wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
5774 else//tenda
5775 wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name);
5776 }
5777 else if(apIndex == 5) //public_wifi for 5G
5778 {
5779 wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
5780 }
5781
5782 GetIfacestatus(interface_name, interface_status);
5783
5784 if(0 != strcmp(interface_status, "1"))
5785 return RETURN_ERR;
5786
5787 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5788 system(cmd);
5789
5790 fp = fopen("/tmp/SSID_Stats.txt", "r");
5791 if(fp == NULL)
5792 {
5793 printf("/tmp/SSID_Stats.txt not exists \n");
5794 return RETURN_ERR;
5795 }
5796 fclose(fp);
5797
5798 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5799 File_Reading(buf, Value);
5800 output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10);
5801
5802 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5803 File_Reading(buf, Value);
5804 output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10);
5805
5806 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
5807 File_Reading(buf, Value);
5808 output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10);
5809
5810 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5811 File_Reading(buf, Value);
5812 output_struct->wifi_BytesSent = strtoul(Value, NULL, 10);
5813
5814 /* There is no specific parameter from caller to associate the value wifi_Associations */
5815 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);
5816 //_syscmd(cmd, buf, sizeof(buf));
5817 //sscanf(buf,"%lu", &output_struct->wifi_Associations);
5818 }
5819#endif
5820 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5821 return RETURN_OK;
5822}
5823
5824INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
5825{
5826 char interface_name[MAX_BUF_SIZE] = {0};
5827 char interface_status[MAX_BUF_SIZE] = {0};
5828 char Value[MAX_BUF_SIZE] = {0};
5829 char buf[MAX_CMD_SIZE] = {0};
5830 char cmd[MAX_CMD_SIZE] = {0};
5831 FILE *fp = NULL;
5832
5833 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5834 if (NULL == output_struct)
5835 return RETURN_ERR;
5836
5837 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
5838
5839 if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
5840 return RETURN_ERR;
5841 GetIfacestatus(interface_name, interface_status);
5842
5843 if(0 != strcmp(interface_status, "1"))
5844 return RETURN_ERR;
5845
5846 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
5847 system(cmd);
5848
5849 fp = fopen("/tmp/SSID_Stats.txt", "r");
5850 if(fp == NULL)
5851 {
5852 printf("/tmp/SSID_Stats.txt not exists \n");
5853 return RETURN_ERR;
5854 }
5855 fclose(fp);
5856
5857 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5858 File_Reading(buf, Value);
5859 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
5860
5861 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
5862 File_Reading(buf, Value);
5863 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
5864
5865 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5866 File_Reading(buf, Value);
5867 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
5868
5869 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
5870 File_Reading(buf, Value);
5871 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
5872
5873 output_struct->wifi_UnicastPacketsSent = 0;
5874 output_struct->wifi_UnicastPacketsReceived = 0;
5875 output_struct->wifi_MulticastPacketsSent = 0;
5876 output_struct->wifi_MulticastPacketsReceived = 0;
5877 output_struct->wifi_BroadcastPacketsSent = 0;
5878 output_struct->wifi_BroadcastPacketsRecevied = 0;
5879 output_struct->wifi_UnknownPacketsReceived = 0;
5880
5881 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5882 return RETURN_OK;
5883}
5884
5885INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
5886{
5887 INT status = RETURN_ERR;
5888
5889 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5890 //Below values should get updated from hal
5891 output_struct->wifi_RetransCount=0;
5892 output_struct->wifi_FailedRetransCount=0;
5893 output_struct->wifi_RetryCount=0;
5894 output_struct->wifi_MultipleRetryCount=0;
5895 output_struct->wifi_ACKFailureCount=0;
5896 output_struct->wifi_AggregatedPacketCount=0;
5897
5898 status = RETURN_OK;
5899 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5900
5901 return status;
5902}
5903
5904INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
5905{
5906 INT status = RETURN_ERR;
5907 UINT index;
5908 wifi_neighbor_ap_t *pt=NULL;
5909
5910 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5911 *output_array_size=2;
5912 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
5913 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
5914 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
5915 strcpy(pt->ap_Radio,"");
5916 strcpy(pt->ap_SSID,"");
5917 strcpy(pt->ap_BSSID,"");
5918 strcpy(pt->ap_Mode,"");
5919 pt->ap_Channel=1;
5920 pt->ap_SignalStrength=0;
5921 strcpy(pt->ap_SecurityModeEnabled,"");
5922 strcpy(pt->ap_EncryptionMode,"");
5923 strcpy(pt->ap_OperatingFrequencyBand,"");
5924 strcpy(pt->ap_SupportedStandards,"");
5925 strcpy(pt->ap_OperatingStandards,"");
5926 strcpy(pt->ap_OperatingChannelBandwidth,"");
5927 pt->ap_BeaconPeriod=1;
5928 pt->ap_Noise=0;
5929 strcpy(pt->ap_BasicDataTransferRates,"");
5930 strcpy(pt->ap_SupportedDataTransferRates,"");
5931 pt->ap_DTIMPeriod=1;
5932 pt->ap_ChannelUtilization = 1;
5933 }
5934
5935 status = RETURN_OK;
5936 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5937
5938 return status;
5939}
5940
5941//----------------- AP HAL -------------------------------
5942
5943//>> Deprecated: used for old RDKB code.
5944INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
5945{
5946 if (NULL == output_ulong || NULL == output_struct)
5947 return RETURN_ERR;
5948 *output_ulong = 0;
5949 *output_struct = NULL;
5950 return RETURN_OK;
5951}
5952
5953#ifdef HAL_NETLINK_IMPL
5954static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
5955 struct nlattr *tb[NL80211_ATTR_MAX + 1];
5956 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
5957 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
5958 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
5959 char mac_addr[20];
5960 static int count=0;
5961 int rate=0;
5962
5963 wifi_device_info_t *out = (wifi_device_info_t*)arg;
5964
5965 nla_parse(tb,
5966 NL80211_ATTR_MAX,
5967 genlmsg_attrdata(gnlh, 0),
5968 genlmsg_attrlen(gnlh, 0),
5969 NULL);
5970
5971 if(!tb[NL80211_ATTR_STA_INFO]) {
5972 fprintf(stderr, "sta stats missing!\n");
5973 return NL_SKIP;
5974 }
5975
5976
5977 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
5978 fprintf(stderr, "failed to parse nested attributes!\n");
5979 return NL_SKIP;
5980 }
5981
5982 //devIndex starts from 1
5983 if( ++count == out->wifi_devIndex )
5984 {
5985 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
5986 //Getting the mac addrress
5987 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
5988
5989 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
5990 fprintf(stderr, "failed to parse nested rate attributes!");
5991 return NL_SKIP;
5992 }
5993
5994 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
5995 if(rinfo[NL80211_RATE_INFO_BITRATE])
5996 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
5997 out->wifi_devTxRate = rate/10;
5998 }
5999
6000 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
6001 fprintf(stderr, "failed to parse nested rate attributes!");
6002 return NL_SKIP;
6003 }
6004
6005 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
6006 if(rinfo[NL80211_RATE_INFO_BITRATE])
6007 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
6008 out->wifi_devRxRate = rate/10;
6009 }
6010 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
6011 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
6012
6013 out->wifi_devAssociatedDeviceAuthentiationState = 1;
6014 count = 0; //starts the count for next cycle
6015 return NL_STOP;
6016 }
6017
6018 return NL_SKIP;
6019
6020}
6021#endif
6022
6023INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
6024{
6025#ifdef HAL_NETLINK_IMPL
6026 Netlink nl = {0};
6027 char if_name[10] = {0};
6028 char interface_name[16] = {0};
6029
6030 wifi_device_info_t info = {0};
6031 info.wifi_devIndex = devIndex;
6032
6033 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6034 return RETURN_ERR;
6035
6036 snprintf(if_name,sizeof(if_name),"%s", interface_name);
6037
6038 nl.id = initSock80211(&nl);
6039
6040 if (nl.id < 0) {
6041 fprintf(stderr, "Error initializing netlink \n");
6042 return -1;
6043 }
6044
6045 struct nl_msg* msg = nlmsg_alloc();
6046
6047 if (!msg) {
6048 fprintf(stderr, "Failed to allocate netlink message.\n");
6049 nlfree(&nl);
6050 return -2;
6051 }
6052
6053 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +08006054 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +08006055 NL_AUTO_SEQ,
6056 nl.id,
6057 0,
6058 NLM_F_DUMP,
6059 NL80211_CMD_GET_STATION,
6060 0);
6061
6062 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +08006063 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +08006064 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
6065 nl_recvmsgs(nl.socket, nl.cb);
6066 nlmsg_free(msg);
6067 nlfree(&nl);
6068
6069 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
6070 output_struct->wifi_devRxRate = info.wifi_devRxRate;
6071 output_struct->wifi_devTxRate = info.wifi_devTxRate;
6072 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
6073 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
6074 return RETURN_OK;
6075#else
6076 //iw utility to retrieve station information
6077#define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt"
6078#define SIGNALFILE "/tmp/wifi_signalstrength.txt"
6079#define MACFILE "/tmp/wifi_AssoMac.txt"
6080#define TXRATEFILE "/tmp/wifi_txrate.txt"
6081#define RXRATEFILE "/tmp/wifi_rxrate.txt"
6082 FILE *file = NULL;
6083 char if_name[10] = {'\0'};
6084 char pipeCmd[256] = {'\0'};
6085 char line[256] = {0};
6086 char interface_name[16] = {0};
6087 int count = 0, device = 0;
6088
6089 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
6090 return RETURN_ERR;
6091
6092 snprintf(if_name,sizeof(if_name),"%s", interface_name);
6093
6094 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name);
6095 file = popen(pipeCmd, "r");
6096
6097 if(file == NULL)
6098 return RETURN_ERR; //popen failed
6099
6100 fgets(line, sizeof line, file);
6101 device = atoi(line);
6102 pclose(file);
6103
6104 if(device == 0)
6105 return RETURN_ERR; //No devices are connected
6106
6107 sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name);
6108 system(pipeCmd);
6109
6110 system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE);
6111
6112 system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE);
6113
6114 system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE);
6115
6116 system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE);
6117
6118 //devIndex starts from 1, ++count
6119 if((file = fopen(SIGNALFILE, "r")) != NULL )
6120 {
6121 for(count =0;fgets(line, sizeof line, file) != NULL;)
6122 {
6123 if (++count == devIndex)
6124 {
6125 output_struct->wifi_devSignalStrength = atoi(line);
6126 break;
6127 }
6128 }
6129 fclose(file);
6130 }
6131 else
6132 fprintf(stderr,"fopen wifi_signalstrength.txt failed");
6133
6134 if((file = fopen(MACFILE, "r")) != NULL )
6135 {
6136 for(count =0;fgets(line, sizeof line, file) != NULL;)
6137 {
6138 if (++count == devIndex)
6139 {
6140 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]);
6141 break;
6142 }
6143 }
6144 fclose(file);
6145 }
6146 else
6147 fprintf(stderr,"fopen wifi_AssoMac.txt failed");
6148
6149 if((file = fopen(TXRATEFILE, "r")) != NULL )
6150 {
6151 for(count =0;fgets(line, sizeof line, file) != NULL;)
6152 {
6153 if (++count == devIndex)
6154 {
6155 output_struct->wifi_devTxRate = atoi(line);
6156 break;
6157 }
6158 }
6159 fclose(file);
6160 }
6161 else
6162 fprintf(stderr,"fopen wifi_txrate.txt failed");
6163
6164 if((file = fopen(RXRATEFILE, "r")) != NULL)
6165 {
6166 for(count =0;fgets(line, sizeof line, file) != NULL;)
6167 {
6168 if (++count == devIndex)
6169 {
6170 output_struct->wifi_devRxRate = atoi(line);
6171 break;
6172 }
6173 }
6174 fclose(file);
6175 }
6176 else
6177 fprintf(stderr,"fopen wifi_rxrate.txt failed");
6178
6179 output_struct->wifi_devAssociatedDeviceAuthentiationState = 1;
6180
6181 return RETURN_OK;
6182#endif
6183}
6184
6185INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
6186{
6187 if (NULL == device)
6188 return RETURN_ERR;
6189 return RETURN_OK;
6190}
6191//<<
6192
6193
6194//--------------wifi_ap_hal-----------------------------
6195//enables CTS protection for the radio used by this AP
6196INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
6197{
6198 //save config and Apply instantly
6199 return RETURN_ERR;
6200}
6201
6202// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
6203INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
6204{
6205 char config_file[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08006206 char config_dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006207 char buf[64] = {'\0'};
developerd1824452023-05-18 12:30:04 +08006208 struct params list = {0};
6209 struct params dat = {0};
6210 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08006211
6212 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6213 list.name = "ht_coex";
6214 snprintf(buf, sizeof(buf), "%d", enable);
6215 list.value = buf;
6216
developerd1824452023-05-18 12:30:04 +08006217 dat.name = "HT_BSSCoexistence";
6218 dat.value = buf;
6219
6220 band = wifi_index_to_band(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08006221 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developerd1824452023-05-18 12:30:04 +08006222 snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
developer72fb0bb2023-01-11 09:46:29 +08006223 wifi_hostapdWrite(config_file, &list, 1);
developer262f4cb2023-05-24 12:22:04 +08006224 wifi_datfileWrite(config_dat_file, &dat, 1);
developer72fb0bb2023-01-11 09:46:29 +08006225 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6226
6227 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6228
6229 return RETURN_OK;
6230}
6231
6232//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
6233INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
6234{
6235 char config_file[MAX_BUF_SIZE] = {'\0'};
6236 char buf[MAX_BUF_SIZE] = {'\0'};
6237 struct params list;
6238
6239 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6240 if (threshold < 256 || threshold > 2346 )
6241 return RETURN_ERR;
6242 list.name = "fragm_threshold";
6243 snprintf(buf, sizeof(buf), "%d", threshold);
6244 list.value = buf;
6245
6246 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
6247 wifi_hostapdWrite(config_file, &list, 1);
6248 wifi_hostapdProcessUpdate(apIndex, &list, 1);
6249
6250 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6251
6252 return RETURN_OK;
6253}
6254
6255// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
6256INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
6257{
6258 char config_file[64] = {'\0'};
6259 char cmd[512] = {'\0'};
6260 char buf[512] = {'\0'};
6261 char stbc_config[16] = {'\0'};
6262 wifi_band band;
6263 int iterator = 0;
6264 BOOL current_stbc = FALSE;
6265 int ant_count = 0;
6266 int ant_bitmap = 0;
6267 struct params list;
developera1255e42023-05-13 17:45:02 +08006268 char dat_file[64] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006269
6270 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6271
6272 band = wifi_index_to_band(radioIndex);
6273 if (band == band_invalid)
6274 return RETURN_ERR;
6275
6276 if (band == band_2_4)
6277 iterator = 1;
developera1255e42023-05-13 17:45:02 +08006278 else if ((band == band_5) || (band == band_6))
developer72fb0bb2023-01-11 09:46:29 +08006279 iterator = 2;
6280 else
6281 return RETURN_OK;
6282
6283 wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
6284 for (; ant_bitmap > 0; ant_bitmap >>= 1)
6285 ant_count += ant_bitmap & 1;
6286
6287 if (ant_count == 1 && STBC_Enable == TRUE) {
6288 fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__);
6289 return RETURN_OK;
6290 }
6291
6292 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6293
6294 // set ht and vht config
6295 for (int i = 0; i < iterator; i++) {
6296 memset(stbc_config, 0, sizeof(stbc_config));
6297 memset(cmd, 0, sizeof(cmd));
6298 memset(buf, 0, sizeof(buf));
6299 list.name = (i == 0)?"ht_capab":"vht_capab";
6300 snprintf(stbc_config, sizeof(stbc_config), "%s", list.name);
6301 snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config);
6302 _syscmd(cmd, buf, sizeof(buf));
6303 if (strlen(buf) != 0)
6304 current_stbc = TRUE;
6305 if (current_stbc == STBC_Enable)
6306 continue;
6307
6308 if (STBC_Enable == TRUE) {
6309 // Append the STBC flags in capab config
6310 memset(cmd, 0, sizeof(cmd));
6311 if (i == 0)
6312 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
6313 else
6314 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
6315 _syscmd(cmd, buf, sizeof(buf));
6316 } else if (STBC_Enable == FALSE) {
6317 // Remove the STBC flags and remain other flags in capab
6318 memset(cmd, 0, sizeof(cmd));
6319 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6320 _syscmd(cmd, buf, sizeof(buf));
6321 memset(cmd, 0, sizeof(cmd));
6322 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
6323 _syscmd(cmd, buf, sizeof(buf));
6324 }
6325 wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
6326 list.value = buf;
6327 wifi_hostapdProcessUpdate(radioIndex, &list, 1);
6328 }
developera1255e42023-05-13 17:45:02 +08006329 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6330 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
6331 _syscmd(cmd, buf, sizeof(buf));
6332 if ((band == band_5) || (band == band_6)) {
6333 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
6334 _syscmd(cmd, buf, sizeof(buf));
6335 }
6336 /*wifi_reloadAp(radioIndex);
6337 the caller do this.*/
developer72fb0bb2023-01-11 09:46:29 +08006338
6339 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6340 return RETURN_OK;
6341}
6342
6343// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
6344INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
6345{
developer2c22d832023-05-18 17:46:26 +08006346 char dat_file[128] = {0};
6347 BOOL enable;
6348 wifi_band band;
6349 char amdus_buff[8] = {'\0'};
developer72fb0bb2023-01-11 09:46:29 +08006350
developer2c22d832023-05-18 17:46:26 +08006351 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006352
developer2c22d832023-05-18 17:46:26 +08006353 band = wifi_index_to_band(radioIndex);
6354 if (band == band_invalid) {
6355 printf("%s:Band Error\n", __func__);
6356 return RETURN_ERR;
6357 }
6358 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6359 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6360 if (strncmp(amdus_buff, "1", 1) == 0)
developer72fb0bb2023-01-11 09:46:29 +08006361 *output_bool = TRUE;
developer2c22d832023-05-18 17:46:26 +08006362 else
6363 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +08006364
developer2c22d832023-05-18 17:46:26 +08006365 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6366
6367 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006368}
6369
6370// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
6371INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
6372{
developer2c22d832023-05-18 17:46:26 +08006373 char dat_file[128] = {0};
6374 BOOL enable;
6375 wifi_band band;
6376 char amdus_buff[8] = {'\0'};
6377 struct params params = {0};
developer72fb0bb2023-01-11 09:46:29 +08006378
developer2c22d832023-05-18 17:46:26 +08006379 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006380
developer2c22d832023-05-18 17:46:26 +08006381 band = wifi_index_to_band(radioIndex);
6382 if (band == band_invalid) {
6383 printf("%s:Band Error\n", __func__);
6384 return RETURN_ERR;
6385 }
6386 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6387 wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff));
6388 if (strncmp(amdus_buff, "1", 1) == 0)
6389 enable = TRUE;
6390 else
6391 enable = FALSE;
6392 if (amsduEnable == enable)
6393 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006394
developer2c22d832023-05-18 17:46:26 +08006395 params.name = "HT_AMSDU";
6396 if (amsduEnable)
6397 params.value = "1";
6398 else
6399 params.value = "0";
6400 wifi_datfileWrite(dat_file, &params, 1);
6401 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006402
developer2c22d832023-05-18 17:46:26 +08006403 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08006404
developer72fb0bb2023-01-11 09:46:29 +08006405 return RETURN_OK;
6406}
6407
6408//P2 // outputs the number of Tx streams
6409INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
6410{
6411 char buf[8] = {0};
6412 char cmd[128] = {0};
6413 int phyId = 0;
6414
6415 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6416
6417 phyId = radio_index_to_phy(radioIndex);
6418 snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
6419 _syscmd(cmd, buf, sizeof(buf));
6420
6421 *output_int = (INT)strtol(buf, NULL, 16);
6422
6423 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6424
6425 return RETURN_OK;
6426}
6427
6428INT fitChainMask(INT radioIndex, int antcount)
6429{
6430 char buf[128] = {0};
6431 char cmd[128] = {0};
6432 char config_file[64] = {0};
6433 wifi_band band;
6434 struct params list[2] = {0};
6435
6436 band = wifi_index_to_band(radioIndex);
6437 if (band == band_invalid)
6438 return RETURN_ERR;
6439
6440 list[0].name = "he_mu_beamformer";
6441 list[1].name = "he_su_beamformer";
6442
6443 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
6444 if (antcount == 1) {
6445 // remove config about multiple antennas
6446 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
6447 _syscmd(cmd, buf, sizeof(buf));
6448
6449 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
6450 _syscmd(cmd, buf, sizeof(buf));
6451
6452 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
6453 _syscmd(cmd, buf, sizeof(buf));
6454
6455 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
6456 _syscmd(cmd, buf, sizeof(buf));
6457
6458 list[0].value = "0";
6459 list[1].value = "0";
6460 } else {
6461 // 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.
6462 if (band == band_2_4 || band == band_5) {
6463 snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6464 _syscmd(cmd, buf, sizeof(buf));
6465 if (strlen(buf) > 0) {
6466 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
6467 _syscmd(cmd, buf, sizeof(buf));
6468 }
6469 }
6470 if (band == band_5) {
6471 snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
6472 _syscmd(cmd, buf, sizeof(buf));
6473 if (strlen(buf) > 0) {
6474 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
6475 _syscmd(cmd, buf, sizeof(buf));
6476 }
6477 }
6478
6479 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-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/$/[SU-BEAMFORMER]/' %s", config_file);
6483 _syscmd(cmd, buf, sizeof(buf));
6484 }
6485
6486 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
6487 _syscmd(cmd, buf, sizeof(buf));
6488 if (strlen(buf) == 0) {
6489 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
6490 _syscmd(cmd, buf, sizeof(buf));
6491 }
6492
6493 snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
6494 _syscmd(cmd, buf, sizeof(buf));
6495 if (strlen(buf) == 0) {
6496 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
6497 } else {
6498 snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
6499 }
6500 _syscmd(cmd, buf, sizeof(buf));
6501
6502 list[0].value = "1";
6503 list[1].value = "1";
6504 }
6505 wifi_hostapdWrite(config_file, list, 2);
6506}
6507
6508//P2 // sets the number of Tx streams to an enviornment variable
6509INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
6510{
6511 char cmd[128] = {0};
6512 char buf[128] = {0};
6513 int phyId = 0;
6514 int cur_mask = 0;
developera1255e42023-05-13 17:45:02 +08006515 int antcountmsk = 0;
6516 INT cur_nss = 0;
6517 UCHAR dat_file[64] = {0};
6518 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +08006519
6520 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6521
6522 if (numStreams <= 0) {
6523 fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams);
6524 return RETURN_ERR;
6525 }
6526
developera1255e42023-05-13 17:45:02 +08006527 wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
6528 for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
6529 cur_nss += 1;
6530 WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
6531 if (cur_nss == numStreams)
developer72fb0bb2023-01-11 09:46:29 +08006532 return RETURN_OK;
6533
6534 wifi_setRadioEnable(radioIndex, FALSE);
6535
6536 phyId = radio_index_to_phy(radioIndex);
developera1255e42023-05-13 17:45:02 +08006537 //iw need mask value.
6538 for (;numStreams > 0; numStreams--)
6539 antcountmsk |= 0x1 << (numStreams - 1);
6540 snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
developer72fb0bb2023-01-11 09:46:29 +08006541 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08006542 if (strlen(buf) > 0) {
6543 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6544 return RETURN_ERR;
6545 }
developera1255e42023-05-13 17:45:02 +08006546 band = wifi_index_to_band(radioIndex);
6547 if (band == band_invalid) {
6548 printf("%s:Band Error\n", __func__);
6549 return RETURN_ERR;
6550 }
6551 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
6552 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
6553 _syscmd(cmd, buf, sizeof(buf));
6554 if (strlen(buf) > 0) {
6555 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6556 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08006557 }
developera1255e42023-05-13 17:45:02 +08006558 snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
6559 _syscmd(cmd, buf, sizeof(buf));
6560 if (strlen(buf) > 0) {
6561 fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf);
6562 return RETURN_ERR;
6563 }
6564 fitChainMask(radioIndex, numStreams);
developer72fb0bb2023-01-11 09:46:29 +08006565 wifi_setRadioEnable(radioIndex, TRUE);
6566
6567 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6568 return RETURN_OK;
6569}
6570
6571//P2 // outputs the number of Rx streams
6572INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
6573{
6574 char buf[8] = {0};
6575 char cmd[128] = {0};
6576 int phyId = 0;
6577
6578 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6579
6580 phyId = radio_index_to_phy(radioIndex);
6581 sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
6582 _syscmd(cmd, buf, sizeof(buf));
6583
6584 *output_int = (INT)strtol(buf, NULL, 16);
6585
6586 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6587
6588 return RETURN_OK;
6589}
6590
6591//P2 // sets the number of Rx streams to an enviornment variable
6592INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
6593{
6594 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6595 if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
6596 fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__);
6597 return RETURN_ERR;
6598 }
6599 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6600 return RETURN_ERR;
6601}
6602
6603//Get radio RDG enable setting
6604INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
6605{
developer47cc27a2023-05-17 23:09:58 +08006606 if (NULL == output_bool)
6607 return RETURN_ERR;
6608
6609 *output_bool = TRUE;
6610 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006611}
6612
6613//Get radio RDG enable setting
6614INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
6615{
developer47cc27a2023-05-17 23:09:58 +08006616 char cmd[MAX_CMD_SIZE] = {0};
6617 char buf[MAX_BUF_SIZE] = {0};
6618 char rdg_status[2] = {0};
6619 char dat_file[MAX_CMD_SIZE] = {0};
6620 struct params params = {0};
6621
6622 if (NULL == output_bool)
6623 return RETURN_ERR;
6624
6625 /*prepare dat file path*/
6626 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6627
6628 wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
6629 if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
6630 *output_bool = TRUE;
6631 else
6632 *output_bool = FALSE;
6633
6634 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006635}
6636
6637//Set radio RDG enable setting
6638INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
6639{
developer47cc27a2023-05-17 23:09:58 +08006640 char cmd[MAX_CMD_SIZE] = {0};
6641 char buf[MAX_BUF_SIZE] = {0};
6642 char dat_file[MAX_CMD_SIZE] = {0};
6643 struct params params = {0};
6644
6645 /*prepare dat file path*/
6646 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
6647
6648 params.name = "HT_RDG";
6649
6650 if (enable) {
6651 params.value = "1";
6652 } else {
6653 params.value = "0";
6654 }
6655
6656 wifi_datfileWrite(dat_file, &params, 1);
6657
6658 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006659}
6660
developer5cd4c862023-05-26 09:34:42 +08006661
6662int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006663{
developer5cd4c862023-05-26 09:34:42 +08006664 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6665 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6666 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6667 unsigned char status;
6668 unsigned char *out_status = data;
6669 int err = 0;
developer8e6583c2023-05-23 13:36:06 +08006670
developer5cd4c862023-05-26 09:34:42 +08006671 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6672 genlmsg_attrlen(gnlh, 0), NULL);
6673 if (err < 0){
6674 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6675 return err;
6676 }
developer8e6583c2023-05-23 13:36:06 +08006677
developer5cd4c862023-05-26 09:34:42 +08006678 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6679 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6680 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6681 if (err < 0){
6682 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6683 return err;
6684 }
developer8e6583c2023-05-23 13:36:06 +08006685
developer5cd4c862023-05-26 09:34:42 +08006686 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
6687 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
6688 if (status == 0) {
6689 wifi_debug(DEBUG_NOTICE, "disabled\n");
6690 } else {
6691 wifi_debug(DEBUG_NOTICE, "enabled\n");
6692 }
6693 *out_status = status;
6694 }
6695 }
developer8e6583c2023-05-23 13:36:06 +08006696
developer5cd4c862023-05-26 09:34:42 +08006697 return 0;
6698}
developer8e6583c2023-05-23 13:36:06 +08006699
developer5cd4c862023-05-26 09:34:42 +08006700int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
6701{
6702 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6703 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
6704 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6705 unsigned char status;
6706 unsigned char *out_status = data;
6707 int err = 0;
6708
6709 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6710 genlmsg_attrlen(gnlh, 0), NULL);
6711 if (err < 0) {
6712 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6713 return err;
6714 }
6715
6716 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6717 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
6718 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6719 if (err < 0) {
6720 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
6721 return err;
6722 }
6723
6724 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
6725 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
6726 if (status == 0) {
6727 wifi_debug(DEBUG_NOTICE, "disabled\n");
6728 } else {
6729 wifi_debug(DEBUG_NOTICE, "enabled\n");
6730 }
6731 *out_status = status;
6732 }
6733 }
6734
6735 return NL_OK;
developer72fb0bb2023-01-11 09:46:29 +08006736}
6737
developer5cd4c862023-05-26 09:34:42 +08006738INT mtk_wifi_get_ba_decl_auto_status(
6739 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
6740{
6741 char inf_name[IF_NAME_SIZE] = {0};
6742 struct mtk_nl80211_param params;
6743 unsigned int if_idx = 0;
6744 int ret = -1;
6745 struct unl unl_ins;
6746 struct nl_msg *msg = NULL;
6747 struct nlattr * msg_data = NULL;
6748 struct mtk_nl80211_param param;
6749
6750 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6751 return RETURN_ERR;
6752 if_idx = if_nametoindex(inf_name);
6753 if (!if_idx) {
6754 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6755 return RETURN_ERR;
6756 }
6757 /*init mtk nl80211 vendor cmd*/
6758 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
6759 param.if_type = NL80211_ATTR_IFINDEX;
6760 param.if_idx = if_idx;
6761
6762 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6763 if (ret) {
6764 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6765 return RETURN_ERR;
6766 }
6767 /*add mtk vendor cmd data*/
6768 if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
6769 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6770 nlmsg_free(msg);
6771 goto err;
6772 }
6773
6774 /*send mtk nl80211 vendor msg*/
6775 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6776 if (ret) {
6777 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6778 goto err;
6779 }
6780 /*deinit mtk nl80211 vendor msg*/
6781 mtk_nl80211_deint(&unl_ins);
6782 wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool);
6783 return RETURN_OK;
6784err:
6785 mtk_nl80211_deint(&unl_ins);
6786 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6787 return RETURN_ERR;
6788}
6789//Get radio ADDBA enable setting
6790INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
6791{
6792 if (output_bool == NULL) {
6793 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6794 return RETURN_ERR;
6795 }
6796 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6797 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
6798 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
6799 MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
6800 return RETURN_ERR;
6801 }
6802 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6803 return RETURN_OK;
6804}
6805
developer72fb0bb2023-01-11 09:46:29 +08006806//Set radio ADDBA enable setting
6807INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
6808{
6809 return RETURN_ERR;
6810}
6811
6812//Get radio auto block ack enable setting
6813INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
6814{
developer5cd4c862023-05-26 09:34:42 +08006815 if (output_bool == NULL) {
6816 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6817 return RETURN_ERR;
6818 }
developer8e6583c2023-05-23 13:36:06 +08006819
developer5cd4c862023-05-26 09:34:42 +08006820 if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
6821 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
6822 mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
6823 wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
6824 MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
6825 return RETURN_ERR;
6826 }
6827 wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
6828 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08006829}
6830
6831//Set radio auto block ack enable setting
6832INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
6833{
6834 return RETURN_ERR;
6835}
6836
6837//Get radio 11n pure mode enable support
6838INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
6839{
6840 if (NULL == output_bool)
6841 return RETURN_ERR;
6842 *output_bool = TRUE;
6843 return RETURN_OK;
6844}
6845
6846//Get radio 11n pure mode enable setting
6847INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
6848{
6849 if (NULL == output_bool)
6850 return RETURN_ERR;
6851 *output_bool = TRUE;
6852 return RETURN_OK;
6853}
6854
6855//Set radio 11n pure mode enable setting
6856INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
6857{
6858 return RETURN_ERR;
6859}
6860
developer5cd4c862023-05-26 09:34:42 +08006861
6862int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
developer72fb0bb2023-01-11 09:46:29 +08006863{
developer5cd4c862023-05-26 09:34:42 +08006864 struct nlattr *tb[NL80211_ATTR_MAX + 1];
6865 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
6866 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
6867 unsigned char status = 0, *out_status = data;
6868 int err = 0;
developer72fb0bb2023-01-11 09:46:29 +08006869
developer5cd4c862023-05-26 09:34:42 +08006870 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
6871 genlmsg_attrlen(gnlh, 0), NULL);
6872 if (err < 0) {
6873 wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
6874 return err;
6875 }
developer72fb0bb2023-01-11 09:46:29 +08006876
developer5cd4c862023-05-26 09:34:42 +08006877 if (tb[NL80211_ATTR_VENDOR_DATA]) {
6878 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
6879 tb[NL80211_ATTR_VENDOR_DATA], NULL);
6880 if (err < 0){
6881 wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
6882 return err;
6883 }
developer72fb0bb2023-01-11 09:46:29 +08006884
developer5cd4c862023-05-26 09:34:42 +08006885 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
6886 status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
6887 if (status == 0) {
6888 wifi_debug(DEBUG_NOTICE, "disabled\n");
6889 } else {
6890 wifi_debug(DEBUG_NOTICE, "enabled\n");
6891 }
6892 *out_status = status;
6893 wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
6894 }
6895 }
6896
6897 return 0;
6898}
6899
6900INT mtk_wifi_set_igmp_en_status(
6901 INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
6902 unsigned char in_en_stat, BOOL *output_bool)
6903{
6904 char inf_name[IF_NAME_SIZE] = {0};
6905 struct mtk_nl80211_param params;
6906 unsigned int if_idx = 0;
6907 int ret = -1;
6908 struct unl unl_ins;
6909 struct nl_msg *msg = NULL;
6910 struct nlattr * msg_data = NULL;
6911 struct mtk_nl80211_param param;
6912
6913 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
6914 return RETURN_ERR;
6915 if_idx = if_nametoindex(inf_name);
6916 if (!if_idx) {
6917 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
6918 return RETURN_ERR;
6919 }
6920 /*init mtk nl80211 vendor cmd*/
6921 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
6922 param.if_type = NL80211_ATTR_IFINDEX;
6923 param.if_idx = if_idx;
6924
6925 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
6926 if (ret) {
6927 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
6928 return RETURN_ERR;
6929 }
6930 /*add mtk vendor cmd data*/
6931 if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
6932 wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
6933 nlmsg_free(msg);
6934 goto err;
6935 }
6936
6937 /*send mtk nl80211 vendor msg*/
6938 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
6939 if (ret) {
6940 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
6941 goto err;
6942 }
6943 /*deinit mtk nl80211 vendor msg*/
6944 mtk_nl80211_deint(&unl_ins);
6945 if (output_bool) {
6946 wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
6947 } else {
6948 wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
6949 }
6950 return RETURN_OK;
6951err:
6952 mtk_nl80211_deint(&unl_ins);
6953 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
6954 return RETURN_ERR;
6955}
6956
6957
6958//Get radio IGMP snooping enable setting
6959INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
6960{
6961 if (output_bool == NULL) {
6962 wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
6963 return RETURN_ERR;
6964 }
6965 if (mtk_wifi_set_igmp_en_status
6966 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
6967 mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
6968 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
6969 return RETURN_ERR;
6970 }
6971 wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool);
developer72fb0bb2023-01-11 09:46:29 +08006972 return RETURN_OK;
6973}
6974
6975//Set radio IGMP snooping enable setting
6976INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
6977{
developer5cd4c862023-05-26 09:34:42 +08006978 if (mtk_wifi_set_igmp_en_status
6979 (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
6980 NULL, enable, NULL) != RETURN_OK) {
6981 wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
6982 return RETURN_ERR;
6983 }
6984 wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable);
developer72fb0bb2023-01-11 09:46:29 +08006985 return RETURN_OK;
6986}
6987
6988//Get the Reset count of radio
developer69b61b02023-03-07 17:17:44 +08006989INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
developer72fb0bb2023-01-11 09:46:29 +08006990{
developer69b61b02023-03-07 17:17:44 +08006991 if (NULL == output_int)
developer72fb0bb2023-01-11 09:46:29 +08006992 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +08006993 *output_int = get_radio_reset_cnt(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +08006994
6995 return RETURN_OK;
6996}
6997
6998
6999//---------------------------------------------------------------------------------------------------
7000//
7001// Additional Wifi AP level APIs used for Access Point devices
7002//
7003//---------------------------------------------------------------------------------------------------
7004
7005// creates a new ap and pushes these parameters to the hardware
7006INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
7007{
7008 // Deprecated when use hal version 3, use wifi_createVap() instead.
7009 return RETURN_OK;
7010}
7011
7012// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
7013INT wifi_deleteAp(INT apIndex)
7014{
developer7e4a2a62023-04-06 19:56:03 +08007015 char interface_name[16] = {0};
7016 char buf[MAX_BUF_SIZE];
7017 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08007018
developer7e4a2a62023-04-06 19:56:03 +08007019 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7020 return RETURN_ERR;
developer8a3bbbf2023-03-15 17:47:23 +08007021
developer7e4a2a62023-04-06 19:56:03 +08007022 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
7023 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007024
developer7e4a2a62023-04-06 19:56:03 +08007025 wifi_removeApSecVaribles(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007026
developer7e4a2a62023-04-06 19:56:03 +08007027 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007028}
7029
7030// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
7031INT wifi_getApName(INT apIndex, CHAR *output_string)
7032{
developer7e4a2a62023-04-06 19:56:03 +08007033 char interface_name[IF_NAME_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08007034 int radio_idx = 0;
7035 int bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08007036
developer7e4a2a62023-04-06 19:56:03 +08007037 if(!output_string)
7038 return RETURN_ERR;
7039
7040 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
7041 vap_index_to_array_index(apIndex, &radio_idx, &bss_idx);
7042
7043 snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model.
7044 } else
7045 snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
7046
7047 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007048}
7049
7050// Outputs the index number in that corresponds to the SSID string
7051INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
7052{
developer7e4a2a62023-04-06 19:56:03 +08007053 char cmd [128] = {0};
7054 char buf[32] = {0};
7055 char ap_idx = 0;
7056 char *apIndex_str = NULL;
7057 char radio_idx = 0;
7058 char bss_idx = 0;
developer72fb0bb2023-01-11 09:46:29 +08007059
developer7e4a2a62023-04-06 19:56:03 +08007060 snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'",
7061 inputSsidString);
7062 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007063
developer7e4a2a62023-04-06 19:56:03 +08007064 if (strlen(buf)) {
7065 apIndex_str = strtok(buf, "\n");
7066 *output_int = strtoul(apIndex_str, NULL, 10);
7067 return RETURN_OK;
7068 }
developer72fb0bb2023-01-11 09:46:29 +08007069
developer7e4a2a62023-04-06 19:56:03 +08007070 /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
7071 if (strstr(inputSsidString, PREFIX_WIFI6G)) {
7072 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
7073 radio_idx = 2;
7074 } else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
7075 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
7076 radio_idx = 1;
7077 } else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
7078 bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
7079 radio_idx = 0;
7080 } else {
7081 printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
7082 __func__, inputSsidString, ap_idx);
7083 *output_int = -1;
7084 return RETURN_ERR;
7085 }
7086
7087 ap_idx = array_index_to_vap_index(radio_idx, bss_idx);
7088
7089 if (ap_idx >= 0 && ap_idx < MAX_VAP) {
7090 printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n",
7091 __func__, inputSsidString, ap_idx);
7092 *output_int = ap_idx;
7093 return RETURN_OK;
7094 }
7095
7096 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007097}
7098
7099INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
7100{
7101 return wifi_getIndexFromName(inputSsidString, output_int);
7102}
7103
7104// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
7105INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
7106{
7107 char buf[MAX_BUF_SIZE] = {0};
7108 char cmd[MAX_CMD_SIZE] = {0};
7109 char config_file[MAX_BUF_SIZE] = {0};
7110
7111 if(NULL == output_string)
7112 return RETURN_ERR;
7113
7114 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7115 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
7116 if((strcmp(buf,"3")==0))
7117 snprintf(output_string, 32, "WPAand11i");
7118 else if((strcmp(buf,"2")==0))
7119 snprintf(output_string, 32, "11i");
7120 else if((strcmp(buf,"1")==0))
7121 snprintf(output_string, 32, "WPA");
7122 else
7123 snprintf(output_string, 32, "None");
7124
7125 return RETURN_OK;
7126}
7127
7128// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
7129INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
7130{
7131 char config_file[MAX_BUF_SIZE] = {0};
7132 struct params list;
7133
7134 if (NULL == beaconTypeString)
7135 return RETURN_ERR;
7136 list.name = "wpa";
7137 list.value = "0";
7138
7139 if((strcmp(beaconTypeString,"WPAand11i")==0))
7140 list.value="3";
7141 else if((strcmp(beaconTypeString,"11i")==0))
7142 list.value="2";
7143 else if((strcmp(beaconTypeString,"WPA")==0))
7144 list.value="1";
7145
7146 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7147 wifi_hostapdWrite(config_file, &list, 1);
7148 wifi_hostapdProcessUpdate(apIndex, &list, 1);
7149 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
7150 return RETURN_OK;
7151}
7152
7153// sets the beacon interval on the hardware for this AP
7154INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
7155{
7156 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7157 struct params params={'\0'};
7158 char buf[MAX_BUF_SIZE] = {'\0'};
7159 char config_file[MAX_BUF_SIZE] = {'\0'};
7160
7161 params.name = "beacon_int";
7162 snprintf(buf, sizeof(buf), "%u", beaconInterval);
7163 params.value = buf;
7164
7165 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7166 wifi_hostapdWrite(config_file, &params, 1);
developer69b61b02023-03-07 17:17:44 +08007167
developer72fb0bb2023-01-11 09:46:29 +08007168 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7169 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7170 return RETURN_OK;
7171}
7172
7173INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
7174{
7175 if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
7176 return RETURN_ERR;
7177 return RETURN_OK;
7178}
7179
7180// Get the packet size threshold supported.
7181INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
7182{
7183 //save config and apply instantly
7184 if (NULL == output_bool)
7185 return RETURN_ERR;
7186 *output_bool = TRUE;
7187 return RETURN_OK;
7188}
7189
7190// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
7191INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
7192{
developer72fb0bb2023-01-11 09:46:29 +08007193 char buf[16] = {0};
7194 char config_file[128] = {0};
7195 struct params param = {0};
7196
7197 if (threshold > 65535) {
7198 fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold);
7199 return RETURN_ERR;
7200 }
7201
developer23e71282023-01-18 10:25:19 +08007202 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007203 snprintf(buf, sizeof(buf), "%u", threshold);
7204 param.name = "rts_threshold";
7205 param.value = buf;
7206 wifi_hostapdWrite(config_file, &param, 1);
7207 wifi_hostapdProcessUpdate(apIndex, &param, 1);
7208 wifi_reloadAp(apIndex);
7209
7210 return RETURN_OK;
7211}
7212
7213// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7214INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
7215{
7216 if (NULL == output_string)
7217 return RETURN_ERR;
7218 snprintf(output_string, 32, "TKIPandAESEncryption");
7219 return RETURN_OK;
7220
7221}
7222
7223// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7224INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
7225{
7226 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7227 char *param_name = NULL;
7228 char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
7229
7230 if(NULL == output_string)
7231 return RETURN_ERR;
7232
7233 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7234 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
7235
7236 if(strcmp(buf,"0")==0)
7237 {
7238 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
7239 snprintf(output_string, 32, "None");
7240 return RETURN_OK;
7241 }
7242 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
7243 param_name = "rsn_pairwise";
7244 else if((strcmp(buf,"1")==0))
7245 param_name = "wpa_pairwise";
7246 else
7247 return RETURN_ERR;
7248 memset(output_string,'\0',32);
7249 wifi_hostapdRead(config_file,param_name,output_string,32);
7250 if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
7251 param_name = "wpa_pairwise";
7252 memset(output_string, '\0', 32);
7253 wifi_hostapdRead(config_file, param_name, output_string, 32);
7254 }
7255 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
7256
developere5750452023-05-15 16:46:42 +08007257 if(strcmp(output_string,"TKIP CCMP") == 0)
7258 strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption"));
7259 else if(strcmp(output_string,"TKIP") == 0)
developer72fb0bb2023-01-11 09:46:29 +08007260 strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption"));
7261 else if(strcmp(output_string,"CCMP") == 0)
7262 strncpy(output_string,"AESEncryption", strlen("AESEncryption"));
developer72fb0bb2023-01-11 09:46:29 +08007263
7264 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7265 return RETURN_OK;
7266}
7267
7268// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
7269INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
7270{
7271 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7272 struct params params={'\0'};
7273 char output_string[32];
7274 char config_file[MAX_BUF_SIZE] = {0};
7275
7276 memset(output_string,'\0',32);
developere5750452023-05-15 16:46:42 +08007277 wifi_getApBeaconType(apIndex,output_string);
developer72fb0bb2023-01-11 09:46:29 +08007278
7279 if(strcmp(encMode, "TKIPEncryption") == 0)
7280 params.value = "TKIP";
7281 else if(strcmp(encMode,"AESEncryption") == 0)
7282 params.value = "CCMP";
7283 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
7284 params.value = "TKIP CCMP";
7285
7286 if((strcmp(output_string,"WPAand11i")==0))
7287 {
7288 params.name = "wpa_pairwise";
7289 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7290 wifi_hostapdWrite(config_file, &params, 1);
7291 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7292
7293 params.name = "rsn_pairwise";
7294 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7295 wifi_hostapdWrite(config_file, &params, 1);
7296 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7297
7298 return RETURN_OK;
7299 }
7300 else if((strcmp(output_string,"11i")==0))
7301 {
7302 params.name = "rsn_pairwise";
7303 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7304 wifi_hostapdWrite(config_file, &params, 1);
7305 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7306 return RETURN_OK;
7307 }
7308 else if((strcmp(output_string,"WPA")==0))
7309 {
7310 params.name = "wpa_pairwise";
7311 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7312 wifi_hostapdWrite(config_file, &params, 1);
7313 wifi_hostapdProcessUpdate(apIndex, &params, 1);
7314 return RETURN_OK;
7315 }
7316
7317 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7318 return RETURN_OK;
7319}
7320
7321// deletes internal security varable settings for this ap
7322INT wifi_removeApSecVaribles(INT apIndex)
7323{
7324 //TODO: remove the entry in hostapd config file
7325 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name);
7326 //_syscmd(cmd, buf, sizeof(buf));
7327
7328 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name);
7329 //_syscmd(cmd, buf, sizeof(buf));
7330 return RETURN_ERR;
7331}
7332
7333// changes the hardware settings to disable encryption on this ap
7334INT wifi_disableApEncryption(INT apIndex)
7335{
7336 //Apply instantly
7337 return RETURN_ERR;
7338}
7339
7340// set the authorization mode on this ap
7341// mode mapping as: 1: open, 2: shared, 4:auto
7342INT wifi_setApAuthMode(INT apIndex, INT mode)
7343{
7344 struct params params={0};
7345 char config_file[64] = {0};
7346 int ret;
7347
7348 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
7349
7350 wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode);
7351 params.name = "auth_algs";
7352
developere5750452023-05-15 16:46:42 +08007353 if ((mode & 1 && mode & 2) || mode & 4)
developer72fb0bb2023-01-11 09:46:29 +08007354 params.value = "3";
7355 else if (mode & 2)
7356 params.value = "2";
7357 else if (mode & 1)
7358 params.value = "1";
7359 else
7360 params.value = "0";
7361
7362 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7363 wifi_hostapdWrite(config_file, &params, 1);
7364 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08007365 wifi_reloadAp(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08007366 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
7367
7368 return RETURN_OK;
7369}
7370
7371// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7372INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7373{
7374 //save to wifi config, and wait for wifi restart to apply
7375 struct params params={'\0'};
7376 char config_file[MAX_BUF_SIZE] = {0};
7377 int ret;
7378
7379 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7380 if(authMode == NULL)
7381 return RETURN_ERR;
7382
7383 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
7384 params.name = "wpa_key_mgmt";
7385
7386 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
7387 params.value = "WPA-PSK";
7388 else if(strcmp(authMode,"EAPAuthentication") == 0)
7389 params.value = "WPA-EAP";
7390 else if (strcmp(authMode, "SAEAuthentication") == 0)
7391 params.value = "SAE";
7392 else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
7393 params.value = "WPA-EAP-SUITE-B-192";
7394 else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
7395 params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
developer3086e2f2023-01-17 09:40:01 +08007396 else if (strcmp(authMode, "Enhanced_Open") == 0)
7397 params.value = "OWE";
developer72fb0bb2023-01-11 09:46:29 +08007398 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
7399 return RETURN_OK; //This is taken careof in beaconType
7400
7401 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7402 ret=wifi_hostapdWrite(config_file,&params,1);
7403 if(!ret)
7404 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
7405 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7406
7407 return ret;
7408}
7409
7410// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
7411INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
7412{
7413 //save to wifi config, and wait for wifi restart to apply
7414 char BeaconType[50] = {0};
7415 char config_file[MAX_BUF_SIZE] = {0};
7416
7417 *authMode = 0;
7418 wifi_getApBeaconType(apIndex,BeaconType);
7419 printf("%s____%s \n",__FUNCTION__,BeaconType);
7420
7421 if(strcmp(BeaconType,"None") == 0)
7422 strcpy(authMode,"None");
7423 else
7424 {
7425 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7426 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
7427 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
7428 if(strcmp(authMode,"WPA-PSK") == 0)
7429 strcpy(authMode,"SharedAuthentication");
7430 else if(strcmp(authMode,"WPA-EAP") == 0)
7431 strcpy(authMode,"EAPAuthentication");
7432 }
7433
7434 return RETURN_OK;
7435}
7436
7437// Outputs the number of stations associated per AP
7438INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
7439{
7440 char interface_name[16] = {0};
7441 char cmd[128]={0};
7442 char buf[128]={0};
7443 BOOL status = false;
7444
7445 if(apIndex > MAX_APS)
7446 return RETURN_ERR;
7447
7448 wifi_getApEnable(apIndex,&status);
7449 if (!status)
7450 return RETURN_OK;
7451
7452 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
7453 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7454 return RETURN_ERR;
7455 sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name);
7456 _syscmd(cmd, buf, sizeof(buf));
7457 sscanf(buf,"%lu", output_ulong);
7458
7459 return RETURN_OK;
7460}
7461
7462// manually removes any active wi-fi association with the device specified on this ap
7463INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
7464{
developer7e4a2a62023-04-06 19:56:03 +08007465 char inf_name[16] = {0};
7466 char cmd[MAX_CMD_SIZE] = {0};
7467 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007468
developer7e4a2a62023-04-06 19:56:03 +08007469 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +08007470 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007471
7472 snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
7473 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +08007474
7475 return RETURN_OK;
7476}
7477
7478// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
7479INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
7480{
developer7e4a2a62023-04-06 19:56:03 +08007481 int max_radio_num = 0;
7482
7483 if(NULL == output_int)
7484 return RETURN_ERR;
7485
7486 wifi_getMaxRadioNumber(&max_radio_num);
7487 *output_int = apIndex % max_radio_num;
7488
7489 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007490}
7491
7492// sets the radio index for the specific ap
7493INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
7494{
7495 //set to config only and wait for wifi reset to apply settings
7496 return RETURN_ERR;
7497}
7498
developer121a8e72023-05-22 09:19:39 +08007499
7500#define MAX_ACL_DUMP_LEN 4096
7501int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
7502{
7503 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7504 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
7505 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7506 char *show_str = NULL;
developer2edaf012023-05-24 14:24:53 +08007507 int err = 0;
developer121a8e72023-05-22 09:19:39 +08007508 unsigned short acl_result_len = 0;
7509 struct mtk_nl80211_cb_data *cb_data = cb;
developer121a8e72023-05-22 09:19:39 +08007510 if (!msg || !cb_data) {
developer2edaf012023-05-24 14:24:53 +08007511 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 +08007512 return NL_SKIP;
7513 }
developer121a8e72023-05-22 09:19:39 +08007514 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7515 genlmsg_attrlen(gnlh, 0), NULL);
7516 if (err < 0) {
developer2edaf012023-05-24 14:24:53 +08007517 wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
developer121a8e72023-05-22 09:19:39 +08007518 return NL_SKIP;
7519 }
developer121a8e72023-05-22 09:19:39 +08007520 if (tb[NL80211_ATTR_VENDOR_DATA]) {
7521 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
7522 tb[NL80211_ATTR_VENDOR_DATA], NULL);
7523 if (err < 0)
7524 return NL_SKIP;
7525 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
7526 acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7527 show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
7528 if (acl_result_len > MAX_ACL_DUMP_LEN) {
7529 wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
7530 return NL_SKIP;
7531 } else if (*(show_str + acl_result_len - 1) != '\0') {
7532 wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
7533 *(show_str + acl_result_len - 1) = '\0';
7534 }
7535 wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
developer2edaf012023-05-24 14:24:53 +08007536
7537 if (cb_data->out_len >= acl_result_len) {
7538 memset(cb_data->out_buf, 0, cb_data->out_len);
7539 /*skip the first line: 'policy=1\n' to find the acl mac addrs*/
7540 memmove(cb_data->out_buf, show_str, acl_result_len);
7541 wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
7542 } else {
7543 memset(cb_data->out_buf, 0, cb_data->out_len);
developer121a8e72023-05-22 09:19:39 +08007544 }
developer121a8e72023-05-22 09:19:39 +08007545 } else
7546 wifi_debug(DEBUG_ERROR, "no acl result attr\n");
7547 } else
7548 wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
7549 return NL_OK;
7550}
developer72fb0bb2023-01-11 09:46:29 +08007551// Get the ACL MAC list per AP
developer2edaf012023-05-24 14:24:53 +08007552INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
developer72fb0bb2023-01-11 09:46:29 +08007553{
developer7e4a2a62023-04-06 19:56:03 +08007554 char inf_name[IF_NAME_SIZE] = {0};
developer121a8e72023-05-22 09:19:39 +08007555 struct mtk_nl80211_param params;
7556 unsigned int if_idx = 0;
7557 int ret = -1;
7558 struct unl unl_ins;
7559 struct nl_msg *msg = NULL;
7560 struct nlattr * msg_data = NULL;
7561 struct mtk_nl80211_param param;
7562 struct mtk_nl80211_cb_data cb_data;
developer7e4a2a62023-04-06 19:56:03 +08007563 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7564 return RETURN_ERR;
developer121a8e72023-05-22 09:19:39 +08007565 if_idx = if_nametoindex(inf_name);
7566 if (!if_idx) {
developer2edaf012023-05-24 14:24:53 +08007567 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
developer121a8e72023-05-22 09:19:39 +08007568 return RETURN_ERR;
7569 }
7570 /*init mtk nl80211 vendor cmd*/
7571 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7572 param.if_type = NL80211_ATTR_IFINDEX;
7573 param.if_idx = if_idx;
7574
7575 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7576 if (ret) {
7577 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7578 return RETURN_ERR;
7579 }
developer121a8e72023-05-22 09:19:39 +08007580 /*add mtk vendor cmd data*/
7581 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
developer2edaf012023-05-24 14:24:53 +08007582 wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
developer121a8e72023-05-22 09:19:39 +08007583 nlmsg_free(msg);
7584 goto err;
7585 }
developer72fb0bb2023-01-11 09:46:29 +08007586
developer121a8e72023-05-22 09:19:39 +08007587 /*send mtk nl80211 vendor msg*/
7588 cb_data.out_buf = macArray;
7589 cb_data.out_len = buf_size;
7590
7591 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
7592 if (ret) {
7593 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7594 goto err;
7595 }
7596 /*deinit mtk nl80211 vendor msg*/
7597 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007598 wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
developer72fb0bb2023-01-11 09:46:29 +08007599 return RETURN_OK;
developer121a8e72023-05-22 09:19:39 +08007600err:
7601 mtk_nl80211_deint(&unl_ins);
developer2edaf012023-05-24 14:24:53 +08007602 wifi_debug(DEBUG_ERROR,"send cmd fails\n");
developer121a8e72023-05-22 09:19:39 +08007603 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007604}
7605
developer2edaf012023-05-24 14:24:53 +08007606INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7607{
7608 char *mac_arry_buf = NULL;
7609
7610 mac_arry_buf = malloc(buf_size);
7611 if (!mac_arry_buf) {
7612 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
7613 return RETURN_ERR;
7614 }
7615 memset(mac_arry_buf, 0, buf_size);
7616 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
7617 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
7618 free(mac_arry_buf);
7619 mac_arry_buf = NULL;
7620 return RETURN_ERR;
7621 }
7622 /*
7623 mtk format to wifi hal format:
7624 "policy=1
7625 00:11:22:33:44:55
7626 00:11:22:33:44:66
7627 "
7628 -->
7629 "00:11:22:33:44:55
7630 00:11:22:33:44:66
7631 "
7632 */
7633 memset(macArray, 0, buf_size);
7634 if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
7635 memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
7636 wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
7637 }
7638 free(mac_arry_buf);
7639 mac_arry_buf = NULL;
7640 return RETURN_OK;
7641}
7642
developer72fb0bb2023-01-11 09:46:29 +08007643INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
7644{
developer72fb0bb2023-01-11 09:46:29 +08007645
developer7e4a2a62023-04-06 19:56:03 +08007646 wifi_getApAclDevices(apIndex, macArray, buf_size);
developer72fb0bb2023-01-11 09:46:29 +08007647
7648 return RETURN_OK;
7649}
7650
7651
7652// Get the list of stations associated per AP
7653INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
7654{
developer7e4a2a62023-04-06 19:56:03 +08007655 char interface_name[IF_NAME_SIZE] = {0};
7656 char cmd[MAX_CMD_SIZE];
developer72fb0bb2023-01-11 09:46:29 +08007657
developer7e4a2a62023-04-06 19:56:03 +08007658 if(apIndex > 3) //Currently supporting apIndex upto 3
7659 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007660
developer7e4a2a62023-04-06 19:56:03 +08007661 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
7662 return RETURN_ERR;
7663
7664 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name);
7665 _syscmd(cmd, macArray, buf_size);
7666 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08007667}
7668
developer8dd72532023-05-17 19:58:35 +08007669int hex2num(char c)
7670{
7671 if (c >= '0' && c <= '9')
7672 return c - '0';
7673 if (c >= 'a' && c <= 'f')
7674 return c - 'a' + 10;
7675 if (c >= 'A' && c <= 'F')
7676 return c - 'A' + 10;
7677 return -1;
7678}
7679
7680/**
7681 * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
7682 * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
7683 * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
7684 * Returns: Characters used (> 0) on success, -1 on failure
7685 */
7686int hwaddr_aton2(const char *txt, unsigned char *addr)
7687{
7688 int i;
7689 const char *pos = txt;
7690
7691 for (i = 0; i < 6; i++) {
7692 int a, b;
7693
7694 while (*pos == ':' || *pos == '.' || *pos == '-')
7695 pos++;
7696
7697 a = hex2num(*pos++);
7698 if (a < 0)
7699 return -1;
7700 b = hex2num(*pos++);
7701 if (b < 0)
7702 return -1;
7703 *addr++ = (a << 4) | b;
7704 }
7705
7706 return pos - txt;
7707}
7708
developer72fb0bb2023-01-11 09:46:29 +08007709// adds the mac address to the filter list
7710//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7711INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7712{
developer7e4a2a62023-04-06 19:56:03 +08007713 char inf_name[IF_NAME_SIZE] = {0};
developer8dd72532023-05-17 19:58:35 +08007714 int if_idx, ret = 0;
developer49b17232023-05-19 16:35:19 +08007715 struct nl_msg *msg = NULL;
7716 struct nlattr * msg_data = NULL;
7717 struct mtk_nl80211_param param;
developer8dd72532023-05-17 19:58:35 +08007718 unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
7719 struct unl unl_ins;
developer7e4a2a62023-04-06 19:56:03 +08007720 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7721 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +08007722 if (!DeviceMacAddress)
7723 return RETURN_ERR;
developer8dd72532023-05-17 19:58:35 +08007724 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
developer2edaf012023-05-24 14:24:53 +08007725 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
developer8dd72532023-05-17 19:58:35 +08007726 return RETURN_ERR;
7727 }
developer8dd72532023-05-17 19:58:35 +08007728 if_idx = if_nametoindex(inf_name);
developer2edaf012023-05-24 14:24:53 +08007729 if (!if_idx) {
7730 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7731 return RETURN_ERR;
7732 }
developer49b17232023-05-19 16:35:19 +08007733 /*init mtk nl80211 vendor cmd*/
7734 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7735 param.if_type = NL80211_ATTR_IFINDEX;
7736 param.if_idx = if_idx;
7737 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7738 if (ret) {
7739 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007740 return RETURN_ERR;
7741 }
developer49b17232023-05-19 16:35:19 +08007742 /*add mtk vendor cmd data*/
7743 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
developer2edaf012023-05-24 14:24:53 +08007744 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
developer8dd72532023-05-17 19:58:35 +08007745 nlmsg_free(msg);
7746 goto err;
7747 }
developer49b17232023-05-19 16:35:19 +08007748 /*send mtk nl80211 vendor msg*/
7749 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7750 if (ret) {
7751 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
developer8dd72532023-05-17 19:58:35 +08007752 goto err;
7753 }
developer49b17232023-05-19 16:35:19 +08007754 /*deinit mtk nl80211 vendor msg*/
7755 mtk_nl80211_deint(&unl_ins);
7756 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer8dd72532023-05-17 19:58:35 +08007757 return RETURN_OK;
7758err:
developer49b17232023-05-19 16:35:19 +08007759 mtk_nl80211_deint(&unl_ins);
7760 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
developer8dd72532023-05-17 19:58:35 +08007761 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007762}
7763
7764// deletes the mac address from the filter list
7765//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
7766INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
7767{
developer2edaf012023-05-24 14:24:53 +08007768 struct unl unl_ins;
7769 int if_idx = 0, ret = 0;
7770 struct nl_msg *msg = NULL;
7771 struct nlattr * msg_data = NULL;
7772 struct mtk_nl80211_param param;
developer7e4a2a62023-04-06 19:56:03 +08007773 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007774 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007775
developer7e4a2a62023-04-06 19:56:03 +08007776 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7777 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007778
developer7e4a2a62023-04-06 19:56:03 +08007779 if (!DeviceMacAddress)
7780 return RETURN_ERR;
7781
developer2edaf012023-05-24 14:24:53 +08007782 if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
7783 wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
7784 return RETURN_ERR;
7785 }
developer72fb0bb2023-01-11 09:46:29 +08007786
developer2edaf012023-05-24 14:24:53 +08007787 if_idx = if_nametoindex(inf_name);
7788 if (!if_idx) {
7789 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7790 return RETURN_ERR;
7791 }
7792 /*init mtk nl80211 vendor cmd*/
7793 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7794 param.if_type = NL80211_ATTR_IFINDEX;
7795 param.if_idx = if_idx;
7796 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7797 if (ret) {
7798 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7799 return RETURN_ERR;
7800 }
7801 /*add mtk vendor cmd data*/
7802 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
7803 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7804 nlmsg_free(msg);
7805 goto err;
7806 }
7807 /*send mtk nl80211 vendor msg*/
7808 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7809 if (ret) {
7810 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7811 goto err;
7812 }
7813 /*deinit mtk nl80211 vendor msg*/
7814 mtk_nl80211_deint(&unl_ins);
7815 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
7816 return RETURN_OK;
7817err:
7818 mtk_nl80211_deint(&unl_ins);
7819 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7820 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007821}
7822
7823// outputs the number of devices in the filter list
7824INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
7825{
developer7e4a2a62023-04-06 19:56:03 +08007826 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +08007827 char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
7828 UINT buf_size = 1024;
7829 UINT sta_num = 0;
7830 unsigned char mac[ETH_ALEN] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007831 if(output_uint == NULL)
7832 return RETURN_ERR;
7833
developer2edaf012023-05-24 14:24:53 +08007834 mac_arry = (char *)malloc(buf_size);
7835 if (mac_arry == NULL) {
7836 wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
developer7e4a2a62023-04-06 19:56:03 +08007837 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007838 }
7839 memset(mac_arry, buf_size, 0);
7840 /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
7841 if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
7842 wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
7843 return RETURN_ERR;
7844 }
7845 /*count the acl str nums:*/
7846 wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
developer7e4a2a62023-04-06 19:56:03 +08007847
developer2edaf012023-05-24 14:24:53 +08007848 /*mac addr string format:
7849 exp1: 00:11:22:33:44:55\0
7850 exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
7851 */
7852 ptr = mac_arry;
7853 while (sscanf(ptr, "%17s", mac_str) == 1) {
7854 if (hwaddr_aton2(mac_str, mac) >= 0)
7855 sta_num++;
7856 ptr = strstr(ptr, mac_str) + strlen(mac_str);
7857 }
7858 *output_uint = sta_num;
7859 wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
7860 free(mac_arry);
7861 mac_arry = NULL;
developer7e4a2a62023-04-06 19:56:03 +08007862 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007863err:
7864 free(mac_arry);
7865 mac_arry = NULL;
7866 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007867}
7868
7869INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
7870{
7871 char cmd[128]={'\0'};
7872 char buf[128]={'\0'};
7873
7874 if(strcmp(action,"DENY")==0)
7875 {
7876 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
7877 system(buf);
7878 return RETURN_OK;
7879 }
7880
7881 if(strcmp(action,"ALLOW")==0)
7882 {
7883 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
7884 system(buf);
7885 return RETURN_OK;
7886 }
7887
7888 return RETURN_ERR;
7889
7890}
7891
7892// enable kick for devices on acl black list
7893INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
7894{
developer47cc27a2023-05-17 23:09:58 +08007895 char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
7896 char assocArray[MAX_BUF_SIZE] = {0}, *asso = NULL;
developer72fb0bb2023-01-11 09:46:29 +08007897
7898 wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
7899 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
7900
developer7e4a2a62023-04-06 19:56:03 +08007901 /* if there are no devices connected there is nothing to do */
developer72fb0bb2023-01-11 09:46:29 +08007902 if (strlen(assocArray) < 17)
7903 return RETURN_OK;
7904
developer7e4a2a62023-04-06 19:56:03 +08007905 if (enable == TRUE) {
7906 /* kick off the MAC which is in ACL array (deny list) */
7907 acl = strtok(aclArray, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007908 while (acl != NULL) {
7909 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
7910 wifi_kickApAssociatedDevice(apIndex, acl);
7911
developer7e4a2a62023-04-06 19:56:03 +08007912 acl = strtok(NULL, "\n");
developer72fb0bb2023-01-11 09:46:29 +08007913 }
7914 wifi_setApMacAddressControlMode(apIndex, 2);
developer7e4a2a62023-04-06 19:56:03 +08007915 } else
developer72fb0bb2023-01-11 09:46:29 +08007916 wifi_setApMacAddressControlMode(apIndex, 0);
developer72fb0bb2023-01-11 09:46:29 +08007917
developer72fb0bb2023-01-11 09:46:29 +08007918 return RETURN_OK;
7919}
7920
7921INT wifi_setPreferPrivateConnection(BOOL enable)
7922{
7923 return RETURN_OK;
7924}
7925
7926// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
7927INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
7928{
developer2edaf012023-05-24 14:24:53 +08007929 int if_idx = 0, ret = 0;
7930 struct unl unl_ins;
7931 struct nl_msg *msg = NULL;
7932 struct nlattr * msg_data = NULL;
7933 struct mtk_nl80211_param param;
7934 int acl_policy = -1;
developer7e4a2a62023-04-06 19:56:03 +08007935 char inf_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08007936
developer7e4a2a62023-04-06 19:56:03 +08007937 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
7938 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +08007939 if_idx = if_nametoindex(inf_name);
7940 if (!if_idx) {
7941 wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
7942 return RETURN_ERR;
7943 }
7944 /*init mtk nl80211 vendor cmd*/
7945 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
7946 param.if_type = NL80211_ATTR_IFINDEX;
7947 param.if_idx = if_idx;
7948 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
7949 if (ret) {
7950 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
7951 return RETURN_ERR;
7952 }
7953 /*add mtk vendor cmd data*/
7954 if (filterMode == 0) {
7955 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
7956 } else if (filterMode == 1) {
7957 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
7958 } else if (filterMode == 2) {
7959 acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
7960 } else {
7961 wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
7962 nlmsg_free(msg);
7963 goto err;
7964 }
7965 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
7966 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
7967 nlmsg_free(msg);
7968 goto err;
7969 }
7970 /*send mtk nl80211 vendor msg*/
7971 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
7972 if (ret) {
7973 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
7974 goto err;
7975 }
7976 /*deinit mtk nl80211 vendor msg*/
7977 mtk_nl80211_deint(&unl_ins);
7978 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
developer7e4a2a62023-04-06 19:56:03 +08007979 return RETURN_OK;
developer2edaf012023-05-24 14:24:53 +08007980err:
7981 mtk_nl80211_deint(&unl_ins);
7982 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
7983 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08007984}
7985
7986// 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.
7987INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
7988{
7989 return RETURN_ERR;
7990}
7991
7992// gets the vlan ID for this ap from an internal enviornment variable
7993INT wifi_getApVlanID(INT apIndex, INT *output_int)
7994{
7995 if(apIndex==0)
7996 {
7997 *output_int=100;
7998 return RETURN_OK;
7999 }
8000
8001 return RETURN_ERR;
8002}
8003
8004// sets the vlan ID for this ap to an internal enviornment variable
8005INT wifi_setApVlanID(INT apIndex, INT vlanId)
8006{
8007 //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)
8008 return RETURN_ERR;
8009}
8010
8011// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
8012INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
8013{
8014 snprintf(bridgeName, 32, "brlan0");
8015 snprintf(IP, 32, "10.0.0.1");
8016 snprintf(subnet, 32, "255.255.255.0");
8017
8018 return RETURN_OK;
8019}
8020
8021//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
8022INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
8023{
8024 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
8025 return RETURN_ERR;
8026}
8027
8028// reset the vlan configuration for this ap
8029INT wifi_resetApVlanCfg(INT apIndex)
8030{
developera1255e42023-05-13 17:45:02 +08008031 char interface_name[16] = {0};
developer2202b332023-05-24 16:23:22 +08008032 int if_idx, ret = 0;
8033 struct nl_msg *msg = NULL;
8034 struct nlattr * msg_data = NULL;
8035 struct mtk_nl80211_param param;
8036 struct unl unl_ins;
8037 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08008038
developer2202b332023-05-24 16:23:22 +08008039 if (apIndex > MAX_APS) {
8040 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8041 return RETURN_ERR;
8042 }
developer72fb0bb2023-01-11 09:46:29 +08008043
developer2202b332023-05-24 16:23:22 +08008044 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8045 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8046 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008047
developer2202b332023-05-24 16:23:22 +08008048 /*step 1. mwctl dev %s set vlan_tag 0*/
8049 if_idx = if_nametoindex(interface_name);
8050 /*init mtk nl80211 vendor cmd*/
8051 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
8052 param.if_type = NL80211_ATTR_IFINDEX;
8053 param.if_idx = if_idx;
8054 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
developer72fb0bb2023-01-11 09:46:29 +08008055
developer2202b332023-05-24 16:23:22 +08008056 if (ret) {
8057 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8058 return RETURN_ERR;
8059 }
developer72fb0bb2023-01-11 09:46:29 +08008060
developer2202b332023-05-24 16:23:22 +08008061 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
8062 printf("Nla put attribute error\n");
8063 nlmsg_free(msg);
8064 goto err;
8065 }
developer72fb0bb2023-01-11 09:46:29 +08008066
developer2202b332023-05-24 16:23:22 +08008067 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8068 if (ret) {
8069 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8070 goto err;
8071 }
8072 mtk_nl80211_deint(&unl_ins);
8073 wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n");
developer72fb0bb2023-01-11 09:46:29 +08008074
developer2202b332023-05-24 16:23:22 +08008075 /*step 2. mwctl dev %s set vlan_priority 0*/
8076 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8077 if (ret) {
8078 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8079 return RETURN_ERR;
8080 }
developer72fb0bb2023-01-11 09:46:29 +08008081
developer2202b332023-05-24 16:23:22 +08008082 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
8083 printf("Nla put attribute error\n");
8084 nlmsg_free(msg);
8085 goto err;
8086 }
developer72fb0bb2023-01-11 09:46:29 +08008087
developer2202b332023-05-24 16:23:22 +08008088 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8089 if (ret) {
8090 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8091 goto err;
8092 }
8093 mtk_nl80211_deint(&unl_ins);
8094 wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n");
8095
8096 /*step 3. mwctl dev %s set vlan_id 0*/
8097 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8098 if (ret) {
8099 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
developera1255e42023-05-13 17:45:02 +08008100 return RETURN_ERR;
developer2202b332023-05-24 16:23:22 +08008101 }
developer72fb0bb2023-01-11 09:46:29 +08008102
developer2202b332023-05-24 16:23:22 +08008103 if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
8104 printf("Nla put attribute error\n");
8105 nlmsg_free(msg);
8106 goto err;
8107 }
8108
8109 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8110 if (ret) {
8111 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8112 goto err;
8113 }
8114 mtk_nl80211_deint(&unl_ins);
8115 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
8116
8117 /*step 4. mwctl dev %s set vlan_en 0*/
8118 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8119 if (ret) {
8120 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8121 return RETURN_ERR;
8122 }
8123
8124 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
8125 printf("Nla put attribute error\n");
8126 nlmsg_free(msg);
8127 goto err;
8128 }
8129
8130 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8131 if (ret) {
8132 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8133 goto err;
8134 }
8135 mtk_nl80211_deint(&unl_ins);
8136 wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n");
8137
8138 /*step 5. mwctl dev %s set vlan_policy 0:4*/
8139 vlan_param.direction = 0;
8140 vlan_param.policy = 4;
8141 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8142 if (ret) {
8143 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8144 return RETURN_ERR;
8145 }
8146 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
8147 printf("Nla put attribute error\n");
8148 nlmsg_free(msg);
8149 goto err;
8150 }
8151
8152 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8153 if (ret) {
8154 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8155 goto err;
8156 }
8157 mtk_nl80211_deint(&unl_ins);
8158 wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n");
8159
8160 /*step 6. mwctl dev %s set vlan_policy 1:0*/
8161 vlan_param.direction = 1;
8162 vlan_param.policy = 0;
8163 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8164 if (ret) {
8165 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8166 return RETURN_ERR;
8167 }
8168
8169 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
8170 printf("Nla put attribute error\n");
8171 nlmsg_free(msg);
8172 goto err;
8173 }
8174
8175 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8176 if (ret) {
8177 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8178 goto err;
8179 }
8180 /*deinit mtk nl80211 vendor msg*/
8181 mtk_nl80211_deint(&unl_ins);
8182 wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n");
8183
8184 /*TODO need to modify VLAN config in dat file*/
8185 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8186
8187 return RETURN_OK;
8188err:
8189 mtk_nl80211_deint(&unl_ins);
8190 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8191 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008192}
8193
8194// 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.
8195INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
8196{
8197 return RETURN_ERR;
8198}
8199
8200// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
8201INT wifi_startHostApd()
8202{
8203 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8204 system("systemctl start hostapd.service");
8205 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8206 return RETURN_OK;
8207 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
8208}
8209
8210// stops hostapd
developer69b61b02023-03-07 17:17:44 +08008211INT wifi_stopHostApd()
developer72fb0bb2023-01-11 09:46:29 +08008212{
8213 char cmd[128] = {0};
8214 char buf[128] = {0};
8215
8216 sprintf(cmd,"systemctl stop hostapd");
8217 _syscmd(cmd, buf, sizeof(buf));
8218
8219 return RETURN_OK;
8220}
8221
8222// restart hostapd dummy function
8223INT wifi_restartHostApd()
8224{
8225 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8226 system("systemctl restart hostapd-global");
8227 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8228
8229 return RETURN_OK;
8230}
8231
8232static int align_hostapd_config(int index)
8233{
8234 ULONG lval;
8235 wifi_getRadioChannel(index%2, &lval);
8236 wifi_setRadioChannel(index%2, lval);
8237 return RETURN_OK;
8238}
8239
8240// sets the AP enable status variable for the specified ap.
8241INT wifi_setApEnable(INT apIndex, BOOL enable)
8242{
developer7e4a2a62023-04-06 19:56:03 +08008243 char interface_name[16] = {0};
8244 char config_file[MAX_BUF_SIZE] = {0};
8245 char cmd[MAX_CMD_SIZE] = {0};
8246 char buf[MAX_BUF_SIZE] = {0};
developer47cc27a2023-05-17 23:09:58 +08008247 BOOL status = FALSE;
developer7e4a2a62023-04-06 19:56:03 +08008248 int max_radio_num = 0;
8249 int phyId = 0;
developer72fb0bb2023-01-11 09:46:29 +08008250
developer7e4a2a62023-04-06 19:56:03 +08008251 wifi_getApEnable(apIndex, &status);
developer72fb0bb2023-01-11 09:46:29 +08008252
developer7e4a2a62023-04-06 19:56:03 +08008253 wifi_getMaxRadioNumber(&max_radio_num);
8254 if (enable == status)
8255 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008256
developer7e4a2a62023-04-06 19:56:03 +08008257 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8258 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008259
developer7e4a2a62023-04-06 19:56:03 +08008260 if (enable == TRUE) {
8261 int radioIndex = apIndex % max_radio_num;
8262 phyId = radio_index_to_phy(radioIndex);
developerf3c7d292023-05-29 17:57:16 +08008263 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name);
8264 _syscmd(cmd, buf, sizeof(buf));
developer8a3bbbf2023-03-15 17:47:23 +08008265
developer7e4a2a62023-04-06 19:56:03 +08008266 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
8267 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
8268 _syscmd(cmd, buf, sizeof(buf));
8269 } else {
8270 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
8271 _syscmd(cmd, buf, sizeof(buf));
developerf3c7d292023-05-29 17:57:16 +08008272 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name);
8273 _syscmd(cmd, buf, sizeof(buf));
developer7e4a2a62023-04-06 19:56:03 +08008274 }
8275 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
8276 interface_name, interface_name, enable, VAP_STATUS_FILE);
8277 _syscmd(cmd, buf, sizeof(buf));
8278 //Wait for wifi up/down to apply
8279 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008280}
8281
8282// Outputs the setting of the internal variable that is set by wifi_setApEnable().
8283INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
8284{
developer7e4a2a62023-04-06 19:56:03 +08008285 char interface_name[IF_NAME_SIZE] = {0};
8286 char cmd[MAX_CMD_SIZE] = {0};
8287 char buf[MAX_BUF_SIZE] = {0};
developere740c2a2023-05-23 18:34:32 +08008288 int ret;
developer72fb0bb2023-01-11 09:46:29 +08008289
developer7e4a2a62023-04-06 19:56:03 +08008290 if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
8291 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008292
developer7e4a2a62023-04-06 19:56:03 +08008293 *output_bool = 0;
developer72fb0bb2023-01-11 09:46:29 +08008294
developer7e4a2a62023-04-06 19:56:03 +08008295 if ((apIndex >= 0) && (apIndex < MAX_APS)) {
8296 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
8297 *output_bool = FALSE;
8298 return RETURN_OK;
8299 }
developere740c2a2023-05-23 18:34:32 +08008300 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status", interface_name);
8301 ret = system(cmd);
8302 if (ret == 0)
8303 *output_bool = 1;
developer7e4a2a62023-04-06 19:56:03 +08008304 }
developer72fb0bb2023-01-11 09:46:29 +08008305
developer7e4a2a62023-04-06 19:56:03 +08008306 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008307}
8308
developer69b61b02023-03-07 17:17:44 +08008309// Outputs the AP "Enabled" "Disabled" status from driver
8310INT wifi_getApStatus(INT apIndex, CHAR *output_string)
developer72fb0bb2023-01-11 09:46:29 +08008311{
developer7e4a2a62023-04-06 19:56:03 +08008312 char cmd[128] = {0};
8313 char buf[128] = {0};
8314 BOOL output_bool;
developer72fb0bb2023-01-11 09:46:29 +08008315
developer7e4a2a62023-04-06 19:56:03 +08008316 if (!output_string) {
8317 printf("%s: null pointer!", __func__);
8318 return RETURN_ERR;
8319 }
developer72fb0bb2023-01-11 09:46:29 +08008320
developer7e4a2a62023-04-06 19:56:03 +08008321 wifi_getApEnable(apIndex, &output_bool);
developer72fb0bb2023-01-11 09:46:29 +08008322
developer7e4a2a62023-04-06 19:56:03 +08008323 if(output_bool == 1)
8324 snprintf(output_string, 32, "Up");
8325 else
8326 snprintf(output_string, 32, "Disable");
8327
8328 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008329}
8330
8331//Indicates whether or not beacons include the SSID name.
8332// outputs a 1 if SSID on the AP is enabled, else outputs 0
8333INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
8334{
8335 //get the running status
8336 char config_file[MAX_BUF_SIZE] = {0};
8337 char buf[16] = {0};
8338
8339 if (!output)
8340 return RETURN_ERR;
8341
8342 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8343 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
8344 // default is enable
8345 if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
8346 *output = TRUE;
8347
8348 return RETURN_OK;
8349}
8350
8351// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
8352INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
8353{
8354 //store the config, apply instantly
8355 char config_file[MAX_BUF_SIZE] = {0};
8356 struct params list;
8357
8358 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8359 list.name = "ignore_broadcast_ssid";
8360 list.value = enable?"0":"1";
8361
8362 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8363 wifi_hostapdWrite(config_file, &list, 1);
8364 wifi_hostapdProcessUpdate(apIndex, &list, 1);
8365 //TODO: call hostapd_cli for dynamic_config_control
8366 wifi_reloadAp(apIndex);
8367 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8368
8369 return RETURN_OK;
8370}
8371
8372//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
8373INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
8374{
developer47cc27a2023-05-17 23:09:58 +08008375 /* get the running status */
8376 if(!output_uint)
8377 return RETURN_ERR;
8378
8379 *output_uint = 15;
8380 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +08008381}
8382
developer47cc27a2023-05-17 23:09:58 +08008383/*Do not support AP retry limit fix*/
developer72fb0bb2023-01-11 09:46:29 +08008384INT wifi_setApRetryLimit(INT apIndex, UINT number)
8385{
developer47cc27a2023-05-17 23:09:58 +08008386 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008387}
8388
developer95c045d2023-05-24 19:26:28 +08008389int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
8390{
8391 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8392 struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
8393 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8394 unsigned char *status = (unsigned char * *)data;
8395 int err = 0;
8396 //u16 acl_result_len = 0;
8397
8398 err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
8399 genlmsg_attrlen(gnlh, 0), NULL);
8400 if (err < 0)
8401 return err;
8402
8403 if (tb[NL80211_ATTR_VENDOR_DATA]) {
8404 err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
8405 tb[NL80211_ATTR_VENDOR_DATA], NULL);
8406 if (err < 0)
8407 return err;
8408
8409 if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
8410 //acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
8411 *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
8412 }
8413 }
8414
8415 return 0;
8416}
8417
developer72fb0bb2023-01-11 09:46:29 +08008418//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
8419INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
8420{
developer95c045d2023-05-24 19:26:28 +08008421 int if_idx, ret = 0;
developer8e6583c2023-05-23 13:36:06 +08008422 char interface_name[16] = {0};
developer95c045d2023-05-24 19:26:28 +08008423 unsigned char status = 0;
8424 struct nl_msg *msg = NULL;
8425 struct nlattr * msg_data = NULL;
8426 struct mtk_nl80211_param param;
8427 struct unl unl_ins;
8428 struct vlan_policy_param vlan_param;
developer8e6583c2023-05-23 13:36:06 +08008429
8430 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008431 if(!output)
8432 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008433
developer95c045d2023-05-24 19:26:28 +08008434 if (apIndex > MAX_APS) {
8435 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8436 return RETURN_ERR;
8437 }
8438
developer8e6583c2023-05-23 13:36:06 +08008439 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8440 return RETURN_ERR;
developer95c045d2023-05-24 19:26:28 +08008441
8442 if_idx = if_nametoindex(interface_name);
8443 /*init mtk nl80211 vendor cmd*/
8444 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8445 param.if_type = NL80211_ATTR_IFINDEX;
8446 param.if_idx = if_idx;
8447 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8448
8449 if (ret) {
8450 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8451 return RETURN_ERR;
8452 }
8453
8454 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
8455 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8456 nlmsg_free(msg);
8457 goto err;
8458 }
8459
8460 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
8461 (void *)&status);
8462 if (ret) {
8463 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8464 goto err;
8465 }
8466 mtk_nl80211_deint(&unl_ins);
8467
8468 *output = status == 0 ? FALSE : TRUE;
8469 wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
developer8e6583c2023-05-23 13:36:06 +08008470
8471 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008472 return RETURN_OK;
developer95c045d2023-05-24 19:26:28 +08008473err:
8474 mtk_nl80211_deint(&unl_ins);
8475 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8476 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008477}
8478
8479//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
8480INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
8481{
8482 //get the running status from driver
8483 char cmd[128] = {0};
8484 char buf[128] = {0};
8485 int max_radio_num = 0, radioIndex = 0;
8486 int phyId = 0;
8487
8488 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8489
8490 wifi_getMaxRadioNumber(&max_radio_num);
8491 radioIndex = apIndex % max_radio_num;
8492 phyId = radio_index_to_phy(radioIndex);
8493 snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId);
8494 _syscmd(cmd,buf, sizeof(buf));
8495
8496 if (strlen(buf) > 0)
8497 *output = true;
8498
8499 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8500
8501 return RETURN_OK;
8502}
8503
8504//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
8505INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
8506{
developer95c045d2023-05-24 19:26:28 +08008507 return wifi_getApWMMCapability(apIndex, output);
developer72fb0bb2023-01-11 09:46:29 +08008508}
8509
8510// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
8511INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
8512{
developer95c045d2023-05-24 19:26:28 +08008513 int if_idx, ret = 0;
8514 char interface_name[16] = {0};
8515 unsigned char status = 0;
8516 struct nl_msg *msg = NULL;
8517 struct nlattr * msg_data = NULL;
8518 struct mtk_nl80211_param param;
8519 struct unl unl_ins;
8520 struct vlan_policy_param vlan_param;
developer72fb0bb2023-01-11 09:46:29 +08008521
developer95c045d2023-05-24 19:26:28 +08008522 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08008523
developer95c045d2023-05-24 19:26:28 +08008524 if (apIndex > MAX_APS) {
8525 wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
8526 return RETURN_ERR;
8527 }
developer72fb0bb2023-01-11 09:46:29 +08008528
developer95c045d2023-05-24 19:26:28 +08008529 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8530 return RETURN_ERR;
developer8e6583c2023-05-23 13:36:06 +08008531
developer95c045d2023-05-24 19:26:28 +08008532 if_idx = if_nametoindex(interface_name);
8533 /*init mtk nl80211 vendor cmd*/
8534 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
8535 param.if_type = NL80211_ATTR_IFINDEX;
8536 param.if_idx = if_idx;
8537 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
8538
8539 if (ret) {
8540 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
8541 return RETURN_ERR;
8542 }
8543
8544 if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
8545 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
8546 nlmsg_free(msg);
8547 goto err;
8548 }
8549
8550 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
8551 if (ret) {
8552 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
8553 goto err;
8554 }
8555 mtk_nl80211_deint(&unl_ins);
8556
8557 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8558 return RETURN_OK;
8559err:
8560 mtk_nl80211_deint(&unl_ins);
8561 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
8562 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +08008563}
8564
developer95c045d2023-05-24 19:26:28 +08008565
developer72fb0bb2023-01-11 09:46:29 +08008566//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.
8567INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
8568{
8569 //get the running status from driver
8570 if(!output)
8571 return RETURN_ERR;
8572
8573 char config_file[128] = {0};
8574 char buf[16] = {0};
8575
8576 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8577 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
8578 if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
8579 *output = TRUE;
8580 else
8581 *output = FALSE;
8582
8583 return RETURN_OK;
8584}
8585
8586// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
8587INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
8588{
8589 //save config and apply instantly.
8590 char config_file[MAX_BUF_SIZE] = {0};
8591 struct params list;
8592
8593 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8594 list.name = "uapsd_advertisement_enabled";
8595 list.value = enable?"1":"0";
8596
8597 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8598 wifi_hostapdWrite(config_file, &list, 1);
8599 wifi_hostapdProcessUpdate(apIndex, &list, 1);
developere82c0ca2023-05-10 16:25:35 +08008600 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +08008601 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8602
8603 return RETURN_OK;
8604}
8605
8606// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
8607INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
8608{
8609 char interface_name[16] = {0};
8610 // assume class 0->BE, 1->BK, 2->VI, 3->VO
8611 char cmd[128] = {0};
8612 char buf[128] = {0};
8613 char ack_filepath[128] = {0};
8614 uint16_t bitmap = 0;
8615 uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
8616 FILE *f = NULL;
8617
8618 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
8619
8620 // Get current setting
8621 snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
8622 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath);
8623 _syscmd(cmd, buf, sizeof(buf));
8624 if (strlen(buf) > 0)
8625 bitmap = strtoul(buf, NULL, 10);
8626
8627 bitmap = strtoul(buf, NULL, 10);
8628
8629 if (ackPolicy == TRUE) { // True, unset this class
8630 bitmap &= ~class_map[class];
8631 } else { // False, set this class
8632 bitmap |= class_map[class];
8633 }
8634
8635 f = fopen(ack_filepath, "w");
8636 if (f == NULL) {
8637 fprintf(stderr, "%s: fopen failed\n", __func__);
8638 return RETURN_ERR;
8639 }
8640 fprintf(f, "%hu", bitmap);
8641 fclose(f);
8642
8643 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
8644 return RETURN_ERR;
8645 snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
8646 _syscmd(cmd, buf, sizeof(buf));
8647
8648 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
8649 return RETURN_OK;
8650}
8651
8652//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.
8653INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
8654{
8655 //get the running status from driver
8656 if(!output_uint)
8657 return RETURN_ERR;
8658
8659 char output[16]={'\0'};
8660 char config_file[MAX_BUF_SIZE] = {0};
8661
8662 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8663 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
8664 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
8665 else {
8666 int device_num = atoi(output);
8667 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
8668 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
8669 return RETURN_ERR;
8670 }
8671 else {
8672 *output_uint = device_num;
8673 }
8674 }
8675
8676 return RETURN_OK;
8677}
8678
8679INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
8680{
8681 //store to wifi config, apply instantly
8682 char str[MAX_BUF_SIZE]={'\0'};
8683 char cmd[MAX_CMD_SIZE]={'\0'};
8684 struct params params;
8685 char config_file[MAX_BUF_SIZE] = {0};
8686
8687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8688 if (number > MAX_ASSOCIATED_STA_NUM) {
8689 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
8690 return RETURN_ERR;
8691 }
8692 sprintf(str, "%d", number);
8693 params.name = "max_num_sta";
8694 params.value = str;
8695
8696 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
8697 int ret = wifi_hostapdWrite(config_file, &params, 1);
8698 if (ret) {
8699 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
8700 ,__func__, ret);
8701 }
8702
8703 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
8704 if (ret) {
8705 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
8706 ,__func__, ret);
8707 }
8708 wifi_reloadAp(apIndex);
8709 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8710
8711 return RETURN_OK;
8712}
8713
8714//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.
8715INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
8716{
8717 //get the current threshold
8718 if(!output_uint)
8719 return RETURN_ERR;
8720 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
8721 if (*output_uint == 0)
8722 *output_uint = 50;
8723 return RETURN_OK;
8724}
8725
8726INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
8727{
8728 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
8729 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
8730 return RETURN_OK;
8731 return RETURN_ERR;
8732}
8733
8734//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.
8735INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
8736{
8737 if(!output_uint)
8738 return RETURN_ERR;
8739 *output_uint = 3;
8740 return RETURN_OK;
8741}
8742
8743//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
8744INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
8745{
8746 if(!output_uint)
8747 return RETURN_ERR;
8748 *output_uint = 3;
8749 return RETURN_OK;
8750}
8751
8752//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.
8753INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
8754{
8755 if(!output_in_seconds)
8756 return RETURN_ERR;
8757 *output_in_seconds = 0;
8758 return RETURN_OK;
8759}
8760
8761//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
8762INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
8763{
8764 if(!output || apIndex>=MAX_APS)
8765 return RETURN_ERR;
8766 //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
8767 snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise");
8768 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008769}
developer72fb0bb2023-01-11 09:46:29 +08008770
8771//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
8772INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
8773{
8774 char config_file[128] = {0};
8775 char wpa[16] = {0};
8776 char key_mgmt[64] = {0};
8777 char buf[16] = {0};
8778 if (!output)
8779 return RETURN_ERR;
8780
8781 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
8782 wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
8783
8784 strcpy(output, "None");//Copying "None" to output string for default case
8785 wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
8786 if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
8787 if (!strcmp(wpa, "1"))
8788 snprintf(output, 32, "WPA-Personal");
8789 else if (!strcmp(wpa, "2"))
8790 snprintf(output, 32, "WPA2-Personal");
8791 else if (!strcmp(wpa, "3"))
8792 snprintf(output, 32, "WPA-WPA2-Personal");
8793
developere5750452023-05-15 16:46:42 +08008794 } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
8795 snprintf(output, 32, "WPA3-Enterprise");
developer72fb0bb2023-01-11 09:46:29 +08008796 } else if (strstr(key_mgmt, "WPA-EAP")) {
8797 if (!strcmp(wpa, "1"))
8798 snprintf(output, 32, "WPA-Enterprise");
8799 else if (!strcmp(wpa, "2"))
8800 snprintf(output, 32, "WPA2-Enterprise");
8801 else if (!strcmp(wpa, "3"))
8802 snprintf(output, 32, "WPA-WPA2-Enterprise");
8803 } else if (strstr(key_mgmt, "SAE")) {
8804 if (strstr(key_mgmt, "WPA-PSK") == NULL)
8805 snprintf(output, 32, "WPA3-Personal");
8806 else
8807 snprintf(output, 32, "WPA3-Personal-Transition");
developer72fb0bb2023-01-11 09:46:29 +08008808 }
8809
8810 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
8811 return RETURN_OK;
8812#if 0
8813 //TODO: need to revisit below implementation
8814 char securityType[32], authMode[32];
8815 int enterpriseMode=0;
8816
8817 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8818 if(!output)
8819 return RETURN_ERR;
8820
8821 wifi_getApBeaconType(apIndex, securityType);
8822 strcpy(output,"None");//By default, copying "None" to output string
8823 if (strncmp(securityType,"None", strlen("None")) == 0)
8824 return RETURN_OK;
8825
8826 wifi_getApBasicAuthenticationMode(apIndex, authMode);
8827 enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0;
8828
8829 if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0)
8830 snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal");
8831 else if (strncmp(securityType, "WPA", strlen("WPA")) == 0)
8832 snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal");
8833 else if (strncmp(securityType, "11i", strlen("11i")) == 0)
8834 snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal");
8835 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8836
8837 return RETURN_OK;
8838#endif
8839}
developer69b61b02023-03-07 17:17:44 +08008840
developer72fb0bb2023-01-11 09:46:29 +08008841INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
8842{
8843 char securityType[32];
8844 char authMode[32];
8845
8846 //store settings and wait for wifi up to apply
8847 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8848 if(!encMode)
8849 return RETURN_ERR;
8850
8851 if (strcmp(encMode, "None")==0)
8852 {
8853 strcpy(securityType,"None");
8854 strcpy(authMode,"None");
8855 }
8856 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
8857 {
8858 strcpy(securityType,"WPAand11i");
8859 strcpy(authMode,"PSKAuthentication");
8860 }
8861 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
8862 {
8863 strcpy(securityType,"WPAand11i");
8864 strcpy(authMode,"EAPAuthentication");
8865 }
8866 else if (strcmp(encMode, "WPA-Personal")==0)
8867 {
8868 strcpy(securityType,"WPA");
8869 strcpy(authMode,"PSKAuthentication");
8870 }
8871 else if (strcmp(encMode, "WPA-Enterprise")==0)
8872 {
8873 strcpy(securityType,"WPA");
8874 strcpy(authMode,"EAPAuthentication");
8875 }
8876 else if (strcmp(encMode, "WPA2-Personal")==0)
8877 {
8878 strcpy(securityType,"11i");
8879 strcpy(authMode,"PSKAuthentication");
8880 }
8881 else if (strcmp(encMode, "WPA2-Enterprise")==0)
8882 {
8883 strcpy(securityType,"11i");
8884 strcpy(authMode,"EAPAuthentication");
8885 }
8886 else if (strcmp(encMode, "WPA3-Personal") == 0)
8887 {
8888 strcpy(securityType,"11i");
8889 strcpy(authMode,"SAEAuthentication");
8890 }
8891 else if (strcmp(encMode, "WPA3-Personal-Transition") == 0)
8892 {
8893 strcpy(securityType, "11i");
8894 strcpy(authMode, "PSK-SAEAuthentication");
8895 }
8896 else if (strcmp(encMode, "WPA3-Enterprise") == 0)
8897 {
8898 strcpy(securityType,"11i");
8899 strcpy(authMode,"EAP_192-bit_Authentication");
8900 }
developer3086e2f2023-01-17 09:40:01 +08008901 else if (strcmp(encMode, "OWE") == 0)
8902 {
8903 strcpy(securityType,"11i");
8904 strcpy(authMode,"Enhanced_Open");
8905 }
developer72fb0bb2023-01-11 09:46:29 +08008906 else
8907 {
8908 strcpy(securityType,"None");
8909 strcpy(authMode,"None");
8910 }
8911 wifi_setApBeaconType(apIndex, securityType);
8912 wifi_setApBasicAuthenticationMode(apIndex, authMode);
8913 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8914
8915 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08008916}
developer72fb0bb2023-01-11 09:46:29 +08008917
8918
8919//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
8920// output_string must be pre-allocated as 64 character string by caller
8921// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8922INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
8923{
8924 char buf[16] = {0};
8925 char config_file[MAX_BUF_SIZE] = {0};
8926
8927 if(output_string==NULL)
8928 return RETURN_ERR;
8929
8930 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8931 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8932
8933 if(strcmp(buf,"0")==0)
8934 {
8935 printf("wpa_mode is %s ......... \n",buf);
8936 return RETURN_ERR;
8937 }
8938
8939 wifi_dbg_printf("\nFunc=%s\n",__func__);
8940 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
developere5750452023-05-15 16:46:42 +08008941 wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
developer72fb0bb2023-01-11 09:46:29 +08008942 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8943
8944 return RETURN_OK;
8945}
8946
8947// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
8948// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
8949INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
8950{
8951 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
8952 struct params params={'\0'};
8953 int ret;
8954 char config_file[MAX_BUF_SIZE] = {0};
8955
8956 if(NULL == preSharedKey)
8957 return RETURN_ERR;
8958
developere5750452023-05-15 16:46:42 +08008959 params.name = "wpa_psk";
developer72fb0bb2023-01-11 09:46:29 +08008960
developere5750452023-05-15 16:46:42 +08008961 if(strlen(preSharedKey) != 64)
developer72fb0bb2023-01-11 09:46:29 +08008962 {
developere5750452023-05-15 16:46:42 +08008963 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
developer72fb0bb2023-01-11 09:46:29 +08008964 return RETURN_ERR;
8965 }
8966 params.value = preSharedKey;
8967 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8968 ret = wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +08008969 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08008970 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08008971 wifi_reloadAp(apIndex);
8972 }
developer72fb0bb2023-01-11 09:46:29 +08008973 return ret;
8974 //TODO: call hostapd_cli for dynamic_config_control
8975}
8976
8977//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
8978// outputs the passphrase, maximum 63 characters
8979INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
8980{
8981 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
8982
8983 wifi_dbg_printf("\nFunc=%s\n",__func__);
8984 if (NULL == output_string)
8985 return RETURN_ERR;
8986
8987 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
8988 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
8989 if(strcmp(buf,"0")==0)
8990 {
8991 printf("wpa_mode is %s ......... \n",buf);
8992 return RETURN_ERR;
8993 }
8994
8995 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
8996 wifi_dbg_printf("\noutput_string=%s\n",output_string);
8997
8998 return RETURN_OK;
8999}
9000
9001// sets the passphrase enviornment variable, max 63 characters
9002INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
9003{
9004 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
9005 struct params params={'\0'};
9006 char config_file[MAX_BUF_SIZE] = {0};
9007 int ret;
9008
9009 if(NULL == passPhrase)
9010 return RETURN_ERR;
9011
9012 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
9013 {
9014 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
9015 return RETURN_ERR;
9016 }
9017 params.name = "wpa_passphrase";
9018 params.value = passPhrase;
9019 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
9020 ret=wifi_hostapdWrite(config_file,&params,1);
developere5750452023-05-15 16:46:42 +08009021 if(!ret) {
developer72fb0bb2023-01-11 09:46:29 +08009022 wifi_hostapdProcessUpdate(apIndex, &params, 1);
developere5750452023-05-15 16:46:42 +08009023 wifi_reloadAp(apIndex);
9024 }
developer72fb0bb2023-01-11 09:46:29 +08009025
9026 return ret;
9027}
9028
9029//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.
9030INT wifi_setApSecurityReset(INT apIndex)
9031{
9032 char original_config_file[64] = {0};
9033 char current_config_file[64] = {0};
9034 char buf[64] = {0};
9035 char cmd[64] = {0};
9036 char wpa[4] = {0};
9037 char wpa_psk[64] = {0};
9038 char wpa_passphrase[64] = {0};
9039 char wpa_psk_file[128] = {0};
9040 char wpa_key_mgmt[64] = {0};
9041 char wpa_pairwise[32] = {0};
9042 wifi_band band;
9043 struct params list[6];
9044
9045 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9046
9047 band = wifi_index_to_band(apIndex);
9048 if (band == band_2_4)
9049 sprintf(original_config_file, "/etc/hostapd-2G.conf");
9050 else if (band == band_5)
9051 sprintf(original_config_file, "/etc/hostapd-5G.conf");
9052 else if (band == band_6)
9053 sprintf(original_config_file, "/etc/hostapd-6G.conf");
9054 else
9055 return RETURN_ERR;
9056
9057 wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
9058 list[0].name = "wpa";
9059 list[0].value = wpa;
developer69b61b02023-03-07 17:17:44 +08009060
developer72fb0bb2023-01-11 09:46:29 +08009061 wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
9062 list[1].name = "wpa_psk";
9063 list[1].value = wpa_psk;
9064
9065 wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
9066 list[2].name = "wpa_passphrase";
9067 list[2].value = wpa_passphrase;
9068
9069 wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
9070
9071 if (strlen(wpa_psk_file) == 0)
9072 strcpy(wpa_psk_file, PSK_FILE);
9073
9074 if (access(wpa_psk_file, F_OK) != 0) {
9075 sprintf(cmd, "touch %s", wpa_psk_file);
9076 _syscmd(cmd, buf, sizeof(buf));
9077 }
9078 list[3].name = "wpa_psk_file";
9079 list[3].value = wpa_psk_file;
9080
9081 wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
9082 list[4].name = "wpa_key_mgmt";
9083 list[4].value = wpa_key_mgmt;
9084
9085 wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
9086 list[5].name = "wpa_pairwise";
9087 list[5].value = wpa_pairwise;
9088
9089 sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
9090 wifi_hostapdWrite(current_config_file, list, 6);
9091
9092 wifi_setApEnable(apIndex, FALSE);
9093 wifi_setApEnable(apIndex, TRUE);
9094
9095 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9096 return RETURN_OK;
9097}
9098
9099//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).
9100INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
9101{
9102 char config_file[64] = {0};
9103 char buf[64] = {0};
9104 char cmd[256] = {0};
9105
9106 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9107
9108 if(!IP_output || !Port_output || !RadiusSecret_output)
9109 return RETURN_ERR;
9110
9111 // Read the first matched config
9112 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9113 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9114 _syscmd(cmd, buf, sizeof(buf));
9115 strncpy(IP_output, buf, 64);
9116
9117 memset(buf, 0, sizeof(buf));
9118 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9119 _syscmd(cmd, buf, sizeof(buf));
9120 *Port_output = atoi(buf);
9121
9122 memset(buf, 0, sizeof(buf));
9123 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
9124 _syscmd(cmd, buf, sizeof(buf));
9125 strncpy(RadiusSecret_output, buf, 64);
9126
9127 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9128 return RETURN_OK;
9129}
9130
9131INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
9132{
9133 char config_file[64] = {0};
9134 char port_str[8] = {0};
9135 char cmd[256] = {0};
9136 char buf[128] = {0};
9137
9138 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9139
developere5750452023-05-15 16:46:42 +08009140 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
9141 return RETURN_ERR;
9142
9143 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
9144 return RETURN_ERR;
9145
developer72fb0bb2023-01-11 09:46:29 +08009146 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9147
9148 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file);
9149 _syscmd(cmd, buf, sizeof(buf));
9150 memset(cmd, 0, sizeof(cmd));
9151
9152 snprintf(port_str, sizeof(port_str), "%d", port);
9153 if (strlen(buf) == 0)
9154 // Append
9155 snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
9156 "auth_server_addr=%s\\n"
9157 "auth_server_port=%s\\n"
9158 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
9159 else {
9160 // Delete the three lines setting after the "# radius 1" comment
9161 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
9162 _syscmd(cmd, buf, sizeof(buf));
9163 memset(cmd, 0, sizeof(cmd));
9164 // Use "# radius 1" comment to find the location to insert the radius setting
9165 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
9166 "# radius 1\\n"
9167 "auth_server_addr=%s\\n"
9168 "auth_server_port=%s\\n"
9169 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9170 }
9171 if(_syscmd(cmd, buf, sizeof(buf))) {
9172 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9173 return RETURN_ERR;
9174 }
9175
9176 wifi_reloadAp(apIndex);
9177 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9178 return RETURN_OK;
9179}
9180
9181INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
9182{
9183 char config_file[64] = {0};
9184 char buf[64] = {0};
9185 char cmd[256] = {0};
9186
9187 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9188
9189 if(!IP_output || !Port_output || !RadiusSecret_output)
9190 return RETURN_ERR;
9191
9192 // Read the second matched config
9193 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9194 sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9195 _syscmd(cmd, buf, sizeof(buf));
9196 strncpy(IP_output, buf, 64);
9197
9198 memset(buf, 0, sizeof(buf));
9199 sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9200 _syscmd(cmd, buf, sizeof(buf));
9201 *Port_output = atoi(buf);
9202
9203 memset(buf, 0, sizeof(buf));
9204 sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file);
9205 _syscmd(cmd, buf, sizeof(buf));
9206 strncpy(RadiusSecret_output, buf, 64);
9207
9208 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9209 return RETURN_OK;
9210}
9211
9212INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
9213{
9214 char config_file[64] = {0};
9215 char port_str[8] = {0};
9216 char cmd[256] = {0};
9217 char buf[128] = {0};
9218
9219 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9220
developere5750452023-05-15 16:46:42 +08009221 if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
9222 return RETURN_ERR;
9223
9224 if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info
9225 return RETURN_ERR;
9226
developer72fb0bb2023-01-11 09:46:29 +08009227 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9228
9229 snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file);
9230 _syscmd(cmd, buf, sizeof(buf));
9231 memset(cmd, 0, sizeof(cmd));
9232
9233 snprintf(port_str, sizeof(port_str), "%d", port);
9234 if (strlen(buf) == 0)
9235 // Append
9236 snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
9237 "auth_server_addr=%s\\n"
9238 "auth_server_port=%s\\n"
9239 "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
9240 else {
9241 // Delete the three lines setting after the "# radius 2" comment
9242 snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
9243 _syscmd(cmd, buf, sizeof(buf));
9244 memset(cmd, 0, sizeof(cmd));
9245 // Use "# radius 2" comment to find the location to insert the radius setting
9246 snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
9247 "# radius 2\\n"
9248 "auth_server_addr=%s\\n"
9249 "auth_server_port=%s\\n"
9250 "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
9251 }
9252 if(_syscmd(cmd, buf, sizeof(buf))) {
9253 wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd);
9254 return RETURN_ERR;
9255 }
9256
9257 wifi_reloadAp(apIndex);
9258 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9259 return RETURN_OK;
9260}
9261
9262//RadiusSettings
9263INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
9264{
9265 if(!output)
9266 return RETURN_ERR;
9267
9268 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
developer69b61b02023-03-07 17:17:44 +08009269 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
9270 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
9271 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
9272 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 +08009273 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 +08009274 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
9275 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
9276 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 +08009277 //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.
9278
9279 return RETURN_OK;
9280}
9281
9282INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
9283{
9284 //store the paramters, and apply instantly
9285 return RETURN_ERR;
9286}
9287
9288//Device.WiFi.AccessPoint.{i}.WPS.Enable
9289//Enables or disables WPS functionality for this access point.
9290// outputs the WPS enable state of this ap in output_bool
9291INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
9292{
9293 char interface_name[16] = {0};
9294 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
9295 if(!output_bool)
9296 return RETURN_ERR;
9297 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9298 return RETURN_ERR;
9299 sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name);
9300 _syscmd(cmd, buf, sizeof(buf));
9301 if(strstr(buf, "configured"))
9302 *output_bool=TRUE;
9303 else
9304 *output_bool=FALSE;
9305
9306 return RETURN_OK;
developer69b61b02023-03-07 17:17:44 +08009307}
developer72fb0bb2023-01-11 09:46:29 +08009308
9309//Device.WiFi.AccessPoint.{i}.WPS.Enable
9310// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
9311INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
9312{
9313 char config_file[MAX_BUF_SIZE] = {0};
developere5750452023-05-15 16:46:42 +08009314 char buf[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009315 struct params params;
9316
9317 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9318 //store the paramters, and wait for wifi up to apply
9319 params.name = "wps_state";
developere5750452023-05-15 16:46:42 +08009320 if (enable == TRUE) {
9321 wifi_getApBeaconType(apIndex, buf);
9322 if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption
9323 params.value = "1";
9324 else // If ap set encryption
9325 params.value = "2";
9326 } else {
9327 params.value = "0";
9328 }
developer72fb0bb2023-01-11 09:46:29 +08009329
9330 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9331 wifi_hostapdWrite(config_file, &params, 1);
9332 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9333 wifi_reloadAp(apIndex);
9334
9335 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9336 return RETURN_OK;
9337}
9338
9339//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
9340INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
9341{
9342 if(!output)
9343 return RETURN_ERR;
9344 snprintf(output, 128, "PushButton,PIN");
9345 return RETURN_OK;
9346}
9347
9348//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9349//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.
9350// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
9351INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
9352{
9353 if(!output)
9354 return RETURN_ERR;
9355 snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
9356
9357 return RETURN_OK;
9358}
9359
9360//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
9361// 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
9362INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
9363{
9364 //apply instantly. No setting need to be stored.
9365 char methods[MAX_BUF_SIZE], *token, *next_token;
9366 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
9367 struct params params;
9368
9369 if(!methodString)
9370 return RETURN_ERR;
9371 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9372 //store the paramters, and wait for wifi up to apply
9373
9374 snprintf(methods, sizeof(methods), "%s", methodString);
9375 for(token=methods; *token; token=next_token)
9376 {
9377 strtok_r(token, ",", &next_token);
9378 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
9379 snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
9380 else if(*token=='E')
9381 {
9382 if(!strcmp(methods, "Ethernet"))
9383 snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
9384 else if(!strcmp(methods, "ExternalNFCToken"))
9385 snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
9386 else
9387 printf("%s: Unknown WpsConfigMethod\n", __func__);
9388 }
9389 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
9390 snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
9391 else if(*token=='N' && !strcmp(token, "NFCInterface"))
9392 snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
9393 else if(*token=='P' )
9394 {
9395 if(!strcmp(token, "PushButton"))
developere5750452023-05-15 16:46:42 +08009396 snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
developer72fb0bb2023-01-11 09:46:29 +08009397 else if(!strcmp(token, "PIN"))
9398 snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
9399 else
9400 printf("%s: Unknown WpsConfigMethod\n", __func__);
9401 }
9402 else
9403 printf("%s: Unknown WpsConfigMethod\n", __func__);
9404 }
9405 params.name = "config_methods";
9406 params.value = config_methods;
9407 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9408 wifi_hostapdWrite(config_file, &params, 1);
9409 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9410 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9411
9412 return RETURN_OK;
9413}
9414
9415// outputs the pin value, ulong_pin must be allocated by the caller
9416INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
9417{
9418 char buf[MAX_BUF_SIZE] = {0};
9419 char cmd[MAX_CMD_SIZE] = {0};
9420
9421 if(!output_ulong)
9422 return RETURN_ERR;
9423 snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
9424 _syscmd(cmd, buf, sizeof(buf));
9425 if(strlen(buf) > 0)
9426 *output_ulong=strtoul(buf, NULL, 10);
9427
9428 return RETURN_OK;
9429}
9430
9431// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
9432INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
9433{
9434 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
9435 char ap_pin[16] = {0};
9436 char buf[MAX_BUF_SIZE] = {0};
9437 char config_file[MAX_BUF_SIZE] = {0};
9438 ULONG prev_pin = 0;
9439 struct params params;
9440
9441 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9442 snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
9443 params.name = "ap_pin";
9444 params.value = ap_pin;
9445 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
9446 wifi_hostapdWrite(config_file, &params, 1);
9447 wifi_hostapdProcessUpdate(apIndex, &params, 1);
9448 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9449
9450 return RETURN_OK;
9451}
9452
9453// Output string is either Not configured or Configured, max 32 characters
9454INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
9455{
9456 char interface_name[16] = {0};
9457 char cmd[MAX_CMD_SIZE];
9458 char buf[MAX_BUF_SIZE]={0};
9459
9460 if(!output_string)
9461 return RETURN_ERR;
9462 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9463 snprintf(output_string, 32, "Not configured");
9464 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9465 return RETURN_ERR;
9466 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
9467 _syscmd(cmd, buf, sizeof(buf));
9468
9469 if(!strncmp(buf, "configured", 10))
9470 snprintf(output_string, 32, "Configured");
9471 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9472
9473 return RETURN_OK;
9474}
9475
9476// sets the WPS pin for this AP
9477INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
9478{
9479 char interface_name[16] = {0};
9480 char cmd[MAX_CMD_SIZE];
9481 char buf[MAX_BUF_SIZE]={0};
9482 BOOL enable;
9483
9484 wifi_getApEnable(apIndex, &enable);
9485 if (!enable)
9486 return RETURN_ERR;
9487 wifi_getApWpsEnable(apIndex, &enable);
9488 if (!enable)
9489 return RETURN_ERR;
9490
9491 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9492 return RETURN_ERR;
9493 snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
9494 _syscmd(cmd, buf, sizeof(buf));
9495 if((strstr(buf, "OK"))!=NULL)
9496 return RETURN_OK;
9497
9498 return RETURN_ERR;
9499}
9500
9501// This function is called when the WPS push button has been pressed for this AP
9502INT wifi_setApWpsButtonPush(INT apIndex)
9503{
9504 char cmd[MAX_CMD_SIZE];
9505 char buf[MAX_BUF_SIZE]={0};
9506 char interface_name[16] = {0};
9507 BOOL enable=FALSE;
9508
9509 wifi_getApEnable(apIndex, &enable);
9510 if (!enable)
9511 return RETURN_ERR;
9512
9513 wifi_getApWpsEnable(apIndex, &enable);
9514 if (!enable)
9515 return RETURN_ERR;
9516
9517 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9518 return RETURN_ERR;
9519
9520 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
9521 _syscmd(cmd, buf, sizeof(buf));
9522
9523 if((strstr(buf, "OK"))!=NULL)
9524 return RETURN_OK;
9525 return RETURN_ERR;
9526}
9527
9528// cancels WPS mode for this AP
9529INT wifi_cancelApWPS(INT apIndex)
9530{
9531 char interface_name[16] = {0};
9532 char cmd[MAX_CMD_SIZE];
9533 char buf[MAX_BUF_SIZE]={0};
9534
9535 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9536 return RETURN_ERR;
9537 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name);
9538 _syscmd(cmd,buf, sizeof(buf));
9539
9540 if((strstr(buf, "OK"))!=NULL)
9541 return RETURN_OK;
9542 return RETURN_ERR;
9543}
9544
9545//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
9546//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
9547INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
9548{
9549 char interface_name[16] = {0};
9550 FILE *f = NULL;
9551 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
9552 char cmd[256] = {0}, buf[2048] = {0};
9553 char *param = NULL, *value = NULL, *line=NULL;
9554 size_t len = 0;
9555 ssize_t nread = 0;
9556 wifi_associated_dev_t *dev=NULL;
9557
9558 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9559 *associated_dev_array = NULL;
9560 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
9561 return RETURN_ERR;
9562 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
9563 _syscmd(cmd,buf,sizeof(buf));
9564 *output_array_size = atoi(buf);
9565
9566 if (*output_array_size <= 0)
9567 return RETURN_OK;
9568
9569 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
9570 *associated_dev_array = dev;
9571 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
9572 _syscmd(cmd,buf,sizeof(buf));
9573 f = fopen("/tmp/connected_devices.txt", "r");
9574 if (f==NULL)
9575 {
9576 *output_array_size=0;
9577 return RETURN_ERR;
9578 }
9579 while ((getline(&line, &len, f)) != -1)
9580 {
9581 param = strtok(line,"=");
9582 value = strtok(NULL,"=");
9583
9584 if( strcmp("flags",param) == 0 )
9585 {
9586 value[strlen(value)-1]='\0';
9587 if(strstr (value,"AUTHORIZED") != NULL )
9588 {
9589 dev[auth_temp].cli_AuthenticationState = 1;
9590 dev[auth_temp].cli_Active = 1;
9591 auth_temp++;
9592 read_flag=1;
9593 }
9594 }
9595 if(read_flag==1)
9596 {
9597 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
9598 {
9599 value[strlen(value)-1]='\0';
9600 sscanf(value, "%x:%x:%x:%x:%x:%x",
9601 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
9602 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
9603 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
9604 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
9605 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
9606 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
9607 mac_temp++;
9608 read_flag=0;
9609 }
9610 }
9611 }
9612 *output_array_size = auth_temp;
9613 auth_temp=0;
9614 mac_temp=0;
9615 free(line);
9616 fclose(f);
9617 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9618 return RETURN_OK;
9619}
9620
9621#define MACADDRESS_SIZE 6
9622
9623INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9624{
9625 FILE *fp = NULL;
9626 char str[MAX_BUF_SIZE] = {0};
9627 int wificlientindex = 0 ;
9628 int count = 0;
9629 int signalstrength = 0;
9630 int arr[MACADDRESS_SIZE] = {0};
9631 unsigned char mac[MACADDRESS_SIZE] = {0};
9632 UINT wifi_count = 0;
9633 char virtual_interface_name[MAX_BUF_SIZE] = {0};
9634 char pipeCmd[MAX_CMD_SIZE] = {0};
9635
9636 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9637 *output_array_size = 0;
9638 *associated_dev_array = NULL;
9639
9640 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
9641 fp = popen(pipeCmd, "r");
developer69b61b02023-03-07 17:17:44 +08009642 if (fp == NULL)
developer72fb0bb2023-01-11 09:46:29 +08009643 {
9644 printf("Failed to run command inside function %s\n",__FUNCTION__ );
9645 return RETURN_ERR;
9646 }
9647
9648 /* Read the output a line at a time - output it. */
9649 fgets(str, sizeof(str)-1, fp);
9650 wifi_count = (unsigned int) atoi ( str );
9651 *output_array_size = wifi_count;
9652 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
9653 pclose(fp);
9654
9655 if(wifi_count == 0)
9656 {
9657 return RETURN_OK;
9658 }
9659 else
9660 {
9661 wifi_associated_dev3_t* temp = NULL;
9662 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
9663 if(temp == NULL)
9664 {
9665 printf("Error Statement. Insufficient memory \n");
9666 return RETURN_ERR;
9667 }
9668
9669 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
9670 system(pipeCmd);
9671 memset(pipeCmd,0,sizeof(pipeCmd));
9672 if(apIndex == 0)
9673 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
9674 else if(apIndex == 1)
9675 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
9676 system(pipeCmd);
9677
9678 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
9679 if(fp == NULL)
9680 {
9681 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
9682 free(temp);
9683 return RETURN_ERR;
9684 }
9685 fclose(fp);
9686
9687 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
9688 fp = popen(pipeCmd, "r");
9689 if(fp)
9690 {
9691 for(count =0 ; count < wifi_count; count++)
9692 {
9693 fgets(str, MAX_BUF_SIZE, fp);
9694 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
9695 {
9696 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
9697 {
9698 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
9699
9700 }
9701 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
9702 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]);
9703 }
9704 temp[count].cli_AuthenticationState = 1; //TODO
9705 temp[count].cli_Active = 1; //TODO
9706 }
9707 pclose(fp);
9708 }
9709
9710 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
9711 fp = popen(pipeCmd, "r");
9712 if(fp)
developer69b61b02023-03-07 17:17:44 +08009713 {
developer72fb0bb2023-01-11 09:46:29 +08009714 pclose(fp);
9715 }
9716 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
9717 if(fp)
9718 {
9719 for(count =0 ; count < wifi_count ;count++)
9720 {
9721 fgets(str, MAX_BUF_SIZE, fp);
9722 signalstrength = atoi(str);
9723 temp[count].cli_SignalStrength = signalstrength;
9724 temp[count].cli_RSSI = signalstrength;
9725 temp[count].cli_SNR = signalstrength + 95;
9726 }
9727 pclose(fp);
9728 }
9729
9730
9731 if((apIndex == 0) || (apIndex == 4))
9732 {
9733 for(count =0 ; count < wifi_count ;count++)
developer69b61b02023-03-07 17:17:44 +08009734 {
developer72fb0bb2023-01-11 09:46:29 +08009735 strcpy(temp[count].cli_OperatingStandard,"g");
9736 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
9737 }
9738
9739 //BytesSent
9740 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
9741 fp = popen(pipeCmd, "r");
9742 if(fp)
developer69b61b02023-03-07 17:17:44 +08009743 {
developer72fb0bb2023-01-11 09:46:29 +08009744 pclose(fp);
9745 }
9746 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
9747 if(fp)
9748 {
9749 for (count = 0; count < wifi_count; count++)
9750 {
9751 fgets(str, MAX_BUF_SIZE, fp);
9752 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
9753 }
9754 pclose(fp);
9755 }
9756
9757 //BytesReceived
9758 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
9759 fp = popen(pipeCmd, "r");
9760 if (fp)
9761 {
9762 pclose(fp);
9763 }
9764 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
9765 if (fp)
9766 {
9767 for (count = 0; count < wifi_count; count++)
9768 {
9769 fgets(str, MAX_BUF_SIZE, fp);
9770 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
9771 }
9772 pclose(fp);
9773 }
9774
9775 //PacketsSent
9776 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
9777 fp = popen(pipeCmd, "r");
9778 if (fp)
9779 {
9780 pclose(fp);
9781 }
9782
9783 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
9784 if (fp)
9785 {
9786 for (count = 0; count < wifi_count; count++)
9787 {
9788 fgets(str, MAX_BUF_SIZE, fp);
9789 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
9790 }
9791 pclose(fp);
9792 }
9793
9794 //PacketsReceived
9795 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
9796 fp = popen(pipeCmd, "r");
9797 if (fp)
9798 {
9799 pclose(fp);
9800 }
9801 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
9802 if (fp)
9803 {
9804 for (count = 0; count < wifi_count; count++)
9805 {
9806 fgets(str, MAX_BUF_SIZE, fp);
9807 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
9808 }
9809 pclose(fp);
9810 }
9811
9812 //ErrorsSent
9813 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9814 fp = popen(pipeCmd, "r");
9815 if (fp)
9816 {
9817 pclose(fp);
9818 }
9819 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9820 if (fp)
9821 {
9822 for (count = 0; count < wifi_count; count++)
9823 {
9824 fgets(str, MAX_BUF_SIZE, fp);
9825 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9826 }
9827 pclose(fp);
9828 }
9829
9830 //ErrorsSent
9831 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
9832 fp = popen(pipeCmd, "r");
9833 if (fp)
9834 {
9835 pclose(fp);
9836 }
9837 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
9838 if (fp)
9839 {
9840 for (count = 0; count < wifi_count; count++)
9841 {
9842 fgets(str, MAX_BUF_SIZE, fp);
9843 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
9844 }
9845 pclose(fp);
9846 }
9847
9848 //LastDataDownlinkRate
9849 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
9850 fp = popen(pipeCmd, "r");
9851 if (fp)
9852 {
9853 pclose(fp);
9854 }
9855 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
9856 if (fp)
9857 {
9858 for (count = 0; count < wifi_count; count++)
9859 {
9860 fgets(str, MAX_BUF_SIZE, fp);
9861 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
9862 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
9863 }
9864 pclose(fp);
9865 }
9866
9867 //LastDataUplinkRate
9868 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
9869 fp = popen(pipeCmd, "r");
9870 if (fp)
9871 {
9872 pclose(fp);
9873 }
9874 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
9875 if (fp)
9876 {
9877 for (count = 0; count < wifi_count; count++)
9878 {
9879 fgets(str, MAX_BUF_SIZE, fp);
9880 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
9881 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
9882 }
9883 pclose(fp);
9884 }
9885
9886 }
9887 else if ((apIndex == 1) || (apIndex == 5))
9888 {
9889 for (count = 0; count < wifi_count; count++)
9890 {
9891 strcpy(temp[count].cli_OperatingStandard, "a");
9892 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
9893 temp[count].cli_BytesSent = 0;
9894 temp[count].cli_BytesReceived = 0;
9895 temp[count].cli_LastDataUplinkRate = 0;
9896 temp[count].cli_LastDataDownlinkRate = 0;
9897 temp[count].cli_PacketsSent = 0;
9898 temp[count].cli_PacketsReceived = 0;
9899 temp[count].cli_ErrorsSent = 0;
9900 }
9901 }
9902
9903 for (count = 0; count < wifi_count; count++)
9904 {
9905 temp[count].cli_Retransmissions = 0;
9906 temp[count].cli_DataFramesSentAck = 0;
9907 temp[count].cli_DataFramesSentNoAck = 0;
9908 temp[count].cli_MinRSSI = 0;
9909 temp[count].cli_MaxRSSI = 0;
9910 strncpy(temp[count].cli_InterferenceSources, "", 64);
9911 memset(temp[count].cli_IPAddress, 0, 64);
9912 temp[count].cli_RetransCount = 0;
9913 temp[count].cli_FailedRetransCount = 0;
9914 temp[count].cli_RetryCount = 0;
9915 temp[count].cli_MultipleRetryCount = 0;
9916 }
9917 *associated_dev_array = temp;
9918 }
9919 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9920 return RETURN_OK;
9921}
9922
developer7e4a2a62023-04-06 19:56:03 +08009923int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
developer72fb0bb2023-01-11 09:46:29 +08009924{
developer7e4a2a62023-04-06 19:56:03 +08009925 char cmd[MAX_CMD_SIZE] = {0};
9926 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +08009927
developer7e4a2a62023-04-06 19:56:03 +08009928 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
9929
9930 snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
9931 interface_name);
9932 _syscmd(cmd, buf, MAX_BUF_SIZE);
9933
9934 strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */
9935
9936 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +08009937 return RETURN_OK;
9938}
9939
9940/* #define HOSTAPD_STA_PARAM_ENTRIES 29
9941struct hostapd_sta_param {
9942 char key[50];
9943 char value[100];
9944}
9945
9946static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){
9947 int i = 0;
9948
9949 while(i<HOSTAPD_STA_PARAM_ENTRIES) {
9950 if (strncmp(params[i].key,key,50) == 0){
9951 return &params[i].value;
9952 }
9953 i++;
9954 }
9955 return NULL;
9956
9957} */
9958
9959static unsigned int count_occurences(const char *buf, const char *word)
9960{
9961 unsigned int n = 0;
9962 char *ptr = strstr(buf, word);
9963
9964 while (ptr++) {
9965 n++;
9966 ptr = strstr(ptr, word);
9967 }
9968
9969 wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word);
9970 return n;
9971}
9972
9973static const char *get_line_from_str_buf(const char *buf, char *line)
9974{
9975 int i;
9976 int n = strlen(buf);
9977
9978 for (i = 0; i < n; i++) {
9979 line[i] = buf[i];
9980 if (buf[i] == '\n') {
9981 line[i] = '\0';
9982 return &buf[i + 1];
9983 }
9984 }
9985
9986 return NULL;
9987}
9988
9989INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
9990{
developer0d26f2c2023-05-25 19:46:36 +08009991 char interface_name[16] = {0};
9992 FILE *f = NULL;
9993 int auth_temp= -1;
9994 char cmd[256] = {0}, buf[2048] = {0};
9995 char *param = NULL, *value = NULL, *line=NULL;
9996 size_t len = 0;
9997 wifi_associated_dev3_t *dev=NULL;
developer72fb0bb2023-01-11 09:46:29 +08009998
9999 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developer0d26f2c2023-05-25 19:46:36 +080010000 *associated_dev_array = NULL;
10001 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +080010002 return RETURN_ERR;
developer0d26f2c2023-05-25 19:46:36 +080010003 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
10004 _syscmd(cmd, buf, sizeof(buf));
10005 *output_array_size = atoi(buf);
developer72fb0bb2023-01-11 09:46:29 +080010006
developer0d26f2c2023-05-25 19:46:36 +080010007 if (*output_array_size <= 0)
10008 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010009
developer0d26f2c2023-05-25 19:46:36 +080010010 dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10011 *associated_dev_array = dev;
10012 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
10013 _syscmd(cmd,buf,sizeof(buf));
10014 f = fopen("/tmp/diagnostic3_devices.txt", "r");
10015 if (f == NULL)
10016 {
10017 *output_array_size=0;
developer72fb0bb2023-01-11 09:46:29 +080010018 return RETURN_ERR;
10019 }
developer0d26f2c2023-05-25 19:46:36 +080010020 while ((getline(&line, &len, f)) != -1)
10021 {
10022 param = strtok(line, "=");
10023 value = strtok(NULL, "=");
developer72fb0bb2023-01-11 09:46:29 +080010024
developer0d26f2c2023-05-25 19:46:36 +080010025 if( strcmp("flags",param) == 0 )
10026 {
10027 value[strlen(value)-1]='\0';
10028 if(strstr (value,"AUTHORIZED") != NULL )
10029 {
10030 auth_temp++;
10031 dev[auth_temp].cli_AuthenticationState = 1;
10032 dev[auth_temp].cli_Active = 1;
developer72fb0bb2023-01-11 09:46:29 +080010033 }
developer0d26f2c2023-05-25 19:46:36 +080010034 } else if (auth_temp < 0) {
10035 continue;
10036 } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
10037 {
10038 value[strlen(value)-1]='\0';
10039 sscanf(value, "%x:%x:%x:%x:%x:%x",
10040 (unsigned int *)&dev[auth_temp].cli_MACAddress[0],
10041 (unsigned int *)&dev[auth_temp].cli_MACAddress[1],
10042 (unsigned int *)&dev[auth_temp].cli_MACAddress[2],
10043 (unsigned int *)&dev[auth_temp].cli_MACAddress[3],
10044 (unsigned int *)&dev[auth_temp].cli_MACAddress[4],
10045 (unsigned int *)&dev[auth_temp].cli_MACAddress[5]);
10046 } else if (strcmp("signal", param) == 0) {
10047 value[strlen(value)-1]='\0';
10048 sscanf(value, "%d", &dev[auth_temp].cli_RSSI);
10049 dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
developer72fb0bb2023-01-11 09:46:29 +080010050 }
developer0d26f2c2023-05-25 19:46:36 +080010051 }
10052 if (line)
10053 free(line);
10054 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080010055 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080010056 return RETURN_OK;
10057}
10058
10059#if 0
10060//To-do
10061INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10062{
10063 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10064
10065 //Using different approach to get required WiFi Parameters from system available commands
developer69b61b02023-03-07 17:17:44 +080010066#if 0
developer72fb0bb2023-01-11 09:46:29 +080010067 FILE *f;
10068 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
10069 char cmd[256], buf[2048];
10070 char *param , *value, *line=NULL;
10071 size_t len = 0;
10072 ssize_t nread;
10073 wifi_associated_dev3_t *dev=NULL;
10074 *associated_dev_array = NULL;
10075 sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name);
10076 _syscmd(cmd,buf,sizeof(buf));
10077 *output_array_size = atoi(buf);
10078
10079 if (*output_array_size <= 0)
10080 return RETURN_OK;
10081
10082 dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t));
10083 *associated_dev_array = dev;
10084 sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name);
10085 _syscmd(cmd,buf,sizeof(buf));
10086 f = fopen("/tmp/connected_devices.txt", "r");
10087 if (f==NULL)
10088 {
10089 *output_array_size=0;
10090 return RETURN_ERR;
10091 }
10092 while ((nread = getline(&line, &len, f)) != -1)
10093 {
10094 param = strtok(line,"=");
10095 value = strtok(NULL,"=");
10096
10097 if( strcmp("flags",param) == 0 )
10098 {
10099 value[strlen(value)-1]='\0';
10100 if(strstr (value,"AUTHORIZED") != NULL )
10101 {
10102 dev[auth_temp].cli_AuthenticationState = 1;
10103 dev[auth_temp].cli_Active = 1;
10104 auth_temp++;
10105 read_flag=1;
10106 }
10107 }
10108 if(read_flag==1)
10109 {
10110 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
10111 {
10112 value[strlen(value)-1]='\0';
10113 sscanf(value, "%x:%x:%x:%x:%x:%x",
10114 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
10115 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
10116 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
10117 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
10118 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
10119 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
10120
10121 }
10122 else if( strcmp("rx_packets",param) == 0 )
10123 {
10124 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived));
10125 }
10126
10127 else if( strcmp("tx_packets",param) == 0 )
10128 {
developer69b61b02023-03-07 17:17:44 +080010129 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent));
developer72fb0bb2023-01-11 09:46:29 +080010130 }
10131
10132 else if( strcmp("rx_bytes",param) == 0 )
10133 {
10134 sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived));
10135 }
10136
10137 else if( strcmp("tx_bytes",param) == 0 )
10138 {
developer69b61b02023-03-07 17:17:44 +080010139 sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent));
developer72fb0bb2023-01-11 09:46:29 +080010140 mac_temp++;
10141 read_flag=0;
developer69b61b02023-03-07 17:17:44 +080010142 }
developer72fb0bb2023-01-11 09:46:29 +080010143 }
10144 }
10145
10146 *output_array_size = auth_temp;
10147 auth_temp=0;
10148 mac_temp=0;
10149 free(line);
10150 fclose(f);
10151#endif
10152 char interface_name[MAX_BUF_SIZE] = {0};
10153 char wifi_status[MAX_BUF_SIZE] = {0};
10154 char hostapdconf[MAX_BUF_SIZE] = {0};
10155
10156 wifi_associated_dev3_t *dev_array = NULL;
10157 ULONG wifi_count = 0;
10158
10159 *associated_dev_array = NULL;
10160 *output_array_size = 0;
10161
10162 printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex);
10163 //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI.
10164 {
10165 sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex);
10166
10167 wifi_GetInterfaceName(interface_name, hostapdconf);
10168
10169 if(strlen(interface_name) > 1)
10170 {
10171 wifihal_interfacestatus(wifi_status,interface_name);
10172 if(strcmp(wifi_status,"RUNNING") == 0)
10173 {
10174 wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count);
10175
10176 *associated_dev_array = dev_array;
developer69b61b02023-03-07 17:17:44 +080010177 *output_array_size = wifi_count;
developer72fb0bb2023-01-11 09:46:29 +080010178 }
10179 else
10180 {
10181 *associated_dev_array = NULL;
10182 }
10183 }
10184 }
10185
10186 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10187 return RETURN_OK;
10188}
10189#endif
10190
10191/* getIPAddress function */
10192/**
10193* @description Returning IpAddress of the Matched String
10194*
developer69b61b02023-03-07 17:17:44 +080010195* @param
developer72fb0bb2023-01-11 09:46:29 +080010196* @str Having MacAddress
developer69b61b02023-03-07 17:17:44 +080010197* @ipaddr Having ipaddr
developer72fb0bb2023-01-11 09:46:29 +080010198* @return The status of the operation
10199* @retval RETURN_OK if successful
10200* @retval RETURN_ERR if any error is detected
10201*
10202*/
10203
10204INT getIPAddress(char *str,char *ipaddr)
10205{
10206 FILE *fp = NULL;
10207 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
10208 int LeaseTime = 0,ret = 0;
10209 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
10210 {
10211 return RETURN_ERR;
10212 }
10213
10214 while ( fgets(buf, sizeof(buf), fp)!= NULL )
10215 {
10216 /*
10217 Sample:sss
10218 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
10219 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
10220 */
10221 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
10222 &(LeaseTime),
10223 phyAddr,
10224 ipAddr,
10225 hostName
10226 );
10227 if(ret != 4)
10228 continue;
10229 if(strcmp(str,phyAddr) == 0)
10230 strcpy(ipaddr,ipAddr);
10231 }
10232 fclose(fp);
10233 return RETURN_OK;
10234}
10235
10236/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
10237/**
10238* @description Returning Inactive wireless connected clients informations
10239*
developer69b61b02023-03-07 17:17:44 +080010240* @param
developer72fb0bb2023-01-11 09:46:29 +080010241* @filename Holding private_wifi 2g/5g content files
10242* @associated_dev_array Having inactiv wireless clients informations
10243* @output_array_size Returning Inactive wireless counts
10244* @return The status of the operation
10245* @retval RETURN_OK if successful
10246* @retval RETURN_ERR if any error is detected
10247*
10248*/
10249
10250INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
10251{
10252 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10253 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
10254 FILE *fp = NULL;
10255 int arr[MACADDRESS_SIZE] = {0};
10256 unsigned char mac[MACADDRESS_SIZE] = {0};
10257 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
10258 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
10259 fp = popen(buf,"r");
10260 if(fp == NULL)
10261 return RETURN_ERR;
10262 else
10263 {
10264 fgets(path,sizeof(path),fp);
10265 maccount = atoi(path);
10266 }
10267 pclose(fp);
10268 *output_array_size = maccount;
10269 wifi_associated_dev3_t* temp = NULL;
10270 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
10271 *associated_dev_array = temp;
10272 if(temp == NULL)
10273 {
10274 printf("Error Statement. Insufficient memory \n");
10275 return RETURN_ERR;
10276 }
10277 memset(buf,0,sizeof(buf));
10278 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
10279 fp = popen(buf,"r");
10280 if (fp == NULL) {
10281 fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
10282 return RETURN_ERR;
10283 }
10284 for(count = 0; count < maccount ; count++)
10285 {
10286 fgets(path,sizeof(path),fp);
10287 for(i = 0; path[i]!='\n';i++)
10288 str[i]=path[i];
10289 str[i]='\0';
10290 getIPAddress(str,ipaddr);
10291 memset(buf,0,sizeof(buf));
10292 if(strlen(ipaddr) > 0)
10293 {
10294 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
10295 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
10296 {
10297 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10298 {
10299 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10300 {
10301 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
10302
10303 }
10304 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10305 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]);
10306 }
10307 temp[count].cli_AuthenticationState = 0; //TODO
developer69b61b02023-03-07 17:17:44 +080010308 temp[count].cli_Active = 0; //TODO
developer72fb0bb2023-01-11 09:46:29 +080010309 temp[count].cli_SignalStrength = 0;
10310 }
10311 else //Active wireless clients info
10312 {
10313 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
10314 {
10315 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
10316 {
10317 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
10318
10319 }
10320 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
10321 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]);
10322 }
10323 temp[count].cli_Active = 1;
10324 }
10325 }
10326 memset(ipaddr,0,sizeof(ipaddr));
10327 }
10328 pclose(fp);
10329 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10330 return RETURN_OK;
10331}
10332//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
10333//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
10334//To get Band Steering Capability
10335INT wifi_getBandSteeringCapability(BOOL *support)
10336{
10337 *support = FALSE;
10338 return RETURN_OK;
10339}
10340
10341
10342//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
10343//To get Band Steering enable status
10344INT wifi_getBandSteeringEnable(BOOL *enable)
10345{
10346 *enable = FALSE;
10347 return RETURN_OK;
10348}
10349
10350//To turn on/off Band steering
10351INT wifi_setBandSteeringEnable(BOOL enable)
10352{
10353 return RETURN_OK;
10354}
10355
10356//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
10357//To get Band Steering AP group
10358INT wifi_getBandSteeringApGroup(char *output_ApGroup)
10359{
10360 if (NULL == output_ApGroup)
10361 return RETURN_ERR;
10362
10363 strcpy(output_ApGroup, "1,2");
10364 return RETURN_OK;
10365}
10366
10367//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
10368//to set and read the band steering BandUtilizationThreshold parameters
10369INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
10370{
10371 return RETURN_ERR;
10372}
10373
10374INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
10375{
10376 return RETURN_ERR;
10377}
10378
10379//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
10380//to set and read the band steering RSSIThreshold parameters
10381INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
10382{
10383 return RETURN_ERR;
10384}
10385
10386INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
10387{
10388 return RETURN_ERR;
10389}
10390
10391
10392//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
10393//to set and read the band steering physical modulation rate threshold parameters
10394INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
10395{
10396 //If chip is not support, return -1
10397 return RETURN_ERR;
10398}
10399
10400INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
10401{
10402 //If chip is not support, return -1
10403 return RETURN_ERR;
10404}
10405
10406//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
10407//to set and read the inactivity time (in seconds) for steering under overload condition
10408INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
10409{
10410 return RETURN_ERR;
10411}
10412
10413INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
10414{
10415 return RETURN_ERR;
10416}
10417
10418//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
10419//to set and read the inactivity time (in seconds) for steering under Idle condition
10420INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
10421{
10422 return RETURN_ERR;
10423}
10424
10425INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
10426{
10427 return RETURN_ERR;
10428}
10429
10430//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
10431//pClientMAC[64]
10432//pSourceSSIDIndex[64]
10433//pDestSSIDIndex[64]
10434//pSteeringReason[256]
10435INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
10436{
10437 //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
10438 *pSteeringTime=time(NULL);
10439 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
10440 return RETURN_OK;
10441}
10442
10443INT wifi_ifConfigDown(INT apIndex)
10444{
10445 INT status = RETURN_OK;
10446 char cmd[64];
10447
10448 snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
10449 printf("%s: %s\n", __func__, cmd);
10450 system(cmd);
10451
10452 return status;
10453}
10454
10455INT wifi_ifConfigUp(INT apIndex)
10456{
10457 char interface_name[16] = {0};
10458 char cmd[128];
10459 char buf[1024];
10460
10461 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
10462 return RETURN_ERR;
10463 snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name);
10464 _syscmd(cmd, buf, sizeof(buf));
10465 return 0;
10466}
10467
10468//>> Deprecated. Replace with wifi_applyRadioSettings
10469INT wifi_pushBridgeInfo(INT apIndex)
10470{
developerb2977562023-05-24 17:54:12 +080010471 char ip[32] = {0};
10472 char subnet[32] = {0};
10473 char bridge[32] = {0};
10474 char cmd[128] = {0};
10475 char buf[1024] = {0};
developer72fb0bb2023-01-11 09:46:29 +080010476
developerb2977562023-05-24 17:54:12 +080010477 wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
developer72fb0bb2023-01-11 09:46:29 +080010478
developerb2977562023-05-24 17:54:12 +080010479 snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
10480 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080010481
developerb2977562023-05-24 17:54:12 +080010482 return 0;
developer72fb0bb2023-01-11 09:46:29 +080010483}
10484
10485INT wifi_pushChannel(INT radioIndex, UINT channel)
10486{
10487 char interface_name[16] = {0};
10488 char cmd[128];
10489 char buf[1024];
10490 int apIndex;
10491
developer69b61b02023-03-07 17:17:44 +080010492 apIndex=(radioIndex==0)?0:1;
developer72fb0bb2023-01-11 09:46:29 +080010493 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
10494 return RETURN_ERR;
10495 snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel);
10496 _syscmd(cmd,buf, sizeof(buf));
10497
10498 return 0;
10499}
10500
10501INT wifi_pushChannelMode(INT radioIndex)
10502{
10503 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
10504 return RETURN_ERR;
10505}
10506
10507INT wifi_pushDefaultValues(INT radioIndex)
10508{
10509 //Apply Comcast specified default radio settings instantly
10510 //AMPDU=1
10511 //AMPDUFrames=32
10512 //AMPDULim=50000
10513 //txqueuelen=1000
10514
10515 return RETURN_ERR;
10516}
10517
10518INT wifi_pushTxChainMask(INT radioIndex)
10519{
10520 //Apply default TxChainMask instantly
10521 return RETURN_ERR;
10522}
10523
10524INT wifi_pushRxChainMask(INT radioIndex)
10525{
10526 //Apply default RxChainMask instantly
10527 return RETURN_ERR;
10528}
10529
10530INT wifi_pushSSID(INT apIndex, CHAR *ssid)
10531{
developer7e4a2a62023-04-06 19:56:03 +080010532 INT status;
developer72fb0bb2023-01-11 09:46:29 +080010533
developer7e4a2a62023-04-06 19:56:03 +080010534 status = wifi_setSSIDName(apIndex, ssid);
10535 wifi_quick_reload_ap(apIndex);
developer72fb0bb2023-01-11 09:46:29 +080010536
developer7e4a2a62023-04-06 19:56:03 +080010537 return status;
developer72fb0bb2023-01-11 09:46:29 +080010538}
10539
10540INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
10541{
10542 //Apply default Ssid Advertisement instantly
10543 return RETURN_ERR;
10544}
10545
10546INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
10547{
developere82c0ca2023-05-10 16:25:35 +080010548 time_t now;
10549
10550 time(&now);
10551 if (now > radio_up_time[radioIndex])
10552 *output = now - radio_up_time[radioIndex];
10553 else {
10554 *output = 0;
10555 return RETURN_ERR;
10556 }
10557
10558 return RETURN_OK;
developer72fb0bb2023-01-11 09:46:29 +080010559}
10560
10561INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
10562{
10563 return RETURN_OK;
10564}
10565
10566INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
10567{
10568 return RETURN_OK;
10569}
10570
10571//To-do
10572INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
10573{
10574 char output[16]={'\0'};
10575 char config_file[MAX_BUF_SIZE] = {0};
10576
10577 if (!output_string)
10578 return RETURN_ERR;
10579
10580 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10581 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
10582
10583 if (strlen(output) == 0)
10584 snprintf(output_string, 64, "Disabled");
10585 else if (strncmp(output, "0", 1) == 0)
10586 snprintf(output_string, 64, "Disabled");
10587 else if (strncmp(output, "1", 1) == 0)
10588 snprintf(output_string, 64, "Optional");
10589 else if (strncmp(output, "2", 1) == 0)
10590 snprintf(output_string, 64, "Required");
10591 else {
10592 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
10593 return RETURN_ERR;
10594 }
10595
10596 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
10597 return RETURN_OK;
10598}
10599INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
10600{
10601 char str[MAX_BUF_SIZE]={'\0'};
10602 char cmd[MAX_CMD_SIZE]={'\0'};
10603 struct params params;
10604 char config_file[MAX_BUF_SIZE] = {0};
10605
10606 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10607 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
10608 return RETURN_ERR;
10609
10610 params.name = "ieee80211w";
10611 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
10612 params.value = "0";
10613 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
10614 params.value = "1";
10615 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
10616 params.value = "2";
10617 else{
10618 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
10619 return RETURN_ERR;
10620 }
10621 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
10622 wifi_hostapdWrite(config_file, &params, 1);
10623 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
10624 return RETURN_OK;
10625}
10626INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
10627{
10628 char output[16]={'\0'};
10629 char config_file[MAX_BUF_SIZE] = {0};
10630
10631 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerc0772e62023-05-18 15:10:48 +080010632 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
developer262f4cb2023-05-24 12:22:04 +080010633 wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
developer72fb0bb2023-01-11 09:46:29 +080010634
developer262f4cb2023-05-24 12:22:04 +080010635 if (output == NULL)
10636 *output_bool = FALSE;
10637 else if (strncmp(output, "1", 1) == 0)
10638 *output_bool = TRUE;
10639 else if (strncmp(output, "2", 1) == 0)
10640 *output_bool = TRUE;
10641 else if (strncmp(output, "3", 1) == 0)
10642 *output_bool = TRUE;
10643 else
10644 *output_bool = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080010645 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
10646
10647 return RETURN_OK;
10648}
10649
10650INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
10651{
10652 return RETURN_OK;
10653}
10654
10655INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
10656{
10657 return RETURN_OK;
10658}
10659
10660INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
10661{
10662 return RETURN_OK;
10663}
10664
10665INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10666{
10667 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10668 char config_file[MAX_BUF_SIZE] = {0};
10669
10670 if (NULL == output)
10671 return RETURN_ERR;
10672 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10673 wifi_hostapdRead(config_file,"hw_mode",output,64);
10674
10675 if(strcmp(output,"b")==0)
10676 sprintf(output, "%s", "1,2,5.5,11");
10677 else if (strcmp(output,"a")==0)
10678 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
10679 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
10680 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
10681
10682 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10683 return RETURN_OK;
10684}
10685
10686INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10687{
10688 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10689 char *temp;
10690 char temp_output[128];
10691 char temp_TransmitRates[128];
10692 char config_file[MAX_BUF_SIZE] = {0};
10693
10694 if (NULL == output)
10695 return RETURN_ERR;
10696
10697 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10698 wifi_hostapdRead(config_file,"supported_rates",output,64);
10699
10700 if (strlen(output) == 0) {
10701 wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
10702 return RETURN_OK;
10703 }
10704 strcpy(temp_TransmitRates,output);
10705 strcpy(temp_output,"");
10706 temp = strtok(temp_TransmitRates," ");
10707 while(temp!=NULL)
10708 {
10709 temp[strlen(temp)-1]=0;
10710 if((temp[0]=='5') && (temp[1]=='\0'))
10711 {
10712 temp="5.5";
10713 }
10714 strcat(temp_output,temp);
10715 temp = strtok(NULL," ");
10716 if(temp!=NULL)
10717 {
10718 strcat(temp_output,",");
10719 }
10720 }
10721 strcpy(output,temp_output);
10722 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10723
10724 return RETURN_OK;
10725}
10726
10727INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
10728{
10729 return RETURN_OK;
10730}
10731
10732
10733INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
10734{
10735 int i=0;
10736 char *temp;
10737 char temp1[128] = {0};
10738 char temp_output[128] = {0};
10739 char temp_TransmitRates[128] = {0};
10740 struct params params={'\0'};
10741 char config_file[MAX_BUF_SIZE] = {0};
10742 wifi_band band = wifi_index_to_band(wlanIndex);
10743
10744 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
10745 if(NULL == output)
10746 return RETURN_ERR;
10747 strcpy(temp_TransmitRates,output);
10748
10749 for(i=0;i<strlen(temp_TransmitRates);i++)
10750 {
10751 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
10752 {
10753 continue;
10754 }
10755 else
10756 {
10757 return RETURN_ERR;
10758 }
10759 }
10760 strcpy(temp_output,"");
10761 temp = strtok(temp_TransmitRates,",");
10762 while(temp!=NULL)
10763 {
10764 strcpy(temp1,temp);
10765 if(band == band_5)
10766 {
10767 if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
10768 {
10769 return RETURN_ERR;
10770 }
10771 }
10772
10773 if(strcmp(temp,"5.5")==0)
10774 {
10775 strcpy(temp1,"55");
10776 }
10777 else
10778 {
10779 strcat(temp1,"0");
10780 }
10781 strcat(temp_output,temp1);
10782 temp = strtok(NULL,",");
10783 if(temp!=NULL)
10784 {
10785 strcat(temp_output," ");
10786 }
10787 }
10788 strcpy(output,temp_output);
10789
10790 params.name = "supported_rates";
10791 params.value = output;
10792
10793 wifi_dbg_printf("\n%s:",__func__);
10794 wifi_dbg_printf("params.value=%s\n",params.value);
10795 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
10796 wifi_hostapdWrite(config_file,&params,1);
10797 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
10798
10799 return RETURN_OK;
10800}
10801
10802
10803static char *sncopy(char *dst, int dst_sz, const char *src)
10804{
10805 if (src && dst && dst_sz > 0) {
10806 strncpy(dst, src, dst_sz);
10807 dst[dst_sz - 1] = '\0';
10808 }
10809 return dst;
10810}
10811
10812static int util_get_sec_chan_offset(int channel, const char* ht_mode)
10813{
10814 if (0 == strcmp(ht_mode, "HT40") ||
10815 0 == strcmp(ht_mode, "HT80") ||
10816 0 == strcmp(ht_mode, "HT160")) {
10817 switch (channel) {
10818 case 1 ... 7:
10819 case 36:
10820 case 44:
10821 case 52:
10822 case 60:
10823 case 100:
10824 case 108:
10825 case 116:
10826 case 124:
10827 case 132:
10828 case 140:
10829 case 149:
10830 case 157:
10831 return 1;
10832 case 8 ... 13:
10833 case 40:
10834 case 48:
10835 case 56:
10836 case 64:
10837 case 104:
10838 case 112:
10839 case 120:
10840 case 128:
10841 case 136:
10842 case 144:
10843 case 153:
10844 case 161:
10845 return -1;
10846 default:
10847 return -EINVAL;
10848 }
10849 }
10850
10851 return -EINVAL;
10852}
10853
10854static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
10855{
10856 int idx = channel%8;
10857 if (0 == strcmp(ht_mode, "HT40") ||
10858 0 == strcmp(ht_mode, "HT80") ||
10859 0 == strcmp(ht_mode, "HT160")) {
10860 switch (idx) {
10861 case 1:
10862 return 1;
10863 case 5:
10864 return -1;
10865 default:
10866 return -EINVAL;
10867 }
10868 }
10869
10870 return -EINVAL;
10871}
10872static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
10873{
10874 if (NULL == hw_mode) return;
10875
10876 if (0 == strcmp(hw_mode, "ac"))
10877 sncopy(bw_mode, bw_mode_len, "ht vht");
10878
10879 if (0 == strcmp(hw_mode, "n"))
10880 sncopy(bw_mode, bw_mode_len, "ht");
10881
10882 return;
10883}
10884
10885static int util_chan_to_freq(int chan)
10886{
10887 if (chan == 14)
10888 return 2484;
10889 else if (chan < 14)
10890 return 2407 + chan * 5;
10891 else if (chan >= 182 && chan <= 196)
10892 return 4000 + chan * 5;
10893 else
10894 return 5000 + chan * 5;
10895 return 0;
10896}
10897
10898static int util_6G_chan_to_freq(int chan)
10899{
10900 if (chan)
10901 return 5950 + chan * 5;
10902 else
10903 return 0;
developer69b61b02023-03-07 17:17:44 +080010904
developer72fb0bb2023-01-11 09:46:29 +080010905}
10906const int *util_unii_5g_chan2list(int chan, int width)
10907{
10908 static const int lists[] = {
10909 // <width>, <chan1>, <chan2>..., 0,
10910 20, 36, 0,
10911 20, 40, 0,
10912 20, 44, 0,
10913 20, 48, 0,
10914 20, 52, 0,
10915 20, 56, 0,
10916 20, 60, 0,
10917 20, 64, 0,
10918 20, 100, 0,
10919 20, 104, 0,
10920 20, 108, 0,
10921 20, 112, 0,
10922 20, 116, 0,
10923 20, 120, 0,
10924 20, 124, 0,
10925 20, 128, 0,
10926 20, 132, 0,
10927 20, 136, 0,
10928 20, 140, 0,
10929 20, 144, 0,
10930 20, 149, 0,
10931 20, 153, 0,
10932 20, 157, 0,
10933 20, 161, 0,
10934 20, 165, 0,
10935 40, 36, 40, 0,
10936 40, 44, 48, 0,
10937 40, 52, 56, 0,
10938 40, 60, 64, 0,
10939 40, 100, 104, 0,
10940 40, 108, 112, 0,
10941 40, 116, 120, 0,
10942 40, 124, 128, 0,
10943 40, 132, 136, 0,
10944 40, 140, 144, 0,
10945 40, 149, 153, 0,
10946 40, 157, 161, 0,
10947 80, 36, 40, 44, 48, 0,
10948 80, 52, 56, 60, 64, 0,
10949 80, 100, 104, 108, 112, 0,
10950 80, 116, 120, 124, 128, 0,
10951 80, 132, 136, 140, 144, 0,
10952 80, 149, 153, 157, 161, 0,
10953 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
10954 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
10955 -1 // final delimiter
10956 };
10957 const int *start;
10958 const int *p;
10959
10960 for (p = lists; *p != -1; p++) {
10961 if (*p == width) {
10962 for (start = ++p; *p != 0; p++) {
10963 if (*p == chan)
10964 return start;
10965 }
10966 }
10967 // move to the end of channel list of given width
10968 while (*p != 0) {
10969 p++;
10970 }
10971 }
10972
10973 return NULL;
10974}
10975
10976static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
10977{
10978 if (NULL == ht_mode)
10979 return 0;
10980
10981 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
10982 const int *chans = util_unii_5g_chan2list(channel, width);
10983 int sum = 0;
10984 int cnt = 0;
10985
10986 if (NULL == chans)
10987 return 0;
10988
10989 while (*chans) {
10990 sum += *chans;
10991 cnt++;
10992 chans++;
10993 }
10994 if (cnt == 0)
10995 return 0;
10996 return sum / cnt;
10997}
10998
10999static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
11000{
11001 if (NULL == ht_mode)
11002 return 0;
11003
11004 int width = strtol((ht_mode + 2), NULL, 10);
11005
11006 int idx = 0 ;
11007 int centerchan = 0;
11008 int chan_ofs = 1;
11009
11010 if (width == 40){
11011 idx = ((channel/4) + chan_ofs)%2;
11012 switch (idx) {
11013 case 0:
11014 centerchan = (channel - 2);
11015 break;
11016 case 1:
11017 centerchan = (channel + 2);
developer69b61b02023-03-07 17:17:44 +080011018 break;
developer72fb0bb2023-01-11 09:46:29 +080011019 default:
11020 return -EINVAL;
11021 }
11022 }else if (width == 80){
developer69b61b02023-03-07 17:17:44 +080011023 idx = ((channel/4) + chan_ofs)%4;
developer72fb0bb2023-01-11 09:46:29 +080011024 switch (idx) {
11025 case 0:
11026 centerchan = (channel - 6);
11027 break;
11028 case 1:
11029 centerchan = (channel + 6);
11030 break;
11031 case 2:
11032 centerchan = (channel + 2);
11033 break;
11034 case 3:
11035 centerchan = (channel - 2);
11036 break;
11037 default:
11038 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080011039 }
developer72fb0bb2023-01-11 09:46:29 +080011040 }else if (width == 160){
11041 switch (channel) {
11042 case 1 ... 29:
11043 centerchan = 15;
11044 break;
11045 case 33 ... 61:
11046 centerchan = 47;
11047 break;
11048 case 65 ... 93:
11049 centerchan = 79;
11050 break;
11051 case 97 ... 125:
11052 centerchan = 111;
11053 break;
11054 case 129 ... 157:
11055 centerchan = 143;
11056 break;
11057 case 161 ... 189:
11058 centerchan = 175;
11059 break;
11060 case 193 ... 221:
11061 centerchan = 207;
11062 break;
11063 default:
11064 return -EINVAL;
developer69b61b02023-03-07 17:17:44 +080011065 }
developer72fb0bb2023-01-11 09:46:29 +080011066 }
11067 return centerchan;
11068}
11069static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
11070{
11071 BOOL onlyG, onlyN, onlyA;
11072 CHAR tmp[64];
11073 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
11074 if (ret == RETURN_OK) {
11075 sncopy(hw_mode, hw_mode_size, tmp);
11076 }
11077 return ret;
11078}
11079
11080INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
11081{
11082 // Sample commands:
11083 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
11084 // hostapd_cli -i wifi0 chan_switch 30 2437
developer72fb0bb2023-01-11 09:46:29 +080011085 int freq = 0, ret = 0;
11086 char center_freq1_str[32] = ""; // center_freq1=%d
11087 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
11088 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
11089 char hw_mode[16] = ""; // n|ac
11090 char bw_mode[16] = ""; // ht|ht vht
11091 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
11092 char interface_name[16] = {0};
11093 int sec_chan_offset;
11094 int width;
11095 char config_file[64] = {0};
11096 BOOL stbcEnable = FALSE;
11097 char *ext_str = "None";
11098 wifi_band band = band_invalid;
11099 int center_chan = 0;
11100 int center_freq1 = 0;
11101
11102 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex);
11103
11104 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
11105 return RETURN_ERR;
11106
11107 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11108
11109 band = wifi_index_to_band(radioIndex);
11110
11111 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
11112
11113 // Get radio mode HT20|HT40|HT80 etc.
11114 if (channel){
11115 if (band == band_6){
11116 freq = util_6G_chan_to_freq(channel);
11117 }else{
11118 freq = util_chan_to_freq(channel);
11119 }
11120 snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
11121
11122 // Provide bandwith if specified
11123 if (channel_width_MHz > 20) {
11124 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
11125 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
11126 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
11127
11128 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
11129 }else if (channel_width_MHz == 20){
11130 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
11131 }
11132
11133
11134 if (channel_width_MHz > 20) {
11135 if (band == band_6){
11136 center_chan = util_unii_6g_centerfreq(ht_mode, channel);
11137 if(center_chan){
11138 center_freq1 = util_6G_chan_to_freq(center_chan);
11139 }
11140 }else{
11141 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
11142 if(center_chan){
11143 center_freq1 = util_chan_to_freq(center_chan);
11144 }
11145 }
developer69b61b02023-03-07 17:17:44 +080011146
developer72fb0bb2023-01-11 09:46:29 +080011147 if (center_freq1)
11148 snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
developer69b61b02023-03-07 17:17:44 +080011149
developer72fb0bb2023-01-11 09:46:29 +080011150 }
11151
11152 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
11153 if (band == band_6){
11154 sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
11155 }else{
11156 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
11157 }
11158 if (sec_chan_offset != -EINVAL)
11159 snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
11160
11161 // Only the first AP, other are hanging on the same radio
developerfead3972023-05-25 20:15:02 +080011162 ret = wifi_setChannel_netlink(radioIndex, &channel, NULL);
developerd1824452023-05-18 12:30:04 +080011163 if (ret != RETURN_OK) {
developerfead3972023-05-25 20:15:02 +080011164 fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__);
developerd1824452023-05-18 12:30:04 +080011165 return RETURN_ERR;
11166 }
11167 /* wifi_dbg_printf("execute: '%s'\n", cmd);
developerf6a87542023-05-16 15:47:28 +080011168 ret = _syscmd(cmd, buf, sizeof(buf));
developerd1824452023-05-18 12:30:04 +080011169 wifi_reloadAp(radioIndex); */
developer72fb0bb2023-01-11 09:46:29 +080011170
11171 ret = wifi_setRadioChannel(radioIndex, channel);
11172 if (ret != RETURN_OK) {
11173 fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__);
11174 return RETURN_ERR;
11175 }
11176
developer262f4cb2023-05-24 12:22:04 +080011177 if (sec_chan_offset == 1)
11178 ext_str = "Above";
11179 else if (sec_chan_offset == -1)
11180 ext_str = "Below";
developer72fb0bb2023-01-11 09:46:29 +080011181
developerd1824452023-05-18 12:30:04 +080011182 /*wifi_setRadioCenterChannel(radioIndex, center_chan); */
developer72fb0bb2023-01-11 09:46:29 +080011183
11184 } else {
11185 if (channel_width_MHz > 20)
11186 ext_str = "Above";
11187 }
11188
11189 wifi_setRadioExtChannel(radioIndex, ext_str);
11190
11191 char mhz_str[16];
11192 snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
11193 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
11194
11195 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11196
11197 return RETURN_OK;
11198}
11199
11200INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
11201{
11202 int index = -1;
11203 wifi_neighbor_ap2_t *scan_array = NULL;
11204 char cmd[256]={0};
11205 char buf[128]={0};
11206 char file_name[32] = {0};
11207 char filter_SSID[32] = {0};
11208 char line[256] = {0};
11209 char interface_name[16] = {0};
11210 char *ret = NULL;
11211 int freq=0;
11212 FILE *f = NULL;
11213 size_t len=0;
11214 int channels_num = 0;
11215 int vht_channel_width = 0;
11216 int get_noise_ret = RETURN_ERR;
11217 bool filter_enable = false;
11218 bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd.
11219 int phyId = 0;
11220
11221 WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
11222
11223 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
11224 f = fopen(file_name, "r");
11225 if (f != NULL) {
11226 fgets(filter_SSID, sizeof(file_name), f);
11227 if (strlen(filter_SSID) != 0)
11228 filter_enable = true;
11229 fclose(f);
11230 }
11231
11232 if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK)
11233 return RETURN_ERR;
11234
11235 phyId = radio_index_to_phy(radio_index);
11236
11237 snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
11238 _syscmd(cmd, buf, sizeof(buf));
11239 channels_num = strtol(buf, NULL, 10);
11240
11241 sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
11242 // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
11243 fprintf(stderr, "cmd: %s\n", cmd);
11244 if ((f = popen(cmd, "r")) == NULL) {
11245 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11246 return RETURN_ERR;
11247 }
developer69b61b02023-03-07 17:17:44 +080011248
developer72fb0bb2023-01-11 09:46:29 +080011249 struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
11250 get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
developer69b61b02023-03-07 17:17:44 +080011251
developer72fb0bb2023-01-11 09:46:29 +080011252 ret = fgets(line, sizeof(line), f);
11253 while (ret != NULL) {
11254 if(strstr(line, "BSS") != NULL) { // new neighbor info
developer69b61b02023-03-07 17:17:44 +080011255 // 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 +080011256 // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
11257 // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
11258
11259 if (!filter_BSS) {
11260 index++;
11261 wifi_neighbor_ap2_t *tmp;
11262 tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
11263 if (tmp == NULL) { // no more memory to use
11264 index--;
11265 wifi_dbg_printf("%s: realloc failed\n", __func__);
11266 break;
11267 }
11268 scan_array = tmp;
11269 }
11270 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
11271
11272 filter_BSS = false;
11273 sscanf(line, "BSS %17s", scan_array[index].ap_BSSID);
11274 strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
11275 strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
11276 strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
11277 } else if (strstr(line, "freq") != NULL) {
11278 sscanf(line," freq: %d", &freq);
11279 scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
11280
11281 if (freq >= 2412 && freq <= 2484) {
11282 strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
11283 strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
11284 strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
11285 }
11286 else if (freq >= 5160 && freq <= 5805) {
11287 strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
11288 strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
11289 strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
11290 }
11291
11292 scan_array[index].ap_Noise = 0;
11293 if (get_noise_ret == RETURN_OK) {
11294 for (int i = 0; i < channels_num; i++) {
11295 if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
11296 scan_array[index].ap_Noise = channels_noise_arr[i].noise;
11297 break;
11298 }
11299 }
11300 }
11301 } else if (strstr(line, "beacon interval") != NULL) {
11302 sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod));
11303 } else if (strstr(line, "signal") != NULL) {
11304 sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength));
11305 } else if (strstr(line,"SSID") != NULL) {
11306 sscanf(line," SSID: %s", scan_array[index].ap_SSID);
11307 if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
11308 filter_BSS = true;
11309 }
11310 } else if (strstr(line, "Supported rates") != NULL) {
11311 char SRate[80] = {0}, *tmp = NULL;
11312 memset(buf, 0, sizeof(buf));
11313 strcpy(SRate, line);
11314 tmp = strtok(SRate, ":");
11315 tmp = strtok(NULL, ":");
11316 strcpy(buf, tmp);
11317 memset(SRate, 0, sizeof(SRate));
11318
11319 tmp = strtok(buf, " \n");
11320 while (tmp != NULL) {
11321 strcat(SRate, tmp);
11322 if (SRate[strlen(SRate) - 1] == '*') {
11323 SRate[strlen(SRate) - 1] = '\0';
11324 }
11325 strcat(SRate, ",");
11326
11327 tmp = strtok(NULL, " \n");
11328 }
11329 SRate[strlen(SRate) - 1] = '\0';
11330 strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate);
11331 } else if (strstr(line, "DTIM") != NULL) {
11332 sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf);
11333 } else if (strstr(line, "VHT capabilities") != NULL) {
11334 strcat(scan_array[index].ap_SupportedStandards, ",ac");
11335 strcpy(scan_array[index].ap_OperatingStandards, "ac");
11336 } else if (strstr(line, "HT capabilities") != NULL) {
11337 strcat(scan_array[index].ap_SupportedStandards, ",n");
11338 strcpy(scan_array[index].ap_OperatingStandards, "n");
11339 } else if (strstr(line, "VHT operation") != NULL) {
11340 ret = fgets(line, sizeof(line), f);
11341 sscanf(line," * channel width: %d", &vht_channel_width);
11342 if(vht_channel_width == 1) {
11343 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
11344 } else {
11345 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
11346 }
11347 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11348 continue;
11349 } else if (strstr(line, "HT operation") != NULL) {
11350 ret = fgets(line, sizeof(line), f);
11351 sscanf(line," * secondary channel offset: %s", &buf);
11352 if (!strcmp(buf, "above")) {
11353 //40Mhz +
11354 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
11355 }
11356 else if (!strcmp(buf, "below")) {
11357 //40Mhz -
11358 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
11359 } else {
11360 //20Mhz
11361 snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
11362 }
11363 if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information
11364 continue;
11365 } else if (strstr(line, "HE capabilities") != NULL) {
11366 strcat(scan_array[index].ap_SupportedStandards, ",ax");
11367 strcpy(scan_array[index].ap_OperatingStandards, "ax");
11368 ret = fgets(line, sizeof(line), f);
11369 if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
11370 if (strstr(line, "HE40/2.4GHz") != NULL)
11371 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS");
11372 else
11373 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20");
11374 } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
11375 if (strstr(line, "HE80/5GHz") != NULL) {
11376 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80");
11377 ret = fgets(line, sizeof(line), f);
11378 } else
11379 continue;
11380 if (strstr(line, "HE160/5GHz") != NULL)
11381 strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160");
11382 }
11383 continue;
11384 } else if (strstr(line, "WPA") != NULL) {
11385 strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA");
11386 } else if (strstr(line, "RSN") != NULL) {
11387 strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN");
11388 } else if (strstr(line, "Group cipher") != NULL) {
11389 sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode);
11390 if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
11391 strcpy(scan_array[index].ap_EncryptionMode, "AES");
11392 }
11393 }
11394 ret = fgets(line, sizeof(line), f);
11395 }
11396
11397 if (!filter_BSS) {
11398 *output_array_size = index + 1;
11399 } else {
11400 memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
11401 *output_array_size = index;
11402 }
11403 *neighbor_ap_array = scan_array;
11404 pclose(f);
11405 free(channels_noise_arr);
11406 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11407 return RETURN_OK;
11408}
11409
11410INT wifi_getApAssociatedDeviceStats(
11411 INT apIndex,
11412 mac_address_t *clientMacAddress,
11413 wifi_associated_dev_stats_t *associated_dev_stats,
11414 u64 *handle)
11415{
11416 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
11417 char interface_name[50] = {0};
11418 char cmd[1024] = {0};
11419 char mac_str[18] = {0};
11420 char *key = NULL;
11421 char *val = NULL;
11422 FILE *f = NULL;
11423 char *line = NULL;
11424 size_t len = 0;
11425
11426 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11427 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11428 return RETURN_ERR;
11429 }
11430
11431 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
11432 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
11433 if((f = popen(cmd, "r")) == NULL) {
11434 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
11435 return RETURN_ERR;
11436 }
11437
11438 while ((getline(&line, &len, f)) != -1) {
11439 key = strtok(line,":");
11440 val = strtok(NULL,":");
11441
11442 if(!strncmp(key,"rx bytes",8))
11443 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
11444 if(!strncmp(key,"tx bytes",8))
11445 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
11446 if(!strncmp(key,"rx packets",10))
11447 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11448 if(!strncmp(key,"tx packets",10))
11449 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
11450 if(!strncmp(key,"tx retries",10))
11451 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
11452 if(!strncmp(key,"tx failed",9))
11453 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
11454 if(!strncmp(key,"rx drop misc",13))
11455 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
11456 if(!strncmp(key,"rx bitrate",10)) {
11457 val = strtok(val, " ");
11458 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
11459 }
11460 if(!strncmp(key,"tx bitrate",10)) {
11461 val = strtok(val, " ");
11462 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
11463 }
11464 }
11465 free(line);
11466 pclose(f);
11467 return RETURN_OK;
11468}
11469
11470INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
11471{
developer7e4a2a62023-04-06 19:56:03 +080011472 char interface_name[IF_NAME_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080011473 char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0};
11474
developer7e4a2a62023-04-06 19:56:03 +080011475 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11476
developer72fb0bb2023-01-11 09:46:29 +080011477 if (NULL == output_string)
11478 return RETURN_ERR;
11479
11480 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
11481 return RETURN_ERR;
developer7e4a2a62023-04-06 19:56:03 +080011482
11483 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 +080011484 _syscmd(cmd, buf, sizeof(buf));
11485
11486 //size of SSID name restricted to value less than 32 bytes
11487 snprintf(output_string, 32, "%s", buf);
developer7e4a2a62023-04-06 19:56:03 +080011488 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
developer72fb0bb2023-01-11 09:46:29 +080011489
11490 return RETURN_OK;
11491}
11492
11493INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
11494{
developer2edaf012023-05-24 14:24:53 +080011495 char *mac_arry_buf = NULL;
11496 INT policy = -1;
11497 INT buf_size = 1024;
developer72fb0bb2023-01-11 09:46:29 +080011498
developer2edaf012023-05-24 14:24:53 +080011499 mac_arry_buf = malloc(buf_size);
11500 if (!mac_arry_buf) {
11501 wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
developer7e4a2a62023-04-06 19:56:03 +080011502 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080011503 }
11504 memset(mac_arry_buf, 0, buf_size);
11505 if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
11506 wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
11507 goto err;
11508 }
11509 /*
11510 mtk format to get policy:
11511 "policy=1
11512 00:11:22:33:44:55
11513 00:11:22:33:44:66
11514 "
11515 */
11516 if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
11517 wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
11518 goto err;
11519 }
11520 if (!(policy >=0 && policy <= 2)){
11521 wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
11522 goto err;
11523 }
11524 *output_filterMode = policy;
11525 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
11526 free(mac_arry_buf);
11527 mac_arry_buf = NULL;
11528 return RETURN_OK;
11529err:
11530 free(mac_arry_buf);
11531 mac_arry_buf = NULL;
11532 wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
11533 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011534}
11535
developer2edaf012023-05-24 14:24:53 +080011536
developer72fb0bb2023-01-11 09:46:29 +080011537INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
11538{
11539 FILE *fp = NULL;
11540 char str[MAX_BUF_SIZE] = {0};
11541 int wificlientindex = 0 ;
11542 int count = 0;
11543 int signalstrength = 0;
11544 int arr[MACADDRESS_SIZE] = {0};
11545 unsigned char mac[MACADDRESS_SIZE] = {0};
11546 UINT wifi_count = 0;
11547 char virtual_interface_name[MAX_BUF_SIZE] = {0};
11548 char pipeCmd[MAX_CMD_SIZE] = {0};
11549
11550 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11551 *output_array_size = 0;
11552 *associated_dev_array = NULL;
11553 char interface_name[50] = {0};
11554
11555 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
11556 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
11557 return RETURN_ERR;
11558 }
11559
11560 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
11561 fp = popen(pipeCmd, "r");
11562 if (fp == NULL)
11563 {
11564 printf("Failed to run command inside function %s\n",__FUNCTION__ );
11565 return RETURN_ERR;
11566 }
11567
11568 /* Read the output a line at a time - output it. */
11569 fgets(str, sizeof(str)-1, fp);
11570 wifi_count = (unsigned int) atoi ( str );
11571 *output_array_size = wifi_count;
11572 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
11573 pclose(fp);
11574
11575 if(wifi_count == 0)
11576 {
11577 return RETURN_OK;
11578 }
11579 else
11580 {
11581 wifi_associated_dev2_t* temp = NULL;
11582 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
11583 *associated_dev_array = temp;
11584 if(temp == NULL)
11585 {
11586 printf("Error Statement. Insufficient memory \n");
11587 return RETURN_ERR;
11588 }
11589
11590 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
11591 system(pipeCmd);
11592
11593 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
11594 if(fp == NULL)
11595 {
11596 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
11597 return RETURN_ERR;
11598 }
11599 fclose(fp);
11600
11601 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
11602 fp = popen(pipeCmd, "r");
11603 if(fp)
11604 {
11605 for(count =0 ; count < wifi_count; count++)
11606 {
11607 fgets(str, MAX_BUF_SIZE, fp);
11608 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
11609 {
11610 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
11611 {
11612 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
11613
11614 }
11615 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
11616 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]);
11617 }
11618 temp[count].cli_AuthenticationState = 1; //TODO
11619 temp[count].cli_Active = 1; //TODO
11620 }
11621 pclose(fp);
11622 }
11623
11624 //Updating RSSI per client
11625 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
11626 fp = popen(pipeCmd, "r");
11627 if(fp)
11628 {
11629 pclose(fp);
11630 }
11631 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
11632 if(fp)
11633 {
11634 for(count =0 ; count < wifi_count ;count++)
11635 {
11636 fgets(str, MAX_BUF_SIZE, fp);
11637 signalstrength = atoi(str);
11638 temp[count].cli_RSSI = signalstrength;
11639 }
11640 pclose(fp);
11641 }
11642
11643
11644 //LastDataDownlinkRate
11645 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
11646 fp = popen(pipeCmd, "r");
11647 if (fp)
11648 {
11649 pclose(fp);
11650 }
11651 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
11652 if (fp)
11653 {
11654 for (count = 0; count < wifi_count; count++)
11655 {
11656 fgets(str, MAX_BUF_SIZE, fp);
11657 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
11658 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
11659 }
11660 pclose(fp);
11661 }
11662
11663 //LastDataUplinkRate
11664 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
11665 fp = popen(pipeCmd, "r");
11666 if (fp)
11667 {
11668 pclose(fp);
11669 }
11670 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
11671 if (fp)
11672 {
11673 for (count = 0; count < wifi_count; count++)
11674 {
11675 fgets(str, MAX_BUF_SIZE, fp);
11676 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
11677 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
11678 }
11679 pclose(fp);
11680 }
11681 }
11682 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11683 return RETURN_OK;
11684
11685}
11686
11687INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
11688{
11689#if 0
11690 /*char buf[1024] = {0};
11691 sprintf(cmd, "ifconfig %s ", interface_name);
11692 _syscmd(cmd, buf, sizeof(buf));*/
11693
11694 output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters.
11695 output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters.
11696 output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface.
11697 output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface.
11698
11699 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.
11700 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].
11701 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].
11702 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].
11703 output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012].
11704 output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac.
11705
11706 output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors.
11707 output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11708 output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
11709 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.
11710 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.
11711 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.
11712 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.
11713 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.
11714 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.
11715 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.
11716 output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol.
11717#endif
11718
11719 FILE *fp = NULL;
11720 char interface_name[50] = {0};
11721 char pipeCmd[128] = {0};
11722 char str[256] = {0};
11723 wifi_ssidTrafficStats2_t *out = output_struct;
11724
11725 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
11726 if (!output_struct)
11727 return RETURN_ERR;
11728
11729 memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
11730 if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
11731 return RETURN_ERR;
11732 sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name);
11733
11734 fp = popen(pipeCmd, "r");
11735 if (fp == NULL) {
11736 fprintf(stderr, "%s: popen failed\n", __func__);
11737 return RETURN_ERR;
11738 }
11739 fgets(str, sizeof(str), fp);
11740 pclose(fp);
11741
11742 if (strlen(str) == 0) // interface not exist
11743 return RETURN_OK;
11744
11745 sscanf(str, "%*[^:]: %lu %lu %lu %lu %* %* %* %* %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
11746 &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
11747
11748 memset(str, 0, sizeof(str));
11749 sprintf(pipeCmd, "tail -n1 /proc/net/netstat");
11750 fp = popen(pipeCmd, "r");
11751 if (fp == NULL) {
11752 fprintf(stderr, "%s: popen failed\n", __func__);
11753 return RETURN_ERR;
11754 }
11755 fgets(str, sizeof(str), fp);
11756
11757 sscanf(str, "%*[^:]: %* %* %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
11758 &out->ssid_BroadcastPacketsSent);
11759 pclose(fp);
11760
11761 out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
11762 out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
11763
11764 // Not supported
11765 output_struct->ssid_RetransCount = 0;
11766 output_struct->ssid_FailedRetransCount = 0;
11767 output_struct->ssid_RetryCount = 0;
11768 output_struct->ssid_MultipleRetryCount = 0;
11769 output_struct->ssid_ACKFailureCount = 0;
11770 output_struct->ssid_AggregatedPacketCount = 0;
11771
11772 return RETURN_OK;
11773}
11774
11775//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).
11776INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
11777{
11778 char output_val[16]={'\0'};
11779 char config_file[MAX_BUF_SIZE] = {0};
11780
11781 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11782 if (!output)
11783 return RETURN_ERR;
11784 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11785 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
11786
11787 if( strcmp(output_val,"1") == 0 )
11788 *output = TRUE;
11789 else
11790 *output = FALSE;
11791 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11792
11793 return RETURN_OK;
11794}
11795
11796INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
11797{
11798 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11799 char str[MAX_BUF_SIZE]={'\0'};
11800 char string[MAX_BUF_SIZE]={'\0'};
11801 char cmd[MAX_CMD_SIZE]={'\0'};
11802 char *ch;
11803 char config_file[MAX_BUF_SIZE] = {0};
11804 struct params params;
11805
11806 if(enable == TRUE)
11807 strcpy(string,"1");
11808 else
11809 strcpy(string,"0");
11810
11811 params.name = "ap_isolate";
11812 params.value = string;
11813
11814 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
11815 wifi_hostapdWrite(config_file,&params,1);
11816 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11817
11818 return RETURN_OK;
11819}
11820
11821INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
11822{
developera1255e42023-05-13 17:45:02 +080011823 char mgmtpwr_file[32] = {0};
11824 char cmd[64] = {0};
11825 char buf[32]={0};
11826
developer72fb0bb2023-01-11 09:46:29 +080011827 if (NULL == output_dBm)
11828 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080011829 snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
11830 snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file);
11831 _syscmd(cmd, buf, sizeof(buf));
11832 if (strlen(buf) > 0)
11833 *output_dBm = strtol(buf, NULL, 10);
11834 else
11835 *output_dBm = 23;
developer72fb0bb2023-01-11 09:46:29 +080011836 return RETURN_OK;
11837}
11838
11839INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
11840{
developera1255e42023-05-13 17:45:02 +080011841 char interface_name[16] = {0};
developera1255e42023-05-13 17:45:02 +080011842 char mgmt_pwr_file[128]={0};
11843 FILE *f = NULL;
developerfead3972023-05-25 20:15:02 +080011844 int if_idx, ret = 0;
11845 struct nl_msg *msg = NULL;
11846 struct nlattr * msg_data = NULL;
11847 struct mtk_nl80211_param param;
11848 struct unl unl_ins;
11849 char power[16] = {0};
developera1255e42023-05-13 17:45:02 +080011850
11851 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11852
11853 if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
11854 return RETURN_ERR;
developerfead3972023-05-25 20:15:02 +080011855
11856 if_idx = if_nametoindex(interface_name);
11857 /*init mtk nl80211 vendor cmd*/
11858 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
11859 param.if_type = NL80211_ATTR_IFINDEX;
11860 param.if_idx = if_idx;
11861
11862 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
11863 if (ret) {
11864 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
11865 return RETURN_ERR;
11866 }
11867
11868 /*add mtk vendor cmd data*/
11869 snprintf(power, sizeof(power), "%d", dBm);
11870 if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
11871 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
11872 nlmsg_free(msg);
11873 goto err;
11874 }
11875
11876 /*send mtk nl80211 vendor msg*/
11877 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
11878 if (ret) {
11879 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
11880 goto err;
11881 }
11882
11883 /*deinit mtk nl80211 vendor msg*/
11884 mtk_nl80211_deint(&unl_ins);
11885 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
11886
developera1255e42023-05-13 17:45:02 +080011887 snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
11888 f = fopen(mgmt_pwr_file, "w");
11889 if (f == NULL) {
11890 fprintf(stderr, "%s: fopen failed\n", __func__);
11891 return RETURN_ERR;
11892 }
11893 fprintf(f, "%d", dBm);
11894 fclose(f);
developer72fb0bb2023-01-11 09:46:29 +080011895 return RETURN_OK;
developerfead3972023-05-25 20:15:02 +080011896err:
11897 mtk_nl80211_deint(&unl_ins);
11898 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
11899 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080011900}
11901INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
11902{
11903 return RETURN_OK;
11904}
11905INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
11906{
11907 return RETURN_OK;
11908}
11909INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
11910{
11911 return RETURN_OK;
11912}
11913INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
11914{
11915 return RETURN_OK;
11916}
11917INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
11918{
11919 char config_file[MAX_BUF_SIZE] = {0};
11920 struct params list;
11921
11922 list.name = "bss_transition";
11923 list.value = activate?"1":"0";
11924 snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
11925 wifi_hostapdWrite(config_file, &list, 1);
11926
11927 return RETURN_OK;
11928}
11929wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
11930
11931void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
11932{
11933 return;
11934}
11935
11936INT wifi_setApCsaDeauth(INT apIndex, INT mode)
11937{
11938 // TODO Implement me!
11939 return RETURN_OK;
11940}
11941
11942INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
11943{
11944 char file_name[128] = {0};
11945 char buf[128] = {0};
11946 FILE *f = NULL;
11947 int max_num_radios = 0;
11948
11949 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
11950
11951 wifi_getMaxRadioNumber(&max_num_radios);
11952 if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
11953 for (int index = 0; index < max_num_radios; index++) {
11954 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
11955 f = fopen(file_name, "w");
11956 if (f == NULL)
11957 return RETURN_ERR;
11958 // For mode == 0 is to disable filter, just don't write to the file.
11959 if (mode)
11960 fprintf(f, "%s", essid);
11961
11962 fclose(f);
11963 }
11964 } else { // special case, need to set AP's SSID as filter for each radio.
11965 snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
11966 f = fopen(file_name, "w");
11967 if (f == NULL)
11968 return RETURN_ERR;
11969
11970 // For mode == 0 is to disable filter, just don't write to the file.
11971 if (mode)
11972 fprintf(f, "%s", essid);
11973
11974 fclose(f);
11975 }
11976
11977 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
11978 return RETURN_OK;
11979}
11980
11981INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
11982{
11983 // TODO Implement me!
11984 //Apply wifi_pushRadioChannel() instantly
11985 return RETURN_ERR;
11986}
11987
11988INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
11989{
11990 // TODO Implement me!
11991 return RETURN_OK;
11992}
11993
11994#ifdef HAL_NETLINK_IMPL
11995static int tidStats_callback(struct nl_msg *msg, void *arg) {
11996 struct nlattr *tb[NL80211_ATTR_MAX + 1];
11997 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
11998 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
11999 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
12000 int rem , tid_index = 0;
12001
12002 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
12003 wifi_associated_dev_tid_entry_t *stats_entry;
12004
12005 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
12006 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
12007 };
12008 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
12009 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
12010 };
12011
12012 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
12013 genlmsg_attrlen(gnlh, 0), NULL);
12014
12015
12016 if (!tb[NL80211_ATTR_STA_INFO]) {
12017 fprintf(stderr, "station stats missing!\n");
12018 return NL_SKIP;
12019 }
12020
12021 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
12022 tb[NL80211_ATTR_STA_INFO],
12023 stats_policy)) {
12024 fprintf(stderr, "failed to parse nested attributes!\n");
12025 return NL_SKIP;
12026 }
12027
developer386281b2023-05-20 15:43:13 +080012028 if (sinfo[NL80211_STA_INFO_TID_STATS]) {
12029 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
12030 {
12031 stats_entry = &out->tid_array[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080012032
developer386281b2023-05-20 15:43:13 +080012033 stats_entry->tid = tid_index;
12034 stats_entry->ac = _tid_ac_index_get[tid_index];
developer72fb0bb2023-01-11 09:46:29 +080012035
developer386281b2023-05-20 15:43:13 +080012036 if(sinfo[NL80211_STA_INFO_TID_STATS])
12037 {
12038 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
12039 printf("failed to parse nested stats attributes!");
12040 return NL_SKIP;
12041 }
developer72fb0bb2023-01-11 09:46:29 +080012042 }
developer386281b2023-05-20 15:43:13 +080012043 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12044 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
developer72fb0bb2023-01-11 09:46:29 +080012045
developer386281b2023-05-20 15:43:13 +080012046 if(tid_index < (PS_MAX_TID - 1))
12047 tid_index++;
12048 }
developer72fb0bb2023-01-11 09:46:29 +080012049 }
12050 //ToDo: sum_time_ms, ewma_time_ms
12051 return NL_SKIP;
12052}
12053#endif
12054
12055INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
12056{
12057#ifdef HAL_NETLINK_IMPL
12058 Netlink nl;
12059 char if_name[10];
12060 char interface_name[16] = {0};
12061
12062 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12063 return RETURN_ERR;
12064
12065 snprintf(if_name, sizeof(if_name), "%s", interface_name);
12066
12067 nl.id = initSock80211(&nl);
12068
12069 if (nl.id < 0) {
12070 fprintf(stderr, "Error initializing netlink \n");
12071 return -1;
12072 }
12073
12074 struct nl_msg* msg = nlmsg_alloc();
12075
12076 if (!msg) {
12077 fprintf(stderr, "Failed to allocate netlink message.\n");
12078 nlfree(&nl);
12079 return -2;
12080 }
12081
12082 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012083 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012084 NL_AUTO_SEQ,
12085 nl.id,
12086 0,
12087 0,
12088 NL80211_CMD_GET_STATION,
12089 0);
12090
12091 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12092 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12093 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
developer8dd72532023-05-17 19:58:35 +080012094 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012095 nl_recvmsgs(nl.socket, nl.cb);
12096 nlmsg_free(msg);
12097 nlfree(&nl);
12098 return RETURN_OK;
12099#else
12100//iw implementation
12101#define TID_STATS_FILE "/tmp/tid_stats_file.txt"
12102#define TOTAL_MAX_LINES 50
12103
12104 char buf[256] = {'\0'}; /* or other suitable maximum line size */
12105 char if_name[32] = {0};
12106 FILE *fp=NULL;
12107 char pipeCmd[1024]= {'\0'};
12108 int lines,tid_index=0;
12109 char mac_addr[20] = {'\0'};
12110
12111 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12112 return RETURN_ERR;
12113
12114 wifi_associated_dev_tid_entry_t *stats_entry;
12115
12116 strcpy(mac_addr,clientMacAddress);
12117
12118 snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name);
12119 fp= popen(pipeCmd,"r");
12120 if(fp == NULL)
12121 {
12122 perror("popen for station dump failed\n");
12123 return RETURN_ERR;
12124 }
12125 pclose(fp);
12126
12127 snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1");
12128 fp=popen(pipeCmd,"r");
12129 if(fp == NULL)
12130 {
12131 perror("popen for grep station failed\n");
12132 return RETURN_ERR;
12133 }
12134 else if(fgets(buf,sizeof(buf),fp) != NULL)
12135 lines=atoi(buf);
12136 else
12137 {
12138 pclose(fp);
12139 fprintf(stderr,"No devices are connected \n");
12140 return RETURN_ERR;
12141 }
12142 pclose(fp);
12143
12144 if(lines == 1)
12145 lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output
12146
12147 for(tid_index=0; tid_index<PS_MAX_TID; tid_index++)
12148 {
12149 stats_entry = &tid_stats->tid_array[tid_index];
12150 stats_entry->tid = tid_index;
12151
12152 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);
12153
12154 fp=popen(pipeCmd,"r");
12155 if(fp ==NULL)
12156 {
12157 perror("Failed to read from tid file \n");
12158 return RETURN_ERR;
12159 }
12160 else if(fgets(buf,sizeof(buf),fp) != NULL)
12161 stats_entry->num_msdus = atol(buf);
12162
12163 pclose(fp);
12164 stats_entry->ac = _tid_ac_index_get[tid_index];
12165// TODO:
12166// ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus
12167// ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval
12168 }
12169 return RETURN_OK;
12170#endif
12171}
12172
12173
12174INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
12175{
12176 char interface_name[16] = {0};
12177 char cmd[128]={0};
12178 char buf[128]={0};
12179 int freq = 0;
12180
12181 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12182
12183 // full mode is used to scan all channels.
12184 // multiple channels is ambiguous, iw can not set multiple frequencies in one time.
12185 if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
12186 ieee80211_channel_to_frequency(chan_list[0], &freq);
12187
12188 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
12189 return RETURN_ERR;
12190
12191 if (freq)
12192 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
12193 else
12194 snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
12195
12196 _syscmd(cmd, buf, sizeof(buf));
12197 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12198
12199 return RETURN_OK;
12200}
12201
12202
12203INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
12204{
12205 // TODO Implement me!
12206 return RETURN_ERR;
12207}
12208
12209INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
12210{
12211 // TODO Implement me!
12212 return RETURN_ERR;
12213}
12214
12215INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
12216{
12217 // TODO Implement me!
12218 return RETURN_ERR;
12219}
12220
12221INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
12222{
12223 // TODO Implement me!
12224 return RETURN_ERR;
12225}
12226
12227INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
12228{
12229 // TODO Implement me!
12230 return RETURN_ERR;
12231}
12232
12233INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
12234{
12235 // TODO Implement me!
12236 return RETURN_ERR;
12237}
12238
12239INT wifi_steering_eventUnregister(void)
12240{
12241 // TODO Implement me!
12242 return RETURN_ERR;
12243}
12244
12245INT wifi_delApAclDevices(INT apIndex)
12246{
developer7e4a2a62023-04-06 19:56:03 +080012247 char inf_name[IF_NAME_SIZE] = {0};
developer2edaf012023-05-24 14:24:53 +080012248 struct unl unl_ins;
12249 int if_idx = 0, ret = 0;
12250 struct nl_msg *msg = NULL;
12251 struct nlattr * msg_data = NULL;
12252 struct mtk_nl80211_param param;
developer72fb0bb2023-01-11 09:46:29 +080012253
developer7e4a2a62023-04-06 19:56:03 +080012254 if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
12255 return RETURN_ERR;
developer2edaf012023-05-24 14:24:53 +080012256 if_idx = if_nametoindex(inf_name);
12257 if (!if_idx) {
12258 wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
12259 return RETURN_ERR;
12260 }
12261 /*init mtk nl80211 vendor cmd*/
12262 param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
12263 param.if_type = NL80211_ATTR_IFINDEX;
12264 param.if_idx = if_idx;
12265 ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
12266 if (ret) {
12267 wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
12268 return RETURN_ERR;
12269 }
12270 /*add mtk vendor cmd data*/
12271 if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
12272 wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
12273 nlmsg_free(msg);
12274 goto err;
12275 }
12276 /*send mtk nl80211 vendor msg*/
12277 ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
12278 if (ret) {
12279 wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
12280 goto err;
12281 }
12282 /*deinit mtk nl80211 vendor msg*/
12283 mtk_nl80211_deint(&unl_ins);
12284 wifi_debug(DEBUG_NOTICE, "set cmd success.\n");
12285 return RETURN_OK;
12286err:
12287 mtk_nl80211_deint(&unl_ins);
12288 wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
12289 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080012290
12291 return RETURN_OK;
12292}
12293
12294#ifdef HAL_NETLINK_IMPL
12295static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
12296 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12297 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12298 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12299 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12300 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12301 char mac_addr[20],dev[20];
12302
12303 nla_parse(tb,
12304 NL80211_ATTR_MAX,
12305 genlmsg_attrdata(gnlh, 0),
12306 genlmsg_attrlen(gnlh, 0),
12307 NULL);
12308
12309 if(!tb[NL80211_ATTR_STA_INFO]) {
12310 fprintf(stderr, "sta stats missing!\n");
12311 return NL_SKIP;
12312 }
12313
12314 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12315 fprintf(stderr, "failed to parse nested attributes!\n");
12316 return NL_SKIP;
12317 }
12318 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
12319
12320 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12321
developer386281b2023-05-20 15:43:13 +080012322 if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12323 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
12324 fprintf(stderr, "failed to parse nested rate attributes!");
12325 return NL_SKIP;
12326 }
developer72fb0bb2023-01-11 09:46:29 +080012327 }
12328
12329 if(sinfo[NL80211_STA_INFO_TID_STATS])
12330 {
12331 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12332 printf("failed to parse nested stats attributes!");
12333 return NL_SKIP;
12334 }
12335 }
developer5a1194f2023-05-24 16:00:03 +080012336 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developer72fb0bb2023-01-11 09:46:29 +080012337
developereb1ea832023-05-24 14:46:27 +080012338 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
12339 {
12340 printf("Type is VHT\n");
12341 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12342 ((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 +080012343
developereb1ea832023-05-24 14:46:27 +080012344 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12345 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
12346 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12347 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12348 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12349 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12350 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12351 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
12352 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
12353 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12354 }
12355 else
12356 {
12357 printf(" OFDM or CCK \n");
12358 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
12359 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
12360 }
12361 }
developer72fb0bb2023-01-11 09:46:29 +080012362
developereff896f2023-05-29 14:52:55 +080012363 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
12364 if(rinfo[NL80211_RATE_INFO_MCS])
12365 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12366 }
12367 if(sinfo[NL80211_STA_INFO_RX_BYTES64])
12368 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
12369 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
12370 ((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 +080012371
developereff896f2023-05-29 14:52:55 +080012372 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12373 if(stats_info[NL80211_TID_STATS_RX_MSDU])
12374 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
12375 }
developer72fb0bb2023-01-11 09:46:29 +080012376
developereff896f2023-05-29 14:52:55 +080012377 if (sinfo[NL80211_STA_INFO_SIGNAL])
12378 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
12379 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
12380 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
12381 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
12382 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
12383 //rssi_array need to be filled
12384 return NL_SKIP;
developer72fb0bb2023-01-11 09:46:29 +080012385}
12386#endif
12387
12388INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12389{
12390#ifdef HAL_NETLINK_IMPL
12391 Netlink nl;
12392 char if_name[32];
12393 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12394 return RETURN_ERR;
12395
12396 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
12397
12398 if (*output_array_size <= 0)
12399 return RETURN_OK;
12400
12401 nl.id = initSock80211(&nl);
12402
12403 if (nl.id < 0) {
12404 fprintf(stderr, "Error initializing netlink \n");
12405 return 0;
12406 }
12407
12408 struct nl_msg* msg = nlmsg_alloc();
12409
12410 if (!msg) {
12411 fprintf(stderr, "Failed to allocate netlink message.\n");
12412 nlfree(&nl);
12413 return 0;
12414 }
12415
12416 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012417 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012418 NL_AUTO_SEQ,
12419 nl.id,
12420 0,
12421 0,
12422 NL80211_CMD_GET_STATION,
12423 0);
12424
12425 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
12426 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12427 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012428 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012429 nl_recvmsgs(nl.socket, nl.cb);
12430 nlmsg_free(msg);
12431 nlfree(&nl);
12432 return RETURN_OK;
12433#else
12434 //TODO Implement me
12435 return RETURN_OK;
12436#endif
12437}
12438
12439#ifdef HAL_NETLINK_IMPL
12440static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
12441 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12442 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12443 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
12444 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
12445 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
12446 char mac_addr[20],dev[20];
12447
12448 nla_parse(tb,
12449 NL80211_ATTR_MAX,
12450 genlmsg_attrdata(gnlh, 0),
12451 genlmsg_attrlen(gnlh, 0),
12452 NULL);
12453
12454 if(!tb[NL80211_ATTR_STA_INFO]) {
12455 fprintf(stderr, "sta stats missing!\n");
12456 return NL_SKIP;
12457 }
12458
12459 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
12460 fprintf(stderr, "failed to parse nested attributes!\n");
12461 return NL_SKIP;
12462 }
12463
12464 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
12465
12466 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12467
developer386281b2023-05-20 15:43:13 +080012468 if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12469 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
12470 fprintf(stderr, "failed to parse nested rate attributes!");
12471 return NL_SKIP;
12472 }
developer72fb0bb2023-01-11 09:46:29 +080012473 }
12474
12475 if(sinfo[NL80211_STA_INFO_TID_STATS])
12476 {
12477 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
12478 printf("failed to parse nested stats attributes!");
12479 return NL_SKIP;
12480 }
12481 }
developera6beea42023-05-24 16:44:05 +080012482 if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
developereb1ea832023-05-24 14:46:27 +080012483 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
12484 {
12485 printf("Type is VHT\n");
12486 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
12487 ((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 +080012488
developereb1ea832023-05-24 14:46:27 +080012489 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
12490 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
12491 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
12492 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12493 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
12494 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12495 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
12496 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
12497 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
12498 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
12499 }
12500 else
12501 {
12502 printf(" OFDM or CCK \n");
developer72fb0bb2023-01-11 09:46:29 +080012503 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
developereb1ea832023-05-24 14:46:27 +080012504 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
12505 }
developer72fb0bb2023-01-11 09:46:29 +080012506 }
12507
12508 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
12509 if(rinfo[NL80211_RATE_INFO_MCS])
12510 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
12511 }
12512
12513 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
12514 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
12515 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
12516 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
12517
12518 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
developereff896f2023-05-29 14:52:55 +080012519 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
12520 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
developer72fb0bb2023-01-11 09:46:29 +080012521
developereff896f2023-05-29 14:52:55 +080012522 if(sinfo[NL80211_STA_INFO_TID_STATS]) {
12523 if(stats_info[NL80211_TID_STATS_TX_MSDU])
12524 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
12525 }
developer72fb0bb2023-01-11 09:46:29 +080012526
12527 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
12528 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
12529
developereff896f2023-05-29 14:52:55 +080012530 if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
12531 ((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 +080012532
12533 return NL_SKIP;
12534}
12535#endif
12536
12537INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
12538{
12539#ifdef HAL_NETLINK_IMPL
12540 Netlink nl;
12541 char if_name[10];
12542 char interface_name[16] = {0};
12543 if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK)
12544 return RETURN_ERR;
12545
12546 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
12547
12548 if (*output_array_size <= 0)
12549 return RETURN_OK;
12550
12551 snprintf(if_name, sizeof(if_name), "%s", interface_name);
12552
12553 nl.id = initSock80211(&nl);
12554
12555 if(nl.id < 0) {
12556 fprintf(stderr, "Error initializing netlink \n");
12557 return 0;
12558 }
12559
12560 struct nl_msg* msg = nlmsg_alloc();
12561
12562 if(!msg) {
12563 fprintf(stderr, "Failed to allocate netlink message.\n");
12564 nlfree(&nl);
12565 return 0;
12566 }
12567
12568 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012569 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012570 NL_AUTO_SEQ,
12571 nl.id,
12572 0,
12573 0,
12574 NL80211_CMD_GET_STATION,
12575 0);
12576
12577 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
12578 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
12579 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
developer8dd72532023-05-17 19:58:35 +080012580 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012581 nl_recvmsgs(nl.socket, nl.cb);
12582 nlmsg_free(msg);
12583 nlfree(&nl);
12584 return RETURN_OK;
12585#else
12586 //TODO Implement me
12587 return RETURN_OK;
12588#endif
12589}
12590
12591INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
12592{
12593 // TODO Implement me!
12594 char buf[MAX_BUF_SIZE] = {0};
12595 char config_file[MAX_BUF_SIZE] = {0};
12596
12597 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
12598 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
12599 *activate = (strncmp("1",buf,1) == 0);
12600
12601 return RETURN_OK;
12602}
12603
12604INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
12605{
12606 char config_file[MAX_BUF_SIZE] = {0};
12607 struct params list;
12608
12609 list.name = "rrm_neighbor_report";
12610 list.value = activate?"1":"0";
12611 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12612 wifi_hostapdWrite(config_file, &list, 1);
12613
12614 return RETURN_OK;
12615}
12616
12617INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
12618{
12619 char buf[32] = {0};
12620 char config_file[MAX_BUF_SIZE] = {0};
12621
12622 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
12623 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
12624 *activate = (strncmp("1",buf,1) == 0);
12625
12626 return RETURN_OK;
12627}
12628#undef HAL_NETLINK_IMPL
12629#ifdef HAL_NETLINK_IMPL
12630static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
12631 struct nlattr *tb[NL80211_ATTR_MAX + 1];
12632 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
12633 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
12634 char dev[20];
12635 int freq =0 ;
12636 static int i=0;
12637
12638 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
12639
12640 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
12641 };
12642
12643 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
12644
12645 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
12646
12647 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
12648 fprintf(stderr, "survey data missing!\n");
12649 return NL_SKIP;
12650 }
12651
12652 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
12653 {
12654 fprintf(stderr, "failed to parse nested attributes!\n");
12655 return NL_SKIP;
12656 }
12657
12658
12659 if(out[0].array_size == 1 )
12660 {
12661 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
12662 {
12663 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12664 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12665 out[0].ch_number = ieee80211_frequency_to_channel(freq);
12666
12667 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12668 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12669 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12670 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12671 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12672 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12673 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12674 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12675 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12676 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12677 if (sinfo[NL80211_SURVEY_INFO_TIME])
12678 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12679 return NL_STOP;
12680 }
12681 }
12682 else
12683 {
12684 if ( i <= out[0].array_size )
12685 {
12686 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
12687 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
12688 out[i].ch_number = ieee80211_frequency_to_channel(freq);
12689
12690 if (sinfo[NL80211_SURVEY_INFO_NOISE])
12691 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
12692 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
12693 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
12694 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
12695 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
12696 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
12697 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
12698 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
12699 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
12700 if (sinfo[NL80211_SURVEY_INFO_TIME])
12701 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
12702 }
12703 }
12704
12705 i++;
12706 return NL_SKIP;
12707}
12708#endif
12709
12710static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
12711{
12712 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
12713 FILE *fp;
12714
12715 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
12716 {
12717 printf("Creating Frequency-Channel Map\n");
12718 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
12719 }
12720 snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
12721 if((fp = popen(command, "r")))
12722 {
12723 fgets(output, sizeof(output), fp);
12724 *freqMHz = atoi(output);
12725 pclose(fp);
12726 }
12727
12728 return 0;
12729}
12730
12731static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz)
12732{
12733 int freqMHz = -1;
12734 char cmd[MAX_CMD_SIZE] = {'\0'};
12735 char interface_name[16] = {0};
12736
12737 ieee80211_channel_to_frequency(channel, &freqMHz);
12738 if (freqMHz == -1) {
12739 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
12740 return -1;
12741 }
12742
12743 wifi_GetInterfaceName(radioIndex, interface_name);
12744 if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) {
12745 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
12746 radioIndex, freqMHz);
12747 return -1;
12748 }
12749
12750 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
12751 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
12752 return -1;
12753 }
12754
12755 return 0;
12756}
12757
12758static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
12759{
12760 const char *ptr = buf;
12761 char *key = NULL;
12762 char *val = NULL;
12763 char line[256] = { '\0' };
12764
12765 while (ptr = get_line_from_str_buf(ptr, line)) {
12766 if (strstr(line, "Frequency")) continue;
12767
12768 key = strtok(line, ":");
12769 val = strtok(NULL, " ");
12770 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
12771
12772 if (!strcmp(key, "noise")) {
12773 sscanf(val, "%d", &stats->ch_noise);
12774 if (stats->ch_noise == 0) {
12775 // Workaround for missing noise information.
12776 // Assume -95 for 2.4G and -103 for 5G
12777 if (radioIndex == 0) stats->ch_noise = -95;
12778 if (radioIndex == 1) stats->ch_noise = -103;
12779 }
12780 }
12781 else if (!strcmp(key, "channel active time")) {
12782 sscanf(val, "%llu", &stats->ch_utilization_total);
12783 }
12784 else if (!strcmp(key, "channel busy time")) {
12785 sscanf(val, "%llu", &stats->ch_utilization_busy);
12786 }
12787 else if (!strcmp(key, "channel receive time")) {
12788 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
12789 }
12790 else if (!strcmp(key, "channel transmit time")) {
12791 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
12792 }
12793 };
12794
12795 return 0;
12796}
12797
12798INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
12799{
12800 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
12801#ifdef HAL_NETLINK_IMPL
12802 Netlink nl;
12803 wifi_channelStats_t_loc local[array_size];
12804 char if_name[32];
12805
12806 local[0].array_size = array_size;
12807
12808 if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK)
12809 return RETURN_ERR;
12810
12811 nl.id = initSock80211(&nl);
12812
12813 if (nl.id < 0) {
12814 fprintf(stderr, "Error initializing netlink \n");
12815 return -1;
12816 }
12817
12818 struct nl_msg* msg = nlmsg_alloc();
12819
12820 if (!msg) {
12821 fprintf(stderr, "Failed to allocate netlink message.\n");
12822 nlfree(&nl);
12823 return -2;
12824 }
12825
12826 genlmsg_put(msg,
developer8dd72532023-05-17 19:58:35 +080012827 NL_AUTO_PID,
developer72fb0bb2023-01-11 09:46:29 +080012828 NL_AUTO_SEQ,
12829 nl.id,
12830 0,
12831 NLM_F_DUMP,
12832 NL80211_CMD_GET_SURVEY,
12833 0);
12834
12835 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
developer8dd72532023-05-17 19:58:35 +080012836 nl_send_auto_complete(nl.socket, msg);
developer72fb0bb2023-01-11 09:46:29 +080012837 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
12838 nl_recvmsgs(nl.socket, nl.cb);
12839 nlmsg_free(msg);
12840 nlfree(&nl);
12841 //Copying the Values
12842 for(int i=0;i<array_size;i++)
12843 {
12844 input_output_channelStats_array[i].ch_number = local[i].ch_number;
12845 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
12846 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
12847 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
12848 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
12849 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
12850 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
12851 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
12852 }
12853#else
12854 ULONG channel = 0;
12855 int i;
12856 int number_of_channels = array_size;
12857 char buf[512];
12858 INT ret;
12859 wifi_channelStats_t tmp_stats;
12860
12861 if (number_of_channels == 0) {
12862 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
12863 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
12864 return RETURN_ERR;
12865 }
12866 number_of_channels = 1;
12867 input_output_channelStats_array[0].ch_number = channel;
12868 }
12869
12870 for (i = 0; i < number_of_channels; i++) {
12871
12872 input_output_channelStats_array[i].ch_noise = 0;
12873 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
12874 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
12875 input_output_channelStats_array[i].ch_utilization_busy = 0;
12876 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
12877 input_output_channelStats_array[i].ch_utilization_total = 0;
12878
12879 memset(buf, 0, sizeof(buf));
12880 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
12881 return RETURN_ERR;
12882 }
12883 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
12884 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
12885 return RETURN_ERR;
12886 }
12887
12888 // XXX: fake missing 'self' counter which is not available in iw survey output
12889 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
12890 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
12891
12892 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
12893 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
12894 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
12895 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
12896 input_output_channelStats_array[i].ch_utilization_total *= 1000;
12897
12898 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",
12899 __func__,
12900 input_output_channelStats_array[i].ch_number,
12901 input_output_channelStats_array[i].ch_noise,
12902 input_output_channelStats_array[i].ch_utilization_total,
12903 input_output_channelStats_array[i].ch_utilization_busy,
12904 input_output_channelStats_array[i].ch_utilization_busy_rx,
12905 input_output_channelStats_array[i].ch_utilization_busy_tx,
12906 input_output_channelStats_array[i].ch_utilization_busy_self,
12907 input_output_channelStats_array[i].ch_utilization_busy_ext);
12908 }
12909#endif
12910 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
12911 return RETURN_OK;
12912}
12913#define HAL_NETLINK_IMPL
12914
12915/* Hostapd events */
12916
12917#ifndef container_of
12918#define offset_of(st, m) ((size_t)&(((st *)0)->m))
12919#define container_of(ptr, type, member) \
12920 ((type *)((char *)ptr - offset_of(type, member)))
12921#endif /* container_of */
12922
12923struct ctrl {
12924 char sockpath[128];
12925 char sockdir[128];
12926 char bss[IFNAMSIZ];
12927 char reply[4096];
12928 int ssid_index;
12929 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
12930 void (*overrun)(struct ctrl *ctrl);
12931 struct wpa_ctrl *wpa;
12932 unsigned int ovfl;
12933 size_t reply_len;
12934 int initialized;
12935 ev_timer retry;
12936 ev_timer watchdog;
12937 ev_stat stat;
12938 ev_io io;
12939};
12940static wifi_newApAssociatedDevice_callback clients_connect_cb;
12941static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
12942static struct ctrl wpa_ctrl[MAX_APS];
12943static int initialized;
12944
12945static unsigned int ctrl_get_drops(struct ctrl *ctrl)
12946{
12947 char cbuf[256] = {};
12948 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
12949 struct cmsghdr *cmsg;
12950 unsigned int ovfl = ctrl->ovfl;
12951 unsigned int drop;
12952
12953 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
12954 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
12955 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
12956 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
12957
12958 drop = ovfl - ctrl->ovfl;
12959 ctrl->ovfl = ovfl;
12960
12961 return drop;
12962}
12963
12964static void ctrl_close(struct ctrl *ctrl)
12965{
12966 if (ctrl->io.cb)
12967 ev_io_stop(EV_DEFAULT_ &ctrl->io);
12968 if (ctrl->retry.cb)
12969 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
12970 if (!ctrl->wpa)
12971 return;
12972
12973 wpa_ctrl_detach(ctrl->wpa);
12974 wpa_ctrl_close(ctrl->wpa);
12975 ctrl->wpa = NULL;
12976 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
12977}
12978
12979static void ctrl_process(struct ctrl *ctrl)
12980{
12981 const char *str;
12982 int drops;
12983 int level;
12984 int err;
12985
12986 /* Example events:
12987 *
12988 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
12989 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
12990 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
12991 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
12992 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
12993 */
12994 if (!(str = index(ctrl->reply, '>')))
12995 return;
12996 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
12997 return;
12998
12999 str++;
13000
13001 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
13002 if (!(str = index(ctrl->reply, ' ')))
13003 return;
13004 wifi_associated_dev_t sta;
13005 memset(&sta, 0, sizeof(sta));
13006
13007 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
13008 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
13009 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
13010
13011 sta.cli_Active=true;
13012
13013 (clients_connect_cb)(ctrl->ssid_index, &sta);
13014 goto handled;
13015 }
13016
13017 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
13018 if (!(str = index(ctrl->reply, ' ')))
13019 return;
13020
13021 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
13022 goto handled;
13023 }
13024
13025 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
13026 printf("CTRL_WPA: handle TERMINATING event\n");
13027 goto retry;
13028 }
13029
13030 if (strncmp("AP-DISABLED", str, 11) == 0) {
13031 printf("CTRL_WPA: handle AP-DISABLED\n");
13032 goto retry;
13033 }
13034
13035 printf("Event not supported!!\n");
13036
13037handled:
13038
13039 if ((drops = ctrl_get_drops(ctrl))) {
13040 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
13041 if (ctrl->overrun)
13042 ctrl->overrun(ctrl);
13043 }
13044
13045 return;
13046
13047retry:
13048 printf("WPA_CTRL: closing\n");
13049 ctrl_close(ctrl);
13050 printf("WPA_CTRL: retrying from ctrl prcoess\n");
13051 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
13052}
13053
13054static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
13055{
13056 struct ctrl *ctrl = container_of(io, struct ctrl, io);
13057 int err;
13058
13059 memset(ctrl->reply, 0, sizeof(ctrl->reply));
13060 ctrl->reply_len = sizeof(ctrl->reply) - 1;
13061 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
13062 ctrl->reply[ctrl->reply_len] = 0;
13063 if (err < 0) {
13064 if (errno == EAGAIN || errno == EWOULDBLOCK)
13065 return;
13066 ctrl_close(ctrl);
13067 ev_timer_again(EV_A_ &ctrl->retry);
13068 return;
13069 }
13070
13071 ctrl_process(ctrl);
13072}
13073
13074static int ctrl_open(struct ctrl *ctrl)
13075{
13076 int fd;
13077
13078 if (ctrl->wpa)
13079 return 0;
13080
13081 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
13082 if (!ctrl->wpa)
13083 goto err;
13084
13085 if (wpa_ctrl_attach(ctrl->wpa) < 0)
13086 goto err_close;
13087
13088 fd = wpa_ctrl_get_fd(ctrl->wpa);
13089 if (fd < 0)
13090 goto err_detach;
13091
13092 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
13093 goto err_detach;
13094
13095 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
13096 ev_io_start(EV_DEFAULT_ &ctrl->io);
13097
13098 return 0;
13099
13100err_detach:
13101 wpa_ctrl_detach(ctrl->wpa);
13102err_close:
13103 wpa_ctrl_close(ctrl->wpa);
13104err:
13105 ctrl->wpa = NULL;
13106 return -1;
13107}
13108
13109static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
13110{
13111 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
13112
13113 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
13114 ctrl_open(ctrl);
13115}
13116
13117static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
13118{
13119 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
13120
13121 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
13122 if (ctrl_open(ctrl) == 0) {
13123 printf("WPA_CTRL: retry successful\n");
13124 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
13125 }
13126}
13127
13128int ctrl_enable(struct ctrl *ctrl)
13129{
13130 if (ctrl->wpa)
13131 return 0;
13132
13133 if (!ctrl->stat.cb) {
13134 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
13135 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
13136 }
13137
13138 if (!ctrl->retry.cb) {
13139 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
13140 }
13141
13142 return ctrl_open(ctrl);
13143}
13144
13145static void
13146ctrl_msg_cb(char *buf, size_t len)
13147{
13148 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
13149
13150 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
13151 ctrl_process(ctrl);
13152}
13153
13154static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
13155{
13156 int err;
13157
13158 if (!ctrl->wpa)
13159 return -1;
13160 if (*reply_len < 2)
13161 return -1;
13162
13163 (*reply_len)--;
13164 ctrl->reply_len = sizeof(ctrl->reply);
13165 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
13166 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
13167 if (err < 0)
13168 return err;
13169
13170 if (ctrl->reply_len > *reply_len)
13171 ctrl->reply_len = *reply_len;
13172
13173 *reply_len = ctrl->reply_len;
13174 memcpy(reply, ctrl->reply, *reply_len);
13175 reply[*reply_len - 1] = 0;
13176 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
13177 return 0;
13178}
13179
13180static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
13181{
13182 const char *pong = "PONG";
13183 const char *ping = "PING";
13184 char reply[1024];
13185 size_t len = sizeof(reply);
13186 int err;
13187 ULONG s, snum;
13188 INT ret;
13189 BOOL status;
13190
13191 printf("WPA_CTRL: watchdog cb\n");
13192
13193 ret = wifi_getSSIDNumberOfEntries(&snum);
13194 if (ret != RETURN_OK) {
13195 printf("%s: failed to get SSID count", __func__);
13196 return;
13197 }
13198
13199 if (snum > MAX_APS) {
13200 printf("more ssid than supported! %lu\n", snum);
13201 return;
13202 }
13203
13204 for (s = 0; s < snum; s++) {
13205 if (wifi_getApEnable(s, &status) != RETURN_OK) {
13206 printf("%s: failed to get AP Enable for index: %lu\n", __func__, s);
13207 continue;
13208 }
13209 if (status == false) continue;
13210
13211 memset(reply, 0, sizeof(reply));
13212 len = sizeof(reply);
13213 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
13214 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
13215 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
13216 continue;
13217
13218 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
13219 ctrl_close(&wpa_ctrl[s]);
13220 printf("WPA_CTRL: ev_timer_again %lu\n", s);
13221 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
13222 }
13223}
13224
13225static int init_wpa()
13226{
13227 int ret = 0, i = 0;
13228 ULONG s, snum;
13229
13230 ret = wifi_getSSIDNumberOfEntries(&snum);
13231 if (ret != RETURN_OK) {
13232 printf("%s: failed to get SSID count", __func__);
13233 return RETURN_ERR;
13234 }
13235
13236 if (snum > MAX_APS) {
13237 printf("more ssid than supported! %lu\n", snum);
13238 return RETURN_ERR;
13239 }
13240
13241 for (s = 0; s < snum; s++) {
13242 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
13243 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
13244 wpa_ctrl[s].ssid_index = s;
13245 ctrl_enable(&wpa_ctrl[s]);
13246 }
13247
13248 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
13249 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
13250
13251 initialized = 1;
13252 printf("WPA_CTRL: initialized\n");
13253
13254 return RETURN_OK;
13255}
13256
13257void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
13258{
13259 clients_connect_cb = callback_proc;
13260 if (!initialized)
13261 init_wpa();
13262}
13263
13264void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
13265{
13266 clients_disconnect_cb = callback_proc;
13267 if (!initialized)
13268 init_wpa();
13269}
13270
13271INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
13272{
13273 // TODO Implement me!
13274 return RETURN_ERR;
13275}
13276
13277INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
13278{
13279 // TODO Implement me!
13280 return RETURN_ERR;
13281}
13282
13283INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
13284{
13285 int i;
developerd1824452023-05-18 12:30:04 +080013286 int phyId = -1;
13287 char cmd[256] = {0};
13288 char channel_numbers_buf[256] = {0};
13289 char dfs_state_buf[256] = {0};
13290 char line[256] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013291 const char *ptr;
developerd1824452023-05-18 12:30:04 +080013292 BOOL dfs_enable = false;
developer72fb0bb2023-01-11 09:46:29 +080013293
developerd1824452023-05-18 12:30:04 +080013294 memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
developer72fb0bb2023-01-11 09:46:29 +080013295
developerd1824452023-05-18 12:30:04 +080013296 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
13297 phyId = radio_index_to_phy(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013298
developerd1824452023-05-18 12:30:04 +080013299 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 +080013300
developerd1824452023-05-18 12:30:04 +080013301 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
13302 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13303 return RETURN_ERR;
developer72fb0bb2023-01-11 09:46:29 +080013304 }
13305
developerd1824452023-05-18 12:30:04 +080013306 ptr = channel_numbers_buf;
13307 i = 0;
13308 while (ptr = get_line_from_str_buf(ptr, line)) {
13309 if (i >= outputMapSize) {
13310 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
13311 return RETURN_ERR;
13312 }
13313 sscanf(line, "%d", &outputMap[i].ch_number);
13314
13315 memset(cmd, 0, sizeof(cmd));
13316 // Below command should fetch string for DFS state (usable, available or unavailable)
13317 // Example line: "DFS state: usable (for 78930 sec)"
13318 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) {
13319 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
developer72fb0bb2023-01-11 09:46:29 +080013320 return RETURN_ERR;
13321 }
13322
developerd1824452023-05-18 12:30:04 +080013323 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
13324 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
developer72fb0bb2023-01-11 09:46:29 +080013325 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
13326 return RETURN_ERR;
13327 }
13328
developerd1824452023-05-18 12:30:04 +080013329 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
developer59fda4f2023-05-16 15:47:38 +080013330
developerd1824452023-05-18 12:30:04 +080013331 if (!strcmp(dfs_state_buf, "usable")) {
13332 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
13333 } else if (!strcmp(dfs_state_buf, "available")) {
13334 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
13335 } else if (!strcmp(dfs_state_buf, "unavailable")) {
13336 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
13337 } else {
13338 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
developer72fb0bb2023-01-11 09:46:29 +080013339 }
developerd1824452023-05-18 12:30:04 +080013340 i++;
developer59fda4f2023-05-16 15:47:38 +080013341 }
developer40ba1762023-05-13 11:03:49 +080013342
developerd1824452023-05-18 12:30:04 +080013343 return RETURN_OK;
13344
developer72fb0bb2023-01-11 09:46:29 +080013345 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
13346 return RETURN_ERR;
13347}
13348
13349INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
13350{
13351 // TODO Implement me!
13352 return RETURN_ERR;
13353}
13354
13355INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
13356{
13357 return RETURN_OK;
13358}
13359
13360INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
13361{
13362 // TODO Implement me!
13363 return RETURN_ERR;
13364}
13365
13366INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
13367{
13368 // TODO API refrence Implementaion is present on RPI hal
13369 return RETURN_ERR;
13370}
13371
13372INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
13373{
developera1255e42023-05-13 17:45:02 +080013374/*
developer72fb0bb2023-01-11 09:46:29 +080013375 char interface_name[16] = {0};
13376 char cmd[128]={'\0'};
13377 char buf[128]={'\0'};
13378 char *support;
13379 int maximum_tx = 0, current_tx = 0;
developera1255e42023-05-13 17:45:02 +080013380*/ ULONG pwr_percentage = 0;
developer72fb0bb2023-01-11 09:46:29 +080013381
13382 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13383 if(txpwr_pcntg == NULL)
13384 return RETURN_ERR;
13385
developera1255e42023-05-13 17:45:02 +080013386 wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
13387 *txpwr_pcntg = pwr_percentage;
13388/* if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
developer72fb0bb2023-01-11 09:46:29 +080013389 return RETURN_ERR;
13390
13391 // Get the maximum tx power of the device
13392 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name);
13393 _syscmd(cmd, buf, sizeof(buf));
13394 maximum_tx = strtol(buf, NULL, 10);
13395
13396 // Get the current tx power
13397 memset(cmd, 0, sizeof(cmd));
13398 memset(buf, 0, sizeof(buf));
13399 snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name);
13400 _syscmd(cmd, buf, sizeof(buf));
13401 current_tx = strtol(buf, NULL, 10);
13402
13403 // Get the power supported list and find the current power percentage in supported list
13404 memset(buf, 0, sizeof(buf));
13405 wifi_getRadioTransmitPowerSupported(apIndex, buf);
13406 support = strtok(buf, ",");
13407 while(true)
13408 {
13409 if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal.
13410 *txpwr_pcntg = 100;
13411 wifi_dbg_printf("current power is not in supported list\n");
13412 return RETURN_OK;
13413 }
13414 int tmp = maximum_tx*strtol(support, NULL, 10)/100;
13415 if (tmp == current_tx) {
13416 *txpwr_pcntg = strtol(support, NULL, 10);
13417 break;
13418 }
13419 support = strtok(NULL, ",");
13420 }
developera1255e42023-05-13 17:45:02 +080013421*/
developer72fb0bb2023-01-11 09:46:29 +080013422 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13423 return RETURN_OK;
13424}
13425
13426INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
13427{
13428 // TODO precac feature.
developerd1824452023-05-18 12:30:04 +080013429 struct params params[2] = {0};
developer72fb0bb2023-01-11 09:46:29 +080013430 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080013431 BOOL dfs_enable = false;
13432 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080013433
13434 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
developerd1824452023-05-18 12:30:04 +080013435 band = wifi_index_to_band(radioIndex);
13436 wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
developer72fb0bb2023-01-11 09:46:29 +080013437
developerd1824452023-05-18 12:30:04 +080013438 if (dfs_enable == false) {
13439 WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
13440 return RETURN_ERR;
13441 }
13442 params[0].name = "DfsZeroWaitDefault";
13443 params[0].value = enable?"1":"0";
13444 params[1].name = "DfsDedicatedZeroWait";
13445 params[1].value = enable?"1":"0";
13446 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13447 wifi_datfileWrite(config_file, params, 2);
developerc0772e62023-05-18 15:10:48 +080013448 wifi_reloadAp(radioIndex);
developer72fb0bb2023-01-11 09:46:29 +080013449 /* TODO precac feature */
13450
13451 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13452 return RETURN_OK;
13453}
13454
13455INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
13456{
13457 char config_file[128] = {0};
developerd1824452023-05-18 12:30:04 +080013458 char buf1[32] = {0};
13459 char buf2[32] = {0};
13460 wifi_band band = band_invalid;
developer72fb0bb2023-01-11 09:46:29 +080013461
13462 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13463 if (NULL == enable || NULL == precac)
13464 return RETURN_ERR;
developerd1824452023-05-18 12:30:04 +080013465 band = wifi_index_to_band(radioIndex);
13466 snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13467 wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
13468 wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
13469 if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
developer72fb0bb2023-01-11 09:46:29 +080013470 *enable = true;
13471 else
13472 *enable = false;
13473
13474 /* TODO precac feature */
13475
13476 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13477 return RETURN_OK;
13478}
13479
13480INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
13481{
13482 *supported = TRUE;
13483 return RETURN_OK;
13484}
13485
13486INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
13487{
developera1255e42023-05-13 17:45:02 +080013488 UCHAR dat_file[64] = {0};
13489 wifi_band band = band_invalid;
13490 char cmd[128] = {0};
13491 char buf[256] = {0};
13492 char ofdmabuf[32] = {'\0'};
13493 char mimobuf[32] = {'\0'};
13494 char new_ofdmabuf[32] = {'\0'};
13495 char new_mimobuf[32] = {'\0'};
13496 struct params params[2];
13497 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13498 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13499 UCHAR bss_cnt = 0;
13500 UCHAR val_cnt = 0;
13501 char *token = NULL;
developer72fb0bb2023-01-11 09:46:29 +080013502
developera1255e42023-05-13 17:45:02 +080013503 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13504 if ((mu_type < WIFI_DL_MU_TYPE_NONE)
13505 || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
13506 printf("%s:mu_type input Error", __func__);
13507 return RETURN_ERR;
13508 }
13509 band = wifi_index_to_band(radio_index);
13510 if (band == band_invalid) {
13511 printf("%s:Band Error\n", __func__);
13512 return RETURN_ERR;
13513 }
13514 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13515 /*get current value in dat file*/
13516 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13517 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
13518 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13519 get_bssnum_byindex(radio_index, &bss_cnt);
13520 val_cnt = 2*bss_cnt - 1;
13521 WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
13522 if ((val_cnt >= sizeof(new_ofdmabuf))
13523 || (val_cnt >= sizeof(new_mimobuf))) {
13524 printf("%s:bss cnt Error", __func__, bss_cnt);
13525 return RETURN_ERR;
13526 }
13527 /*translate set value*/
13528 if (mu_type == WIFI_DL_MU_TYPE_NONE) {
13529 strncpy(new_ofdmabuf, str_zero, val_cnt);
13530 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013531 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
developera1255e42023-05-13 17:45:02 +080013532 strncpy(new_ofdmabuf, str_one, val_cnt);
13533 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013534 } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
developera1255e42023-05-13 17:45:02 +080013535 strncpy(new_ofdmabuf, str_zero, val_cnt);
13536 strncpy(new_mimobuf, str_one, val_cnt);
13537 } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
13538 strncpy(new_ofdmabuf, str_one, val_cnt);
13539 strncpy(new_mimobuf, str_one, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013540 }
developera1255e42023-05-13 17:45:02 +080013541 WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13542 /*same value, not operation*/
13543 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13544 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13545 printf("%s:Reduntant value\n", __func__);
13546 return RETURN_OK;
13547 }
13548 /*modify dat file to new file*/
13549 params[0].name="MuOfdmaDlEnable";
13550 params[0].value=new_ofdmabuf;
13551 params[1].name="MuMimoDlEnable";
13552 params[1].value=new_mimobuf;
13553 wifi_datfileWrite(dat_file, params, 2);
13554 /*hostapd control restarp ap to take effect on these new value*/
13555 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013556 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13557 return RETURN_OK;
13558}
13559
13560INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
13561{
13562 struct params params={0};
13563 char config_file[64] = {0};
13564 char buf[64] = {0};
13565 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080013566 UCHAR dat_file[64] = {0};
13567 wifi_band band = band_invalid;
13568 char ofdmabuf[32] = {'\0'};
13569 char mimobuf[32] = {'\0'};
13570 char *token = NULL;
13571 UCHAR ofdma = 0;
13572 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013573
13574 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13575
13576 if (mu_type == NULL)
13577 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013578 band = wifi_index_to_band(radio_index);
13579 if (band == band_invalid) {
13580 printf("%s:Band Error\n", __func__);
13581 return RETURN_ERR;
13582 }
13583 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13584 /*get current value in dat file*/
13585 wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
13586 wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013587
developera1255e42023-05-13 17:45:02 +080013588 token = strtok(ofdmabuf, ";");
13589 ofdma = strtol(token, NULL, 10);
13590 token = strtok(mimobuf, ";");
13591 mimo = strtol(token, NULL, 10);
13592 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo);
13593 if ((ofdma == 1) && (mimo == 1))
13594 *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
13595 else if ((ofdma == 0) && (mimo == 1))
13596 *mu_type = WIFI_DL_MU_TYPE_MIMO;
13597 else if ((ofdma == 1) && (mimo == 0))
13598 *mu_type = WIFI_DL_MU_TYPE_OFDMA;
13599 else
13600 *mu_type = WIFI_DL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013601 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13602 return RETURN_OK;
13603}
13604
13605INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
13606{
13607 // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
developera1255e42023-05-13 17:45:02 +080013608 UCHAR dat_file[64] = {0};
13609 wifi_band band = band_invalid;
13610 char cmd[128] = {0};
13611 char buf[256] = {0};
13612 char ofdmabuf[32] = {'\0'};
13613 char mimobuf[32] = {'\0'};
13614 char new_ofdmabuf[32] = {'\0'};
13615 char new_mimobuf[32] = {'\0'};
13616 struct params params[2];
13617 char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
13618 char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
13619 UCHAR bss_cnt = 0;
13620 UCHAR val_cnt = 0;
developer72fb0bb2023-01-11 09:46:29 +080013621
developera1255e42023-05-13 17:45:02 +080013622 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13623 band = wifi_index_to_band(radio_index);
13624 if (band == band_invalid) {
13625 printf("%s:Band Error\n", __func__);
13626 return RETURN_ERR;
13627 }
13628 if ((mu_type < WIFI_UL_MU_TYPE_NONE)
13629 || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
13630 printf("%s:mu_type input Error\n", __func__);
13631 return RETURN_ERR;
13632 }
13633 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13634 /*get current value in dat file*/
13635 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13636 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
13637 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
13638 get_bssnum_byindex(radio_index, &bss_cnt);
13639 val_cnt = 2*bss_cnt - 1;
13640 printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
13641 if ((val_cnt >= sizeof(new_ofdmabuf))
13642 || (val_cnt >= sizeof(new_mimobuf))) {
13643 printf("%s:bss cnt Error\n", __func__, val_cnt);
13644 return RETURN_ERR;
13645 }
13646 /*translate set value*/
13647 if (mu_type == WIFI_UL_MU_TYPE_NONE) {
13648 strncpy(new_ofdmabuf, str_zero, val_cnt);
13649 strncpy(new_mimobuf, str_zero, val_cnt);
developer72fb0bb2023-01-11 09:46:29 +080013650 }
developera1255e42023-05-13 17:45:02 +080013651 if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
13652 strncpy(new_ofdmabuf, str_one, val_cnt);
13653 strncpy(new_mimobuf, str_zero, val_cnt);
13654 }
13655 printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
13656 /*same value, not operation*/
13657 if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
13658 && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
13659 printf("%s:Reduntant value\n", __func__);
13660 return RETURN_OK;
13661 }
13662 /*modify dat file to new file*/
13663 params[0].name="MuOfdmaUlEnable";
13664 params[0].value=new_ofdmabuf;
13665 params[1].name="MuMimoUlEnable";
13666 params[1].value=new_mimobuf;
13667 wifi_datfileWrite(dat_file, params, 2);
13668 wifi_reloadAp(radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013669 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13670 return RETURN_OK;
13671}
13672
13673INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
13674{
13675 struct params params={0};
13676 char config_file[64] = {0};
13677 char buf[64] = {0};
13678 unsigned int get_mu_type = 0;
developera1255e42023-05-13 17:45:02 +080013679 UCHAR dat_file[64] = {0};
13680 wifi_band band = band_invalid;
13681 char ofdmabuf[32] = {'\0'};
13682 char mimobuf[32] = {'\0'};
13683 char *token = NULL;
13684 UCHAR ofdma = 0;
13685 UCHAR mimo = 0;
developer72fb0bb2023-01-11 09:46:29 +080013686
13687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13688
13689 if (mu_type == NULL)
13690 return RETURN_ERR;
developera1255e42023-05-13 17:45:02 +080013691 band = wifi_index_to_band(radio_index);
13692 if (band == band_invalid) {
13693 printf("%s:Band Error", __func__);
13694 return RETURN_ERR;
13695 }
13696 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13697 /*get current value in dat file*/
13698 wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
13699 wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
developer72fb0bb2023-01-11 09:46:29 +080013700
developera1255e42023-05-13 17:45:02 +080013701 token = strtok(ofdmabuf, ";");
13702 ofdma = strtol(token, NULL, 10);
13703 token = strtok(mimobuf, ";");
13704 mimo = strtol(token, NULL, 10);
13705 WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
13706 if ((ofdma == 1) && (mimo == 0))
13707 *mu_type = WIFI_UL_MU_TYPE_OFDMA;
13708 else
13709 *mu_type = WIFI_UL_MU_TYPE_NONE;
developer72fb0bb2023-01-11 09:46:29 +080013710 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13711 return RETURN_OK;
13712}
13713
13714
13715INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
13716{
13717 char cmd[128] = {0};
13718 char buf[256] = {0};
13719 char config_file[64] = {0};
13720 char GI[8] = {0};
13721 int mode_map = 0;
13722 FILE *f = NULL;
13723 wifi_band band = band_invalid;
developera1255e42023-05-13 17:45:02 +080013724 char dat_file[64] = {'\0'};
13725 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080013726
13727 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13728
13729 if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
13730 wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__);
13731 return RETURN_ERR;
13732 }
developera1255e42023-05-13 17:45:02 +080013733 /*sanity check*/
13734 if (((guard_interval == wifi_guard_interval_1600)
13735 || (guard_interval == wifi_guard_interval_3200))
13736 && (mode_map & (WIFI_MODE_BE | WIFI_MODE_AX) == 0)) {
13737 wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__);
13738 return RETURN_ERR;
13739 }
developer72fb0bb2023-01-11 09:46:29 +080013740 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
13741 band = wifi_index_to_band(radio_index);
13742
13743 // Hostapd are not supported HE mode GI 1600, 3200 ns.
13744 if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI
13745 snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
13746 _syscmd(cmd, buf, sizeof(buf));
13747 } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
13748 wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
13749 if (strstr(buf, "[SHORT-GI-") == NULL) {
13750 snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
13751 _syscmd(cmd, buf, sizeof(buf));
13752 }
13753 if (band == band_5) {
13754 wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
13755 if (strstr(buf, "[SHORT-GI-") == NULL) {
13756 snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
13757 _syscmd(cmd, buf, sizeof(buf));
13758 }
13759 }
13760 }
developera1255e42023-05-13 17:45:02 +080013761 /*wifi_reloadAp(radio_index);
13762 caller "wifi_setRadioOperatingParameters" have done this step.
13763 */
13764 snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
13765 if (guard_interval == wifi_guard_interval_400) {
13766 params[0].name = "HT_GI";
13767 params[0].value = "1";
13768 params[1].name = "VHT_SGI";
13769 params[1].value = "1";
13770 wifi_datfileWrite(dat_file, params, 2);
developer72fb0bb2023-01-11 09:46:29 +080013771 strcpy(GI, "0.4");
developera1255e42023-05-13 17:45:02 +080013772 } else {
13773 params[0].name = "HT_GI";
13774 params[0].value = "0";
13775 params[1].name = "VHT_SGI";
13776 params[1].value = "0";
13777 /*should enable FIXED_HE_GI_SUPPORT in driver*/
13778 params[2].name = "FgiFltf";
13779 if (guard_interval == wifi_guard_interval_800) {
13780 params[2].value = "800";
13781 strcpy(GI, "0.8");
13782 } else if (guard_interval == wifi_guard_interval_1600) {
13783 params[2].value = "1600";
13784 strcpy(GI, "1.6");
13785 } else if (guard_interval == wifi_guard_interval_3200) {
13786 params[2].value = "3200";
13787 strcpy(GI, "3.2");
13788 } else if (guard_interval == wifi_guard_interval_auto) {
13789 params[2].value = "0";
13790 strcpy(GI, "auto");
13791 }
13792 wifi_datfileWrite(dat_file, params, 3);
13793 }
developer72fb0bb2023-01-11 09:46:29 +080013794 // Record GI for get GI function
13795 snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
13796 f = fopen(buf, "w");
13797 if (f == NULL)
13798 return RETURN_ERR;
13799 fprintf(f, "%s", GI);
13800 fclose(f);
13801 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13802 return RETURN_OK;
13803}
13804
13805INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
13806{
13807 char buf[32] = {0};
13808 char cmd[64] = {0};
13809
13810 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13811
13812 if (guard_interval == NULL)
13813 return RETURN_ERR;
13814
developera1255e42023-05-13 17:45:02 +080013815 snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
developer72fb0bb2023-01-11 09:46:29 +080013816 _syscmd(cmd, buf, sizeof(buf));
13817
13818 if (strncmp(buf, "0.4", 3) == 0)
13819 *guard_interval = wifi_guard_interval_400;
13820 else if (strncmp(buf, "0.8", 3) == 0)
13821 *guard_interval = wifi_guard_interval_800;
13822 else if (strncmp(buf, "1.6", 3) == 0)
13823 *guard_interval = wifi_guard_interval_1600;
13824 else if (strncmp(buf, "3.2", 3) == 0)
13825 *guard_interval = wifi_guard_interval_3200;
13826 else
13827 *guard_interval = wifi_guard_interval_auto;
13828
13829 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13830 return RETURN_OK;
13831}
13832
13833INT wifi_setBSSColor(INT radio_index, UCHAR color)
13834{
13835 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
13836 struct params params = {0};
13837 char config_file[128] = {0};
13838 char bss_color[4] ={0};
13839
developera1255e42023-05-13 17:45:02 +080013840 if (color < 1 || color > 63) {
13841 wifi_dbg_printf("color value is err:%d.\n", color);
13842 return RETURN_ERR;
13843 }
developer72fb0bb2023-01-11 09:46:29 +080013844 params.name = "he_bss_color";
13845 snprintf(bss_color, sizeof(bss_color), "%hhu", color);
13846 params.value = bss_color;
13847 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13848 wifi_hostapdWrite(config_file, &params, 1);
developera1255e42023-05-13 17:45:02 +080013849 //wifi_hostapdProcessUpdate(radio_index, &params, 1);
13850 wifi_reloadAp(radio_index);
developer69b61b02023-03-07 17:17:44 +080013851
developer72fb0bb2023-01-11 09:46:29 +080013852 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
13853 return RETURN_OK;
13854}
13855
13856INT wifi_getBSSColor(INT radio_index, UCHAR *color)
13857{
13858 char config_file[128] = {0};
13859 char buf[64] = {0};
13860 char temp_output[128] = {'\0'};
13861
13862 wifi_dbg_printf("\nFunc=%s\n", __func__);
13863 if (NULL == color)
13864 return RETURN_ERR;
13865
13866 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index);
13867 wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
13868
13869 if(strlen(buf) > 0) {
13870 snprintf(temp_output, sizeof(temp_output), "%s", buf);
13871 } else {
13872 snprintf(temp_output, sizeof(temp_output), "1"); // default value
13873 }
13874
13875 *color = (UCHAR)strtoul(temp_output, NULL, 10);
13876 wifi_dbg_printf("\noutput_string=%s\n", color);
13877
13878 return RETURN_OK;
13879}
13880
13881/* multi-psk support */
13882INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
13883{
13884 char cmd[256];
13885 char interface_name[16] = {0};
13886
13887 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13888 return RETURN_ERR;
13889
13890 sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
13891 interface_name,
13892 mac[0],
13893 mac[1],
13894 mac[2],
13895 mac[3],
13896 mac[4],
13897 mac[5]
13898 );
13899 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
13900 _syscmd(cmd, key->wifi_keyId, 64);
13901
13902
13903 return RETURN_OK;
13904}
13905
13906INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13907{
13908 char interface_name[16] = {0};
13909 FILE *fd = NULL;
13910 char fname[100];
13911 char cmd[128] = {0};
13912 char out[64] = {0};
13913 wifi_key_multi_psk_t * key = NULL;
13914 if(keysNumber < 0)
13915 return RETURN_ERR;
13916
13917 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13918 fd = fopen(fname, "w");
13919 if (!fd) {
13920 return RETURN_ERR;
13921 }
13922 key= (wifi_key_multi_psk_t *) keys;
13923 for(int i=0; i<keysNumber; ++i, key++) {
13924 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
13925 }
13926 fclose(fd);
13927
13928 //reload file
13929 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
13930 return RETURN_ERR;
13931 sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
13932 _syscmd(cmd, out, 64);
13933 return RETURN_OK;
13934}
13935
13936INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
13937{
13938 FILE *fd = NULL;
13939 char fname[100];
13940 char * line = NULL;
13941 char * pos = NULL;
13942 size_t len = 0;
13943 ssize_t read = 0;
13944 INT ret = RETURN_OK;
13945 wifi_key_multi_psk_t *keys_it = NULL;
13946
13947 if (keysNumber < 1) {
13948 return RETURN_ERR;
13949 }
13950
13951 snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
13952 fd = fopen(fname, "r");
13953 if (!fd) {
13954 return RETURN_ERR;
13955 }
13956
13957 if (keys == NULL) {
13958 ret = RETURN_ERR;
13959 goto close;
13960 }
13961
13962 keys_it = keys;
13963 while ((read = getline(&line, &len, fd)) != -1) {
13964 //Strip trailing new line if present
13965 if (read > 0 && line[read-1] == '\n') {
13966 line[read-1] = '\0';
13967 }
13968
13969 if(strcmp(line,"keyid=")) {
13970 sscanf(line, "keyid=%s", &(keys_it->wifi_keyId));
13971 if (!(pos = index(line, ' '))) {
13972 ret = RETURN_ERR;
13973 goto close;
13974 }
13975 pos++;
13976 //Here should be 00:00:00:00:00:00
13977 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
13978 printf("Not supported MAC: %s\n", pos);
13979 }
13980 if (!(pos = index(pos, ' '))) {
13981 ret = RETURN_ERR;
13982 goto close;
13983 }
13984 pos++;
13985
13986 //The rest is PSK
13987 snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
13988 keys_it++;
13989
13990 if(--keysNumber <= 0)
13991 break;
13992 }
13993 }
13994
13995close:
13996 free(line);
13997 fclose(fd);
13998 return ret;
13999}
14000/* end of multi-psk support */
14001
14002INT wifi_setNeighborReports(UINT apIndex,
14003 UINT numNeighborReports,
14004 wifi_NeighborReport_t *neighborReports)
14005{
14006 char cmd[256] = { 0 };
14007 char hex_bssid[13] = { 0 };
14008 char bssid[18] = { 0 };
14009 char nr[256] = { 0 };
14010 char ssid[256];
14011 char hex_ssid[256];
14012 char interface_name[16] = {0};
14013 INT ret;
14014
14015 /*rmeove all neighbors*/
14016 wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name);
14017 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
14018 return RETURN_ERR;
14019 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);
14020 system(cmd);
14021
14022 for(unsigned int i = 0; i < numNeighborReports; i++)
14023 {
14024 memset(ssid, 0, sizeof(ssid));
14025 ret = wifi_getSSIDName(apIndex, ssid);
14026 if (ret != RETURN_OK)
14027 return RETURN_ERR;
14028
14029 memset(hex_ssid, 0, sizeof(hex_ssid));
14030 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
14031 sprintf(hex_ssid + k,"%02x", ssid[j]);
14032
14033 snprintf(hex_bssid, sizeof(hex_bssid),
14034 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
14035 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
14036 snprintf(bssid, sizeof(bssid),
14037 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
14038 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
14039
14040 snprintf(nr, sizeof(nr),
14041 "%s" // bssid
14042 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
14043 "%02hhx" // operclass
14044 "%02hhx" // channel
14045 "%02hhx", // phy_mode
14046 hex_bssid,
14047 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
14048 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
14049 neighborReports[i].opClass,
14050 neighborReports[i].channel,
14051 neighborReports[i].phyTable);
14052
14053 snprintf(cmd, sizeof(cmd),
14054 "hostapd_cli set_neighbor "
14055 "%s " // bssid
14056 "ssid=%s " // ssid
14057 "nr=%s " // nr
14058 "-i %s",
14059 bssid,hex_ssid,nr, interface_name);
14060
14061 if (WEXITSTATUS(system(cmd)) != 0)
14062 {
14063 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
14064 }
14065 }
14066
14067 return RETURN_OK;
14068}
14069
14070INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
14071{
14072 return RETURN_OK;
14073}
14074
14075#ifdef _WIFI_HAL_TEST_
14076int main(int argc,char **argv)
14077{
14078 int index;
14079 INT ret=0;
14080 char buf[1024]="";
14081
14082 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14083 if(argc<3)
14084 {
14085 if(argc==2)
14086 {
14087 if(!strcmp(argv[1], "init"))
14088 return wifi_init();
14089 if(!strcmp(argv[1], "reset"))
14090 return wifi_reset();
14091 if(!strcmp(argv[1], "wifi_getHalVersion"))
14092 {
14093 char buffer[64];
14094 if(wifi_getHalVersion(buffer)==RETURN_OK)
14095 printf("Version: %s\n", buffer);
14096 else
14097 printf("Error in wifi_getHalVersion\n");
14098 return RETURN_OK;
14099 }
14100 }
14101 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
14102 exit(-1);
14103 }
14104
14105 index = atoi(argv[2]);
14106 if(strstr(argv[1], "wifi_getApName")!=NULL)
14107 {
14108 wifi_getApName(index,buf);
14109 printf("Ap name is %s \n",buf);
14110 return 0;
14111 }
developerfead3972023-05-25 20:15:02 +080014112 if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
14113 {
14114 UINT pureMode = atoi(argv[3]);
14115
14116 wifi_setRadioMode(index, NULL, pureMode);
14117 printf("Ap SET Radio mode 0x%x\n", pureMode);
14118 return 0;
14119 }
14120 if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
14121 {
14122 ULONG TransmitPower = atoi(argv[3]);
14123
14124 wifi_setRadioTransmitPower(index, TransmitPower);
14125 printf("Ap SET TransmitPower %lu\n", TransmitPower);
14126 return 0;
14127 }
14128 if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
14129 {
14130 INT TransmitPower = atoi(argv[3]);
14131
14132 wifi_setApManagementFramePowerControl(index, TransmitPower);
14133 printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
14134 return 0;
14135 }
14136 if(strstr(argv[1], "wifi_setRadioBW")!=NULL)
14137 {
14138 CHAR *bandwith = argv[3];
14139
14140 wifi_setRadioOperatingChannelBandwidth(index, bandwith);
14141 printf("Ap SET bw %s\n", bandwith);
14142 return 0;
14143 }
14144 if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
14145 {
14146 wifi_factoryResetRadio(index);
14147 printf("wifi_factoryResetRadio ok!\n");
14148 return 0;
14149 }
14150 if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
14151 {
14152 ULONG rst_cnt;
14153 wifi_getRadioResetCount(index, &rst_cnt);
14154 printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
14155 return 0;
14156 }
developer2edaf012023-05-24 14:24:53 +080014157 if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
developer49b17232023-05-19 16:35:19 +080014158 if(argc <= 3 )
14159 {
developer2edaf012023-05-24 14:24:53 +080014160 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
developer49b17232023-05-19 16:35:19 +080014161 exit(-1);
14162 }
14163 wifi_addApAclDevice(index, argv[3]);
14164 return 0;
14165 }
developer2edaf012023-05-24 14:24:53 +080014166 if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
14167 wifi_getApAclDevices(index, buf, 1024);
14168 wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
developer121a8e72023-05-22 09:19:39 +080014169 return 0;
14170 }
developer2edaf012023-05-24 14:24:53 +080014171 if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
14172 if(argc <= 3 )
14173 {
14174 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14175 exit(-1);
14176 }
14177 wifi_delApAclDevice(index, argv[3]);
14178 return 0;
14179 }
14180 if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
14181 wifi_delApAclDevices(index);
14182 return 0;
14183 }
14184 if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
14185 int acl_num = 0;
14186 wifi_getApAclDeviceNum(index, &acl_num);
14187 wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
14188 return 0;
14189 }
14190 if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
14191 wifi_getApDenyAclDevices(index, buf, 1024);
14192 wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
14193 return 0;
14194 }
14195 if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
14196 int filter_mode = 0;
14197 if(argc <= 3 )
14198 {
14199 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14200 exit(-1);
14201 }
14202 filter_mode = atoi(argv[3]);
14203 wifi_setApMacAddressControlMode(index,filter_mode);
14204 return 0;
14205 }
developer5cd4c862023-05-26 09:34:42 +080014206 if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
14207 BOOL output_bool = 0;
14208 wifi_getRadioDeclineBARequestEnable(index, &output_bool);
14209 wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
14210 return 0;
14211 }
14212 if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
14213 BOOL output_bool = 0;
14214 wifi_getRadioAutoBlockAckEnable(index, &output_bool);
14215 wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
14216 return 0;
14217 }
14218
14219 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14220 int filter_mode = 0;
14221 wifi_getApMacAddressControlMode(index, &filter_mode);
14222 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14223 return 0;
14224 }
14225 if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
14226 int enable = 0;
14227 if(argc <= 3 )
14228 {
14229 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14230 exit(-1);
14231 }
14232 enable = (BOOL)atoi(argv[3]);
14233 wifi_setRadioIGMPSnoopingEnable(index, enable);
14234 wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
14235 return 0;
14236 }
14237
14238 if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
14239 BOOL out_status = 0;
14240 wifi_getRadioIGMPSnoopingEnable(index, &out_status);
14241 wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
14242 return 0;
14243 }
developer121a8e72023-05-22 09:19:39 +080014244
developer95c045d2023-05-24 19:26:28 +080014245 if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
14246 int enable = 0;
14247 if(argc <= 3)
14248 {
14249 wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
14250 exit(-1);
14251 }
14252 enable = atoi(argv[3]);
14253 wifi_setApWmmEnable(index,enable);
14254 return 0;
14255 }
developer56fbedb2023-05-30 16:47:05 +080014256 if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
14257 wifi_down();
14258 return 0;
14259 }
developer95c045d2023-05-24 19:26:28 +080014260
developer56fbedb2023-05-30 16:47:05 +080014261 if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
14262 BOOL enable = 0;
14263
14264 wifi_getRadioStatus(index, &enable);
14265 wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
14266 return 0;
14267 }
14268
developer95c045d2023-05-24 19:26:28 +080014269 if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
14270 BOOL enable = 0;
14271
14272 wifi_getApWMMCapability(index, &enable);
14273 wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
14274 return 0;
14275 }
14276
14277 if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
14278 BOOL enable = 0;
14279
14280 wifi_getApWmmEnable(index, &enable);
14281 wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
14282 return 0;
14283 }
14284
developer2edaf012023-05-24 14:24:53 +080014285 if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
14286 int filter_mode = 0;
14287 wifi_getApMacAddressControlMode(index, &filter_mode);
14288 wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
14289 return 0;
14290 }
developer0f10c772023-05-16 21:43:39 +080014291 if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
14292 {
14293 int mode = 0;
14294
14295 wifi_getRadioMode(index, buf, &mode);
14296 printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
14297 return 0;
14298 }
developer72fb0bb2023-01-11 09:46:29 +080014299 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
14300 {
14301 BOOL b = FALSE;
14302 BOOL *output_bool = &b;
14303 wifi_getRadioAutoChannelEnable(index,output_bool);
14304 printf("Channel enabled = %d \n",b);
14305 return 0;
14306 }
14307 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
14308 {
14309 wifi_getApWpaEncryptionMode(index,buf);
14310 printf("encryption enabled = %s\n",buf);
14311 return 0;
14312 }
14313 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
14314 {
14315 BOOL b = FALSE;
14316 BOOL *output_bool = &b;
14317 wifi_getApSsidAdvertisementEnable(index,output_bool);
14318 printf("advertisment enabled = %d\n",b);
14319 return 0;
14320 }
14321 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
14322 {
14323 if(argc <= 3 )
14324 {
14325 printf("Insufficient arguments \n");
14326 exit(-1);
14327 }
14328
14329 char sta[20] = {'\0'};
14330 ULLONG handle= 0;
14331 strcpy(sta,argv[3]);
14332 mac_address_t st;
14333 mac_addr_aton(st,sta);
14334
14335 wifi_associated_dev_tid_stats_t tid_stats;
14336 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
14337 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
14338 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);
14339 }
14340
14341 if(strstr(argv[1], "getApEnable")!=NULL) {
14342 BOOL enable;
14343 ret=wifi_getApEnable(index, &enable);
14344 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14345 }
14346 else if(strstr(argv[1], "setApEnable")!=NULL) {
14347 BOOL enable = atoi(argv[3]);
14348 ret=wifi_setApEnable(index, enable);
14349 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
14350 }
14351 else if(strstr(argv[1], "getApStatus")!=NULL) {
developer69b61b02023-03-07 17:17:44 +080014352 char status[64];
developer72fb0bb2023-01-11 09:46:29 +080014353 ret=wifi_getApStatus(index, status);
14354 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
14355 }
14356 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
14357 {
14358 wifi_getSSIDNameStatus(index,buf);
14359 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
14360 return 0;
developer2202b332023-05-24 16:23:22 +080014361 } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
14362 wifi_resetApVlanCfg(index);
14363 printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
14364 return 0;
developer72fb0bb2023-01-11 09:46:29 +080014365 }
14366 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
14367 wifi_ssidTrafficStats2_t stats={0};
14368 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
14369 printf("%s %d: returns %d\n", argv[1], index, ret);
14370 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
14371 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
14372 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
14373 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
14374 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
14375 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
14376 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
14377 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
14378 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
14379 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
14380 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
14381 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
14382 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
14383 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
14384 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
14385 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
14386 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
14387 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
14388 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
14389 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
14390 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
14391 }
14392 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
14393 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
14394 UINT array_size=0;
14395 UINT i=0;
14396 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
14397 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080014398 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080014399 printf(" neighbor %d:\n", i);
14400 printf(" ap_SSID =%s\n", pt->ap_SSID);
14401 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
14402 printf(" ap_Mode =%s\n", pt->ap_Mode);
14403 printf(" ap_Channel =%d\n", pt->ap_Channel);
14404 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
14405 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14406 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
14407 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
14408 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
14409 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
14410 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
14411 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
14412 printf(" ap_Noise =%d\n", pt->ap_Noise);
14413 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
14414 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
14415 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
developer69b61b02023-03-07 17:17:44 +080014416 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
developer72fb0bb2023-01-11 09:46:29 +080014417 }
14418 if(neighbor_ap_array)
14419 free(neighbor_ap_array); //make sure to free the list
14420 }
14421 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
14422 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
14423 UINT array_size=0;
14424 UINT i=0;
14425 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
14426 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
developer69b61b02023-03-07 17:17:44 +080014427 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
developer72fb0bb2023-01-11 09:46:29 +080014428 printf(" associated_dev %d:\n", i);
14429 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
14430 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
14431 printf(" cli_SNR =%d\n", pt->cli_SNR);
14432 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
14433 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
14434 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
14435 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
14436 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
14437 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
14438 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
14439 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
14440 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
14441 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
14442 }
14443 if(associated_dev_array)
14444 free(associated_dev_array); //make sure to free the list
14445 }
14446
14447 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
14448 {
14449#define MAX_ARRAY_SIZE 64
14450 int i, array_size;
14451 char *p, *ch_str;
14452 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
14453
14454 if(argc != 5)
14455 {
14456 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
14457 exit(-1);
14458 }
14459 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
14460
14461 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
14462 {
14463 strtok_r(ch_str, ",", &p);
14464 input_output_channelStats_array[i].ch_number = atoi(ch_str);
14465 }
14466 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
14467 if(!array_size)
14468 array_size=1;//Need to print current channel statistics
14469 for(i=0; i<array_size; i++)
14470 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
14471 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
14472 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
14473 input_output_channelStats_array[i].ch_number,\
14474 input_output_channelStats_array[i].ch_noise,\
14475 input_output_channelStats_array[i].ch_utilization_busy_rx,\
14476 input_output_channelStats_array[i].ch_utilization_busy_tx,\
14477 input_output_channelStats_array[i].ch_utilization_busy,\
14478 input_output_channelStats_array[i].ch_utilization_busy_ext,\
14479 input_output_channelStats_array[i].ch_utilization_total);
14480 }
14481
14482 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
14483 {
14484 if(argc <= 3 )
14485 {
14486 printf("Insufficient arguments \n");
14487 exit(-1);
14488 }
14489 char mac_addr[20] = {'\0'};
14490 wifi_device_t output_struct;
14491 int dev_index = atoi(argv[3]);
14492
14493 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
14494 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
14495 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);
14496 }
14497
14498 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
14499 {
14500 if (argc <= 3)
14501 {
14502 printf("Insufficient arguments\n");
14503 exit(-1);
14504 }
14505 char args[256];
14506 wifi_NeighborReport_t *neighborReports;
14507
14508 neighborReports = calloc(argc - 2, sizeof(neighborReports));
14509 if (!neighborReports)
14510 {
14511 printf("Failed to allocate memory");
14512 exit(-1);
14513 }
14514
14515 for (int i = 3; i < argc; ++i)
14516 {
14517 char *val;
14518 int j = 0;
14519 memset(args, 0, sizeof(args));
14520 strncpy(args, argv[i], sizeof(args));
14521 val = strtok(args, ";");
14522 while (val != NULL)
14523 {
14524 if (j == 0)
14525 {
14526 mac_addr_aton(neighborReports[i - 3].bssid, val);
14527 } else if (j == 1)
14528 {
14529 neighborReports[i - 3].info = strtol(val, NULL, 16);
14530 } else if (j == 2)
14531 {
14532 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
14533 } else if (j == 3)
14534 {
14535 neighborReports[i - 3].channel = strtol(val, NULL, 16);
14536 } else if (j == 4)
14537 {
14538 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
14539 } else {
14540 printf("Insufficient arguments]n\n");
14541 exit(-1);
14542 }
14543 val = strtok(NULL, ";");
14544 j++;
14545 }
14546 }
14547
14548 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
14549 if (ret != RETURN_OK)
14550 {
14551 printf("wifi_setNeighborReports ret = %d", ret);
14552 exit(-1);
14553 }
14554 }
14555 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
14556 {
14557 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
14558 printf("%s.\n", buf);
14559 else
14560 printf("Error returned\n");
14561 }
14562 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
14563 {
14564 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
14565 printf("%s.\n", buf);
14566 else
14567 printf("Error returned\n");
14568 }
14569 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
14570 {
14571 if (argc <= 2)
14572 {
14573 printf("Insufficient arguments\n");
14574 exit(-1);
14575 }
14576 char buf[64]= {'\0'};
14577 wifi_getRadioOperatingChannelBandwidth(index,buf);
14578 printf("Current bandwidth is %s \n",buf);
14579 return 0;
14580 }
14581 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
14582 {
14583 if (argc <= 5)
14584 {
14585 printf("Insufficient arguments\n");
14586 exit(-1);
14587 }
14588 UINT channel = atoi(argv[3]);
14589 UINT width = atoi(argv[4]);
14590 UINT beacon = atoi(argv[5]);
14591 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
14592 printf("Result = %d", ret);
14593 }
14594
14595 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14596 return 0;
14597}
14598
14599#endif
14600
14601#ifdef WIFI_HAL_VERSION_3
14602
14603INT BitMapToTransmitRates(UINT bitMap, char *BasicRate)
14604{
14605 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14606 if (bitMap & WIFI_BITRATE_1MBPS)
14607 strcat(BasicRate, "1,");
14608 if (bitMap & WIFI_BITRATE_2MBPS)
14609 strcat(BasicRate, "2,");
14610 if (bitMap & WIFI_BITRATE_5_5MBPS)
14611 strcat(BasicRate, "5.5,");
14612 if (bitMap & WIFI_BITRATE_6MBPS)
14613 strcat(BasicRate, "6,");
14614 if (bitMap & WIFI_BITRATE_9MBPS)
14615 strcat(BasicRate, "9,");
14616 if (bitMap & WIFI_BITRATE_11MBPS)
14617 strcat(BasicRate, "11,");
14618 if (bitMap & WIFI_BITRATE_12MBPS)
14619 strcat(BasicRate, "12,");
14620 if (bitMap & WIFI_BITRATE_18MBPS)
14621 strcat(BasicRate, "18,");
14622 if (bitMap & WIFI_BITRATE_24MBPS)
14623 strcat(BasicRate, "24,");
14624 if (bitMap & WIFI_BITRATE_36MBPS)
14625 strcat(BasicRate, "36,");
14626 if (bitMap & WIFI_BITRATE_48MBPS)
14627 strcat(BasicRate, "48,");
14628 if (bitMap & WIFI_BITRATE_54MBPS)
14629 strcat(BasicRate, "54,");
14630 if (strlen(BasicRate) != 0) // remove last comma
14631 BasicRate[strlen(BasicRate) - 1] = '\0';
14632 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14633 return RETURN_OK;
14634}
14635
14636INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
14637{
14638 UINT BitMap = 0;
14639 char *rate;
14640
14641 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14642 rate = strtok(BasicRatesList, ",");
14643 while(rate != NULL)
14644 {
14645 if (strcmp(rate, "1") == 0)
14646 BitMap |= WIFI_BITRATE_1MBPS;
14647 else if (strcmp(rate, "2") == 0)
14648 BitMap |= WIFI_BITRATE_2MBPS;
14649 else if (strcmp(rate, "5.5") == 0)
14650 BitMap |= WIFI_BITRATE_5_5MBPS;
14651 else if (strcmp(rate, "6") == 0)
14652 BitMap |= WIFI_BITRATE_6MBPS;
14653 else if (strcmp(rate, "9") == 0)
14654 BitMap |= WIFI_BITRATE_9MBPS;
14655 else if (strcmp(rate, "11") == 0)
14656 BitMap |= WIFI_BITRATE_11MBPS;
14657 else if (strcmp(rate, "12") == 0)
14658 BitMap |= WIFI_BITRATE_12MBPS;
14659 else if (strcmp(rate, "18") == 0)
14660 BitMap |= WIFI_BITRATE_18MBPS;
14661 else if (strcmp(rate, "24") == 0)
14662 BitMap |= WIFI_BITRATE_24MBPS;
14663 else if (strcmp(rate, "36") == 0)
14664 BitMap |= WIFI_BITRATE_36MBPS;
14665 else if (strcmp(rate, "48") == 0)
14666 BitMap |= WIFI_BITRATE_48MBPS;
14667 else if (strcmp(rate, "54") == 0)
14668 BitMap |= WIFI_BITRATE_54MBPS;
14669 rate = strtok(NULL, ",");
14670 }
14671 *basicRateBitMap = BitMap;
14672 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14673 return RETURN_OK;
14674}
14675
14676// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
14677INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14678{
14679 char buf[128] = {0};
14680 char cmd[128] = {0};
14681 char config_file[64] = {0};
14682 int bandwidth;
14683 int set_mode = 0;
developer56fbedb2023-05-30 16:47:05 +080014684 BOOL drv_dat_change = 0, hapd_conf_change = 0;
developer72fb0bb2023-01-11 09:46:29 +080014685 wifi_radio_operationParam_t current_param;
14686
14687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14688
14689 multiple_set = TRUE;
14690 if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
14691 fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__);
14692 return RETURN_ERR;
14693 }
14694 if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
14695 if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
14696 fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__);
14697 return RETURN_ERR;
14698 }
14699 }
14700
14701 if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
14702 bandwidth = 20;
14703 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
14704 bandwidth = 40;
14705 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
14706 bandwidth = 80;
14707 else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
14708 bandwidth = 160;
14709 if (operationParam->autoChannelEnabled){
14710 if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14711 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14712 return RETURN_ERR;
14713 }
developer69b61b02023-03-07 17:17:44 +080014714 }else{
developer72fb0bb2023-01-11 09:46:29 +080014715 if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
14716 fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__);
14717 return RETURN_ERR;
14718 }
14719 }
14720
14721 if (current_param.variant != operationParam->variant) {
14722 // Two different definition bit map, so need to check every bit.
14723 if (operationParam->variant & WIFI_80211_VARIANT_A)
14724 set_mode |= WIFI_MODE_A;
14725 if (operationParam->variant & WIFI_80211_VARIANT_B)
14726 set_mode |= WIFI_MODE_B;
14727 if (operationParam->variant & WIFI_80211_VARIANT_G)
14728 set_mode |= WIFI_MODE_G;
14729 if (operationParam->variant & WIFI_80211_VARIANT_N)
14730 set_mode |= WIFI_MODE_N;
14731 if (operationParam->variant & WIFI_80211_VARIANT_AC)
14732 set_mode |= WIFI_MODE_AC;
14733 if (operationParam->variant & WIFI_80211_VARIANT_AX)
14734 set_mode |= WIFI_MODE_AX;
14735 // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
14736 memset(buf, 0, sizeof(buf));
developer56fbedb2023-05-30 16:47:05 +080014737 drv_dat_change = TRUE;
developer0f10c772023-05-16 21:43:39 +080014738 if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014739 fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__);
14740 return RETURN_ERR;
14741 }
14742 }
14743 if (current_param.dtimPeriod != operationParam->dtimPeriod) {
developer56fbedb2023-05-30 16:47:05 +080014744 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014745 if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) {
14746 fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__);
14747 return RETURN_ERR;
14748 }
14749 }
14750 if (current_param.beaconInterval != operationParam->beaconInterval) {
developer56fbedb2023-05-30 16:47:05 +080014751 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014752 if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) {
14753 fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__);
14754 return RETURN_ERR;
14755 }
14756 }
14757 if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
developer56fbedb2023-05-30 16:47:05 +080014758 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014759 BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf);
14760 if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14761 fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__);
14762 return RETURN_ERR;
14763 }
14764 }
14765 if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
developer56fbedb2023-05-30 16:47:05 +080014766 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014767 if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) {
14768 fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__);
14769 return RETURN_ERR;
14770 }
14771 }
14772 if (current_param.guardInterval != operationParam->guardInterval) {
developer56fbedb2023-05-30 16:47:05 +080014773 hapd_conf_change = TRUE;
14774 drv_dat_change = TRUE;
14775 if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014776 fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__);
14777 return RETURN_ERR;
14778 }
14779 }
14780 if (current_param.transmitPower != operationParam->transmitPower) {
developer56fbedb2023-05-30 16:47:05 +080014781 drv_dat_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014782 if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
14783 fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__);
14784 return RETURN_ERR;
14785 }
14786 }
14787 if (current_param.rtsThreshold != operationParam->rtsThreshold) {
developer56fbedb2023-05-30 16:47:05 +080014788 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014789 if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) {
14790 fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__);
14791 return RETURN_ERR;
14792 }
14793 }
14794 if (current_param.obssCoex != operationParam->obssCoex) {
developer56fbedb2023-05-30 16:47:05 +080014795 hapd_conf_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014796 if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
14797 fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__);
14798 return RETURN_ERR;
14799 }
14800 }
14801 if (current_param.stbcEnable != operationParam->stbcEnable) {
developer56fbedb2023-05-30 16:47:05 +080014802 hapd_conf_change = TRUE;
14803 drv_dat_change = TRUE;
developer72fb0bb2023-01-11 09:46:29 +080014804 if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
14805 fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__);
14806 return RETURN_ERR;
14807 }
14808 }
14809 if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
14810 if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
14811 fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__);
14812 return RETURN_ERR;
14813 }
14814 }
14815
developer56fbedb2023-05-30 16:47:05 +080014816 /* only down/up interface when dat file has been changed,
14817 * if enable is true, then restart the radio.
14818 */
14819 if (drv_dat_change == TRUE) {
14820 wifi_setRadioEnable(index, FALSE);
14821 if (operationParam->enable == TRUE)
14822 wifi_setRadioEnable(index, TRUE);
14823 } else if (hapd_conf_change == TRUE) {
14824 hostapd_raw_remove_bss(index);
14825 if (operationParam->enable == TRUE)
14826 hostapd_raw_add_bss(index);
14827 }
14828
developer72fb0bb2023-01-11 09:46:29 +080014829 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14830
14831 return RETURN_OK;
14832}
14833
14834INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
14835{
14836 char band[64] = {0};
14837 char buf[256] = {0};
14838 char config_file[64] = {0};
14839 char cmd[128] = {0};
14840 int ret = RETURN_ERR;
14841 int mode = 0;
14842 ULONG channel = 0;
14843 BOOL enabled = FALSE;
14844
14845 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
14846 printf("Entering %s index = %d\n", __func__, (int)index);
14847
14848 memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
14849 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index);
14850 if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
14851 {
14852 fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__);
14853 return RETURN_ERR;
14854 }
14855 operationParam->enable = enabled;
14856
14857 memset(band, 0, sizeof(band));
14858 if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
14859 {
14860 fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__);
14861 return RETURN_ERR;
14862 }
14863
14864 if (!strcmp(band, "2.4GHz"))
14865 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
14866 else if (!strcmp(band, "5GHz"))
14867 operationParam->band = WIFI_FREQUENCY_5_BAND;
14868 else if (!strcmp(band, "6GHz"))
14869 operationParam->band = WIFI_FREQUENCY_6_BAND;
14870 else
14871 {
14872 fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
14873 band);
14874 }
14875
14876 wifi_hostapdRead(config_file, "channel", buf, sizeof(buf));
14877 if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) {
14878 operationParam->channel = 0;
14879 operationParam->autoChannelEnabled = TRUE;
14880 } else {
14881 operationParam->channel = strtol(buf, NULL, 10);
14882 operationParam->autoChannelEnabled = FALSE;
14883 }
14884
14885 memset(buf, 0, sizeof(buf));
14886 if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
14887 fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__);
14888 return RETURN_ERR;
14889 }
14890 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
14891 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
14892 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
14893 else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
14894 else
14895 {
14896 fprintf(stderr, "Unknown channel bandwidth: %s\n", buf);
14897 return false;
14898 }
14899
14900 if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
14901 fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__);
14902 return RETURN_ERR;
14903 }
14904 // Two different definition bit map, so need to check every bit.
14905 if (mode & WIFI_MODE_A)
14906 operationParam->variant |= WIFI_80211_VARIANT_A;
14907 if (mode & WIFI_MODE_B)
14908 operationParam->variant |= WIFI_80211_VARIANT_B;
14909 if (mode & WIFI_MODE_G)
14910 operationParam->variant |= WIFI_80211_VARIANT_G;
14911 if (mode & WIFI_MODE_N)
14912 operationParam->variant |= WIFI_80211_VARIANT_N;
14913 if (mode & WIFI_MODE_AC)
14914 operationParam->variant |= WIFI_80211_VARIANT_AC;
14915 if (mode & WIFI_MODE_AX)
14916 operationParam->variant |= WIFI_80211_VARIANT_AX;
14917 if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
14918 fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__);
14919 return RETURN_ERR;
14920 }
14921 if (wifi_getApDTIMInterval(index, &operationParam->dtimPeriod) != RETURN_OK) {
14922 fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__);
14923 return RETURN_ERR;
14924 }
14925 if (wifi_getRadioBeaconPeriod(index, &operationParam->dtimPeriod) != RETURN_OK) {
14926 fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__);
14927 return RETURN_ERR;
14928 }
14929
14930 memset(buf, 0, sizeof(buf));
14931 if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
14932 fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__);
14933 return RETURN_ERR;
14934 }
14935 TransmitRatesToBitMap(buf, &operationParam->basicDataTransmitRates);
14936
14937 memset(buf, 0, sizeof(buf));
14938 if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
14939 fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__);
14940 return RETURN_ERR;
14941 }
14942 TransmitRatesToBitMap(buf, &operationParam->operationalDataTransmitRates);
14943
14944 memset(buf, 0, sizeof(buf));
14945 wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf));
14946 operationParam->fragmentationThreshold = strtoul(buf, NULL, 10);
14947
14948 if (wifi_getGuardInterval(index, &operationParam->guardInterval) != RETURN_OK) {
14949 fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__);
14950 return RETURN_ERR;
14951 }
developera1255e42023-05-13 17:45:02 +080014952 if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&operationParam->transmitPower) != RETURN_OK) {
developer72fb0bb2023-01-11 09:46:29 +080014953 fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__);
14954 return RETURN_ERR;
14955 }
14956
14957 memset(buf, 0, sizeof(buf));
14958 wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf));
14959 if (strcmp(buf, "-1") == 0) {
14960 operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value
14961 operationParam->ctsProtection = FALSE;
14962 } else {
14963 operationParam->rtsThreshold = strtoul(buf, NULL, 10);
14964 operationParam->ctsProtection = TRUE;
14965 }
14966
14967 memset(buf, 0, sizeof(buf));
14968 wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf));
14969 if (strcmp(buf, "0") == 0)
14970 operationParam->obssCoex = FALSE;
14971 else
14972 operationParam->obssCoex = TRUE;
14973
14974 snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file);
14975 _syscmd(cmd, buf, sizeof(buf));
14976 if (strlen(buf) != 0)
14977 operationParam->stbcEnable = TRUE;
14978 else
14979 operationParam->stbcEnable = FALSE;
14980
14981 if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
14982 fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__);
14983 return RETURN_ERR;
14984 }
14985
14986 // Below value is hardcoded
14987
14988 operationParam->numSecondaryChannels = 0;
14989 for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
14990 operationParam->channelSecondary[i] = 0;
14991 }
14992 operationParam->csa_beacon_count = 15;
14993 operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum
14994
14995 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
14996 return RETURN_OK;
14997}
14998
14999static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
15000{
15001 int max_radio_num = 0;
15002
15003 wifi_getMaxRadioNumber(&max_radio_num);
15004 if (radioIndex >= max_radio_num) {
15005 fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex);
15006 return RETURN_ERR;
15007 }
15008
15009 return (arrayIndex * max_radio_num) + radioIndex;
15010}
15011
developer96b38512023-02-22 11:17:45 +080015012static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
15013{
15014 int max_radio_num = 0;
15015
15016 if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS))
15017 return -1;
15018
15019 wifi_getMaxRadioNumber(&max_radio_num);
15020
15021 (*radioIndex) = vapIndex % max_radio_num;
15022 (*arrayIndex) = vapIndex / max_radio_num;
15023
15024 return 0;
15025}
15026
15027
developer72fb0bb2023-01-11 09:46:29 +080015028wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
15029 if (strncmp(beaconRate, "1Mbps", 5) == 0)
15030 return WIFI_BITRATE_1MBPS;
15031 else if (strncmp(beaconRate, "2Mbps", 5) == 0)
15032 return WIFI_BITRATE_2MBPS;
15033 else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
15034 return WIFI_BITRATE_5_5MBPS;
15035 else if (strncmp(beaconRate, "6Mbps", 5) == 0)
15036 return WIFI_BITRATE_6MBPS;
15037 else if (strncmp(beaconRate, "9Mbps", 5) == 0)
15038 return WIFI_BITRATE_9MBPS;
15039 else if (strncmp(beaconRate, "11Mbps", 6) == 0)
15040 return WIFI_BITRATE_11MBPS;
15041 else if (strncmp(beaconRate, "12Mbps", 6) == 0)
15042 return WIFI_BITRATE_12MBPS;
15043 else if (strncmp(beaconRate, "18Mbps", 6) == 0)
15044 return WIFI_BITRATE_18MBPS;
15045 else if (strncmp(beaconRate, "24Mbps", 6) == 0)
15046 return WIFI_BITRATE_24MBPS;
15047 else if (strncmp(beaconRate, "36Mbps", 6) == 0)
15048 return WIFI_BITRATE_36MBPS;
15049 else if (strncmp(beaconRate, "48Mbps", 6) == 0)
15050 return WIFI_BITRATE_48MBPS;
15051 else if (strncmp(beaconRate, "54Mbps", 6) == 0)
15052 return WIFI_BITRATE_54MBPS;
15053 return WIFI_BITRATE_DEFAULT;
15054}
15055
15056INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str)
15057{
15058 if (beacon == WIFI_BITRATE_1MBPS)
15059 strcpy(beacon_str, "1Mbps");
15060 else if (beacon == WIFI_BITRATE_2MBPS)
15061 strcpy(beacon_str, "2Mbps");
15062 else if (beacon == WIFI_BITRATE_5_5MBPS)
15063 strcpy(beacon_str, "5.5Mbps");
15064 else if (beacon == WIFI_BITRATE_6MBPS)
15065 strcpy(beacon_str, "6Mbps");
15066 else if (beacon == WIFI_BITRATE_9MBPS)
15067 strcpy(beacon_str, "9Mbps");
15068 else if (beacon == WIFI_BITRATE_11MBPS)
15069 strcpy(beacon_str, "11Mbps");
15070 else if (beacon == WIFI_BITRATE_12MBPS)
15071 strcpy(beacon_str, "12Mbps");
15072 else if (beacon == WIFI_BITRATE_18MBPS)
15073 strcpy(beacon_str, "18Mbps");
15074 else if (beacon == WIFI_BITRATE_24MBPS)
15075 strcpy(beacon_str, "24Mbps");
15076 else if (beacon == WIFI_BITRATE_36MBPS)
15077 strcpy(beacon_str, "36Mbps");
15078 else if (beacon == WIFI_BITRATE_48MBPS)
15079 strcpy(beacon_str, "48Mbps");
15080 else if (beacon == WIFI_BITRATE_54MBPS)
15081 strcpy(beacon_str, "54Mbps");
15082 return RETURN_OK;
15083}
15084
15085INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15086{
15087 INT mode = 0;
15088 INT ret = -1;
15089 INT output = 0;
15090 int i = 0;
15091 int vap_index = 0;
15092 BOOL enabled = FALSE;
15093 char buf[256] = {0};
15094 wifi_vap_security_t security = {0};
developer72fb0bb2023-01-11 09:46:29 +080015095
15096 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15097 printf("Entering %s index = %d\n", __func__, (int)index);
15098
developerfde01262023-05-22 15:15:24 +080015099 ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
15100 if (ret != 0) {
15101 fprintf(stderr, "%s: wifi_BandProfileRead BssidNum failed\n", __func__);
15102 return RETURN_ERR;
15103 }
15104
15105 map->num_vaps = atoi(buf);
15106 if (map->num_vaps <= 0) {
15107 fprintf(stderr, "%s: invalid BssidNum %s\n", __func__, buf);
15108 return RETURN_ERR;
15109 }
15110
15111 for (i = 0; i < map->num_vaps; i++)
developer72fb0bb2023-01-11 09:46:29 +080015112 {
15113 map->vap_array[i].radio_index = index;
15114
15115 vap_index = array_index_to_vap_index(index, i);
15116 if (vap_index < 0)
15117 return RETURN_ERR;
15118
15119 strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME);
15120
15121 map->vap_array[i].vap_index = vap_index;
15122
15123 memset(buf, 0, sizeof(buf));
15124 ret = wifi_getApName(vap_index, buf);
15125 if (ret != RETURN_OK) {
15126 printf("%s: wifi_getApName return error\n", __func__);
15127 return RETURN_ERR;
15128 }
15129 snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
15130
15131 memset(buf, 0, sizeof(buf));
15132 ret = wifi_getSSIDName(vap_index, buf);
15133 if (ret != RETURN_OK) {
15134 printf("%s: wifi_getSSIDName return error\n", __func__);
15135 return RETURN_ERR;
15136 }
15137 snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
15138
developere740c2a2023-05-23 18:34:32 +080015139#if 0
developer72fb0bb2023-01-11 09:46:29 +080015140 ret = wifi_getSSIDEnable(vap_index, &enabled);
15141 if (ret != RETURN_OK) {
15142 printf("%s: wifi_getSSIDEnable return error\n", __func__);
15143 return RETURN_ERR;
15144 }
developere740c2a2023-05-23 18:34:32 +080015145#endif
15146 map->vap_array[i].u.bss_info.enabled = true;
developer72fb0bb2023-01-11 09:46:29 +080015147
15148 ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
15149 if (ret != RETURN_OK) {
15150 printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__);
15151 return RETURN_ERR;
15152 }
15153 map->vap_array[i].u.bss_info.showSsid = enabled;
developer69b61b02023-03-07 17:17:44 +080015154
developer72fb0bb2023-01-11 09:46:29 +080015155 ret = wifi_getApIsolationEnable(vap_index, &enabled);
15156 if (ret != RETURN_OK) {
15157 printf("%s: wifi_getApIsolationEnable return error\n", __func__);
15158 return RETURN_ERR;
15159 }
15160 map->vap_array[i].u.bss_info.isolation = enabled;
15161
15162 ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
15163 if (ret != RETURN_OK) {
15164 printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__);
15165 return RETURN_ERR;
15166 }
15167 map->vap_array[i].u.bss_info.bssMaxSta = output;
15168
15169 ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
15170 if (ret != RETURN_OK) {
15171 printf("%s: wifi_getBSSTransitionActivation return error\n", __func__);
15172 return RETURN_ERR;
15173 }
15174 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
15175
15176 ret = wifi_getNeighborReportActivation(vap_index, &enabled);
15177 if (ret != RETURN_OK) {
15178 printf("%s: wifi_getNeighborReportActivation return error\n", __func__);
15179 return RETURN_ERR;
15180 }
15181 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
15182
15183 ret = wifi_getApSecurity(vap_index, &security);
15184 if (ret != RETURN_OK) {
15185 printf("%s: wifi_getApSecurity return error\n", __func__);
15186 return RETURN_ERR;
15187 }
15188 map->vap_array[i].u.bss_info.security = security;
15189
15190 ret = wifi_getApMacAddressControlMode(vap_index, &mode);
15191 if (ret != RETURN_OK) {
15192 printf("%s: wifi_getApMacAddressControlMode return error\n", __func__);
15193 return RETURN_ERR;
15194 }
developer69b61b02023-03-07 17:17:44 +080015195 if (mode == 0)
developer72fb0bb2023-01-11 09:46:29 +080015196 map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
developer69b61b02023-03-07 17:17:44 +080015197 else
developer72fb0bb2023-01-11 09:46:29 +080015198 map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
developer69b61b02023-03-07 17:17:44 +080015199 if (mode == 1)
developer72fb0bb2023-01-11 09:46:29 +080015200 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
developer69b61b02023-03-07 17:17:44 +080015201 else if (mode == 2)
developer72fb0bb2023-01-11 09:46:29 +080015202 map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
15203
15204 ret = wifi_getApWmmEnable(vap_index, &enabled);
15205 if (ret != RETURN_OK) {
15206 printf("%s: wifi_getApWmmEnable return error\n", __func__);
15207 return RETURN_ERR;
15208 }
15209 map->vap_array[i].u.bss_info.wmm_enabled = enabled;
15210
15211 ret = wifi_getApUAPSDCapability(vap_index, &enabled);
15212 if (ret != RETURN_OK) {
15213 printf("%s: wifi_getApUAPSDCapability return error\n", __func__);
15214 return RETURN_ERR;
15215 }
15216 map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
15217
15218 memset(buf, 0, sizeof(buf));
15219 ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
15220 if (ret != RETURN_OK) {
15221 printf("%s: wifi_getApBeaconRate return error\n", __func__);
15222 return RETURN_ERR;
15223 }
15224 map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
15225
15226 memset(buf, 0, sizeof(buf));
15227 ret = wifi_getBaseBSSID(vap_index, buf);
15228 if (ret != RETURN_OK) {
15229 printf("%s: wifi_getBaseBSSID return error\n", __func__);
15230 return RETURN_ERR;
15231 }
developer5b2f10c2023-05-25 17:02:21 +080015232 if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
15233 printf("%s: hwaddr_aton2 fail\n", __func__);
15234 return RETURN_ERR;
15235 }
developer72fb0bb2023-01-11 09:46:29 +080015236
15237 ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
15238 if (ret != RETURN_OK) {
15239 fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
15240 return RETURN_ERR;
15241 }
15242 map->vap_array[i].u.bss_info.mcast2ucast = enabled;
15243
15244 // TODO: wps, noack
15245 }
15246 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15247 return RETURN_OK;
15248}
15249
developer47cc27a2023-05-17 23:09:58 +080015250void checkVapStatus(int apIndex, BOOL *enable)
developer72fb0bb2023-01-11 09:46:29 +080015251{
15252 char if_name[16] = {0};
15253 char cmd[128] = {0};
15254 char buf[128] = {0};
15255
15256 *enable = FALSE;
15257 if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
15258 return;
15259
15260 snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
15261 _syscmd(cmd, buf, sizeof(buf));
15262 if (strlen(buf) > 0)
15263 *enable = TRUE;
15264 return;
15265}
15266
15267static int prepareInterface(UINT apIndex, char *new_interface)
15268{
15269 char cur_interface[16] = {0};
15270 char config_file[128] = {0};
developer8a3bbbf2023-03-15 17:47:23 +080015271 char cmd[MAX_CMD_SIZE] = {0};
15272 char buf[MAX_BUF_SIZE] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015273 int max_radio_num = 0;
15274 int radioIndex = -1;
15275 int phyIndex = -1;
developer8a3bbbf2023-03-15 17:47:23 +080015276 struct params params;
developer72fb0bb2023-01-11 09:46:29 +080015277
15278 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
15279 wifi_hostapdRead(config_file, "interface", cur_interface, sizeof(cur_interface));
15280
15281 if (strncmp(cur_interface, new_interface, sizeof(cur_interface)) != 0) {
developer8a3bbbf2023-03-15 17:47:23 +080015282 wifi_getMaxRadioNumber(&max_radio_num);
developer72fb0bb2023-01-11 09:46:29 +080015283 radioIndex = apIndex % max_radio_num;
15284 phyIndex = radio_index_to_phy(radioIndex);
15285 // disable and del old interface, then add new interface
15286 wifi_setApEnable(apIndex, FALSE);
developer8a3bbbf2023-03-15 17:47:23 +080015287
15288 params.name = "interface";
15289 params.value = new_interface;
15290 wifi_hostapdWrite(config_file, &params, 1);
15291
15292 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyIndex, config_file);
15293 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015294 }
developer8a3bbbf2023-03-15 17:47:23 +080015295
developer72fb0bb2023-01-11 09:46:29 +080015296 // update the vap status file
15297 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=1' %s", cur_interface, new_interface, VAP_STATUS_FILE);
15298 _syscmd(cmd, buf, sizeof(buf));
15299 return RETURN_OK;
15300}
15301
developer56fbedb2023-05-30 16:47:05 +080015302int hostapd_manage_bss(INT apIndex, BOOL enable)
15303{
15304 char interface_name[16] = {0};
15305 char config_file[MAX_BUF_SIZE] = {0};
15306 char cmd[MAX_CMD_SIZE] = {0};
15307 char buf[MAX_BUF_SIZE] = {0};
15308 BOOL status = FALSE;
15309 int max_radio_num = 0;
15310 int phyId = 0;
15311
15312 wifi_getApEnable(apIndex, &status);
15313
15314 wifi_getMaxRadioNumber(&max_radio_num);
15315 if (enable == status)
15316 return RETURN_OK;
15317
15318 if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
15319 return RETURN_ERR;
15320
15321 if (enable == TRUE) {
15322 int radioIndex = apIndex % max_radio_num;
15323 phyId = radio_index_to_phy(radioIndex);
15324 fprintf(stderr, "%s %d\n", __func__, __LINE__);
15325 snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
15326 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
15327 _syscmd(cmd, buf, sizeof(buf));
15328 } else {
15329 fprintf(stderr, "%s %d\n", __func__, __LINE__);
15330 snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name);
15331 _syscmd(cmd, buf, sizeof(buf));
15332 }
15333 snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
15334 interface_name, interface_name, enable, VAP_STATUS_FILE);
15335 _syscmd(cmd, buf, sizeof(buf));
15336 //Wait for wifi up/down to apply
15337 return RETURN_OK;
15338}
15339
15340int hostapd_raw_add_bss(int apIndex)
15341{
15342 return hostapd_manage_bss(apIndex, TRUE);
15343}
15344
15345int hostapd_raw_remove_bss(int apIndex)
15346{
15347 return hostapd_manage_bss(apIndex, FALSE);
15348}
15349
15350int hostapd_raw_restart_bss(int apIndex)
15351{
15352 hostapd_raw_remove_bss(apIndex);
15353 hostapd_raw_add_bss(apIndex);
15354}
15355
developer72fb0bb2023-01-11 09:46:29 +080015356INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
15357{
15358 char interface_name[16] = {0};
15359 unsigned int i;
15360 wifi_vap_info_t *vap_info = NULL;
15361 int acl_mode;
15362 int ret = 0;
15363 char *sec_str = NULL;
15364 char buf[256] = {0};
15365 char cmd[128] = {0};
15366 char config_file[64] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015367 char psk_file[64] = {0};
developer47cc27a2023-05-17 23:09:58 +080015368 BOOL enable = FALSE;
developere740c2a2023-05-23 18:34:32 +080015369 int band_idx;
15370
developer72fb0bb2023-01-11 09:46:29 +080015371
15372 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15373 printf("Entering %s index = %d\n", __func__, (int)index);
15374 for (i = 0; i < map->num_vaps; i++)
15375 {
15376 multiple_set = TRUE;
15377 vap_info = &map->vap_array[i];
15378
15379 // Check vap status file to enable multiple ap if the system boot.
15380 checkVapStatus(vap_info->vap_index, &enable);
15381 if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE)
15382 continue;
15383
15384 fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
15385
developere740c2a2023-05-23 18:34:32 +080015386 band_idx = radio_index_to_band(index);
15387 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
15388 snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
15389 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015390
developer56fbedb2023-05-30 16:47:05 +080015391 struct params params[3];
developer72fb0bb2023-01-11 09:46:29 +080015392 params[0].name = "interface";
15393 params[0].value = vap_info->vap_name;
developer72fb0bb2023-01-11 09:46:29 +080015394 snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index);
developer56fbedb2023-05-30 16:47:05 +080015395 params[1].name = "wpa_psk_file";
15396 params[1].value = psk_file;
15397 params[2].name = "ssid";
15398 params[2].value = vap_info->u.bss_info.ssid;
developer72fb0bb2023-01-11 09:46:29 +080015399
15400 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
developer56fbedb2023-05-30 16:47:05 +080015401 wifi_hostapdWrite(config_file, params, 3);
developer72fb0bb2023-01-11 09:46:29 +080015402
15403 snprintf(cmd, sizeof(cmd), "touch %s", psk_file);
15404 _syscmd(cmd, buf, sizeof(buf));
15405
15406 ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
15407 if (ret != RETURN_OK) {
15408 fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__);
15409 return RETURN_ERR;
15410 }
15411
15412 ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
15413 if (ret != RETURN_OK) {
15414 fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__);
15415 return RETURN_ERR;
15416 }
15417
15418 ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
15419 if (ret != RETURN_OK) {
15420 fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__);
15421 return RETURN_ERR;
15422 }
15423
15424 ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
15425 if (ret != RETURN_OK) {
15426 fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__);
15427 return RETURN_ERR;
15428 }
15429
15430 ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
15431 if (ret != RETURN_OK) {
15432 fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__);
15433 return RETURN_ERR;
15434 }
15435
15436 ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
15437 if (ret != RETURN_OK) {
15438 fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__);
15439 return RETURN_ERR;
15440 }
15441
15442 if (vap_info->u.bss_info.mac_filter_enable == false){
15443 acl_mode = 0;
15444 }else {
15445 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
15446 acl_mode = 2;
15447 snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
15448 _syscmd(cmd, buf, sizeof(buf));
15449 }else{
15450 acl_mode = 1;
15451 }
15452 }
15453
15454 ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
15455 if (ret != RETURN_OK) {
15456 fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__);
15457 return RETURN_ERR;
15458 }
15459
15460 ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
15461 if (ret != RETURN_OK) {
15462 fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__);
15463 return RETURN_ERR;
15464 }
15465
developer0f10c772023-05-16 21:43:39 +080015466 memset(buf, 0, sizeof(buf));
15467 beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf);
15468 ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
15469 if (ret != RETURN_OK) {
15470 fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__);
15471 return RETURN_ERR;
15472 }
developer72fb0bb2023-01-11 09:46:29 +080015473
15474 ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
15475 if (ret != RETURN_OK) {
15476 fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__);
15477 return RETURN_ERR;
15478 }
15479
developer72fb0bb2023-01-11 09:46:29 +080015480 ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
15481 if (ret != RETURN_OK) {
15482 fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__);
15483 return RETURN_ERR;
15484 }
developer56fbedb2023-05-30 16:47:05 +080015485
15486 hostapd_raw_restart_bss(vap_info->vap_index);
developer72fb0bb2023-01-11 09:46:29 +080015487
developer23e71282023-01-18 10:25:19 +080015488 multiple_set = FALSE;
15489
15490 // If config use hostapd_cli to set, we calling these type of functions after enable the ap.
developer72fb0bb2023-01-11 09:46:29 +080015491 ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
15492 if (ret != RETURN_OK) {
15493 fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__);
15494 return RETURN_ERR;
15495 }
15496
15497 // TODO mgmtPowerControl, interworking, wps
15498 }
15499 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15500 return RETURN_OK;
15501}
15502
15503int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
15504{
15505 char *token, *next;
15506 const char s[2] = ",";
15507 int count =0;
15508
15509 /* get the first token */
15510 token = strtok_r(pchannels, s, &next);
15511
15512 /* walk through other tokens */
15513 while( token != NULL && count < MAX_CHANNELS) {
15514 chlistptr->channels_list[count++] = atoi(token);
15515 token = strtok_r(NULL, s, &next);
15516 }
15517
15518 return count;
15519}
15520
15521static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
15522{
15523 INT status;
15524 wifi_channels_list_t *chlistp;
15525 CHAR output_string[64];
15526 CHAR pchannels[128];
15527 CHAR interface_name[16] = {0};
15528 wifi_band band;
15529
15530 if(rcap == NULL)
15531 {
15532 return RETURN_ERR;
15533 }
15534
15535 rcap->numSupportedFreqBand = 1;
15536 band = wifi_index_to_band(radioIndex);
15537
15538 if (band == band_2_4)
15539 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
15540 else if (band == band_5)
15541 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
15542 else if (band == band_6)
15543 rcap->band[0] = WIFI_FREQUENCY_6_BAND;
15544
15545 chlistp = &(rcap->channel_list[0]);
15546 memset(pchannels, 0, sizeof(pchannels));
15547
15548 /* possible number of radio channels */
15549 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
15550 {
15551 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
15552 }
15553 /* Number of channels and list*/
15554 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
15555
15556 /* autoChannelSupported */
15557 /* always ON with wifi_getRadioAutoChannelSupported */
15558 rcap->autoChannelSupported = TRUE;
15559
15560 /* DCSSupported */
15561 /* always ON with wifi_getRadioDCSSupported */
15562 rcap->DCSSupported = TRUE;
15563
15564 /* zeroDFSSupported - TBD */
15565 rcap->zeroDFSSupported = FALSE;
15566
15567 /* Supported Country List*/
15568 memset(output_string, 0, sizeof(output_string));
15569 status = wifi_getRadioCountryCode(radioIndex, output_string);
15570 if( status != 0 ) {
15571 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
15572 return RETURN_ERR;
15573 } else {
15574 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
15575 }
15576 if(!strcmp(output_string,"US")){
15577 rcap->countrySupported[0] = wifi_countrycode_US;
15578 rcap->countrySupported[1] = wifi_countrycode_CA;
15579 } else if (!strcmp(output_string,"CA")) {
15580 rcap->countrySupported[0] = wifi_countrycode_CA;
15581 rcap->countrySupported[1] = wifi_countrycode_US;
15582 } else {
15583 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
15584 }
15585
15586 rcap->numcountrySupported = 2;
15587
15588 /* csi */
15589 rcap->csi.maxDevices = 8;
15590 rcap->csi.soudingFrameSupported = TRUE;
15591
15592 wifi_GetInterfaceName(radioIndex, interface_name);
15593 snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
15594
15595 /* channelWidth - all supported bandwidths */
15596 int i=0;
15597 rcap->channelWidth[i] = 0;
15598 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
15599 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
15600 WIFI_CHANNELBANDWIDTH_40MHZ);
15601
15602 }
15603 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
15604 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
15605 WIFI_CHANNELBANDWIDTH_40MHZ |
15606 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
15607 }
15608
15609
15610 /* mode - all supported variants */
15611 // rcap->mode[i] = WIFI_80211_VARIANT_H;
15612 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
15613 rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX );
15614 }
15615 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
15616 rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX );
15617 }
15618 else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
15619 rcap->mode[i] = ( WIFI_80211_VARIANT_AX );
15620 }
15621 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
15622 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
15623
15624 /* supportedBitRate - all supported bitrates */
15625 rcap->supportedBitRate[i] = 0;
15626 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
15627 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
15628 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
15629 }
15630 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) | rcap->band[i] & (WIFI_FREQUENCY_6_BAND )) {
15631 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
15632 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
15633 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
15634 }
15635
15636
15637 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
15638 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
15639 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
15640 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
15641 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
15642 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
15643 rcap->cipherSupported = 0;
15644 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
15645 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
15646
15647 return RETURN_OK;
15648}
15649
15650INT wifi_getHalCapability(wifi_hal_capability_t *cap)
15651{
15652 INT status = 0, radioIndex = 0;
15653 char cmd[MAX_BUF_SIZE] = {0}, output[MAX_BUF_SIZE] = {0};
15654 int iter = 0;
15655 unsigned int j = 0;
15656 int max_num_radios;
15657 wifi_interface_name_idex_map_t *iface_info = NULL;
15658
15659 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15660
15661 memset(cap, 0, sizeof(wifi_hal_capability_t));
15662
15663 /* version */
15664 cap->version.major = WIFI_HAL_MAJOR_VERSION;
15665 cap->version.minor = WIFI_HAL_MINOR_VERSION;
15666
15667 /* number of radios platform property */
15668 wifi_getMaxRadioNumber(&max_num_radios);
15669 cap->wifi_prop.numRadios = max_num_radios;
15670
15671 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
15672 {
15673 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
15674 if (status != 0) {
15675 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
15676 return RETURN_ERR;
15677 }
15678
15679 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
15680 {
15681 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
15682 {
15683 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
15684 return RETURN_ERR;
15685 }
15686 iface_info = &cap->wifi_prop.interface_map[iter];
15687 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
15688 iface_info->rdk_radio_index = radioIndex;
15689 memset(output, 0, sizeof(output));
15690 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
15691 {
15692 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
15693 }
15694 // TODO: bridge name
15695 // TODO: vlan id
15696 // TODO: primary
15697 iface_info->index = array_index_to_vap_index(radioIndex, j);
15698 memset(output, 0, sizeof(output));
15699 if (wifi_getApName(iface_info->index, output) == RETURN_OK)
15700 {
15701 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
15702 }
15703 iter++;
15704 }
15705 }
15706
15707 cap->BandSteeringSupported = FALSE;
15708 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15709 return RETURN_OK;
15710}
15711
15712INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
15713{
15714 struct params h_config={0};
15715 char config_file[64] = {0};
15716
15717 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15718
15719 h_config.name = "okc";
15720 h_config.value = okc_enable?"1":"0";
15721
15722 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15723 wifi_hostapdWrite(config_file, &h_config, 1);
15724 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15725
15726 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15727 return RETURN_OK;
15728}
15729
15730INT wifi_setSAEMFP(int ap_index, BOOL enable)
15731{
15732 struct params h_config={0};
15733 char config_file[64] = {0};
15734 char buf[128] = {0};
15735
15736 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15737
15738 h_config.name = "sae_require_mfp";
15739 h_config.value = enable?"1":"0";
15740
15741 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15742 wifi_hostapdWrite(config_file, &h_config, 1);
15743 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15744
15745 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15746 return RETURN_OK;
15747}
15748
15749INT wifi_setSAEpwe(int ap_index, int sae_pwe)
15750{
15751 struct params h_config={0};
15752 char config_file[64] = {0};
15753 char buf[128] = {0};
15754
15755 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15756
15757 h_config.name = "sae_pwe";
15758 snprintf(buf, sizeof(buf), "%d", sae_pwe);
15759 h_config.value = buf;
15760
15761 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15762 wifi_hostapdWrite(config_file, &h_config, 1);
15763 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15764
15765 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15766 return RETURN_OK;
15767}
15768
15769INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
15770{
15771 // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
15772 struct params h_config={0};
15773 char config_file[64] = {0};
15774
15775 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
15776
15777 h_config.name = "wpa_disable_eapol_key_retries";
15778 h_config.value = disable_EAPOL_retries?"1":"0";
15779
15780 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
15781 wifi_hostapdWrite(config_file, &h_config, 1);
15782 wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
15783
15784 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
15785 return RETURN_OK;
15786}
15787
15788INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
15789{
15790 char buf[128] = {0};
15791 char config_file[128] = {0};
developere5750452023-05-15 16:46:42 +080015792 char cmd[128] = {0};
developer72fb0bb2023-01-11 09:46:29 +080015793 char password[64] = {0};
15794 char mfp[32] = {0};
15795 char wpa_mode[32] = {0};
15796 BOOL okc_enable = FALSE;
15797 BOOL sae_MFP = FALSE;
15798 BOOL disable_EAPOL_retries = TRUE;
15799 int sae_pwe = 0;
15800 struct params params = {0};
15801 wifi_band band = band_invalid;
15802
15803 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15804
15805 multiple_set = TRUE;
15806 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15807 if (security->mode == wifi_security_mode_none) {
15808 strcpy(wpa_mode, "None");
15809 } else if (security->mode == wifi_security_mode_wpa_personal)
15810 strcpy(wpa_mode, "WPA-Personal");
15811 else if (security->mode == wifi_security_mode_wpa2_personal)
15812 strcpy(wpa_mode, "WPA2-Personal");
15813 else if (security->mode == wifi_security_mode_wpa_wpa2_personal)
15814 strcpy(wpa_mode, "WPA-WPA2-Personal");
15815 else if (security->mode == wifi_security_mode_wpa_enterprise)
15816 strcpy(wpa_mode, "WPA-Enterprise");
15817 else if (security->mode == wifi_security_mode_wpa2_enterprise)
15818 strcpy(wpa_mode, "WPA2-Enterprise");
15819 else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise)
15820 strcpy(wpa_mode, "WPA-WPA2-Enterprise");
15821 else if (security->mode == wifi_security_mode_wpa3_personal) {
15822 strcpy(wpa_mode, "WPA3-Personal");
15823 okc_enable = TRUE;
15824 sae_MFP = TRUE;
15825 sae_pwe = 2;
15826 disable_EAPOL_retries = FALSE;
15827 } else if (security->mode == wifi_security_mode_wpa3_transition) {
15828 strcpy(wpa_mode, "WPA3-Personal-Transition");
15829 okc_enable = TRUE;
15830 sae_MFP = TRUE;
15831 sae_pwe = 2;
15832 disable_EAPOL_retries = FALSE;
15833 } else if (security->mode == wifi_security_mode_wpa3_enterprise) {
15834 strcpy(wpa_mode, "WPA3-Enterprise");
15835 sae_MFP = TRUE;
15836 sae_pwe = 2;
15837 disable_EAPOL_retries = FALSE;
developerd01e3e82023-04-26 19:10:38 +080015838 } else if (security->mode == wifi_security_mode_enhanced_open) {
developer3086e2f2023-01-17 09:40:01 +080015839 strcpy(wpa_mode, "OWE");
15840 sae_MFP = TRUE;
15841 sae_pwe = 2;
15842 disable_EAPOL_retries = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015843 }
15844
15845 band = wifi_index_to_band(ap_index);
15846 if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
15847 fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__);
15848 return RETURN_ERR;
15849 }
15850
15851 wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
15852 wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
15853 wifi_setSAEMFP(ap_index, sae_MFP);
15854 wifi_setSAEpwe(ap_index, sae_pwe);
15855 wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
15856
developerd01e3e82023-04-26 19:10:38 +080015857 if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
developere5750452023-05-15 16:46:42 +080015858 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) {
15859 int key_len = strlen(security->u.key.key);
15860 // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
15861 if (key_len == 64) { // set wpa_psk
15862 strncpy(password, security->u.key.key, 64); // 64 characters
15863 password[64] = '\0';
15864 wifi_setApSecurityPreSharedKey(ap_index, password);
15865 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
15866 } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase
15867 strncpy(password, security->u.key.key, 63);
15868 password[63] = '\0';
15869 wifi_setApSecurityKeyPassphrase(ap_index, password);
15870 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
15871 } else
15872 return RETURN_ERR;
15873 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015874 }
15875 if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
15876 params.name = "sae_password";
15877 params.value = security->u.key.key;
15878 wifi_hostapdWrite(config_file, &params, 1);
developere5750452023-05-15 16:46:42 +080015879 } else { // remove sae_password
15880 snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
15881 _syscmd(cmd, buf, sizeof(buf));
developer72fb0bb2023-01-11 09:46:29 +080015882 }
15883 }
15884
15885 if (security->mode != wifi_security_mode_none) {
15886 memset(&params, 0, sizeof(params));
15887 params.name = "wpa_pairwise";
15888 if (security->encr == wifi_encryption_tkip)
15889 params.value = "TKIP";
15890 else if (security->encr == wifi_encryption_aes)
15891 params.value = "CCMP";
15892 else if (security->encr == wifi_encryption_aes_tkip)
15893 params.value = "TKIP CCMP";
15894 wifi_hostapdWrite(config_file, &params, 1);
15895 }
15896
15897 if (security->mfp == wifi_mfp_cfg_disabled)
15898 strcpy(mfp, "Disabled");
15899 else if (security->mfp == wifi_mfp_cfg_optional)
15900 strcpy(mfp, "Optional");
15901 else if (security->mfp == wifi_mfp_cfg_required)
15902 strcpy(mfp, "Required");
15903 wifi_setApSecurityMFPConfig(ap_index, mfp);
15904
15905 memset(&params, 0, sizeof(params));
15906 params.name = "transition_disable";
15907 if (security->wpa3_transition_disable == TRUE)
15908 params.value = "0x01";
15909 else
15910 params.value = "0x00";
15911 wifi_hostapdWrite(config_file, &params, 1);
15912
15913 memset(&params, 0, sizeof(params));
15914 params.name = "wpa_group_rekey";
15915 snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
15916 params.value = buf;
15917 wifi_hostapdWrite(config_file, &params, 1);
15918
15919 memset(&params, 0, sizeof(params));
15920 params.name = "wpa_strict_rekey";
15921 params.value = security->strict_rekey?"1":"0";
15922 wifi_hostapdWrite(config_file, &params, 1);
15923
15924 memset(&params, 0, sizeof(params));
15925 params.name = "wpa_pairwise_update_count";
developere5750452023-05-15 16:46:42 +080015926 if (security->eapol_key_retries == 0)
15927 security->eapol_key_retries = 4; // 0 is invalid, set to default value.
developer72fb0bb2023-01-11 09:46:29 +080015928 snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
15929 params.value = buf;
15930 wifi_hostapdWrite(config_file, &params, 1);
15931
15932 memset(&params, 0, sizeof(params));
15933 params.name = "disable_pmksa_caching";
15934 params.value = security->disable_pmksa_caching?"1":"0";
15935 wifi_hostapdWrite(config_file, &params, 1);
15936
developer23e71282023-01-18 10:25:19 +080015937 if (multiple_set == FALSE) {
15938 wifi_setApEnable(ap_index, FALSE);
15939 wifi_setApEnable(ap_index, TRUE);
15940 }
developer72fb0bb2023-01-11 09:46:29 +080015941
15942 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
15943
15944 return RETURN_OK;
15945}
15946
15947INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
15948{
15949 char buf[256] = {0};
15950 char config_file[128] = {0};
15951 int disable = 0;
developere5750452023-05-15 16:46:42 +080015952 bool set_sae = FALSE;
developer72fb0bb2023-01-11 09:46:29 +080015953
15954 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
15955 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index);
15956 wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config
15957 security->mode = wifi_security_mode_none;
15958 if (strlen(buf) != 0) {
15959 if (!strcmp(buf, "WPA-Personal"))
15960 security->mode = wifi_security_mode_wpa_personal;
15961 else if (!strcmp(buf, "WPA2-Personal"))
15962 security->mode = wifi_security_mode_wpa2_personal;
15963 else if (!strcmp(buf, "WPA-WPA2-Personal"))
15964 security->mode = wifi_security_mode_wpa_wpa2_personal;
15965 else if (!strcmp(buf, "WPA-Enterprise"))
15966 security->mode = wifi_security_mode_wpa_enterprise;
15967 else if (!strcmp(buf, "WPA2-Enterprise"))
15968 security->mode = wifi_security_mode_wpa2_enterprise;
15969 else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
15970 security->mode = wifi_security_mode_wpa_wpa2_enterprise;
15971 else if (!strcmp(buf, "WPA3-Personal"))
15972 security->mode = wifi_security_mode_wpa3_personal;
15973 else if (!strcmp(buf, "WPA3-Personal-Transition"))
15974 security->mode = wifi_security_mode_wpa3_transition;
15975 else if (!strcmp(buf, "WPA3-Enterprise"))
15976 security->mode = wifi_security_mode_wpa3_enterprise;
developer3086e2f2023-01-17 09:40:01 +080015977 else if (!strcmp(buf, "OWE"))
developerd01e3e82023-04-26 19:10:38 +080015978 security->mode = wifi_security_mode_enhanced_open;
developer72fb0bb2023-01-11 09:46:29 +080015979 }
15980
15981 wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
15982 if (security->mode == wifi_security_mode_none)
15983 security->encr = wifi_encryption_none;
15984 else {
15985 if (strcmp(buf, "TKIP") == 0)
15986 security->encr = wifi_encryption_tkip;
15987 else if (strcmp(buf, "CCMP") == 0)
15988 security->encr = wifi_encryption_aes;
15989 else
15990 security->encr = wifi_encryption_aes_tkip;
15991 }
15992
15993 if (security->mode != wifi_encryption_none) {
15994 memset(buf, 0, sizeof(buf));
15995 // wpa3 can use one or both configs as password, so we check sae_password first.
15996 wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
developere5750452023-05-15 16:46:42 +080015997 if (strlen(buf) != 0) {
15998 if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
15999 security->u.key.type = wifi_security_key_type_sae;
16000 set_sae = TRUE;
16001 strncpy(security->u.key.key, buf, sizeof(buf));
16002 }
16003 wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
16004 if (strlen(buf) != 0){
16005 if (set_sae == TRUE)
16006 security->u.key.type = wifi_security_key_type_psk_sae;
16007 else if (strlen(buf) == 64)
16008 security->u.key.type = wifi_security_key_type_psk;
16009 else
16010 security->u.key.type = wifi_security_key_type_pass;
16011 strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
developer72fb0bb2023-01-11 09:46:29 +080016012 }
developer72fb0bb2023-01-11 09:46:29 +080016013 security->u.key.key[255] = '\0';
16014 }
16015
16016 memset(buf, 0, sizeof(buf));
16017 wifi_getApSecurityMFPConfig(ap_index, buf);
16018 if (strcmp(buf, "Disabled") == 0)
16019 security->mfp = wifi_mfp_cfg_disabled;
16020 else if (strcmp(buf, "Optional") == 0)
16021 security->mfp = wifi_mfp_cfg_optional;
16022 else if (strcmp(buf, "Required") == 0)
16023 security->mfp = wifi_mfp_cfg_required;
16024
16025 memset(buf, 0, sizeof(buf));
16026 security->wpa3_transition_disable = FALSE;
16027 wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
16028 disable = strtol(buf, NULL, 16);
16029 if (disable != 0)
16030 security->wpa3_transition_disable = TRUE;
16031
16032 memset(buf, 0, sizeof(buf));
16033 wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
16034 if (strlen(buf) == 0)
16035 security->rekey_interval = 86400;
16036 else
16037 security->rekey_interval = strtol(buf, NULL, 10);
16038
16039 memset(buf, 0, sizeof(buf));
16040 wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
16041 if (strlen(buf) == 0)
16042 security->strict_rekey = 1;
16043 else
16044 security->strict_rekey = strtol(buf, NULL, 10);
16045
16046 memset(buf, 0, sizeof(buf));
16047 wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
16048 if (strlen(buf) == 0)
16049 security->eapol_key_retries = 4;
16050 else
16051 security->eapol_key_retries = strtol(buf, NULL, 10);
16052
16053 memset(buf, 0, sizeof(buf));
16054 wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
16055 if (strlen(buf) == 0)
16056 security->disable_pmksa_caching = FALSE;
16057 else
16058 security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE;
16059
16060 /* TODO
16061 eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
16062 */
16063 security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
16064 security->eap_identity_req_timeout = 0;
16065 security->eap_identity_req_retries = 0;
16066 security->eap_req_timeout = 0;
16067 security->eap_req_retries = 0;
16068 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16069 return RETURN_OK;
16070}
16071
16072#endif /* WIFI_HAL_VERSION_3 */
16073
16074#ifdef WIFI_HAL_VERSION_3_PHASE2
16075INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
16076{
16077 char interface_name[16] = {0};
16078 char cmd[128] = {0};
16079 char buf[128] = {0};
16080 char *mac_addr = NULL;
16081 BOOL status = FALSE;
16082 size_t len = 0;
16083
16084 if(ap_index > MAX_APS)
16085 return RETURN_ERR;
16086
16087 *output_numDevices = 0;
16088 wifi_getApEnable(ap_index, &status);
16089 if (status == FALSE)
16090 return RETURN_OK;
16091
16092 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
16093 return RETURN_ERR;
16094 sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name);
16095 _syscmd(cmd, buf, sizeof(buf));
16096
16097 mac_addr = strtok(buf, "\n");
16098 for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
16099 *output_numDevices = i + 1;
16100 fprintf(stderr, "mac_addr: %s\n", mac_addr);
16101 addr_ptr = output_deviceMacAddressArray[i];
16102 mac_addr_aton(addr_ptr, mac_addr);
16103 mac_addr = strtok(NULL, "\n");
16104 }
16105
16106 return RETURN_OK;
16107}
16108#else
16109INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
16110{
16111 char interface_name[16] = {0};
16112 char cmd[128];
16113 BOOL status = false;
16114
16115 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
16116 return RETURN_ERR;
16117
16118 output_buf[0] = '\0';
16119
16120 wifi_getApEnable(ap_index,&status);
16121 if (!status)
16122 return RETURN_OK;
16123
16124 if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
16125 return RETURN_ERR;
16126 sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
16127 _syscmd(cmd, output_buf, output_buf_size);
developer69b61b02023-03-07 17:17:44 +080016128
developer72fb0bb2023-01-11 09:46:29 +080016129 return RETURN_OK;
16130}
16131#endif
16132
16133INT wifi_getProxyArp(INT apIndex, BOOL *enable)
16134{
16135 char output[16]={'\0'};
16136 char config_file[MAX_BUF_SIZE] = {0};
16137
16138 if (!enable)
16139 return RETURN_ERR;
16140
16141 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
16142 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
16143
16144 if (strlen(output) == 0)
16145 *enable = FALSE;
16146 else if (strncmp(output, "1", 1) == 0)
16147 *enable = TRUE;
16148 else
16149 *enable = FALSE;
16150
16151 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
16152 return RETURN_OK;
16153}
16154
16155INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
16156{
16157 if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS)
16158 return RETURN_ERR;
16159 *output_enable=TRUE;
16160 return RETURN_OK;
16161}
16162
16163INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
16164{
16165 char cmd[128] = {0};
16166 char buf[128] = {0};
16167 char line[128] = {0};
16168 size_t len = 0;
16169 FILE *f = NULL;
16170 int index = 0;
16171 int exp = 0;
16172 int mantissa = 0;
16173 int duration = 0;
16174 int radio_index = 0;
16175 int max_radio_num = 0;
16176 uint twt_wake_interval = 0;
16177 int phyId = 0;
16178 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
16179
16180 wifi_getMaxRadioNumber(&max_radio_num);
16181
16182 radio_index = ap_index % max_radio_num;
16183
16184 phyId = radio_index_to_phy(radio_index);
16185 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
16186 _syscmd(cmd, buf, sizeof(buf));
16187 *numSessionReturned = strtol(buf, NULL, 10) - 1;
16188 if (*numSessionReturned > maxNumberSessions)
16189 *numSessionReturned = maxNumberSessions;
16190 else if (*numSessionReturned < 1) {
16191 *numSessionReturned = 0;
16192 return RETURN_OK;
16193 }
16194
16195 sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
16196 if ((f = popen(cmd, "r")) == NULL) {
16197 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
16198 return RETURN_ERR;
16199 }
16200
16201 // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
16202 while((fgets(line, sizeof(line), f)) != NULL) {
16203 char *tmp = NULL;
16204 strcpy(buf, line);
16205 tmp = strtok(buf, " ");
16206 twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10);
16207 tmp = strtok(NULL, " ");
16208 twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10);
16209 tmp = strtok(NULL, " ");
16210 if (strstr(tmp, "t")) {
16211 twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
16212 }
16213 if (strstr(tmp, "a")) {
16214 twtSessions[index].twtParameters.operation.announced = TRUE;
16215 }
16216 tmp = strtok(NULL, " ");
16217 exp = strtol(tmp, NULL, 10);
16218 tmp = strtok(NULL, " ");
16219 mantissa = strtol(tmp, NULL, 10);
16220 tmp = strtok(NULL, " ");
16221 duration = strtol(tmp, NULL, 10);
16222
16223 // only implicit supported
16224 twtSessions[index].twtParameters.operation.implicit = TRUE;
16225 // only individual agreement supported
16226 twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
16227
16228 // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
16229 twt_wake_interval = mantissa * (1 << exp);
16230 if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
16231 // Overflow handling
16232 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int
16233 } else {
16234 twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
16235 }
16236 twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
16237 index++;
16238 }
16239
16240 pclose(f);
16241 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
16242 return RETURN_OK;
16243}