blob: ba4b32751856d827e3dfc9a9df6c9e918f32c3f1 [file] [log] [blame]
developer06a01d92022-09-07 16:32:39 +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*/
developerda1ed692022-09-13 13:59:20 +080037#define MTK_IMPL
developer06a01d92022-09-07 16:32:39 +080038#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>
57#include<net/if.h>
58#endif
59
60#include <ev.h>
61#include <wpa_ctrl.h>
62#include <errno.h>
63#include <time.h>
64#define MAC_ALEN 6
65
66#define MAX_BUF_SIZE 128
67#define MAX_CMD_SIZE 1024
68#define MAX_POSSIBLE_CHANNEL_STRING_BUF 512
69#define IF_NAME_SIZE 50
70#define CONFIG_PREFIX "/nvram/hostapd"
71#define ACL_PREFIX "/tmp/hostapd-acl"
developer10adcc12022-09-13 14:39:17 +080072#define DENY_PREFIX "/tmp/hostapd-deny"
developer06a01d92022-09-07 16:32:39 +080073//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
74#define SOCK_PREFIX "/var/run/hostapd/wifi"
75#define VAP_STATUS_FILE "/tmp/vap-status"
76#define DRIVER_2GHZ "ath9k"
77#define DRIVER_5GHZ "ath10k_pci"
78
79/*
80 MAX_APS - Number of all AP available in system
81 2x Home AP
82 2x Backhaul AP
83 2x Guest AP
84 2x Secure Onboard AP
85 2x Service AP
86
87*/
88#define MAX_APS 10
89#define NUMBER_OF_RADIOS 2
90
91#ifndef AP_PREFIX
92#define AP_PREFIX "wifi"
93#endif
94
95#ifndef RADIO_PREFIX
96#define RADIO_PREFIX "wlan"
97#endif
98
99#define MAX_BUF_SIZE 128
100#define MAX_CMD_SIZE 1024
developer0947e1a2022-09-13 14:15:25 +0800101#define MAX_ASSOCIATED_STA_NUM 2007
developer06a01d92022-09-07 16:32:39 +0800102
103//Uncomment to enable debug logs
104//#define WIFI_DEBUG
105
106#ifdef WIFI_DEBUG
107#define wifi_dbg_printf printf
108#define WIFI_ENTRY_EXIT_DEBUG printf
109#else
110#define wifi_dbg_printf(format, args...) printf("")
111#define WIFI_ENTRY_EXIT_DEBUG(format, args...) printf("")
112#endif
113
114#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g
115#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g
116#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g
117#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g
118#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
119#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
120#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
121#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
122#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
123#define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s"
124
125#define HOSTAPD_HT_CAPAB_20 "[SHORT-GI-20]"
126#define HOSTAPD_HT_CAPAB_40 "[SHORT-GI-20][SHORT-GI-40]"
127
128#define BW_FNAME "/nvram/bw_file.txt"
129
130#define PS_MAX_TID 16
131
132static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
133 WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */
134 WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */
135 WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */
136 WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */
137 WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */
138 WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */
139 WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */
140 WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */
141 WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */
142 WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */
143 WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */
144 WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */
145 WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */
146 WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */
147 WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */
148 WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */
149};
150
151typedef unsigned long long u64;
152
153/* Enum to define WiFi Bands */
154typedef enum
155{
156 band_invalid = -1,
157 band_2_4 = 0,
158 band_5 = 1,
159} wifi_band;
160
161#ifdef WIFI_HAL_VERSION_3
162
163// Return number of elements in array
164#ifndef ARRAY_SIZE
165#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
166#endif /* ARRAY_SIZE */
167
168#ifndef ARRAY_AND_SIZE
169#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
170#endif /* ARRAY_AND_SIZE */
171
172#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
173
174typedef struct {
175 int32_t value;
176 int32_t param;
177 intptr_t key;
178 intptr_t data;
179} wifi_secur_list;
180
181wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
182wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
183char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
184
185static wifi_secur_list map_security[] =
186{
187 WIFI_ITEM_STR(wifi_security_mode_none, "None"),
188 WIFI_ITEM_STR(wifi_security_mode_wep_64, "WEP-64"),
189 WIFI_ITEM_STR(wifi_security_mode_wep_128, "WEP-128"),
190 WIFI_ITEM_STR(wifi_security_mode_wpa_personal, "WPA-Personal"),
191 WIFI_ITEM_STR(wifi_security_mode_wpa_enterprise, "WPA-Enterprise"),
192 WIFI_ITEM_STR(wifi_security_mode_wpa2_personal, "WPA2-Personal"),
193 WIFI_ITEM_STR(wifi_security_mode_wpa2_enterprise, "WPA2-Enterprise"),
194 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_personal, "WPA-WPA2-Personal"),
195 WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_enterprise, "WPA-WPA2-Enterprise")
196};
197
198wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
199{
200 wifi_secur_list *item;
201 int i;
202
203 for (item = list,i = 0;i < list_sz; item++, i++) {
204 if ((int)(item->key) == key) {
205 return item;
206 }
207 }
208
209 return NULL;
210}
211
212char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
213{
214 wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key);
215
216 if (!item) {
217 return "";
218 }
219
220 return (char *)(item->data);
221}
222
223wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
224{
225 wifi_secur_list *item;
226 int i;
227
228 for (item = list,i = 0;i < list_sz; item++, i++) {
229 if (strcmp((char *)(item->data), str) == 0) {
230 return item;
231 }
232 }
233
234 return NULL;
235}
236#endif /* WIFI_HAL_VERSION_3 */
237
238#ifdef HAL_NETLINK_IMPL
239typedef struct {
240 int id;
241 struct nl_sock* socket;
242 struct nl_cb* cb;
243} Netlink;
244
245static int mac_addr_aton(unsigned char *mac_addr, char *arg)
246{
247 unsigned int mac_addr_int[6]={};
248 sscanf(arg, "%x:%x:%x:%x:%x:%x", mac_addr_int+0, mac_addr_int+1, mac_addr_int+2, mac_addr_int+3, mac_addr_int+4, mac_addr_int+5);
249 mac_addr[0] = mac_addr_int[0];
250 mac_addr[1] = mac_addr_int[1];
251 mac_addr[2] = mac_addr_int[2];
252 mac_addr[3] = mac_addr_int[3];
253 mac_addr[4] = mac_addr_int[4];
254 mac_addr[5] = mac_addr_int[5];
255 return 0;
256}
257
258static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
259{
260 unsigned int mac_addr_int[6]={};
261 mac_addr_int[0] = arg[0];
262 mac_addr_int[1] = arg[1];
263 mac_addr_int[2] = arg[2];
264 mac_addr_int[3] = arg[3];
265 mac_addr_int[4] = arg[4];
266 mac_addr_int[5] = arg[5];
267 snprintf(mac_addr, 20, "%02x:%02x:%02x:%02x:%02x:%02x", mac_addr_int[0], mac_addr_int[1],mac_addr_int[2],mac_addr_int[3],mac_addr_int[4],mac_addr_int[5]);
268 return;
269}
270
271static int ieee80211_frequency_to_channel(int freq)
272{
273 if (freq == 2484)
274 return 14;
275 else if (freq < 2484)
276 return (freq - 2407) / 5;
277 else if (freq >= 4910 && freq <= 4980)
278 return (freq - 4000) / 5;
279 else if (freq <= 45000)
280 return (freq - 5000) / 5;
281 else if (freq >= 58320 && freq <= 64800)
282 return (freq - 56160) / 2160;
283 else
284 return 0;
285}
286
287static int initSock80211(Netlink* nl) {
288 nl->socket = nl_socket_alloc();
289 if (!nl->socket) {
290 fprintf(stderr, "Failing to allocate the sock\n");
291 return -ENOMEM;
292 }
293
294 nl_socket_set_buffer_size(nl->socket, 8192, 8192);
295
296 if (genl_connect(nl->socket)) {
297 fprintf(stderr, "Failed to connect\n");
298 nl_close(nl->socket);
299 nl_socket_free(nl->socket);
300 return -ENOLINK;
301 }
302
303 nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
304 if (nl->id< 0) {
305 fprintf(stderr, "interface not found.\n");
306 nl_close(nl->socket);
307 nl_socket_free(nl->socket);
308 return -ENOENT;
309 }
310
311 nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
312 if ((!nl->cb)) {
313 fprintf(stderr, "Failed to allocate netlink callback.\n");
314 nl_close(nl->socket);
315 nl_socket_free(nl->socket);
316 return ENOMEM;
317 }
318
319 return nl->id;
320}
321
322static int nlfree(Netlink *nl)
323{
324 nl_cb_put(nl->cb);
325 nl_close(nl->socket);
326 nl_socket_free(nl->socket);
327 return 0;
328}
329
330static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
331 [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
332 [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
333 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
334};
335
336static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
337};
338
339static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
340};
341
342typedef struct _wifi_channelStats_loc {
343 INT array_size;
344 INT ch_number;
345 BOOL ch_in_pool;
346 INT ch_noise;
347 BOOL ch_radar_noise;
348 INT ch_max_80211_rssi;
349 INT ch_non_80211_noise;
350 INT ch_utilization;
351 ULLONG ch_utilization_total;
352 ULLONG ch_utilization_busy;
353 ULLONG ch_utilization_busy_tx;
354 ULLONG ch_utilization_busy_rx;
355 ULLONG ch_utilization_busy_self;
356 ULLONG ch_utilization_busy_ext;
357} wifi_channelStats_t_loc;
358
359typedef struct wifi_device_info {
360 INT wifi_devIndex;
361 UCHAR wifi_devMacAddress[6];
362 CHAR wifi_devIPAddress[64];
363 BOOL wifi_devAssociatedDeviceAuthentiationState;
364 INT wifi_devSignalStrength;
365 INT wifi_devTxRate;
366 INT wifi_devRxRate;
367} wifi_device_info_t;
368
369#endif
370
371//For 5g Alias Interfaces
372static BOOL priv_flag = TRUE;
373static BOOL pub_flag = TRUE;
374static BOOL Radio_flag = TRUE;
375//wifi_setApBeaconRate(1, beaconRate);
376
377struct params
378{
379 char * name;
380 char * value;
381};
382
383static int _syscmd(char *cmd, char *retBuf, int retBufSize)
384{
385 FILE *f;
386 char *ptr = retBuf;
387 int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
388
389 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
390 if((f = popen(cmd, "r")) == NULL) {
391 fprintf(stderr,"\npopen %s error\n", cmd);
392 return RETURN_ERR;
393 }
394
395 while(!feof(f))
396 {
397 *ptr = 0;
398 if(bufSize>=128) {
399 bufbytes=128;
400 } else {
401 bufbytes=bufSize-1;
402 }
403
404 fgets(ptr,bufbytes,f);
405 readbytes=strlen(ptr);
406
407 if(!readbytes)
408 break;
409
410 bufSize-=readbytes;
411 ptr += readbytes;
412 }
413 cmd_ret = pclose(f);
414 retBuf[retBufSize-1]=0;
415 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
416
417 return cmd_ret >> 8;
418}
419
420static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
421{
422 char cmd[MAX_CMD_SIZE]={'\0'};
423 char buf[MAX_BUF_SIZE]={'\0'};
424 int ret = 0;
425
426 sprintf(cmd, "cat %s | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file, param);
427 ret = _syscmd(cmd, buf, sizeof(buf));
428 if ((ret != 0) && (strlen(buf) == 0))
429 return -1;
430 snprintf(output, output_size, "%s", buf);
431
432 return 0;
433}
434
435static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
436{
437 char cmd[MAX_CMD_SIZE]={'\0'};
438 char buf[MAX_BUF_SIZE]={'\0'};
439
440 for(int i=0;i<item_count;i++)
441 {
442 wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf));
443 if (strlen(buf) == 0) //Insert
444 snprintf(cmd, sizeof(cmd), "echo \"%s=%s\" >> %s", list[i].name, list[i].value, conf_file);
445 else //Update
446 snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file);
447 if(_syscmd(cmd, buf, sizeof(buf)))
448 return -1;
449 }
450
451 return 0;
452}
453
454static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
455{
456 char cmd[MAX_CMD_SIZE]="", output[32]="";
457 FILE *fp;
458 int i;
459 //NOTE RELOAD should be done in ApplySSIDSettings
460
461 for(i=0; i<item_count; i++, list++)
462 {
463 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s%d SET %s %s", AP_PREFIX, apIndex, list->name, list->value);
464 if((fp = popen(cmd, "r"))==NULL)
465 {
466 perror("popen failed");
467 return -1;
468 }
469 if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2))
470 {
471 pclose(fp);
472 perror("fgets failed");
473 return -1;
474 }
475 pclose(fp);
476 }
477 return 0;
478}
479
480static int wifi_reloadAp(int apIndex)
481{
482 char cmd[MAX_CMD_SIZE]="";
483 char buf[MAX_BUF_SIZE]="";
484
485 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d reload", AP_PREFIX, apIndex);
486 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
487 return RETURN_ERR;
488
489 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d disable", AP_PREFIX, apIndex);
490 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
491 return RETURN_ERR;
492
493 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d enable", AP_PREFIX, apIndex);
494 if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR)
495 return RETURN_ERR;
496
497 return RETURN_OK;
498}
499
500
501//For Getting Current Interface Name from corresponding hostapd configuration
502void GetInterfaceName(char *interface_name, char *conf_file)
503{
504 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
505 wifi_hostapdRead(conf_file,"interface",interface_name, IF_NAME_SIZE);
506 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
507}
508
509INT File_Reading(CHAR *file, char *Value)
510{
511 FILE *fp = NULL;
512 char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0};
513 int count = 0;
514
515 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
516 fp = popen(file,"r");
517 if(fp == NULL)
518 return RETURN_ERR;
519
520 if(fgets(buf,sizeof(buf) -1,fp) != NULL)
521 {
522 for(count=0;buf[count]!='\n';count++)
523 copy_buf[count]=buf[count];
524 copy_buf[count]='\0';
525 }
526 strcpy(Value,copy_buf);
527 pclose(fp);
528 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
529
530 return RETURN_OK;
531}
532
533void wifi_RestartHostapd_2G()
534{
535 int Public2GApIndex = 4;
536
537 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
538 wifi_setApEnable(Public2GApIndex, FALSE);
539 wifi_setApEnable(Public2GApIndex, TRUE);
540 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
541}
542
543void wifi_RestartHostapd_5G()
544{
545 int Public5GApIndex = 5;
546
547 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
548 wifi_setApEnable(Public5GApIndex, FALSE);
549 wifi_setApEnable(Public5GApIndex, TRUE);
550 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
551}
552
553void wifi_RestartPrivateWifi_2G()
554{
555 int PrivateApIndex = 0;
556
557 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
558 wifi_setApEnable(PrivateApIndex, FALSE);
559 wifi_setApEnable(PrivateApIndex, TRUE);
560 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
561}
562
563void wifi_RestartPrivateWifi_5G()
564{
565 int Private5GApIndex = 1;
566
567 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
568 wifi_setApEnable(Private5GApIndex, FALSE);
569 wifi_setApEnable(Private5GApIndex, TRUE);
570 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
571}
572
573static int writeBandWidth(int radioIndex,char *bw_value)
574{
575 char buf[MAX_BUF_SIZE];
576 char cmd[MAX_CMD_SIZE];
577
578 snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME);
579 if(_syscmd(cmd, buf, sizeof(buf)))
580 {
581 snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME);
582 _syscmd(cmd, buf, sizeof(buf));
583 return RETURN_OK;
584 }
585
586 sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
587 _syscmd(cmd,buf,sizeof(buf));
588 return RETURN_OK;
589}
590
591static int readBandWidth(int radioIndex,char *bw_value)
592{
593 char buf[MAX_BUF_SIZE];
594 char cmd[MAX_CMD_SIZE];
595 sprintf(cmd,"grep 'SET_BW%d=' %s | sed 's/^.*=//'",radioIndex,BW_FNAME);
596 _syscmd(cmd,buf,sizeof(buf));
597 if(NULL!=strstr(buf,"20MHz"))
598 {
599 strcpy(bw_value,"20MHz");
600 }
601 else if(NULL!=strstr(buf,"40MHz"))
602 {
603 strcpy(bw_value,"40MHz");
604 }
605 else if(NULL!=strstr(buf,"80MHz"))
606 {
607 strcpy(bw_value,"80MHz");
608 }
609 else
610 {
611 return RETURN_ERR;
612 }
613 return RETURN_OK;
614}
615
616INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
617{
618 return 0;
619}
620
621INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
622{
623 return 0;
624}
625
626INT wifi_setLED(INT radioIndex, BOOL enable)
627{
628 return 0;
629}
630INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
631{
632 return RETURN_OK;
633}
634/**********************************************************************************
635 *
636 * Wifi Subsystem level function prototypes
637 *
638**********************************************************************************/
639//---------------------------------------------------------------------------------------------------
640//Wifi system api
641//Get the wifi hal version in string, eg "2.0.0". WIFI_HAL_MAJOR_VERSION.WIFI_HAL_MINOR_VERSION.WIFI_HAL_MAINTENANCE_VERSION
642INT wifi_getHalVersion(CHAR *output_string) //RDKB
643{
644 if(!output_string)
645 return RETURN_ERR;
646 snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
647
648 return RETURN_OK;
649}
650
651
652/* wifi_factoryReset() function */
653/**
654* @description Clears internal variables to implement a factory reset of the Wi-Fi
655* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
656*
657* @param None
658*
659* @return The status of the operation.
660* @retval RETURN_OK if successful.
661* @retval RETURN_ERR if any error is detected
662*
663* @execution Synchronous
664* @sideeffect None
665*
666* @note This function must not suspend and must not invoke any blocking system
667* calls. It should probably just send a message to a driver event handler task.
668*
669*/
670INT wifi_factoryReset()
671{
672 char cmd[128];
673
674 /*delete running hostapd conf files*/
675 wifi_dbg_printf("\n[%s]: deleting hostapd conf file %s and %s",__func__,HOSTAPD_CONF_0,HOSTAPD_CONF_1);
676 sprintf(cmd, "rm -rf %s %s",HOSTAPD_CONF_0,HOSTAPD_CONF_1);
677 system(cmd);
678 system("systemctl restart hostapd.service");
679
680 return RETURN_OK;
681}
682
683/* wifi_factoryResetRadios() function */
684/**
685* @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.
686*
687* @param None
688* @return The status of the operation
689* @retval RETURN_OK if successful
690* @retval RETURN_ERR if any error is detected
691*
692* @execution Synchronous
693*
694* @sideeffect None
695*
696* @note This function must not suspend and must not invoke any blocking system
697* calls. It should probably just send a message to a driver event handler task.
698*
699*/
700INT wifi_factoryResetRadios()
701{
702 if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
703 return RETURN_OK;
704
705 return RETURN_ERR;
706}
707
708
709/* wifi_factoryResetRadio() function */
710/**
711* @description Restore selected radio parameters without touching access point parameters
712*
713* @param radioIndex - Index of Wi-Fi Radio channel
714*
715* @return The status of the operation.
716* @retval RETURN_OK if successful.
717* @retval RETURN_ERR if any error is detected
718*
719* @execution Synchronous.
720* @sideeffect None.
721*
722* @note This function must not suspend and must not invoke any blocking system
723* calls. It should probably just send a message to a driver event handler task.
724*
725*/
726INT wifi_factoryResetRadio(int radioIndex) //RDKB
727{
728 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
729 if(radioIndex == 0)
730 system("cp /etc/hostapd-2G.conf /nvram/hostapd0.conf");
731 else if(radioIndex == 1)
732 system("cp /etc/hostapd-5G.conf /nvram/hostapd1.conf");
733 else
734 return RETURN_ERR;
735
736 system("systemctl restart hostapd.service");
737 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
738 return RETURN_OK;
739}
740
741/* wifi_initRadio() function */
742/**
743* Description: This function call initializes the specified radio.
744* Implementation specifics may dictate the functionality since
745* different hardware implementations may have different initilization requirements.
746* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT
747*
748* @return The status of the operation.
749* @retval RETURN_OK if successful.
750* @retval RETURN_ERR if any error is detected
751*
752* @execution Synchronous.
753* @sideeffect None.
754*
755* @note This function must not suspend and must not invoke any blocking system
756* calls. It should probably just send a message to a driver event handler task.
757*
758*/
759INT wifi_initRadio(INT radioIndex)
760{
761 //TODO: Initializes the wifi subsystem (for specified radio)
762 return RETURN_OK;
763}
764void macfilter_init()
765{
766 char count[4]={'\0'};
767 char buf[253]={'\0'};
768 char tmp[19]={'\0'};
769 int dev_count,block,mac_entry=0;
770 char res[4]={'\0'};
771 char acl_file_path[64] = {'\0'};
772 FILE *fp = NULL;
773 int index=0;
774 char iface[10]={'\0'};
775 char config_file[MAX_BUF_SIZE] = {0};
776
777
778 sprintf(acl_file_path,"/tmp/mac_filter.sh");
779
780 fp=fopen(acl_file_path,"w+");
781 sprintf(buf,"#!/bin/sh \n");
782 fprintf(fp,"%s\n",buf);
783
784 system("chmod 0777 /tmp/mac_filter.sh");
785
786 for(index=0;index<=1;index++)
787 {
788 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index);
789 wifi_hostapdRead(config_file, "interface", iface, sizeof(iface));
790 sprintf(buf,"syscfg get %dcountfilter",index);
791 _syscmd(buf,count,sizeof(count));
792 mac_entry=atoi(count);
793
794 sprintf(buf,"syscfg get %dblockall",index);
795 _syscmd(buf,res,sizeof(res));
796 block = atoi(res);
797
798 //Allow only those macs mentioned in ACL
799 if(block==1)
800 {
801 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
802 fprintf(fp,"%s\n",buf);
803 for(dev_count=1;dev_count<=mac_entry;dev_count++)
804 {
805 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
806 _syscmd(buf,tmp,sizeof(tmp));
807 fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp);
808 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp);
809 fprintf(fp,"%s\n",buf);
810 }
811 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp);
812 fprintf(fp,"%s\n",buf);
813 }
814
815 //Block all the macs mentioned in ACL
816 else if(block==2)
817 {
818 sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index);
819 fprintf(fp,"%s\n",buf);
820
821 for(dev_count=1;dev_count<=mac_entry;dev_count++)
822 {
823 sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count);
824 _syscmd(buf,tmp,sizeof(tmp));
825 fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp);
826 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp);
827 fprintf(fp,"%s\n",buf);
828 }
829 }
830 }
831 fclose(fp);
832}
833
834// Initializes the wifi subsystem (all radios)
835INT wifi_init() //RDKB
836{
837 char interface[MAX_BUF_SIZE]={'\0'};
838 char bridge_name[MAX_BUF_SIZE]={'\0'};
839 INT len=0;
840
841 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
842 //Not intitializing macfilter for Turris-Omnia Platform for now
843 //macfilter_init();
844
845 system("/usr/sbin/iw reg set US");
846 system("systemctl start hostapd.service");
847 sleep(2);//sleep to wait for hostapd to start
848
849 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
850
851 return RETURN_OK;
852}
853
854/* wifi_reset() function */
855/**
856* Description: Resets the Wifi subsystem. This includes reset of all AP varibles.
857* Implementation specifics may dictate what is actualy reset since
858* different hardware implementations may have different requirements.
859* Parameters : None
860*
861* @return The status of the operation.
862* @retval RETURN_OK if successful.
863* @retval RETURN_ERR if any error is detected
864*
865* @execution Synchronous.
866* @sideeffect None.
867*
868* @note This function must not suspend and must not invoke any blocking system
869* calls. It should probably just send a message to a driver event handler task.
870*
871*/
872INT wifi_reset()
873{
874 //TODO: resets the wifi subsystem, deletes all APs
developerb222b212022-09-13 14:01:01 +0800875 system("systemctl stop hostapd.service");
876 sleep(2);
877 system("systemctl start hostapd.service");
878 sleep(5);
developer06a01d92022-09-07 16:32:39 +0800879 return RETURN_OK;
880}
881
882/* wifi_down() function */
883/**
884* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
885* Implementation specifics may dictate some functionality since
886* different hardware implementations may have different requirements.
887*
888* @param None
889*
890* @return The status of the operation
891* @retval RETURN_OK if successful
892* @retval RETURN_ERR if any error is detected
893*
894* @execution Synchronous
895* @sideeffect None
896*
897* @note This function must not suspend and must not invoke any blocking system
898* calls. It should probably just send a message to a driver event handler task.
899*
900*/
901INT wifi_down()
902{
903 //TODO: turns off transmit power for the entire Wifi subsystem, for all radios
developerb222b212022-09-13 14:01:01 +0800904 system("systemctl stop hostapd.service");
905 sleep(2);
developer06a01d92022-09-07 16:32:39 +0800906 return RETURN_OK;
907}
908
909
910/* wifi_createInitialConfigFiles() function */
911/**
912* @description This function creates wifi configuration files. The format
913* and content of these files are implementation dependent. This function call is
914* used to trigger this task if necessary. Some implementations may not need this
915* function. If an implementation does not need to create config files the function call can
916* do nothing and return RETURN_OK.
917*
918* @param None
919*
920* @return The status of the operation
921* @retval RETURN_OK if successful
922* @retval RETURN_ERR if any error is detected
923*
924* @execution Synchronous
925* @sideeffect None
926*
927* @note This function must not suspend and must not invoke any blocking system
928* calls. It should probably just send a message to a driver event handler task.
929*
930*/
931INT wifi_createInitialConfigFiles()
932{
933 //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)
934 return RETURN_OK;
935}
936
937// outputs the country code to a max 64 character string
938INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
939{
developer7543b3b2022-09-13 13:47:17 +0800940 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
941 if(!output_string || !(radioIndex==0 || radioIndex==1))
developer06a01d92022-09-07 16:32:39 +0800942 return RETURN_ERR;
developer7543b3b2022-09-13 13:47:17 +0800943
944 sprintf(cmd,"hostapd_cli -i %s%d status driver | grep country | cut -d '=' -f2", AP_PREFIX, radioIndex);
945 _syscmd(cmd, buf, sizeof(buf));
946 if(strlen(buf) > 0)
947 snprintf(output_string, 64, "%s", buf);
948 else
949 return RETURN_ERR;
developer06a01d92022-09-07 16:32:39 +0800950
951 return RETURN_OK;
952}
953
954INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
955{
956 //Set wifi config. Wait for wifi reset to apply
developer7543b3b2022-09-13 13:47:17 +0800957 char str[MAX_BUF_SIZE]={'\0'};
958 char cmd[MAX_CMD_SIZE]={'\0'};
959 struct params params;
960 char config_file[MAX_BUF_SIZE] = {0};
961
962 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
963 if(NULL == CountryCode || strlen(CountryCode) >= 32 )
964 return RETURN_ERR;
965
966 params.name = "country_code";
967 params.value = CountryCode;
968 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, radioIndex);
969 int ret = wifi_hostapdWrite(config_file, &params, 1);
970 if (ret) {
971 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
972 ,__func__, ret);
973 }
974
975 ret = wifi_hostapdProcessUpdate(radioIndex, &params, 1);
976 if (ret) {
977 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
978 ,__func__, ret);
979 }
980 wifi_reloadAp(radioIndex);
981 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
982
developer06a01d92022-09-07 16:32:39 +0800983 return RETURN_OK;
984}
985
986/**********************************************************************************
987 *
988 * Wifi radio level function prototypes
989 *
990**********************************************************************************/
991
992//Get the total number of radios in this wifi subsystem
993INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
994{
995 if (NULL == output)
996 return RETURN_ERR;
997 *output = 2;
998
999 return RETURN_OK;
1000}
1001
1002//Get the total number of SSID entries in this wifi subsystem
1003INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
1004{
1005 if (NULL == output)
1006 return RETURN_ERR;
1007 *output = MAX_APS;
1008
1009 return RETURN_OK;
1010}
1011
1012//Get the Radio enable config parameter
1013INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
1014{
1015 char interface_path[MAX_CMD_SIZE] = {0};
1016 FILE *fp = NULL;
1017
1018 if (NULL == output_bool)
1019 return RETURN_ERR;
1020
1021 *output_bool = FALSE;
1022 if (!((radioIndex == 0) || (radioIndex == 1)))// Target has two wifi radios
1023 return RETURN_ERR;
1024
1025 snprintf(interface_path, sizeof(interface_path), "/sys/class/net/%s%d/address", RADIO_PREFIX, radioIndex);
1026 fp = fopen(interface_path, "r");
developercf48e482022-09-13 14:49:50 +08001027 if(!fp)
developer06a01d92022-09-07 16:32:39 +08001028 {
developercf48e482022-09-13 14:49:50 +08001029 return RETURN_ERR;
developer06a01d92022-09-07 16:32:39 +08001030 }
1031 //TODO: check if hostapd with config is running
developercf48e482022-09-13 14:49:50 +08001032 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0};
1033 sprintf(cmd, "hostapd_cli -i %s%d status | grep state | cut -d '=' -f2", AP_PREFIX, radioIndex);
1034 _syscmd(cmd, buf, sizeof(buf));
developer06a01d92022-09-07 16:32:39 +08001035
developercf48e482022-09-13 14:49:50 +08001036 if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 || strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0)
1037 *output_bool = TRUE;
1038 fclose(fp);
developer06a01d92022-09-07 16:32:39 +08001039 return RETURN_OK;
1040}
1041
1042INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
1043{
1044 char cmd[MAX_CMD_SIZE] = {0};
1045 char buf[MAX_CMD_SIZE] = {0};
1046 int apIndex, ret;
1047 FILE *fp = NULL;
1048
1049 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1050 if(enable==FALSE)
1051 {
1052 for(apIndex=radioIndex; apIndex<MAX_APS; apIndex+=2)
1053 {
1054 //Detaching %s%d from hostapd daemon
1055 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s%d", AP_PREFIX, apIndex);
1056 _syscmd(cmd, buf, sizeof(buf));
1057 if(strncmp(buf, "OK", 2))
1058 fprintf(stderr, "Could not detach %s%d from hostapd daemon", AP_PREFIX, apIndex);
1059 snprintf(cmd, sizeof(cmd), "iw %s%d del", AP_PREFIX, apIndex);
1060 _syscmd(cmd, buf, sizeof(buf));
1061 }
developer456aa3e2022-09-13 14:27:36 +08001062 snprintf(cmd, sizeof(cmd), "ifconfig %s%d down 2>&1", RADIO_PREFIX, radioIndex);
developer06a01d92022-09-07 16:32:39 +08001063 _syscmd(cmd, buf, sizeof(buf));
1064 if(strlen(buf))
developer456aa3e2022-09-13 14:27:36 +08001065 fprintf(stderr, "Could not shut down the radio interface: %s%d", RADIO_PREFIX, radioIndex);
developer06a01d92022-09-07 16:32:39 +08001066 }
1067 else
1068 {
developer456aa3e2022-09-13 14:27:36 +08001069 snprintf(cmd, sizeof(cmd), "ifconfig %s%d up 2>&1", RADIO_PREFIX, radioIndex);
developer06a01d92022-09-07 16:32:39 +08001070 _syscmd(cmd, buf, sizeof(buf));
1071 if(strlen(buf))
developer456aa3e2022-09-13 14:27:36 +08001072 fprintf(stderr, "Could not up the radio interface: %s%d", RADIO_PREFIX, radioIndex);
developer06a01d92022-09-07 16:32:39 +08001073 sleep(1);
1074 if(radioIndex == 1)//If "wlan0" interface created for 5GHz radio, then need to rename to wlan1
1075 {
1076 snprintf(cmd, sizeof(cmd), "/sys/class/net/%s%d/address", RADIO_PREFIX, radioIndex);
1077 fp = fopen(cmd, "r");
1078 if(!fp)
1079 {
1080 snprintf(cmd, sizeof(cmd), "ip link set %s0 down", RADIO_PREFIX);
1081 _syscmd(cmd, buf, sizeof(buf));
1082 snprintf(cmd, sizeof(cmd), "ip link set %s0 name %s%d", RADIO_PREFIX, RADIO_PREFIX, radioIndex);
1083 _syscmd(cmd, buf, sizeof(buf));
1084 }
1085 if(fp)
1086 fclose(fp);
1087 }
1088 for(apIndex=radioIndex; apIndex<MAX_APS; apIndex+=2)
1089 {
1090 snprintf(cmd, sizeof(cmd), "iw %s%d interface add %s%d type __ap", RADIO_PREFIX, radioIndex, AP_PREFIX, apIndex);
1091 ret = _syscmd(cmd, buf, sizeof(buf));
1092 if ( ret == RETURN_ERR)
1093 {
1094 fprintf(stderr, "VAP interface creation failed\n");
1095 continue;
1096 }
1097 snprintf(cmd, sizeof(cmd), "cat %s | grep %s%d | cut -d'=' -f2", VAP_STATUS_FILE, AP_PREFIX, apIndex);
1098 _syscmd(cmd, buf, sizeof(buf));
1099 if(*buf == '1')
1100 {
1101 snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",
1102 radioIndex, apIndex);
1103 _syscmd(cmd, buf, sizeof(buf));
1104 if(strncmp(buf, "OK", 2))
1105 fprintf(stderr, "Could not detach %s%d from hostapd daemon", AP_PREFIX, apIndex);
1106 }
1107 }
1108 }
1109
1110 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1111 return RETURN_OK;
1112}
1113
1114//Get the Radio enable status
1115INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB
1116{
1117 if (NULL == output_bool)
1118 return RETURN_ERR;
1119
1120 return wifi_getRadioEnable(radioIndex, output_bool);
1121}
1122
1123//Get the Radio Interface name from platform, eg "wlan0"
1124INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
1125{
1126 if (NULL == output_string || radioIndex>=NUMBER_OF_RADIOS || radioIndex<0)
1127 return RETURN_ERR;
1128 snprintf(output_string, 64, "%s%d", RADIO_PREFIX, radioIndex);
1129
1130 return RETURN_OK;
1131}
1132
1133//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
1134//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.
1135INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
1136{
1137 char cmd[1024] = {0};
1138 char buf[1024] = {0};
1139 char HConf_file[MAX_BUF_SIZE] = {'\0'};
1140 char interface_name[50] = {0};
1141
1142 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1143 if (NULL == output_string)
1144 return RETURN_ERR;
1145
1146 sprintf(HConf_file,"%s%d%s","/nvram/hostapd",radioIndex,".conf");
1147 GetInterfaceName(interface_name,HConf_file);
1148
1149 sprintf(cmd, "iwconfig %s | grep 'Bit Rate' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1,2", interface_name);
1150 _syscmd(cmd, buf, sizeof(buf));
1151
1152 if(strlen(buf) > 0)
1153 snprintf(output_string, 64, "%s", buf);
1154 else
1155 {
1156 wifi_getRadioOperatingChannelBandwidth(radioIndex,buf);
1157 if((strcmp(buf,"20MHz") == 0) && (radioIndex == 0))
1158 strcpy(output_string,"144 Mb/s");
1159 else if((strcmp(buf,"20MHz") == 0) && (radioIndex == 1))
1160 strcpy(output_string,"54 Mb/s");
1161 else if((strcmp(buf,"40MHz") == 0) && (radioIndex == 1))
1162 strcpy(output_string,"300 Mb/s");
1163 //TODO: CHECK VALID VALUE
1164 }
1165 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1166
1167 return RETURN_OK;
1168}
1169#if 0
1170INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
1171{
1172 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1173 char cmd[64];
1174 char buf[1024];
1175 int apIndex;
1176
1177 if (NULL == output_string)
1178 return RETURN_ERR;
1179
1180 apIndex=(radioIndex==0)?0:1;
1181
1182 snprintf(cmd, sizeof(cmd), "iwconfig %s%d | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", AP_PREFIX, apIndex);
1183 _syscmd(cmd,buf, sizeof(buf));
1184
1185 snprintf(output_string, 64, "%s", buf);
1186 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1187 return RETURN_OK;
1188}
1189#endif
1190
1191
1192//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
1193//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.
1194INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB
1195{
1196 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1197 if (NULL == output_string)
1198 return RETURN_ERR;
1199 snprintf(output_string, 64, (radioIndex == 0)?"2.4GHz":"5GHz");
1200 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1201
1202 return RETURN_OK;
1203#if 0
1204 char buf[MAX_BUF_SIZE]={'\0'};
1205 char str[MAX_BUF_SIZE]={'\0'};
1206 char cmd[MAX_CMD_SIZE]={'\0'};
1207 char *ch=NULL;
1208 char *ch2=NULL;
1209
1210 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1211 if (NULL == output_string)
1212 return RETURN_ERR;
1213
1214
1215 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
1216
1217 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
1218 {
1219 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1220 return RETURN_ERR;
1221 }
1222 ch=strchr(buf,'\n');
1223 *ch='\0';
1224 ch=strchr(buf,'=');
1225 if(ch==NULL)
1226 return RETURN_ERR;
1227
1228
1229 ch++;
1230
1231 /* prepend 0 for channel with single digit. for ex, 6 would be 06 */
1232 strcpy(buf,"0");
1233 if(strlen(ch) == 1)
1234 ch=strcat(buf,ch);
1235
1236
1237 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
1238
1239 if(_syscmd(cmd,str,64) == RETURN_ERR)
1240 {
1241 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1242 return RETURN_ERR;
1243 }
1244
1245
1246 ch2=strchr(str,'\n');
1247 //replace \n with \0
1248 *ch2='\0';
1249 ch2=strchr(str,'=');
1250 if(ch2==NULL)
1251 {
1252 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1253 return RETURN_ERR;
1254 }
1255 else
1256 wifi_dbg_printf("%s",ch2+1);
1257
1258
1259 ch2++;
1260
1261
1262 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch);
1263
1264 memset(buf,'\0',sizeof(buf));
1265 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
1266 {
1267 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1268 return RETURN_ERR;
1269 }
1270 if (strstr(buf,"2.4") != NULL )
1271 strcpy(output_string,"2.4GHz");
1272 else if(strstr(buf,"5.") != NULL )
1273 strcpy(output_string,"5GHz");
1274 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1275
1276 return RETURN_OK;
1277#endif
1278}
1279
1280//Get the frequency band at which the radio is operating, eg: "2.4GHz"
1281//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.
1282INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
1283{
1284 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1285 if (NULL == output_string)
1286 return RETURN_ERR;
1287 snprintf(output_string, 64, (radioIndex == 0)?"2.4GHz":"5GHz");
1288 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1289
1290 return RETURN_OK;
1291#if 0
1292 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1293 char buf[MAX_BUF_SIZE]={'\0'};
1294 char str[MAX_BUF_SIZE]={'\0'};
1295 char cmd[MAX_CMD_SIZE]={'\0'};
1296 char *ch=NULL;
1297 char *ch2=NULL;
1298 char ch1[5]="0";
1299
1300 sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex);
1301
1302 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
1303 {
1304 printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1305 return RETURN_ERR;
1306 }
1307
1308 ch=strchr(buf,'\n');
1309 *ch='\0';
1310 ch=strchr(buf,'=');
1311 if(ch==NULL)
1312 return RETURN_ERR;
1313 ch++;
1314
1315 if(strlen(ch)==1)
1316 {
1317 strcat(ch1,ch);
1318
1319 }
1320 else
1321 {
1322 strcpy(ch1,ch);
1323 }
1324
1325
1326
1327 sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex);
1328 if(_syscmd(cmd,str,64) == RETURN_ERR)
1329 {
1330 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1331 return RETURN_ERR;
1332 }
1333
1334
1335 ch2=strchr(str,'\n');
1336 //replace \n with \0
1337 *ch2='\0';
1338 ch2=strchr(str,'=');
1339 if(ch2==NULL)
1340 {
1341 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1342 return RETURN_ERR;
1343 }
1344 else
1345 wifi_dbg_printf("%s",ch2+1);
1346 ch2++;
1347
1348
1349 sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1);
1350 memset(buf,'\0',sizeof(buf));
1351 if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR)
1352 {
1353 wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__);
1354 return RETURN_ERR;
1355 }
1356
1357
1358 if(strstr(buf,"2.4")!=NULL)
1359 {
1360 strcpy(output_string,"2.4GHz");
1361 }
1362 if(strstr(buf,"5.")!=NULL)
1363 {
1364 strcpy(output_string,"5GHz");
1365 }
1366 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1367 return RETURN_OK;
1368#endif
1369}
1370
1371//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
1372//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.
1373INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
1374{
1375 if (NULL == output_string)
1376 return RETURN_ERR;
1377 snprintf(output_string, 64, (radioIndex==0)?"b,g,n":"a,n,ac");
1378
1379 return RETURN_OK;
1380}
1381
1382//Get the radio operating mode, and pure mode flag. eg: "ac"
1383//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.
1384INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB
1385{
1386 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1387 if (NULL == output_string)
1388 return RETURN_ERR;
1389
1390 if (radioIndex == 0) {
1391 snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others
1392 *gOnly = FALSE;
1393 *nOnly = TRUE;
1394 *acOnly = FALSE;
1395 } else {
1396 snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac"
1397 *gOnly = FALSE;
1398 *nOnly = FALSE;
1399 *acOnly = FALSE;
1400 }
1401 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1402
1403 return RETURN_OK;
1404#if 0
1405 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1406 char buf[64] = {0};
1407 char config_file[MAX_BUF_SIZE] = {0};
1408
1409 if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly))
1410 return RETURN_ERR;
1411
1412 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex);
1413 wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf));
1414
1415 wifi_dbg_printf("\nhw_mode=%s\n",buf);
1416 if (strlen(buf) == 0)
1417 {
1418 wifi_dbg_printf("\nwifi_hostapdRead returned none\n");
1419 return RETURN_ERR;
1420 }
1421 if(strcmp(buf,"g")==0)
1422 {
1423 wifi_dbg_printf("\nG\n");
1424 *gOnly=TRUE;
1425 *nOnly=FALSE;
1426 *acOnly=FALSE;
1427 }
1428 else if(strcmp(buf,"n")==0)
1429 {
1430 wifi_dbg_printf("\nN\n");
1431 *gOnly=FALSE;
1432 *nOnly=TRUE;
1433 *acOnly=FALSE;
1434 }
1435 else if(strcmp(buf,"ac")==0)
1436 {
1437 wifi_dbg_printf("\nac\n");
1438 *gOnly=FALSE;
1439 *nOnly=FALSE;
1440 *acOnly=TRUE;
1441 }
1442 /* hostapd-5G.conf has "a" as hw_mode */
1443 else if(strcmp(buf,"a")==0)
1444 {
1445 wifi_dbg_printf("\na\n");
1446 *gOnly=FALSE;
1447 *nOnly=FALSE;
1448 *acOnly=FALSE;
1449 }
1450 else
1451 wifi_dbg_printf("\nInvalid Mode %s\n", buf);
1452
1453 //for a,n mode
1454 if(radioIndex == 1)
1455 {
1456 wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf));
1457 if(strcmp(buf,"1")==0)
1458 {
1459 strncpy(output_string, "n", 1);
1460 *nOnly=FALSE;
1461 }
1462 }
1463
1464 wifi_dbg_printf("\nReturning from getRadioStandard\n");
1465 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1466 return RETURN_OK;
1467#endif
1468}
1469
1470//Set the radio operating mode, and pure mode flag.
1471INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB
1472{
1473 WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
1474 if (strcmp (channelMode,"11A") == 0)
1475 {
1476 writeBandWidth(radioIndex,"20MHz");
1477 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
1478 printf("\nChannel Mode is 802.11a (5GHz)\n");
1479 }
1480 else if (strcmp (channelMode,"11NAHT20") == 0)
1481 {
1482 writeBandWidth(radioIndex,"20MHz");
1483 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
1484 printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n");
1485 }
1486 else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
1487 {
1488 writeBandWidth(radioIndex,"40MHz");
1489 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
1490 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
1491 }
1492 else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
1493 {
1494 writeBandWidth(radioIndex,"40MHz");
1495 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
1496 printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n");
1497 }
1498 else if (strcmp (channelMode,"11ACVHT20") == 0)
1499 {
1500 writeBandWidth(radioIndex,"20MHz");
1501 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
1502 printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
1503 }
1504 else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
1505 {
1506 writeBandWidth(radioIndex,"40MHz");
1507 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
1508 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
1509 }
1510 else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
1511 {
1512 writeBandWidth(radioIndex,"40MHz");
1513 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
1514 printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
1515 }
1516 else if (strcmp (channelMode,"11ACVHT80") == 0)
1517 {
1518 wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
1519 printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
1520 }
1521 else if (strcmp (channelMode,"11ACVHT160") == 0)
1522 {
1523 wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
1524 printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
1525 }
1526 else if (strcmp (channelMode,"11B") == 0)
1527 {
1528 writeBandWidth(radioIndex,"20MHz");
1529 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
1530 printf("\nChannel Mode is 802.11b(2.4GHz)\n");
1531 }
1532 else if (strcmp (channelMode,"11G") == 0)
1533 {
1534 writeBandWidth(radioIndex,"20MHz");
1535 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
1536 printf("\nChannel Mode is 802.11g(2.4GHz)\n");
1537 }
1538 else if (strcmp (channelMode,"11NGHT20") == 0)
1539 {
1540 writeBandWidth(radioIndex,"20MHz");
1541 wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
1542 printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
1543 }
1544 else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
1545 {
1546 writeBandWidth(radioIndex,"40MHz");
1547 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
1548 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
1549 }
1550 else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
1551 {
1552 writeBandWidth(radioIndex,"40MHz");
1553 wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
1554 printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
1555 }
1556 else
1557 {
1558 return RETURN_ERR;
1559 }
1560 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1561
1562 return RETURN_OK;
1563}
1564
1565//Get the list of supported channel. eg: "1-11"
1566//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.
1567INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB
1568{
1569 if (NULL == output_string)
1570 return RETURN_ERR;
1571 //TODO:read this from iw phy phyX info |grep MHz
1572 snprintf(output_string, 64, (radioIndex == 0)?"1,2,3,4,5,6,7,8,9,10,11":"36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140");
1573#if 0
1574 char IFName[50] ={0};
1575 char buf[MAX_BUF_SIZE] = {0};
1576 char cmd[MAX_CMD_SIZE] = {0};
1577 int count = 0;
1578 if (NULL == output_string)
1579 return RETURN_ERR;
1580
1581 //snprintf(output_string, 256, (radioIndex==0)?"1,6,11":"36,40");
1582 if(radioIndex == 0)
1583 {
1584 GetInterfaceName(IFName,"/nvram/hostapd0.conf");
1585 sprintf(cmd,"%s %s %s","iwlist",IFName,"channel | grep Channel | grep -v 'Current Frequency' | grep 2'\\.' | cut -d ':' -f1 | tr -s ' ' | cut -d ' ' -f3 | sed 's/^0//g' | tr '\\n' ' ' | sed 's/ /,/g' | sed 's/,$/ /g'");
1586 }
1587 else if(radioIndex == 1)
1588 {
1589 GetInterfaceName(IFName,"/nvram/hostapd1.conf");
1590 sprintf(cmd,"%s %s %s","iwlist",IFName,"channel | grep Channel | grep -v 'Current Frequency' | grep '5\\.[1-9]' | cut -d ':' -f1 | tr -s ' ' | cut -d ' ' -f3 | tr '\\n' ' ' | sed 's/ /,/g' | sed 's/,$/ /g'");
1591 }
1592 _syscmd(cmd, buf, sizeof(buf));
1593 if(strlen(buf) > 0)
1594 strcpy(output_string,buf);
1595 else
1596 strcpy(output_string,"0");
1597#endif
1598 return RETURN_OK;
1599}
1600
1601//Get the list for used channel. eg: "1,6,9,11"
1602//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.
1603INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB
1604{
1605 if (NULL == output_string)
1606 return RETURN_ERR;
1607 snprintf(output_string, 256, (radioIndex == 0)?"1,6,11":"36,40");
1608#if 0
1609 char IFName[50] ={0};
1610 char buf[MAX_BUF_SIZE] = {0};
1611 char cmd[MAX_CMD_SIZE] = {0};
1612 if (NULL == output_string)
1613 return RETURN_ERR;
1614
1615 // snprintf(output_string, 256, (radioIndex==0)?"1,6,11":"36,40");
1616 if(radioIndex == 0)
1617 {
1618 GetInterfaceName(IFName, "/nvram/hostapd0.conf");
1619 sprintf(cmd,"%s %s %s","iwlist",IFName,"channel | grep Channel | grep -v 'Current Frequency' | grep 2'\\.' | cut -d ':' -f1 | tr -s ' ' | cut -d ' ' -f3 | sed 's/^0//g' | tr '\\n' ' ' | sed 's/ /,/g' | sed 's/,$/ /g'");
1620 }
1621 else if(radioIndex == 1)
1622 {
1623 GetInterfaceName(IFName, "/nvram/hostapd1.conf");
1624 sprintf(cmd,"%s %s %s","iwlist",IFName,"channel | grep Channel | grep -v 'Current Frequency' | grep 5'\\.[1-9]' | cut -d ':' -f1 | tr -s ' ' | cut -d ' ' -f3 |tr '\\n' ' ' | sed 's/ /,/g' | sed 's/,$/ /g'");
1625 }
1626 _syscmd(cmd,buf, sizeof(buf));
1627 if(strlen(buf) > 0)
1628 strcpy(output_string,buf);
1629 else
1630 strcpy(output_string,"0");
1631#endif
1632 return RETURN_OK;
1633}
1634
1635//Get the running channel number
1636INT wifi_getRadioChannel(INT radioIndex,ULONG *output_ulong) //RDKB
1637{
developerda1ed692022-09-13 13:59:20 +08001638#ifdef MTK_IMPL
1639 if(!wifi_getApChannel(radioIndex, output_ulong))
1640 return RETURN_OK;
1641 else
1642 return RETURN_ERR;
1643#else
developer06a01d92022-09-07 16:32:39 +08001644 char cmd[1024] = {0}, buf[5] = {0};
1645
1646 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1647 if (NULL == output_ulong)
1648 return RETURN_ERR;
1649
1650 snprintf(cmd, sizeof(cmd),
1651 "ls -1 /sys/class/net/%s%d/device/ieee80211/phy*/device/net/ | "
1652 "xargs -I {} iw dev {} info | grep channel | head -n1 | "
1653 "cut -d ' ' -f2", RADIO_PREFIX, radioIndex);
1654 _syscmd(cmd, buf, sizeof(buf));
1655
1656 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
1657 if (*output_ulong <= 0) {
1658 *output_ulong = 0;
1659 return RETURN_ERR;
1660 }
1661
1662 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1663 return RETURN_OK;
developerda1ed692022-09-13 13:59:20 +08001664#endif
developer06a01d92022-09-07 16:32:39 +08001665}
1666
1667
1668INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
1669{
1670 char cmd[1024] = {0}, buf[5] = {0};
1671 char interface_name[50] = {0};
1672
1673 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1674 if (NULL == output_ulong)
1675 return RETURN_ERR;
1676
1677 wifi_getApName(apIndex,interface_name);
1678 snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name);
1679 _syscmd(cmd,buf,sizeof(buf));
1680 *output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
1681 if (*output_ulong == 0) {
1682 return RETURN_ERR;
1683 }
1684
1685 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1686 return RETURN_OK;
1687}
1688
1689//Storing the previous channel value
1690INT wifi_storeprevchanval(INT radioIndex)
1691{
1692 char buf[256] = {0};
1693 char output[4]={'\0'};
1694 char config_file[MAX_BUF_SIZE] = {0};
1695 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
1696 wifi_hostapdRead(config_file, "channel", output, sizeof(output));
1697 if(radioIndex == 0)
1698 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable");
1699 else if(radioIndex == 1)
1700 sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable");
1701 system(buf);
1702 Radio_flag = FALSE;
1703 return RETURN_OK;
1704}
1705
1706//Set the running channel number
1707INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only
1708{
1709 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1710 struct params params={'\0'};
1711 char str_channel[4]={'\0'};
1712 struct params list;
1713 char config_file[MAX_BUF_SIZE] = {0};
1714
1715 list.name = "channel";
1716
1717 if(Radio_flag == TRUE)
1718 wifi_storeprevchanval(radioIndex); //for autochannel
1719
1720 if(radioIndex == 0)
1721 {
1722 switch(channel)
1723 {
1724 case 1: case 2: case 3: case 4: case 5: case 6: case 7: case 8: case 9: case 10: case 11: case 12:
1725 sprintf(str_channel,"%ld", channel);
1726 list.value = str_channel;
1727 break;
1728 default:
1729 return RETURN_ERR;
1730 }
1731 }
1732 else if(radioIndex == 1)
1733 {
1734 switch(channel)
1735 {
1736 case 36: case 40: case 44: case 48: case 52: case 56: case 60: case 64: case 144: case 149: case 153: case 157: case 161: case 165: case 169:
1737 sprintf(str_channel,"%ld", channel);
1738 list.value = str_channel;
1739 break;
1740 default:
1741 return RETURN_ERR;
1742 }
1743 }
1744
1745 for(int i=0; i<=MAX_APS/NUMBER_OF_RADIOS;i++)
1746 {
1747 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(2*i));
1748 wifi_hostapdWrite(config_file,&list,1);
1749 }
1750
1751 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1752 return RETURN_OK;
1753 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
1754 }
1755
1756INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
1757{
1758 struct params list;
1759 char str_idx[16];
1760 char config_file[MAX_BUF_SIZE];
1761
1762 list.name = "vht_oper_centr_freq_seg0_idx";
1763 snprintf(str_idx, sizeof(str_idx), "%d", channel);
1764 list.value = str_idx;
1765
1766 for(int i=0; i<=MAX_APS/NUMBER_OF_RADIOS; i++)
1767 {
1768 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(2*i));
1769 wifi_hostapdWrite(config_file, &list, 1);
1770 }
1771
1772 return RETURN_OK;
1773}
1774
1775//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
1776//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
1777INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
1778{
1779 //Set to wifi config only. Wait for wifi reset to apply.
1780 char buf[256] = {0};
1781 char str_channel[256] = {0};
1782 int count = 0;
1783 ULONG Value = 0;
1784 FILE *fp = NULL;
1785 if(enable == TRUE)
1786 {
1787 if(radioIndex == 0)
1788 {
1789 // _syscmd("cat /var/prevchanval2G_AutoChannelEnable", buf, sizeof(buf));
1790 fp = fopen("/var/prevchanval2G_AutoChannelEnable","r");
1791 }
1792 else if(radioIndex == 1)
1793 {
1794 // _syscmd("cat /var/prevchanval5G_AutoChannelEnable", buf, sizeof(buf));
1795 fp = fopen("/var/prevchanval5G_AutoChannelEnable","r");
1796 }
1797 if(fp == NULL) //first time boot-up
1798 {
1799 if(radioIndex == 0)
1800 Value = 6;
1801 else if(radioIndex == 1)
1802 Value = 36;
1803 }
1804 else
1805 {
1806 if(fgets(buf,sizeof(buf),fp) != NULL)
1807 {
1808 for(count = 0;buf[count]!='\n';count++)
1809 str_channel[count] = buf[count];
1810 str_channel[count] = '\0';
1811 Value = atol(str_channel);
1812 printf("%sValue is %ld \n",__FUNCTION__,Value);
1813 pclose(fp);
1814 }
1815 }
1816 Radio_flag = FALSE;//for storing previous channel value
1817 wifi_setRadioChannel(radioIndex,Value);
1818 return RETURN_OK;
1819 }
1820 return RETURN_ERR;
1821}
1822
1823INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB
1824{
1825 if (NULL == output_bool)
1826 return RETURN_ERR;
1827 *output_bool=FALSE;
1828 return RETURN_OK;
1829}
1830
1831INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB
1832{
1833 if (NULL == output_bool)
1834 return RETURN_ERR;
1835 *output_bool=FALSE;
1836 return RETURN_OK;
1837}
1838
1839INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB
1840{
1841 //Set to wifi config only. Wait for wifi reset to apply.
1842 return RETURN_OK;
1843}
1844
1845INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
1846{
1847 return RETURN_OK;
1848}
1849
1850INT wifi_factoryResetAP(int apIndex)
1851{
1852 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1853 //factory reset is not done for now on Turris
1854 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1855 return RETURN_OK;
1856}
1857
1858//To set Band Steering AP group
1859//To-do
1860INT wifi_setBandSteeringApGroup(char *ApGroup)
1861{
1862 return RETURN_OK;
1863}
1864
1865INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
1866{
1867 return RETURN_OK;
1868}
1869
1870//Check if the driver support the Dfs
1871INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
1872{
1873 if (NULL == output_bool)
1874 return RETURN_ERR;
1875 *output_bool=FALSE;
1876 return RETURN_OK;
1877}
1878
1879//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.
1880//The value of this parameter is a comma seperated list of channel number
1881INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB
1882{
1883 if (NULL == output_pool)
1884 return RETURN_ERR;
1885 if (radioIndex==1)
1886 return RETURN_OK;//TODO need to handle for 5GHz band, i think
1887 snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11");
1888
1889 return RETURN_OK;
1890}
1891
1892INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB
1893{
1894 //Set to wifi config. And apply instantly.
1895 return RETURN_OK;
1896}
1897
1898INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
1899{
1900 if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
1901 return RETURN_ERR;
1902 *output_interval_seconds=1800;
1903 *output_dwell_milliseconds=40;
1904
1905 return RETURN_OK;
1906}
1907
1908INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
1909{
1910 //Set to wifi config. And apply instantly.
1911 return RETURN_OK;
1912}
1913
1914//Get the Dfs enable status
1915INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181
1916{
1917 if (NULL == output_bool)
1918 return RETURN_ERR;
1919 *output_bool = FALSE;
1920
1921 return RETURN_OK;
1922}
1923
1924//Set the Dfs enable status
1925INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181
1926{
1927 return RETURN_ERR;
1928}
1929
1930//Check if the driver support the AutoChannelRefreshPeriod
1931INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
1932{
1933 if (NULL == output_bool)
1934 return RETURN_ERR;
1935 *output_bool=FALSE; //not support
1936
1937 return RETURN_OK;
1938}
1939
1940//Get the ACS refresh period in seconds
1941INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
1942{
1943 if (NULL == output_ulong)
1944 return RETURN_ERR;
1945 *output_ulong=300;
1946
1947 return RETURN_OK;
1948}
1949
1950//Set the ACS refresh period in seconds
1951INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
1952{
1953 return RETURN_ERR;
1954}
1955
1956//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
1957//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.
1958INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
1959{
1960 if (NULL == output_string)
1961 return RETURN_ERR;
1962
1963 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1964 char cmd[1024] = {0}, buf[64] = {0};
1965 int ret = 0, len=0;
1966
1967 snprintf(cmd, sizeof(cmd),
1968 "ls -1 /sys/class/net/%s%d/device/ieee80211/phy*/device/net/ | "
1969 "xargs -I {} iw dev {} info | grep width | head -n1 | "
1970 "cut -d ' ' -f6", RADIO_PREFIX, radioIndex);
1971
1972 ret = _syscmd(cmd, buf, sizeof(buf));
1973 len = strlen(buf);
1974 if((ret != 0) || (len == 0))
1975 {
1976 WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__);
1977 return RETURN_ERR;
1978 }
1979
1980 buf[len-1] = '\0';
1981 snprintf(output_string, 64, "%sMHz", buf);
1982 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
1983
1984#if 0
1985 //TODO: revisit below implementation
1986 char output_buf[8]={0};
1987 char bw_value[10];
1988 char config_file[MAX_BUF_SIZE] = {0};
1989
1990 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
1991 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
1992 wifi_hostapdRead(config_file, "vht_oper_chwidth", output_buf, sizeof(output_buf));
1993 readBandWidth(radioIndex,bw_value);
1994
1995 if(strstr (output_buf,"0") != NULL )
1996 {
1997 strcpy(output_string,bw_value);
1998 }
1999 else if (strstr (output_buf,"1") != NULL)
2000 {
2001 strcpy(output_string,"80MHz");
2002 }
2003 else if (strstr (output_buf,"2") != NULL)
2004 {
2005 strcpy(output_string,"160MHz");
2006 }
2007 else if (strstr (output_buf,"3") != NULL)
2008 {
2009 strcpy(output_string,"80+80");
2010 }
2011 else
2012 {
2013 strcpy(output_string,"Auto");
2014 }
2015 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2016#endif
2017
2018 return RETURN_OK;
2019}
2020
2021//Set the Operating Channel Bandwidth.
2022INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181 //AP only
2023{
2024 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2025 char config_file[MAX_BUF_SIZE];
2026 struct params params[4];
2027 struct params *pptr = params;
2028
2029 if(NULL == output_string)
2030 return RETURN_ERR;
2031
2032 pptr->name = "vht_oper_chwidth";
2033 if(strcmp(output_string,"20MHz") == 0) // This piece of code only support for wifi hal api's validation
2034 pptr->value="0";
2035 else if(strcmp(output_string,"40MHz") == 0)
2036 pptr->value="0";
2037 else if(strcmp(output_string,"80MHz") == 0)
2038 pptr->value="1";
2039 else if(strcmp(output_string,"160MHz") == 0)
2040 pptr->value="2";
2041 else if(strcmp(output_string,"80+80") == 0)
2042 pptr->value="3";
2043 else
2044 {
2045 printf("Invalid Bandwidth \n");
2046 return RETURN_ERR;
2047 }
2048
2049 pptr++; // added vht_oper_chwidth
2050
2051 if(radioIndex == 1)
2052 {
2053 pptr->name= "ieee80211n";
2054 if(strcmp(output_string,"20MHz") == 0)
2055 pptr->value="0";
2056 else if(strcmp(output_string,"40MHz") == 0)
2057 pptr->value="1";
2058 else if(strcmp(output_string,"80MHz") == 0)
2059 pptr->value="1";
2060 else
2061 pptr->value="0";
2062
2063 pptr++; // added ieee80211n
2064
2065 pptr->name="ieee80211ac";
2066 if(strcmp(output_string,"80MHz") == 0)
2067 pptr->value="1";
2068 else
2069 pptr->value="0";
2070 pptr++;
2071 }
2072
2073 for(int i=0; i<=MAX_APS/NUMBER_OF_RADIOS; i++)
2074 {
2075 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(2*i));
2076 wifi_hostapdWrite(config_file, params, (pptr - params));
2077 }
2078
2079 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2080 return RETURN_OK;
2081}
2082
2083//Getting current radio extension channel
2084INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
2085{
2086 CHAR buf[150] = {0};
2087 CHAR cmd[150] = {0};
2088 sprintf(cmd,"%s%s%s","cat ",file," | grep -w ht_capab=");
2089 _syscmd(cmd, buf, sizeof(buf));
2090 if(NULL != strstr(buf,"HT40+"))
2091 strcpy(Value,"AboveControlChannel");
2092 else if(NULL != strstr(buf,"HT40-"))
2093 strcpy(Value,"BelowControlChannel");
2094 return RETURN_OK;
2095}
2096
2097//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
2098//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.
2099INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
2100{
2101 if (NULL == output_string)
2102 return RETURN_ERR;
2103
2104 snprintf(output_string, 64, (radioIndex==0)?"":"BelowControlChannel");
2105#if 0
2106 CHAR Value[100] = {0};
2107 if (NULL == output_string)
2108 return RETURN_ERR;
2109 if(radioIndex == 0)
2110 strcpy(Value,"Auto"); //so far rpi(2G) supports upto 150Mbps (i,e 20MHZ)
2111 else if(radioIndex == 1)//so far rpi(5G) supports upto 300mbps (i,e 20MHz/40MHz)
2112 {
2113 wifi_getRadioOperatingChannelBandwidth(radioIndex,Value);
2114 if(strcmp(Value,"40MHz") == 0)
2115 wifi_halgetRadioExtChannel("/nvram/hostapd1.conf",Value);
2116 else
2117 strcpy(Value,"Auto");
2118 }
2119 strcpy(output_string,Value);
2120#endif
2121
2122 return RETURN_OK;
2123}
2124
2125//Set the extension channel.
2126INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only
2127{
2128 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2129 struct params params={'\0'};
2130 char config_file[MAX_BUF_SIZE] = {0};
2131 char ext_channel[127]={'\0'};
2132
2133 params.name = "ht_capab";
2134
2135 if(radioIndex == 0)
2136 {
2137 if(NULL!= strstr(string,"Above"))
2138 strcpy(ext_channel, HOSTAPD_HT_CAPAB_40 "[HT40+]");
2139 else if(NULL!= strstr(string,"Below"))
2140 strcpy(ext_channel, HOSTAPD_HT_CAPAB_40 "[HT40-]");
2141 else
2142 strcpy(ext_channel, HOSTAPD_HT_CAPAB_20);
2143 }
2144 else if(radioIndex == 1)
2145 {
2146 if(NULL!= strstr(string,"Above"))
2147 strcpy(ext_channel, HOSTAPD_HT_CAPAB_40 "[HT40+]");
2148 else if(NULL!= strstr(string,"Below"))
2149 strcpy(ext_channel, HOSTAPD_HT_CAPAB_40 "[HT40-]");
2150 else
2151 strcpy(ext_channel, HOSTAPD_HT_CAPAB_20);
2152 }
2153
2154 params.value = ext_channel;
2155 for(int i=0; i<=MAX_APS/NUMBER_OF_RADIOS; i++)
2156 {
2157 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(2*i));
2158 wifi_hostapdWrite(config_file, &params, 1);
2159 }
2160
2161 //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply.
2162 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2163 return RETURN_OK;
2164}
2165
2166//Get the guard interval value. eg "400nsec" or "800nsec"
2167//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.
2168INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181
2169{
2170 //save config and apply instantly
2171 if (NULL == output_string)
2172 return RETURN_ERR;
2173 snprintf(output_string, 64, (radioIndex == 0) ? "400nsec" : "400nsec");
2174
2175 return RETURN_OK;
2176}
2177
2178//Set the guard interval value.
2179INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181
2180{
2181 //Apply setting instantly
2182 return RETURN_ERR;
2183}
2184
2185//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
2186INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
2187{
2188 if (NULL == output_int)
2189 return RETURN_ERR;
2190 *output_int=(radioIndex==0)?1:3;
2191
2192 return RETURN_OK;
2193}
2194
2195//Set the Modulation Coding Scheme index
2196INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
2197{
2198 return RETURN_ERR;
2199}
2200
2201//Get supported Transmit Power list, eg : "0,25,50,75,100"
2202//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.
2203INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
2204{
2205 if (NULL == output_list)
2206 return RETURN_ERR;
2207 snprintf(output_list, 64,"0,25,50,75,100");
2208 return RETURN_OK;
2209}
2210
2211//Get current Transmit Power, eg "75", "100"
2212//The transmite power level is in units of full power for this radio.
2213INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB
2214{
2215 char cmd[128]={0};
2216 char buf[256]={0};
2217 INT apIndex;
2218 //save config and apply instantly
2219
2220 if (NULL == output_ulong)
2221 return RETURN_ERR;
2222
2223 //zqiu:TODO:save config
2224 apIndex = (radioIndex==0) ?0 :1;
2225
2226 snprintf(cmd, sizeof(cmd), "iwlist %s%d txpower | grep Tx-Power | cut -d'=' -f2", AP_PREFIX, apIndex);
2227 _syscmd(cmd, buf, sizeof(buf));
2228 *output_ulong = atol(buf);
2229
2230 return RETURN_OK;
2231}
2232
2233//Set Transmit Power
2234//The transmite power level is in units of full power for this radio.
2235INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB
2236{
2237 char cmd[128]={0};
2238 char buf[256]={0};
2239 INT apIndex;
2240
2241 snprintf(cmd, sizeof(cmd), "iwconfig %s%d txpower %lu", AP_PREFIX, radioIndex, TransmitPower);
2242 _syscmd(cmd, buf, sizeof(buf));
2243
2244 return RETURN_OK;
2245}
2246
2247//get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band
2248INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181
2249{
2250 if (NULL == Supported)
2251 return RETURN_ERR;
2252 *Supported = FALSE;
2253
2254 return RETURN_OK;
2255}
2256
2257//Get 80211h feature enable
2258INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
2259{
2260 if (NULL == enable)
2261 return RETURN_ERR;
2262 *enable = FALSE;
2263
2264 return RETURN_OK;
2265}
2266
2267//Set 80211h feature enable
2268INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181
2269{
2270 return RETURN_ERR;
2271}
2272
2273//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.
2274INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3
2275{
2276 if (NULL == output)
2277 return RETURN_ERR;
2278 *output=100;
2279
2280 return RETURN_OK;
2281}
2282
2283//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.
2284INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3
2285{
2286 if (NULL == output)
2287 return RETURN_ERR;
2288 *output = -99;
2289
2290 return RETURN_OK;
2291}
2292
2293INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3
2294{
2295 return RETURN_ERR;
2296}
2297
2298
2299//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
2300INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
2301{
2302 if (NULL == output)
2303 return RETURN_ERR;
2304 *output = 100;
2305
2306 return RETURN_OK;
2307}
2308
2309INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
2310{
2311 return RETURN_ERR;
2312}
2313
2314//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.
2315INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
2316{
2317 if (NULL == output)
2318 return RETURN_ERR;
2319 snprintf(output, 64, (radioIndex == 0) ? "1,2" : "1.5,150");
2320#if 0
2321 //TODO: need to revisit below implementation
2322 char *temp;
2323 char temp_output[128];
2324 char temp_TransmitRates[512];
2325 char config_file[MAX_BUF_SIZE] = {0};
2326
2327 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2328 if (NULL == output)
2329 return RETURN_ERR;
2330 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
2331 wifi_hostapdRead(config_file,"basic_rates",output,64);
2332
2333 strcpy(temp_TransmitRates,output);
2334 strcpy(temp_output,"");
2335 temp = strtok(temp_TransmitRates," ");
2336 while(temp!=NULL)
2337 {
2338 temp[strlen(temp)-1]=0;
2339 if((temp[0]=='5') && (temp[1]=='\0'))
2340 {
2341 temp="5.5";
2342 }
2343 strcat(temp_output,temp);
2344 temp = strtok(NULL," ");
2345 if(temp!=NULL)
2346 {
2347 strcat(temp_output,",");
2348 }
2349 }
2350 strcpy(output,temp_output);
2351 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2352#endif
2353 return RETURN_OK;
2354}
2355
2356INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
2357{
2358 char *temp;
2359 char temp1[128];
2360 char temp_output[128];
2361 char temp_TransmitRates[128];
2362 char set[128];
2363 char sub_set[128];
2364 int set_count=0,subset_count=0;
2365 int set_index=0,subset_index=0;
2366 char *token;
2367 int flag=0, i=0;
2368 struct params params={'\0'};
2369 char config_file[MAX_BUF_SIZE] = {0};
2370
2371 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2372 if(NULL == TransmitRates)
2373 return RETURN_ERR;
2374 strcpy(sub_set,TransmitRates);
2375
2376 //Allow only supported Data transmit rate to be set
2377 wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
2378 token = strtok(sub_set,",");
2379 while( token != NULL ) /* split the basic rate to be set, by comma */
2380 {
2381 sub_set[subset_count]=atoi(token);
2382 subset_count++;
2383 token=strtok(NULL,",");
2384 }
2385 token=strtok(set,",");
2386 while(token!=NULL) /* split the supported rate by comma */
2387 {
2388 set[set_count]=atoi(token);
2389 set_count++;
2390 token=strtok(NULL,",");
2391 }
2392 for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
2393 {
2394 for(set_index=0;set_index < set_count;set_index++)
2395 {
2396 flag=0;
2397 if(sub_set[subset_index]==set[set_index])
2398 break;
2399 else
2400 flag=1; /* No match found */
2401 }
2402 if(flag==1)
2403 return RETURN_ERR; //If value not found return Error
2404 }
2405 strcpy(temp_TransmitRates,TransmitRates);
2406
2407 for(i=0;i<strlen(temp_TransmitRates);i++)
2408 {
2409 //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
2410 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) | (temp_TransmitRates[i]==' ') | (temp_TransmitRates[i]=='.') | (temp_TransmitRates[i]==','))
2411 {
2412 continue;
2413 }
2414 else
2415 {
2416 return RETURN_ERR;
2417 }
2418 }
2419 strcpy(temp_output,"");
2420 temp = strtok(temp_TransmitRates,",");
2421 while(temp!=NULL)
2422 {
2423 strcpy(temp1,temp);
2424 if(radioIndex==1)
2425 {
2426 if((strcmp(temp,"1")==0) | (strcmp(temp,"2")==0) | (strcmp(temp,"5.5")==0))
2427 {
2428 return RETURN_ERR;
2429 }
2430 }
2431
2432 if(strcmp(temp,"5.5")==0)
2433 {
2434 strcpy(temp1,"55");
2435 }
2436 else
2437 {
2438 strcat(temp1,"0");
2439 }
2440 strcat(temp_output,temp1);
2441 temp = strtok(NULL,",");
2442 if(temp!=NULL)
2443 {
2444 strcat(temp_output," ");
2445 }
2446 }
2447 strcpy(TransmitRates,temp_output);
2448
2449 params.name= "basic_rates";
2450 params.value =TransmitRates;
2451
2452 wifi_dbg_printf("\n%s:",__func__);
2453 wifi_dbg_printf("\nparams.value=%s\n",params.value);
2454 wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates);
2455 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
2456 wifi_hostapdWrite(config_file,&params,1);
2457 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2458 return RETURN_OK;
2459}
2460
2461//passing the hostapd configuration file and get the virtual interface of xfinity(2g)
2462INT GetInterfaceName_virtualInterfaceName_2G(char interface_name[50])
2463{
2464 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2465 FILE *fp = NULL;
2466 char path[256] = {0}, output_string[256] = {0};
2467 int count = 0;
2468 char *interface = NULL;
2469
2470 fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r");
2471 if (fp == NULL)
2472 {
2473 printf("Failed to run command in Function %s\n", __FUNCTION__);
2474 return RETURN_ERR;
2475 }
2476 if (fgets(path, sizeof(path) - 1, fp) != NULL)
2477 {
2478 interface = strchr(path, '=');
2479
2480 if (interface != NULL)
2481 {
2482 strcpy(output_string, interface + 1);
2483 for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++)
2484 interface_name[count] = output_string[count];
2485
2486 interface_name[count] = '\0';
2487 }
2488 }
2489 pclose(fp);
2490 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2491 return RETURN_OK;
2492}
2493
2494INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
2495{
2496 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2497 output_struct->radio_BytesSent = 0;
2498 output_struct->radio_BytesReceived = 0;
2499 output_struct->radio_PacketsSent = 0;
2500 output_struct->radio_PacketsReceived = 0;
2501 output_struct->radio_ErrorsSent = 0;
2502 output_struct->radio_ErrorsReceived = 0;
2503 output_struct->radio_DiscardPacketsSent = 0;
2504 output_struct->radio_DiscardPacketsReceived = 0;
2505 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2506 return RETURN_OK;
2507}
2508
2509
2510INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
2511{
2512 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2513 CHAR buf[MAX_CMD_SIZE] = {0};
2514 CHAR Value[MAX_BUF_SIZE] = {0};
2515 FILE *fp = NULL;
2516
2517 if (ifname == NULL || strlen(ifname) <= 1)
2518 return RETURN_OK;
2519
2520 snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
2521 system(buf);
2522
2523 fp = fopen("/tmp/Radio_Stats.txt", "r");
2524 if(fp == NULL)
2525 {
2526 printf("/tmp/Radio_Stats.txt not exists \n");
2527 return RETURN_ERR;
2528 }
2529 fclose(fp);
2530
2531 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
2532 File_Reading(buf, Value);
2533 pStats->radio_PacketsReceived = strtoul(Value, NULL, 10);
2534
2535 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
2536 File_Reading(buf, Value);
2537 pStats->radio_PacketsSent = strtoul(Value, NULL, 10);
2538
2539 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
2540 File_Reading(buf, Value);
2541 pStats->radio_BytesReceived = strtoul(Value, NULL, 10);
2542
2543 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
2544 File_Reading(buf, Value);
2545 pStats->radio_BytesSent = strtoul(Value, NULL, 10);
2546
2547 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
2548 File_Reading(buf, Value);
2549 pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10);
2550
2551 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
2552 File_Reading(buf, Value);
2553 pStats->radio_ErrorsSent = strtoul(Value, NULL, 10);
2554
2555 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
2556 File_Reading(buf, Value);
2557 pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10);
2558
2559 sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
2560 File_Reading(buf, Value);
2561 pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10);
2562
2563 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2564 return RETURN_OK;
2565}
2566
2567INT GetIfacestatus(CHAR *interface_name, CHAR *status)
2568{
2569 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2570 CHAR buf[MAX_CMD_SIZE] = {0};
2571 FILE *fp = NULL;
2572 INT count = 0;
2573
2574 if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL)
2575 {
2576 sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l");
2577 File_Reading(buf, status);
2578 }
2579 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2580 return RETURN_OK;
2581}
2582
2583//Get detail radio traffic static info
2584INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
2585{
2586
2587#if 0
2588 //ifconfig radio_x
2589 output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters.
2590 output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters.
2591 output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface.
2592 output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface.
2593
2594 output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors.
2595 output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
2596 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.
2597 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.
2598
2599 output_struct->radio_PLCPErrorCount=0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
2600 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].
2601 output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error.
2602 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.
2603 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
2604 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
2605 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
2606 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
2607 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
2608
2609 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
2610 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
2611 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
2612 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.
2613
2614 return RETURN_OK;
2615#endif
2616
2617 CHAR private_interface_name[MAX_BUF_SIZE] = {0}, public_interface_name[MAX_BUF_SIZE] = {0};
2618 CHAR private_interface_status[MAX_BUF_SIZE] = {0}, public_interface_status[MAX_BUF_SIZE] = {0};
2619 char buf[MAX_BUF_SIZE] = {0};
2620 char cmd[MAX_CMD_SIZE] = {0};
2621 wifi_radioTrafficStats2_t private_radioTrafficStats = {0}, public_radioTrafficStats = {0};
2622
2623 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
2624 if (NULL == output_struct)
2625 return RETURN_ERR;
2626
2627 if (radioIndex == 0) //2.4GHz ?
2628 {
2629
2630 GetInterfaceName(private_interface_name, "/nvram/hostapd0.conf");
2631
2632 GetIfacestatus(private_interface_name, private_interface_status);
2633
2634 sprintf(cmd, "%s", "cat /nvram/hostapd0.conf | grep bss=");
2635 File_Reading(cmd, buf);
2636
2637 if (buf[0] == '#')
2638 {
2639 GetInterfaceName(public_interface_name, "/nvram/hostapd4.conf");
2640 }
2641 else
2642 {
2643 GetInterfaceName_virtualInterfaceName_2G(public_interface_name);
2644 }
2645
2646 GetIfacestatus(public_interface_name, public_interface_status);
2647
2648 if (strcmp(private_interface_status, "1") == 0)
2649 wifi_halGetIfStats(private_interface_name, &private_radioTrafficStats);
2650 else
2651 wifi_halGetIfStatsNull(&private_radioTrafficStats);
2652
2653 if (strcmp(public_interface_status, "1") == 0)
2654 wifi_halGetIfStats(public_interface_name, &public_radioTrafficStats);
2655 else
2656 wifi_halGetIfStatsNull(&public_radioTrafficStats);
2657 }
2658 else if (radioIndex == 1) //5GHz ?
2659 {
2660 GetInterfaceName(private_interface_name, "/nvram/hostapd1.conf");
2661 GetIfacestatus(private_interface_name, private_interface_status);
2662
2663 GetInterfaceName(public_interface_name, "/nvram/hostapd5.conf");
2664 GetIfacestatus(public_interface_name, public_interface_status);
2665
2666 if (strcmp(private_interface_status, "1") == 0)
2667 wifi_halGetIfStats(private_interface_name, &private_radioTrafficStats);
2668 else
2669 wifi_halGetIfStatsNull(&private_radioTrafficStats);
2670
2671 if (strcmp(public_interface_status, "1") == 0)
2672 wifi_halGetIfStats(public_interface_name, &public_radioTrafficStats);
2673 else
2674 wifi_halGetIfStatsNull(&public_radioTrafficStats);
2675 }
2676
2677 output_struct->radio_BytesSent = private_radioTrafficStats.radio_BytesSent + public_radioTrafficStats.radio_BytesSent;
2678 output_struct->radio_BytesReceived = private_radioTrafficStats.radio_BytesReceived + public_radioTrafficStats.radio_BytesReceived;
2679 output_struct->radio_PacketsSent = private_radioTrafficStats.radio_PacketsSent + public_radioTrafficStats.radio_PacketsSent;
2680 output_struct->radio_PacketsReceived = private_radioTrafficStats.radio_PacketsReceived + public_radioTrafficStats.radio_PacketsReceived;
2681 output_struct->radio_ErrorsSent = private_radioTrafficStats.radio_ErrorsSent + public_radioTrafficStats.radio_ErrorsSent;
2682 output_struct->radio_ErrorsReceived = private_radioTrafficStats.radio_ErrorsReceived + public_radioTrafficStats.radio_ErrorsReceived;
2683 output_struct->radio_DiscardPacketsSent = private_radioTrafficStats.radio_DiscardPacketsSent + public_radioTrafficStats.radio_DiscardPacketsSent;
2684 output_struct->radio_DiscardPacketsReceived = private_radioTrafficStats.radio_DiscardPacketsReceived + public_radioTrafficStats.radio_DiscardPacketsReceived;
2685
2686 output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
2687 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].
2688 output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error.
2689 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.
2690 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
2691 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
2692 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
2693 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
2694 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
2695
2696 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
2697 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
2698 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
2699 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.
2700
2701 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
2702
2703 return RETURN_OK;
2704}
2705
2706//Set radio traffic static Measureing rules
2707INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
2708{
2709 //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
2710 // Else, save the MeasuringRate and MeasuringInterval for future usage
2711
2712 return RETURN_OK;
2713}
2714
2715//To start or stop RadioTrafficStats
2716INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
2717{
2718 //zqiu: If the RadioTrafficStats process running
2719 // if(enable)
2720 // return RETURN_OK.
2721 // else
2722 // Stop RadioTrafficStats process
2723 // Else
2724 // if(enable)
2725 // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds
2726 // else
2727 // return RETURN_OK.
2728
2729 return RETURN_OK;
2730}
2731
2732//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
2733INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
2734{
2735 //zqiu: Please ignor signalIndex.
2736 if (NULL == SignalLevel)
2737 return RETURN_ERR;
2738 *SignalLevel=(radioIndex==0)?-19:-19;
2739
2740 return RETURN_OK;
2741}
2742
2743//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
2744INT wifi_applyRadioSettings(INT radioIndex)
2745{
2746 return RETURN_OK;
2747}
2748
2749//Get the radio index assocated with this SSID entry
2750INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
2751{
2752 if (NULL == radioIndex)
2753 return RETURN_ERR;
2754 *radioIndex=ssidIndex%2;
2755
2756 return RETURN_OK;
2757}
2758
2759//Device.WiFi.SSID.{i}.Enable
2760//Get SSID enable configuration parameters (not the SSID enable status)
2761INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
2762{
2763 if (NULL == output_bool)
2764 return RETURN_ERR;
2765
2766 //For this target, mapping SSID Index 13 & 14 to 2 & 3 respectively.
2767 if(ssidIndex==13 || ssidIndex==14) ssidIndex -= 11;
2768 return wifi_getApEnable(ssidIndex, output_bool);
2769}
2770
2771//Device.WiFi.SSID.{i}.Enable
2772//Set SSID enable configuration parameters
2773INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
2774{
2775 //For this target, mapping SSID Index 13 & 14 to 2 & 3 respectively.
2776 if(ssidIndex==13 || ssidIndex==14) ssidIndex -= 11;
2777 return wifi_setApEnable(ssidIndex, enable);
2778}
2779
2780//Device.WiFi.SSID.{i}.Status
2781//Get the SSID enable status
2782INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
2783{
2784 char cmd[MAX_CMD_SIZE]={0};
2785 char buf[MAX_BUF_SIZE]={0};
2786 BOOL output_bool;
2787
2788 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2789 if (NULL == output_string)
2790 return RETURN_ERR;
2791 //For this target, mapping SSID Index 13 & 14 to 2 & 3 respectively.
2792 if(ssidIndex==13 || ssidIndex==14) ssidIndex -= 11;
2793
2794 wifi_getApEnable(ssidIndex,&output_bool);
2795 snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
2796
2797 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2798 return RETURN_OK;
2799}
2800
2801// Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller.
2802INT wifi_getSSIDName(INT apIndex, CHAR *output)
2803{
2804 char config_file[MAX_BUF_SIZE] = {0};
2805
2806 if (NULL == output)
2807 return RETURN_ERR;
2808
2809 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
2810 wifi_hostapdRead(config_file,"ssid",output,32);
2811
2812 wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output);
2813 return RETURN_OK;
2814}
2815
2816// Set a max 32 byte string and sets an internal variable to the SSID name
2817INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
2818{
2819 char str[MAX_BUF_SIZE]={'\0'};
2820 char cmd[MAX_CMD_SIZE]={'\0'};
2821 struct params params;
2822 char config_file[MAX_BUF_SIZE] = {0};
2823
2824 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2825 if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 )
2826 return RETURN_ERR;
2827
2828 params.name = "ssid";
2829 params.value = ssid_string;
2830 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
2831 wifi_hostapdWrite(config_file, &params, 1);
2832 wifi_hostapdProcessUpdate(apIndex, &params, 1);
2833 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2834
2835 return RETURN_OK;
2836}
2837
2838//Get the BSSID
2839INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB
2840{
2841 char cmd[MAX_CMD_SIZE]="";
2842
2843 if (NULL == output_string)
2844 return RETURN_ERR;
2845
2846 if(ssidIndex >= 0 && ssidIndex < MAX_APS)
2847 {
2848 snprintf(cmd, sizeof(cmd), "iw dev %s%d info |grep addr | awk '{printf $2}'", AP_PREFIX, ssidIndex);
2849 _syscmd(cmd, output_string, 64);
2850 return RETURN_OK;
2851 }
2852 strncpy(output_string, "\0", 1);
2853
2854 return RETURN_ERR;
2855}
2856
2857//Get the MAC address associated with this Wifi SSID
2858INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
2859{
2860 wifi_getBaseBSSID(ssidIndex,output_string);
2861 return RETURN_OK;
2862}
2863
2864//Get the basic SSID traffic static info
2865//Apply SSID and AP (in the case of Acess Point devices) to the hardware
2866//Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0)
2867INT wifi_applySSIDSettings(INT ssidIndex)
2868{
2869 BOOL status = false;
2870 char cmd[MAX_CMD_SIZE] = {0};
2871 char buf[MAX_CMD_SIZE] = {0};
2872 int apIndex, ret;
2873 int radioIndex = ssidIndex % NUMBER_OF_RADIOS;
2874
2875 wifi_getApEnable(ssidIndex,&status);
2876 // Do not apply when ssid index is disabled
2877 if (status == false)
2878 return RETURN_OK;
2879
2880 /* Doing full remove and add for ssid Index
2881 * Not all hostapd options are supported with reload
2882 * for example macaddr_acl
2883 */
2884 if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
2885 return RETURN_ERR;
2886
2887 ret = wifi_setApEnable(ssidIndex,true);
2888
2889 /* Workaround for hostapd issue with multiple bss definitions
2890 * when first created interface will be removed
2891 * then all vaps other vaps on same phy are removed
2892 * after calling setApEnable to false readd all enabled vaps */
2893 for(int i=0; i < MAX_APS/NUMBER_OF_RADIOS; i++) {
2894 apIndex = 2*i+radioIndex;
2895 snprintf(cmd, sizeof(cmd), "cat %s | grep %s%d | cut -d'=' -f2", VAP_STATUS_FILE, AP_PREFIX, apIndex);
2896 _syscmd(cmd, buf, sizeof(buf));
2897 if(*buf == '1')
2898 wifi_setApEnable(apIndex, true);
2899 }
2900
2901 return ret;
2902}
2903
2904//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
2905//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
2906INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
2907{
2908 INT status = RETURN_ERR;
2909 UINT index;
2910 wifi_neighbor_ap2_t *pt=NULL;
2911 char cmd[128]={0};
2912 char buf[8192]={0};
2913
2914 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2915 sprintf(cmd, "iwlist %s%d scan",AP_PREFIX,(radioIndex==0)?0:1); //suppose ap0 mapping to radio0
2916 _syscmd(cmd, buf, sizeof(buf));
2917
2918
2919 *output_array_size=2;
2920 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
2921 *neighbor_ap_array=(wifi_neighbor_ap2_t *)calloc(sizeof(wifi_neighbor_ap2_t), *output_array_size);
2922 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
2923 strcpy(pt->ap_SSID,"");
2924 strcpy(pt->ap_BSSID,"");
2925 strcpy(pt->ap_Mode,"");
2926 pt->ap_Channel=1;
2927 pt->ap_SignalStrength=0;
2928 strcpy(pt->ap_SecurityModeEnabled,"");
2929 strcpy(pt->ap_EncryptionMode,"");
2930 strcpy(pt->ap_OperatingFrequencyBand,"");
2931 strcpy(pt->ap_SupportedStandards,"");
2932 strcpy(pt->ap_OperatingStandards,"");
2933 strcpy(pt->ap_OperatingChannelBandwidth,"");
2934 pt->ap_BeaconPeriod=1;
2935 pt->ap_Noise=0;
2936 strcpy(pt->ap_BasicDataTransferRates,"");
2937 strcpy(pt->ap_SupportedDataTransferRates,"");
2938 pt->ap_DTIMPeriod=1;
2939 pt->ap_ChannelUtilization=0;
2940 }
2941
2942 status = RETURN_OK;
2943 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2944 return status;
2945}
2946
2947//>> Deprecated: used for old RDKB code.
2948INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
2949{
2950 INT status = RETURN_ERR;
2951
2952 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2953 output_struct->wifi_PLCPErrorCount = 0;
2954 output_struct->wifi_FCSErrorCount = 0;
2955 output_struct->wifi_InvalidMACCount = 0;
2956 output_struct->wifi_PacketsOtherReceived = 0;
2957 output_struct->wifi_Noise = 0;
2958 status = RETURN_OK;
2959 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
2960 return status;
2961}
2962
2963INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
2964{
2965 char cmd[128];
2966 char buf[1280];
2967 char *pos = NULL;
2968
2969 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
2970 if (NULL == output_struct)
2971 return RETURN_ERR;
2972
2973 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
2974
2975 snprintf(cmd, sizeof(cmd), "ifconfig %s%d", AP_PREFIX, apIndex);
2976 _syscmd(cmd, buf, sizeof(buf));
2977
2978 pos = buf;
2979 if ((pos = strstr(pos, "RX packets:")) == NULL)
2980 return RETURN_ERR;
2981 output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:"));
2982
2983 if ((pos = strstr(pos, "TX packets:")) == NULL)
2984 return RETURN_ERR;
2985 output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:"));
2986
2987 if ((pos = strstr(pos, "RX bytes:")) == NULL)
2988 return RETURN_ERR;
2989 output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:"));
2990
2991 if ((pos = strstr(pos, "TX bytes:")) == NULL)
2992 return RETURN_ERR;
2993 output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:"));
2994
2995 sprintf(cmd, "wlanconfig %s%d list sta | grep -v HTCAP | wc -l", AP_PREFIX, apIndex);
2996 _syscmd(cmd, buf, sizeof(buf));
2997 sscanf(buf, "%lu", &output_struct->wifi_Associations);
2998
2999#if 0
3000 //TODO: need to revisit below implementation
3001 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3002 char interface_name[MAX_BUF_SIZE] = {0};
3003 char interface_status[MAX_BUF_SIZE] = {0};
3004 char Value[MAX_BUF_SIZE] = {0};
3005 char buf[MAX_CMD_SIZE] = {0};
3006 char cmd[MAX_CMD_SIZE] = {0};
3007 FILE *fp = NULL;
3008
3009 if (NULL == output_struct) {
3010 return RETURN_ERR;
3011 }
3012
3013 memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
3014
3015 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
3016 {
3017 if(apIndex == 0) //private_wifi for 2.4G
3018 {
3019 GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
3020 }
3021 else if(apIndex == 1) //private_wifi for 5G
3022 {
3023 GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
3024 }
3025 else if(apIndex == 4) //public_wifi for 2.4G
3026 {
3027 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
3028 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
3029 {
3030 return RETURN_ERR;
3031 }
3032 if(buf[0] == '#')//tp-link
3033 GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
3034 else//tenda
3035 GetInterfaceName_virtualInterfaceName_2G(interface_name);
3036 }
3037 else if(apIndex == 5) //public_wifi for 5G
3038 {
3039 GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
3040 }
3041
3042 GetIfacestatus(interface_name, interface_status);
3043
3044 if(0 != strcmp(interface_status, "1"))
3045 return RETURN_ERR;
3046
3047 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
3048 system(cmd);
3049
3050 fp = fopen("/tmp/SSID_Stats.txt", "r");
3051 if(fp == NULL)
3052 {
3053 printf("/tmp/SSID_Stats.txt not exists \n");
3054 return RETURN_ERR;
3055 }
3056 fclose(fp);
3057
3058 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
3059 File_Reading(buf, Value);
3060 output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10);
3061
3062 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
3063 File_Reading(buf, Value);
3064 output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10);
3065
3066 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
3067 File_Reading(buf, Value);
3068 output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10);
3069
3070 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
3071 File_Reading(buf, Value);
3072 output_struct->wifi_BytesSent = strtoul(Value, NULL, 10);
3073
3074 /* There is no specific parameter from caller to associate the value wifi_Associations */
3075 //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);
3076 //_syscmd(cmd, buf, sizeof(buf));
3077 //sscanf(buf,"%lu", &output_struct->wifi_Associations);
3078 }
3079#endif
3080 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3081 return RETURN_OK;
3082}
3083
3084INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
3085{
3086 char interface_name[MAX_BUF_SIZE] = {0};
3087 char interface_status[MAX_BUF_SIZE] = {0};
3088 char Value[MAX_BUF_SIZE] = {0};
3089 char buf[MAX_CMD_SIZE] = {0};
3090 char cmd[MAX_CMD_SIZE] = {0};
3091 FILE *fp = NULL;
3092
3093 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3094 if (NULL == output_struct)
3095 return RETURN_ERR;
3096
3097 memset(output_struct, 0, sizeof(wifi_trafficStats_t));
3098
3099 if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5))
3100 {
3101 if(apIndex == 0) //private_wifi for 2.4G
3102 {
3103 GetInterfaceName(interface_name,"/nvram/hostapd0.conf");
3104 }
3105 else if(apIndex == 1) //private_wifi for 5G
3106 {
3107 GetInterfaceName(interface_name,"/nvram/hostapd1.conf");
3108 }
3109 else if(apIndex == 4) //public_wifi for 2.4G
3110 {
3111 sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss=");
3112 if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR)
3113 {
3114 return RETURN_ERR;
3115 }
3116 if(buf[0] == '#')
3117 GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
3118 else
3119 GetInterfaceName_virtualInterfaceName_2G(interface_name);
3120 }
3121 else if(apIndex == 5) //public_wifi for 5G
3122 {
3123 GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
3124 }
3125
3126 GetIfacestatus(interface_name, interface_status);
3127
3128 if(0 != strcmp(interface_status, "1"))
3129 return RETURN_ERR;
3130
3131 snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name);
3132 system(cmd);
3133
3134 fp = fopen("/tmp/SSID_Stats.txt", "r");
3135 if(fp == NULL)
3136 {
3137 printf("/tmp/SSID_Stats.txt not exists \n");
3138 return RETURN_ERR;
3139 }
3140 fclose(fp);
3141
3142 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
3143 File_Reading(buf, Value);
3144 output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10);
3145
3146 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
3147 File_Reading(buf, Value);
3148 output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10);
3149
3150 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
3151 File_Reading(buf, Value);
3152 output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10);
3153
3154 sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
3155 File_Reading(buf, Value);
3156 output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10);
3157 }
3158
3159 output_struct->wifi_UnicastPacketsSent = 0;
3160 output_struct->wifi_UnicastPacketsReceived = 0;
3161 output_struct->wifi_MulticastPacketsSent = 0;
3162 output_struct->wifi_MulticastPacketsReceived = 0;
3163 output_struct->wifi_BroadcastPacketsSent = 0;
3164 output_struct->wifi_BroadcastPacketsRecevied = 0;
3165 output_struct->wifi_UnknownPacketsReceived = 0;
3166
3167 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3168 return RETURN_OK;
3169}
3170
3171INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
3172{
3173 INT status = RETURN_ERR;
3174
3175 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3176 //Below values should get updated from hal
3177 output_struct->wifi_RetransCount=0;
3178 output_struct->wifi_FailedRetransCount=0;
3179 output_struct->wifi_RetryCount=0;
3180 output_struct->wifi_MultipleRetryCount=0;
3181 output_struct->wifi_ACKFailureCount=0;
3182 output_struct->wifi_AggregatedPacketCount=0;
3183
3184 status = RETURN_OK;
3185 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3186
3187 return status;
3188}
3189
3190INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
3191{
3192 INT status = RETURN_ERR;
3193 UINT index;
3194 wifi_neighbor_ap_t *pt=NULL;
3195
3196 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3197 *output_array_size=2;
3198 //zqiu: HAL alloc the array and return to caller. Caller response to free it.
3199 *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
3200 for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
3201 strcpy(pt->ap_Radio,"");
3202 strcpy(pt->ap_SSID,"");
3203 strcpy(pt->ap_BSSID,"");
3204 strcpy(pt->ap_Mode,"");
3205 pt->ap_Channel=1;
3206 pt->ap_SignalStrength=0;
3207 strcpy(pt->ap_SecurityModeEnabled,"");
3208 strcpy(pt->ap_EncryptionMode,"");
3209 strcpy(pt->ap_OperatingFrequencyBand,"");
3210 strcpy(pt->ap_SupportedStandards,"");
3211 strcpy(pt->ap_OperatingStandards,"");
3212 strcpy(pt->ap_OperatingChannelBandwidth,"");
3213 pt->ap_BeaconPeriod=1;
3214 pt->ap_Noise=0;
3215 strcpy(pt->ap_BasicDataTransferRates,"");
3216 strcpy(pt->ap_SupportedDataTransferRates,"");
3217 pt->ap_DTIMPeriod=1;
3218 pt->ap_ChannelUtilization = 1;
3219 }
3220
3221 status = RETURN_OK;
3222 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3223
3224 return status;
3225}
3226
3227//----------------- AP HAL -------------------------------
3228
3229//>> Deprecated: used for old RDKB code.
3230INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
3231{
3232 if (NULL == output_ulong || NULL == output_struct)
3233 return RETURN_ERR;
3234 *output_ulong = 0;
3235 *output_struct = NULL;
3236 return RETURN_OK;
3237}
3238
3239#ifdef HAL_NETLINK_IMPL
3240static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
3241 struct nlattr *tb[NL80211_ATTR_MAX + 1];
3242 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
3243 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
3244 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
3245 char mac_addr[20];
3246 static int count=0;
3247 int rate=0;
3248
3249 wifi_device_info_t *out = (wifi_device_info_t*)arg;
3250
3251 nla_parse(tb,
3252 NL80211_ATTR_MAX,
3253 genlmsg_attrdata(gnlh, 0),
3254 genlmsg_attrlen(gnlh, 0),
3255 NULL);
3256
3257 if(!tb[NL80211_ATTR_STA_INFO]) {
3258 fprintf(stderr, "sta stats missing!\n");
3259 return NL_SKIP;
3260 }
3261
3262
3263 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
3264 fprintf(stderr, "failed to parse nested attributes!\n");
3265 return NL_SKIP;
3266 }
3267
3268 //devIndex starts from 1
3269 if( ++count == out->wifi_devIndex )
3270 {
3271 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
3272 //Getting the mac addrress
3273 mac_addr_aton(out->wifi_devMacAddress,mac_addr);
3274
3275 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
3276 fprintf(stderr, "failed to parse nested rate attributes!");
3277 return NL_SKIP;
3278 }
3279
3280 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
3281 if(rinfo[NL80211_RATE_INFO_BITRATE])
3282 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
3283 out->wifi_devTxRate = rate/10;
3284 }
3285
3286 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
3287 fprintf(stderr, "failed to parse nested rate attributes!");
3288 return NL_SKIP;
3289 }
3290
3291 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
3292 if(rinfo[NL80211_RATE_INFO_BITRATE])
3293 rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
3294 out->wifi_devRxRate = rate/10;
3295 }
3296 if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
3297 out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
3298
3299 out->wifi_devAssociatedDeviceAuthentiationState = 1;
3300 count = 0; //starts the count for next cycle
3301 return NL_STOP;
3302 }
3303
3304 return NL_SKIP;
3305
3306}
3307#endif
3308
3309INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
3310{
3311#ifdef HAL_NETLINK_IMPL
3312 Netlink nl;
3313 char if_name[10];
3314
3315 wifi_device_info_t info;
3316 info.wifi_devIndex = devIndex;
3317
3318 snprintf(if_name,sizeof(if_name),"%s%d", AP_PREFIX, apIndex);
3319
3320 nl.id = initSock80211(&nl);
3321
3322 if (nl.id < 0) {
3323 fprintf(stderr, "Error initializing netlink \n");
3324 return -1;
3325 }
3326
3327 struct nl_msg* msg = nlmsg_alloc();
3328
3329 if (!msg) {
3330 fprintf(stderr, "Failed to allocate netlink message.\n");
3331 nlfree(&nl);
3332 return -2;
3333 }
3334
3335 genlmsg_put(msg,
3336 NL_AUTO_PORT,
3337 NL_AUTO_SEQ,
3338 nl.id,
3339 0,
3340 NLM_F_DUMP,
3341 NL80211_CMD_GET_STATION,
3342 0);
3343
3344 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
3345 nl_send_auto(nl.socket, msg);
3346 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
3347 nl_recvmsgs(nl.socket, nl.cb);
3348 nlmsg_free(msg);
3349 nlfree(&nl);
3350
3351 output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
3352 output_struct->wifi_devRxRate = info.wifi_devRxRate;
3353 output_struct->wifi_devTxRate = info.wifi_devTxRate;
3354 output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
3355 memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
3356 return RETURN_OK;
3357#else
3358 //iw utility to retrieve station information
3359#define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt"
3360#define SIGNALFILE "/tmp/wifi_signalstrength.txt"
3361#define MACFILE "/tmp/wifi_AssoMac.txt"
3362#define TXRATEFILE "/tmp/wifi_txrate.txt"
3363#define RXRATEFILE "/tmp/wifi_rxrate.txt"
3364 FILE *file = NULL;
3365 char if_name[10] = {'\0'};
3366 char pipeCmd[256] = {'\0'};
3367 char line[256];
3368 int count,device = 0;
3369
3370 snprintf(if_name,sizeof(if_name),"%s%d", AP_PREFIX, apIndex);
3371
3372 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name);
3373 file = popen(pipeCmd, "r");
3374
3375 if(file == NULL)
3376 return RETURN_ERR; //popen failed
3377
3378 fgets(line, sizeof line, file);
3379 device = atoi(line);
3380 pclose(file);
3381
3382 if(device == 0)
3383 return RETURN_ERR; //No devices are connected
3384
3385 sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name);
3386 system(pipeCmd);
3387
3388 system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE);
3389
3390 system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE);
3391
3392 system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE);
3393
3394 system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE);
3395
3396 //devIndex starts from 1, ++count
3397 if((file = fopen(SIGNALFILE, "r")) != NULL )
3398 {
3399 for(count =0;fgets(line, sizeof line, file) != NULL;)
3400 {
3401 if (++count == devIndex)
3402 {
3403 output_struct->wifi_devSignalStrength = atoi(line);
3404 break;
3405 }
3406 }
3407 fclose(file);
3408 }
3409 else
3410 fprintf(stderr,"fopen wifi_signalstrength.txt failed");
3411
3412 if((file = fopen(MACFILE, "r")) != NULL )
3413 {
3414 for(count =0;fgets(line, sizeof line, file) != NULL;)
3415 {
3416 if (++count == devIndex)
3417 {
3418 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]);
3419 break;
3420 }
3421 }
3422 fclose(file);
3423 }
3424 else
3425 fprintf(stderr,"fopen wifi_AssoMac.txt failed");
3426
3427 if((file = fopen(TXRATEFILE, "r")) != NULL )
3428 {
3429 for(count =0;fgets(line, sizeof line, file) != NULL;)
3430 {
3431 if (++count == devIndex)
3432 {
3433 output_struct->wifi_devTxRate = atoi(line);
3434 break;
3435 }
3436 }
3437 fclose(file);
3438 }
3439 else
3440 fprintf(stderr,"fopen wifi_txrate.txt failed");
3441
3442 if((file = fopen(RXRATEFILE, "r")) != NULL)
3443 {
3444 for(count =0;fgets(line, sizeof line, file) != NULL;)
3445 {
3446 if (++count == devIndex)
3447 {
3448 output_struct->wifi_devRxRate = atoi(line);
3449 break;
3450 }
3451 }
3452 fclose(file);
3453 }
3454 else
3455 fprintf(stderr,"fopen wifi_rxrate.txt failed");
3456
3457 output_struct->wifi_devAssociatedDeviceAuthentiationState = 1;
3458
3459 return RETURN_OK;
3460#endif
3461}
3462
3463INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
3464{
3465 if (NULL == device)
3466 return RETURN_ERR;
3467 return RETURN_OK;
3468}
3469//<<
3470
3471
3472//--------------wifi_ap_hal-----------------------------
3473//enables CTS protection for the radio used by this AP
3474INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
3475{
3476 //save config and Apply instantly
3477 return RETURN_ERR;
3478}
3479
3480// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
3481INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
3482{
3483 //save config and Apply instantly
3484 return RETURN_ERR;
3485}
3486
3487//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
3488INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
3489{
3490 char cmd[64];
3491 char buf[512];
3492 //save config and apply instantly
3493
3494 //zqiu:TODO: save config
3495 if (threshold > 0) {
3496 snprintf(cmd, sizeof(cmd), "iwconfig %s%d frag %d", AP_PREFIX, apIndex, threshold);
3497 } else {
3498 snprintf(cmd, sizeof(cmd), "iwconfig %s%d frag off", AP_PREFIX, apIndex );
3499 }
3500 _syscmd(cmd,buf, sizeof(buf));
3501
3502 return RETURN_OK;
3503}
3504
3505// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
3506INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
3507{
3508 //Save config and Apply instantly
3509 return RETURN_ERR;
3510}
3511
3512// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
3513INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
3514{
3515 return RETURN_ERR;
3516}
3517
3518// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
3519INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
3520{
3521 //Apply instantly
3522 return RETURN_ERR;
3523}
3524
3525//P2 // outputs the number of Tx streams
3526INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
3527{
3528 return RETURN_ERR;
3529}
3530
3531//P2 // sets the number of Tx streams to an enviornment variable
3532INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
3533{
3534 //save to wifi config, wait for wifi reset or wifi_pushTxChainMask to apply
3535 return RETURN_ERR;
3536}
3537
3538//P2 // outputs the number of Rx streams
3539INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
3540{
3541 if (NULL == output_int)
3542 return RETURN_ERR;
3543 *output_int = 1;
3544 return RETURN_OK;
3545}
3546
3547//P2 // sets the number of Rx streams to an enviornment variable
3548INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
3549{
3550 //save to wifi config, wait for wifi reset or wifi_pushRxChainMask to apply
3551 return RETURN_ERR;
3552}
3553
3554//Get radio RDG enable setting
3555INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
3556{
3557 if (NULL == output_bool)
3558 return RETURN_ERR;
3559 *output_bool = TRUE;
3560 return RETURN_OK;
3561}
3562
3563//Get radio RDG enable setting
3564INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
3565{
3566 if (NULL == output_bool)
3567 return RETURN_ERR;
3568 *output_bool = TRUE;
3569 return RETURN_OK;
3570}
3571
3572//Set radio RDG enable setting
3573INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
3574{
3575 return RETURN_ERR;
3576}
3577
3578//Get radio ADDBA enable setting
3579INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
3580{
3581 if (NULL == output_bool)
3582 return RETURN_ERR;
3583 *output_bool = TRUE;
3584 return RETURN_OK;
3585}
3586
3587//Set radio ADDBA enable setting
3588INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
3589{
3590 return RETURN_ERR;
3591}
3592
3593//Get radio auto block ack enable setting
3594INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
3595{
3596 if (NULL == output_bool)
3597 return RETURN_ERR;
3598 *output_bool = TRUE;
3599 return RETURN_OK;
3600}
3601
3602//Set radio auto block ack enable setting
3603INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
3604{
3605 return RETURN_ERR;
3606}
3607
3608//Get radio 11n pure mode enable support
3609INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
3610{
3611 if (NULL == output_bool)
3612 return RETURN_ERR;
3613 *output_bool = TRUE;
3614 return RETURN_OK;
3615}
3616
3617//Get radio 11n pure mode enable setting
3618INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
3619{
3620 if (NULL == output_bool)
3621 return RETURN_ERR;
3622 *output_bool = TRUE;
3623 return RETURN_OK;
3624}
3625
3626//Set radio 11n pure mode enable setting
3627INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
3628{
3629 return RETURN_ERR;
3630}
3631
3632//Get radio IGMP snooping enable setting
3633INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
3634{
3635 if (NULL == output_bool)
3636 return RETURN_ERR;
3637 *output_bool = TRUE;
3638 return RETURN_OK;
3639}
3640
3641//Set radio IGMP snooping enable setting
3642INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
3643{
3644 return RETURN_ERR;
3645}
3646
3647//Get the Reset count of radio
3648INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
3649{
3650 if (NULL == output_int)
3651 return RETURN_ERR;
3652 *output_int = (radioIndex==0)? 1: 3;
3653
3654 return RETURN_OK;
3655}
3656
3657
3658//---------------------------------------------------------------------------------------------------
3659//
3660// Additional Wifi AP level APIs used for Access Point devices
3661//
3662//---------------------------------------------------------------------------------------------------
3663
3664// creates a new ap and pushes these parameters to the hardware
3665INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
3666{
3667 char buf[1024];
3668 char cmd[128];
3669
3670 if (NULL == essid)
3671 return RETURN_ERR;
3672
3673 snprintf(cmd,sizeof(cmd), "wlanconfig %s%d create wlandev %s%d wlanmode ap", AP_PREFIX, apIndex, RADIO_PREFIX, radioIndex);
3674 _syscmd(cmd, buf, sizeof(buf));
3675
3676 snprintf(cmd,sizeof(cmd), "iwconfig %s%d essid %s mode master", AP_PREFIX, apIndex, essid);
3677 _syscmd(cmd, buf, sizeof(buf));
3678
3679 wifi_pushSsidAdvertisementEnable(apIndex, !hideSsid);
3680
3681 snprintf(cmd,sizeof(cmd), "ifconfig %s%d txqueuelen 1000", AP_PREFIX, apIndex);
3682 _syscmd(cmd, buf, sizeof(buf));
3683
3684 return RETURN_OK;
3685}
3686
3687// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
3688INT wifi_deleteAp(INT apIndex)
3689{
3690 char buf[1024];
3691 char cmd[128];
3692
3693 snprintf(cmd,sizeof(cmd), "wlanconfig %s%d destroy", AP_PREFIX, apIndex);
3694 _syscmd(cmd, buf, sizeof(buf));
3695
3696 wifi_removeApSecVaribles(apIndex);
3697
3698 return RETURN_OK;
3699}
3700
3701// Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller
3702INT wifi_getApName(INT apIndex, CHAR *output_string)
3703{
3704 if(NULL == output_string)
3705 return RETURN_ERR;
3706
3707 snprintf(output_string, 16, "%s%d", AP_PREFIX, apIndex);
3708 return RETURN_OK;
3709}
3710
3711// Outputs the index number in that corresponds to the SSID string
3712INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
3713{
3714 CHAR *pos = NULL;
3715
3716 *output_int = -1;
3717 pos = strstr(inputSsidString, AP_PREFIX);
3718 if(pos)
3719 {
3720 sscanf(pos+strlen(AP_PREFIX),"%d", output_int);
3721 return RETURN_OK;
3722 }
3723 return RETURN_ERR;
3724}
3725
3726INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
3727{
3728 return wifi_getIndexFromName(inputSsidString, output_int);
3729}
3730
3731// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
3732INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
3733{
3734 char buf[MAX_BUF_SIZE] = {0};
3735 char cmd[MAX_CMD_SIZE] = {0};
3736 char config_file[MAX_BUF_SIZE] = {0};
3737
3738 if(NULL == output_string)
3739 return RETURN_ERR;
3740
3741 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3742 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
3743 if((strcmp(buf,"3")==0))
3744 snprintf(output_string, 32, "WPAand11i");
3745 else if((strcmp(buf,"2")==0))
3746 snprintf(output_string, 32, "11i");
3747 else if((strcmp(buf,"1")==0))
3748 snprintf(output_string, 32, "WPA");
3749 else
3750 snprintf(output_string, 32, "None");
3751
3752 return RETURN_OK;
3753}
3754
3755// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
3756INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
3757{
3758 char config_file[MAX_BUF_SIZE] = {0};
3759 struct params list;
3760
3761 if (NULL == beaconTypeString)
3762 return RETURN_ERR;
3763 list.name = "wpa";
3764 list.value = "0";
3765
3766 if((strcmp(beaconTypeString,"WPAand11i")==0))
3767 list.value="3";
3768 else if((strcmp(beaconTypeString,"11i")==0))
3769 list.value="2";
3770 else if((strcmp(beaconTypeString,"WPA")==0))
3771 list.value="1";
3772
3773 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3774 wifi_hostapdWrite(config_file, &list, 1);
3775 wifi_hostapdProcessUpdate(apIndex, &list, 1);
3776 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
3777 return RETURN_OK;
3778}
3779
3780// sets the beacon interval on the hardware for this AP
3781INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
3782{
3783 //save config and apply instantly
3784 return RETURN_ERR;
3785}
3786
3787INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
3788{
3789 //save config and apply instantly
3790 return RETURN_ERR;
3791}
3792
3793// Get the packet size threshold supported.
3794INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
3795{
3796 //save config and apply instantly
3797 if (NULL == output_bool)
3798 return RETURN_ERR;
3799 *output_bool = FALSE;
3800 return RETURN_OK;
3801}
3802
3803// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
3804INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
3805{
3806 char cmd[128];
3807 char buf[512];
3808
3809 if (threshold > 0)
3810 snprintf(cmd, sizeof(cmd), "iwconfig %s%d rts %d", AP_PREFIX, apIndex, threshold);
3811 else
3812 snprintf(cmd, sizeof(cmd), "iwconfig %s%d rts off", AP_PREFIX, apIndex);
3813 _syscmd(cmd, buf, sizeof(buf));
3814
3815 return RETURN_OK;
3816}
3817
3818// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
3819INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
3820{
3821 if (NULL == output_string)
3822 return RETURN_ERR;
3823 snprintf(output_string, 32, "TKIPandAESEncryption");
3824 return RETURN_OK;
3825
3826}
3827
3828// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
3829INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
3830{
3831 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3832 char *param_name, buf[32], config_file[MAX_BUF_SIZE] = {0};
3833
3834 if(NULL == output_string)
3835 return RETURN_ERR;
3836
3837 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3838 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
3839
3840 if(strcmp(buf,"0")==0)
3841 {
3842 printf("%s: wpa_mode is %s ......... \n", __func__, buf);
3843 snprintf(output_string, 32, "None");
3844 return RETURN_OK;
3845 }
3846 else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
3847 param_name = "rsn_pairwise";
3848 else if((strcmp(buf,"1")==0))
3849 param_name = "wpa_pairwise";
3850 else
3851 return RETURN_ERR;
3852 memset(output_string,'\0',32);
3853 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3854 wifi_hostapdRead(config_file,param_name,output_string,32);
3855 wifi_dbg_printf("\n%s output_string=%s",__func__,output_string);
3856
3857 if(strcmp(output_string,"TKIP") == 0)
3858 strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption"));
3859 else if(strcmp(output_string,"CCMP") == 0)
3860 strncpy(output_string,"AESEncryption", strlen("AESEncryption"));
3861 else if(strcmp(output_string,"TKIP CCMP") == 0)
3862 strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption"));
3863
3864 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3865 return RETURN_OK;
3866}
3867
3868// sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
3869INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
3870{
3871 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3872 struct params params={'\0'};
3873 char output_string[32];
3874 char config_file[MAX_BUF_SIZE] = {0};
3875
3876 memset(output_string,'\0',32);
3877 wifi_getApWpaEncryptionMode(apIndex,output_string);
3878
3879 if(strcmp(encMode, "TKIPEncryption") == 0)
3880 params.value = "TKIP";
3881 else if(strcmp(encMode,"AESEncryption") == 0)
3882 params.value = "CCMP";
3883 else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
3884 params.value = "TKIP CCMP";
3885
3886 if((strcmp(output_string,"WPAand11i")==0))
3887 {
3888 params.name = "wpa_pairwise";
3889 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3890 wifi_hostapdWrite(config_file, &params, 1);
3891 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3892
3893 params.name,"rsn_pairwise";
3894 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3895 wifi_hostapdWrite(config_file, &params, 1);
3896 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3897
3898 return RETURN_OK;
3899 }
3900 else if((strcmp(output_string,"11i")==0))
3901 {
3902 params.name = "rsn_pairwise";
3903 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3904 wifi_hostapdWrite(config_file, &params, 1);
3905 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3906 return RETURN_OK;
3907 }
3908 else if((strcmp(output_string,"WPA")==0))
3909 {
3910 params.name = "wpa_pairwise";
3911 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3912 wifi_hostapdWrite(config_file, &params, 1);
3913 wifi_hostapdProcessUpdate(apIndex, &params, 1);
3914 return RETURN_OK;
3915 }
3916
3917 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3918 return RETURN_OK;
3919}
3920
3921// deletes internal security varable settings for this ap
3922INT wifi_removeApSecVaribles(INT apIndex)
3923{
3924 //TODO: remove the entry in hostapd config file
3925 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s%d.conf//g' /tmp/conf_filename", AP_PREFIX, apIndex);
3926 //_syscmd(cmd, buf, sizeof(buf));
3927
3928 //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s%d//g' /tmp/conf_filename", AP_PREFIX, apIndex);
3929 //_syscmd(cmd, buf, sizeof(buf));
3930 return RETURN_ERR;
3931}
3932
3933// changes the hardware settings to disable encryption on this ap
3934INT wifi_disableApEncryption(INT apIndex)
3935{
3936 //Apply instantly
3937 return RETURN_ERR;
3938}
3939
3940// set the authorization mode on this ap
3941// mode mapping as: 1: open, 2: shared, 4:auto
3942INT wifi_setApAuthMode(INT apIndex, INT mode)
3943{
3944 //Apply instantly
3945 return RETURN_ERR;
3946}
3947
3948// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
3949INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
3950{
3951 //save to wifi config, and wait for wifi restart to apply
3952 struct params params={'\0'};
3953 char config_file[MAX_BUF_SIZE] = {0};
3954 int ret;
3955
3956 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
3957 if(authMode == NULL)
3958 return RETURN_ERR;
3959
3960 wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode);
3961 params.name = "wpa_key_mgmt";
3962
3963 if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
3964 params.value = "WPA-PSK";
3965 else if(strcmp(authMode,"EAPAuthentication") == 0)
3966 params.value = "WPA-EAP";
3967 else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
3968 return RETURN_OK; //This is taken careof in beaconType
3969
3970 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3971 ret=wifi_hostapdWrite(config_file,&params,1);
3972 if(!ret)
3973 ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
3974 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
3975
3976 return ret;
3977}
3978
3979// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
3980INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
3981{
3982 //save to wifi config, and wait for wifi restart to apply
3983 char BeaconType[50] = {0};
3984 char config_file[MAX_BUF_SIZE] = {0};
3985
3986 *authMode = 0;
3987 wifi_getApBeaconType(apIndex,BeaconType);
3988 printf("%s____%s \n",__FUNCTION__,BeaconType);
3989
3990 if(strcmp(BeaconType,"None") == 0)
3991 strcpy(authMode,"None");
3992 else
3993 {
3994 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
3995 wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
3996 wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode);
3997 if(strcmp(authMode,"WPA-PSK") == 0)
3998 strcpy(authMode,"SharedAuthentication");
3999 else if(strcmp(authMode,"WPA-EAP") == 0)
4000 strcpy(authMode,"EAPAuthentication");
4001 }
4002
4003 return RETURN_OK;
4004}
4005
4006// Outputs the number of stations associated per AP
4007INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
4008{
4009 char cmd[128]={0};
4010 char buf[128]={0};
4011 BOOL status = false;
4012
4013 if(apIndex > MAX_APS)
4014 return RETURN_ERR;
4015
4016 wifi_getApEnable(apIndex,&status);
4017 if (!status)
4018 return RETURN_OK;
4019
4020 //sprintf(cmd, "iw dev %s%d station dump | grep Station | wc -l", AP_PREFIX, apIndex);//alternate method
4021 sprintf(cmd, "hostapd_cli -i %s%d list_sta | wc -l", AP_PREFIX, apIndex);
4022 _syscmd(cmd, buf, sizeof(buf));
4023 sscanf(buf,"%lu", output_ulong);
4024
4025 return RETURN_OK;
4026}
4027
4028// manually removes any active wi-fi association with the device specified on this ap
4029INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
4030{
4031 char buf[126]={'\0'};
4032
4033 sprintf(buf,"hostapd_cli -i%s%d disassociate %s", AP_PREFIX, apIndex, client_mac);
4034 system(buf);
4035
4036 return RETURN_OK;
4037}
4038
4039// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
4040INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
4041{
4042 if(NULL == output_int)
4043 return RETURN_ERR;
4044 *output_int = apIndex%2;
4045 return RETURN_OK;
4046}
4047
4048// sets the radio index for the specific ap
4049INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
4050{
4051 //set to config only and wait for wifi reset to apply settings
4052 return RETURN_ERR;
4053}
4054
4055// Get the ACL MAC list per AP
4056INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
4057{
4058 char cmd[MAX_CMD_SIZE]={'\0'};
4059 int ret = 0;
4060
4061 sprintf(cmd, "hostapd_cli -i %s%d accept_acl SHOW | awk '{print $1}'", AP_PREFIX,apIndex);
4062 ret = _syscmd(cmd,macArray,buf_size);
4063 if (ret != 0)
4064 return RETURN_ERR;
4065
4066 return RETURN_OK;
4067}
4068
4069// Get the list of stations associated per AP
4070INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
4071{
4072 char cmd[128];
4073
4074 if(apIndex > 3) //Currently supporting apIndex upto 3
4075 return RETURN_ERR;
4076 sprintf(cmd, "hostapd_cli -i %s%d list_sta", AP_PREFIX, apIndex);
4077 //sprintf(buf,"iw dev %s%d station dump | grep Station | cut -d ' ' -f2", AP_PREFIX,apIndex);//alternate method
4078 _syscmd(cmd, macArray, buf_size);
4079
4080 return RETURN_OK;
4081}
4082
4083// adds the mac address to the filter list
4084//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
4085INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
4086{
4087 char cmd[MAX_CMD_SIZE]={'\0'};
4088 char buf[MAX_BUF_SIZE]={'\0'};
4089
4090#if 0
4091 sprintf(cmd, "hostapd_cli -i %s%d accept_acl ADD_MAC %s", AP_PREFIX,apIndex,DeviceMacAddress);
4092 if(_syscmd(cmd,buf,sizeof(buf)))
4093 return RETURN_ERR;
4094#endif
4095 sprintf(cmd, "echo '%s' >> %s%d", DeviceMacAddress, ACL_PREFIX, apIndex);
4096 if(_syscmd(cmd,buf,sizeof(buf)))
4097 return RETURN_ERR;
4098
4099 return RETURN_OK;
4100}
4101
4102// deletes the mac address from the filter list
4103//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
4104INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
4105{
4106 char cmd[MAX_CMD_SIZE]={'\0'};
4107 char buf[MAX_BUF_SIZE]={'\0'};
4108
4109#if 0
4110 sprintf(cmd, "hostapd_cli -i %s%d accept_acl DEL_MAC %s", AP_PREFIX,apIndex,DeviceMacAddress);
4111 if(_syscmd(cmd,buf,sizeof(buf)))
4112 return RETURN_ERR;
4113
4114#endif
4115 sprintf(cmd, "sed -i '/%s/d' %s%d ", DeviceMacAddress, ACL_PREFIX, apIndex);
4116 if(_syscmd(cmd,buf,sizeof(buf)))
4117 return RETURN_ERR;
4118
4119 return RETURN_OK;
4120}
4121
4122// outputs the number of devices in the filter list
4123INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
4124{
4125 if (NULL == output_uint)
4126 return RETURN_ERR;
4127 *output_uint = 0;
4128 return RETURN_ERR;
4129}
4130
4131INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
4132{
4133 char cmd[128]={'\0'};
4134 char buf[128]={'\0'};
4135
4136 if(strcmp(action,"DENY")==0)
4137 {
4138 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac);
4139 system(buf);
4140 return RETURN_OK;
4141 }
4142
4143 if(strcmp(action,"ALLOW")==0)
4144 {
4145 sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac);
4146 system(buf);
4147 return RETURN_OK;
4148 }
4149
4150 return RETURN_ERR;
4151
4152}
4153
4154// enable kick for devices on acl black list
4155INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
4156{
4157 char aclArray[512] = {0}, *acl = NULL;
4158 char assocArray[512] = {0}, *asso = NULL;
4159
4160 wifi_getApAclDevices(apIndex, aclArray, sizeof(aclArray));
4161 wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
4162
4163 // if there are no devices connected there is nothing to do
4164 if (strlen(assocArray) < 17)
4165 return RETURN_OK;
4166
4167 if (enable == TRUE)
4168 {
4169 //kick off the MAC which is in ACL array (deny list)
4170 acl = strtok(aclArray, "\r\n");
4171 while (acl != NULL) {
4172 if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
4173 wifi_kickApAssociatedDevice(apIndex, acl);
4174
4175 acl = strtok(NULL, "\r\n");
4176 }
4177 }
4178 else
4179 {
4180 //kick off the MAC which is not in ACL array (allow list)
4181 asso = strtok(assocArray, "\r\n");
4182 while (asso != NULL) {
4183 if (strlen(asso) >= 17 && !strcasestr(aclArray, asso))
4184 wifi_kickApAssociatedDevice(apIndex, asso);
4185
4186 asso = strtok(NULL, "\r\n");
4187 }
4188 }
4189
4190#if 0
4191 //TODO: need to revisit below implementation
4192 char aclArray[512]={0}, *acl=NULL;
4193 char assocArray[512]={0}, *asso=NULL;
4194 char buf[256]={'\0'};
4195 char action[10]={'\0'};
4196 FILE *fr=NULL;
4197 char interface[10]={'\0'};
4198 char config_file[MAX_BUF_SIZE] = {0};
4199
4200 wifi_getApAclDevices( apIndex, aclArray, sizeof(aclArray));
4201 wifi_getApDevicesAssociated( apIndex, assocArray, sizeof(assocArray));
4202 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4203 wifi_hostapdRead(config_file,"interface",interface,sizeof(interface));
4204
4205 sprintf(buf,"iptables -F WifiServices%d",apIndex);
4206 system(buf);
4207 sprintf(buf,"iptables -D INPUT -j WifiServices%d",apIndex);
4208 system(buf);
4209 sprintf(buf,"iptables -X WifiServices%d",apIndex);
4210 system(buf);
4211 sprintf(buf,"iptables -N WifiServices%d",apIndex);
4212 system(buf);
4213 sprintf(buf,"iptables -I INPUT 21 -j WifiServices%d",apIndex);
4214 system(buf);
4215
4216 if ( enable == TRUE )
4217 {
4218 int device_count=0;
4219 strcpy(action,"DENY");
4220 //kick off the MAC which is in ACL array (deny list)
4221 acl = strtok (aclArray,",");
4222 while (acl != NULL) {
4223 if(strlen(acl)>=17)
4224 {
4225 apply_rules(apIndex, acl,action,interface);
4226 device_count++;
4227 //Register mac to be blocked ,in syscfg.db persistent storage
4228 sprintf(buf,"syscfg set %dmacfilter%d %s",apIndex,device_count,acl);
4229 system(buf);
4230 sprintf(buf,"syscfg set %dcountfilter %d",apIndex,device_count);
4231 system(buf);
4232 system("syscfg commit");
4233
4234 wifi_kickApAssociatedDevice(apIndex, acl);
4235 }
4236 acl = strtok (NULL, ",");
4237 }
4238 }
4239 else
4240 {
4241 int device_count=0;
4242 char cmdmac[20]={'\0'};
4243 strcpy(action,"ALLOW");
4244 //kick off the MAC which is not in ACL array (allow list)
4245 acl = strtok (aclArray,",");
4246 while (acl != NULL) {
4247 if(strlen(acl)>=17)
4248 {
4249 apply_rules(apIndex, acl,action,interface);
4250 device_count++;
4251 //Register mac to be Allowed ,in syscfg.db persistent storage
4252 sprintf(buf,"syscfg set %dmacfilter%d %s",apIndex,device_count,acl);
4253 system(buf);
4254 sprintf(buf,"syscfg set %dcountfilter %d",apIndex,device_count);
4255 system(buf);
4256 sprintf(cmdmac,"%s",acl);
4257 }
4258 acl = strtok (NULL, ",");
4259 }
4260 sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",apIndex,interface,cmdmac);
4261 system(buf);
4262
4263 //Disconnect the mac which is not in ACL
4264 asso = strtok (assocArray,",");
4265 while (asso != NULL) {
4266 if(strlen(asso)>=17 && !strcasestr(aclArray, asso))
4267 wifi_kickApAssociatedDevice(apIndex, asso);
4268 asso = strtok (NULL, ",");
4269 }
4270 }
4271#endif
4272 return RETURN_OK;
4273}
4274
4275INT wifi_setPreferPrivateConnection(BOOL enable)
4276{
4277 char interface_name[100] = {0},ssid_cur_value[50] = {0};
4278 char buf[1024] = {0};
4279
4280 fprintf(stderr,"%s Value of %d",__FUNCTION__,enable);
4281 if(enable == TRUE)
4282 {
4283 GetInterfaceName(interface_name,"/nvram/hostapd4.conf");
4284 sprintf(buf,"ifconfig %s down" ,interface_name);
4285 system(buf);
4286 memset(buf,0,sizeof(buf));
4287 GetInterfaceName(interface_name,"/nvram/hostapd5.conf");
4288 sprintf(buf,"ifconfig %s down" ,interface_name);
4289 system(buf);
4290 }
4291 else
4292 {
4293 File_Reading("cat /tmp/Get5gssidEnable.txt", ssid_cur_value);
4294 if(strcmp(ssid_cur_value,"1") == 0)
4295 wifi_RestartPrivateWifi_5G();
4296 memset(ssid_cur_value,0,sizeof(ssid_cur_value));
4297 File_Reading("cat /tmp/GetPub2gssidEnable.txt", ssid_cur_value);
4298 if(strcmp(ssid_cur_value,"1") == 0)
4299 wifi_RestartHostapd_2G();
4300 memset(ssid_cur_value,0,sizeof(ssid_cur_value));
4301 File_Reading("cat /tmp/GetPub5gssidEnable.txt", ssid_cur_value);
4302 if(strcmp(ssid_cur_value,"1") == 0)
4303 wifi_RestartHostapd_5G();
4304 }
4305 return RETURN_OK;
4306}
4307
4308// sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
4309INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
4310{
4311 int items = 1;
4312 struct params list[2];
4313 char buf[MAX_BUF_SIZE] = {0};
4314 char config_file[MAX_BUF_SIZE] = {0}, acl_file[MAX_BUF_SIZE] = {0};
developer10adcc12022-09-13 14:39:17 +08004315 char deny_file[MAX_BUF_SIZE] = {0};
developer06a01d92022-09-07 16:32:39 +08004316
4317 list[0].name = "macaddr_acl";
developer06a01d92022-09-07 16:32:39 +08004318
developer10adcc12022-09-13 14:39:17 +08004319 if (filterMode == 0) {
4320 sprintf(buf, "%d", 0);
4321 list[0].value = buf;
4322
4323 char cmd[128], rtn[128];
4324 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d deny_acl CLEAR", AP_PREFIX, apIndex);
4325 _syscmd(cmd, rtn, sizeof(rtn));
4326 memset(cmd,0,sizeof(cmd));
4327 // Delete deny_mac_file in hostapd configuration
4328 snprintf(cmd, sizeof(cmd), "sed -i '/deny_mac_file=/d' %s%d.conf ", CONFIG_PREFIX, apIndex);
4329 _syscmd(cmd, rtn, sizeof(rtn));
4330 }
4331 else if (filterMode == 1) {
4332 sprintf(buf, "%d", filterMode);
4333 list[0].value = buf;
developer06a01d92022-09-07 16:32:39 +08004334 sprintf(acl_file,"%s%d",ACL_PREFIX,apIndex);
4335 list[1].name = "accept_mac_file";
4336 list[1].value = acl_file;
4337 items = 2;
developer10adcc12022-09-13 14:39:17 +08004338 } else if (filterMode == 2) {
4339 //TODO: deny_mac_file
4340 sprintf(buf, "%d", 0);
4341 list[0].value = buf;
4342 list[1].name = "deny_mac_file";
4343 sprintf(deny_file,"%s%d", DENY_PREFIX,apIndex);
4344 list[1].value = deny_file;
4345 items = 2;
4346 } else {
4347 return RETURN_ERR;
developer06a01d92022-09-07 16:32:39 +08004348 }
developer10adcc12022-09-13 14:39:17 +08004349
developer06a01d92022-09-07 16:32:39 +08004350 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4351 wifi_hostapdWrite(config_file, list, items);
4352
4353 return RETURN_OK;
4354
4355#if 0
4356 if(apIndex==0 || apIndex==1)
4357 {
4358 //set the filtermode
4359 sprintf(buf,"syscfg set %dblockall %d",apIndex,filterMode);
4360 system(buf);
4361 system("syscfg commit");
4362
4363 if(filterMode==0)
4364 {
4365 sprintf(buf,"iptables -F WifiServices%d",apIndex);
4366 system(buf);
4367 return RETURN_OK;
4368 }
4369 }
4370 return RETURN_OK;
4371#endif
4372}
4373
4374// 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.
4375INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
4376{
4377 return RETURN_ERR;
4378}
4379
4380// gets the vlan ID for this ap from an internal enviornment variable
4381INT wifi_getApVlanID(INT apIndex, INT *output_int)
4382{
4383 if(apIndex=0)
4384 {
4385 *output_int=100;
4386 return RETURN_OK;
4387 }
4388
4389 return RETURN_ERR;
4390}
4391
4392// sets the vlan ID for this ap to an internal enviornment variable
4393INT wifi_setApVlanID(INT apIndex, INT vlanId)
4394{
4395 //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)
4396 return RETURN_ERR;
4397}
4398
4399// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
4400INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
4401{
4402 snprintf(bridgeName, 32, "brlan0");
4403 snprintf(IP, 32, "10.0.0.1");
4404 snprintf(subnet, 32, "255.255.255.0");
4405
4406 return RETURN_OK;
4407}
4408
4409//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
4410INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
4411{
4412 //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
4413 return RETURN_ERR;
4414}
4415
4416// reset the vlan configuration for this ap
4417INT wifi_resetApVlanCfg(INT apIndex)
4418{
4419 //TODO: remove existing vlan for this ap
4420
4421 //Reapply vlan settings
4422 wifi_pushBridgeInfo(apIndex);
4423
4424 return RETURN_ERR;
4425}
4426
4427// 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.
4428INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
4429{
4430 return RETURN_ERR;
4431}
4432
4433// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
4434INT wifi_startHostApd()
4435{
4436 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4437 system("systemctl start hostapd.service");
4438 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4439 return RETURN_OK;
4440 //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
4441}
4442
4443// stops hostapd
4444INT wifi_stopHostApd()
4445{
4446 char cmd[128] = {0};
4447 char buf[128] = {0};
4448
4449 sprintf(cmd,"systemctl stop hostapd");
4450 _syscmd(cmd, buf, sizeof(buf));
4451
4452 return RETURN_OK;
4453}
4454
4455// restart hostapd dummy function
4456INT wifi_restartHostApd()
4457{
4458 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4459 system("systemctl restart hostapd-global");
4460 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4461
4462 return RETURN_OK;
4463}
4464
4465static int align_hostapd_config(int index)
4466{
4467 ULONG lval;
4468 wifi_getRadioChannel(index%2, &lval);
4469 wifi_setRadioChannel(index%2, lval);
4470}
4471
4472// sets the AP enable status variable for the specified ap.
4473INT wifi_setApEnable(INT apIndex, BOOL enable)
4474{
4475 char config_file[MAX_BUF_SIZE] = {0};
4476 char cmd[MAX_CMD_SIZE] = {0};
4477 char buf[MAX_BUF_SIZE] = {0};
4478 BOOL status;
4479
4480 wifi_getApEnable(apIndex,&status);
4481 if (enable == status)
4482 return RETURN_OK;
4483
4484 if (enable == TRUE) {
4485 int radioIndex = apIndex % NUMBER_OF_RADIOS;
4486 align_hostapd_config(apIndex);
4487 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4488 //Hostapd will bring up this interface
4489 sprintf(cmd, "hostapd_cli -i global raw REMOVE %s%d", AP_PREFIX, apIndex);
4490 _syscmd(cmd, buf, sizeof(buf));
4491 sprintf(cmd, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radioIndex, config_file);
4492 _syscmd(cmd, buf, sizeof(buf));
4493 }
4494 else {
4495 sprintf(cmd, "hostapd_cli -i global raw REMOVE %s%d", AP_PREFIX, apIndex);
4496 _syscmd(cmd, buf, sizeof(buf));
4497 sprintf(cmd, "ip link set %s%d down", AP_PREFIX, apIndex);
4498 _syscmd(cmd, buf, sizeof(buf));
4499 }
4500 snprintf(cmd, sizeof(cmd), "sed '/%s%d/c %s%d=%d' -i %s",
4501 AP_PREFIX, apIndex, AP_PREFIX, apIndex, enable, VAP_STATUS_FILE);
4502 _syscmd(cmd, buf, sizeof(buf));
4503 //Wait for wifi up/down to apply
4504 return RETURN_OK;
4505}
4506
4507// Outputs the setting of the internal variable that is set by wifi_setApEnable().
4508INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
4509{
4510 char cmd[MAX_CMD_SIZE] = {'\0'};
4511 char buf[MAX_BUF_SIZE] = {'\0'};
4512
4513 if((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
4514 return RETURN_ERR;
4515
4516 *output_bool = 0;
4517
4518 if((apIndex >= 0) && (apIndex < MAX_APS))//Handling 6 APs
4519 {
4520 sprintf(cmd, "%s%s%d%s", "ifconfig ", AP_PREFIX, apIndex, " | grep UP");
4521 *output_bool = _syscmd(cmd,buf,sizeof(buf))?0:1;
4522 }
4523
4524 return RETURN_OK;
4525}
4526
4527// Outputs the AP "Enabled" "Disabled" status from driver
4528INT wifi_getApStatus(INT apIndex, CHAR *output_string)
4529{
4530 char cmd[128] = {0};
4531 char buf[128] = {0};
4532 BOOL output_bool;
4533
4534 if ( NULL == output_string)
4535 return RETURN_ERR;
4536 wifi_getApEnable(apIndex,&output_bool);
4537
4538 if(output_bool == 1)
4539 snprintf(output_string, 32, "Up");
4540 else
4541 snprintf(output_string, 32, "Disable");
4542
4543 return RETURN_OK;
4544}
4545
4546//Indicates whether or not beacons include the SSID name.
4547// outputs a 1 if SSID on the AP is enabled, else outputs 0
4548INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
4549{
4550 //get the running status
4551 char config_file[MAX_BUF_SIZE] = {0};
4552 char buf[16] = {0};
4553
4554 if (!output)
4555 return RETURN_ERR;
4556
4557 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4558 wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
4559 *output = (strncmp("0",buf,1) == 0);
4560
4561 return RETURN_OK;
4562}
4563
4564// sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable
4565INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
4566{
4567 //store the config, apply instantly
4568 char config_file[MAX_BUF_SIZE] = {0};
4569 struct params list;
4570
4571 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4572 list.name = "ignore_broadcast_ssid";
4573 list.value = enable?"0":"1";
4574
4575 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4576 wifi_hostapdWrite(config_file, &list, 1);
4577 wifi_hostapdProcessUpdate(apIndex, &list, 1);
4578 //TODO: call hostapd_cli for dynamic_config_control
developer384f25c2022-09-13 14:41:20 +08004579 wifi_reloadAp(apIndex);
developer06a01d92022-09-07 16:32:39 +08004580 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4581
4582 return RETURN_OK;
4583}
4584
4585//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
4586INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
4587{
4588 //get the running status
4589 if(!output_uint)
4590 return RETURN_ERR;
4591 *output_uint=16;
4592 return RETURN_OK;
4593}
4594
4595INT wifi_setApRetryLimit(INT apIndex, UINT number)
4596{
4597 //apply instantly
4598 return RETURN_ERR;
4599}
4600
4601//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
4602INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
4603{
4604 if(!output)
4605 return RETURN_ERR;
4606 *output=TRUE;
4607 return RETURN_OK;
4608}
4609
4610//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
4611INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
4612{
4613 //get the running status from driver
4614 if(!output)
4615 return RETURN_ERR;
developer3ab38042022-09-13 14:17:03 +08004616
4617 char config_file[MAX_BUF_SIZE] = {0};
4618 char buf[16] = {0};
4619
4620 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4621 wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
4622 if (strncmp("1",buf,1) == 0)
4623 *output = TRUE;
4624 else
4625 *output = FALSE;
4626
developer06a01d92022-09-07 16:32:39 +08004627 return RETURN_OK;
4628}
4629
4630//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
4631INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
4632{
4633 //get the running status from driver
4634 if(!output)
4635 return RETURN_ERR;
developer3ab38042022-09-13 14:17:03 +08004636
4637 char config_file[MAX_BUF_SIZE] = {0};
4638 char buf[16] = {0};
4639
4640 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4641 wifi_hostapdRead(config_file, "wmm_enabled", buf, sizeof(buf));
4642 if (strncmp("1",buf,1) == 0)
4643 *output = TRUE;
4644 else
4645 *output = FALSE;
4646
developer06a01d92022-09-07 16:32:39 +08004647 return RETURN_OK;
4648}
4649
4650// enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0
4651INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
4652{
4653 //Save config and apply instantly.
developer3ab38042022-09-13 14:17:03 +08004654 char config_file[MAX_BUF_SIZE] = {0};
4655 struct params list;
4656
4657 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4658 list.name = "wmm_enabled";
4659 list.value = enable?"1":"0";
4660
4661 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4662 wifi_hostapdWrite(config_file, &list, 1);
4663 wifi_hostapdProcessUpdate(apIndex, &list, 1);
4664 wifi_reloadAp(apIndex);
4665 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4666
4667 return RETURN_OK;
developer06a01d92022-09-07 16:32:39 +08004668}
4669
4670//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.
4671INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
4672{
4673 //get the running status from driver
4674 if(!output)
4675 return RETURN_ERR;
4676 *output=TRUE;
4677 return RETURN_OK;
4678}
4679
4680// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
4681INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
4682{
4683 //save config and apply instantly.
developer3ab38042022-09-13 14:17:03 +08004684 char config_file[MAX_BUF_SIZE] = {0};
4685 struct params list;
4686
4687 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4688 list.name = "uapsd_advertisement_enabled";
4689 list.value = enable?"1":"0";
4690
4691 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4692 wifi_hostapdWrite(config_file, &list, 1);
4693 wifi_hostapdProcessUpdate(apIndex, &list, 1);
4694 wifi_reloadAp(apIndex);
4695 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4696
4697 return RETURN_OK;
developer06a01d92022-09-07 16:32:39 +08004698}
4699
4700// Sets the WMM ACK polity on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
4701INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB
4702{
4703 //save config and apply instantly.
4704 return RETURN_ERR;
4705}
4706
4707//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.
4708INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
4709{
4710 //get the running status from driver
4711 if(!output_uint)
4712 return RETURN_ERR;
developer0947e1a2022-09-13 14:15:25 +08004713
4714 char output[16]={'\0'};
4715 char config_file[MAX_BUF_SIZE] = {0};
4716
4717 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
4718 wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
4719 if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
4720 else {
4721 int device_num = atoi(output);
4722 if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
4723 wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num);
4724 return RETURN_ERR;
4725 }
4726 else {
4727 *output_uint = device_num;
4728 }
4729 }
4730
developer06a01d92022-09-07 16:32:39 +08004731 return RETURN_OK;
4732}
4733
4734INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
4735{
4736 //store to wifi config, apply instantly
developer0947e1a2022-09-13 14:15:25 +08004737 char str[MAX_BUF_SIZE]={'\0'};
4738 char cmd[MAX_CMD_SIZE]={'\0'};
4739 struct params params;
4740 char config_file[MAX_BUF_SIZE] = {0};
4741
4742 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4743 if (number > MAX_ASSOCIATED_STA_NUM || number < 0) {
4744 WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
4745 return RETURN_ERR;
4746 }
4747 sprintf(str, "%d", number);
4748 params.name = "max_num_sta";
4749 params.value = str;
4750
4751 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex);
4752 int ret = wifi_hostapdWrite(config_file, &params, 1);
4753 if (ret) {
4754 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
4755 ,__func__, ret);
4756 }
4757
4758 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
4759 if (ret) {
4760 WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
4761 ,__func__, ret);
4762 }
4763 wifi_reloadAp(apIndex);
4764 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4765
4766 return RETURN_OK;
developer06a01d92022-09-07 16:32:39 +08004767}
4768
4769//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.
4770INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
4771{
4772 //get the current threshold
4773 if(!output_uint)
4774 return RETURN_ERR;
developer0947e1a2022-09-13 14:15:25 +08004775 wifi_getApMaxAssociatedDevices(apIndex, output_uint);
4776 if (*output_uint == 0)
4777 *output_uint = 50;
developer06a01d92022-09-07 16:32:39 +08004778 return RETURN_OK;
4779}
4780
4781INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
4782{
4783 //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
developer0947e1a2022-09-13 14:15:25 +08004784 if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
4785 return RETURN_OK;
developer06a01d92022-09-07 16:32:39 +08004786 return RETURN_ERR;
4787}
4788
4789//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.
4790INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
4791{
4792 if(!output_uint)
4793 return RETURN_ERR;
4794 *output_uint = 3;
4795 return RETURN_OK;
4796}
4797
4798//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
4799INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
4800{
4801 if(!output_uint)
4802 return RETURN_ERR;
4803 *output_uint = 3;
4804 return RETURN_OK;
4805}
4806
4807//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.
4808INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
4809{
4810 if(!output_in_seconds)
4811 return RETURN_ERR;
4812 *output_in_seconds = 0;
4813 return RETURN_OK;
4814}
4815
4816//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
4817INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
4818{
4819 if(!output || apIndex>=MAX_APS)
4820 return RETURN_ERR;
4821 //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
4822 snprintf(output, 128, "None,WPA2-Personal");
4823 return RETURN_OK;
4824}
4825
4826//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
4827INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
4828{
4829 char config_file[MAX_BUF_SIZE] = {0};
4830 char buf[32] = {0};
4831 if (!output)
4832 return RETURN_ERR;
4833
4834 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
4835 wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
4836
4837 strcpy(output,"None");//Copying "None" to output string for default case
4838 if((strcmp(buf, "3")==0))
4839 snprintf(output, 32, "WPA-WPA2-Personal");
4840 else if((strcmp(buf, "2")==0))
4841 snprintf(output, 32, "WPA2-Personal");
4842 else if((strcmp(buf, "1")==0))
4843 snprintf(output, 32, "WPA-Personal");
4844 //TODO: need to handle enterprise authmode
4845
4846 //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
4847 return RETURN_OK;
4848#if 0
4849 //TODO: need to revisit below implementation
4850 char securityType[32], authMode[32];
4851 int enterpriseMode=0;
4852
4853 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4854 if(!output)
4855 return RETURN_ERR;
4856
4857 wifi_getApBeaconType(apIndex, securityType);
4858 strcpy(output,"None");//By default, copying "None" to output string
4859 if (strncmp(securityType,"None", strlen("None")) == 0)
4860 return RETURN_OK;
4861
4862 wifi_getApBasicAuthenticationMode(apIndex, authMode);
4863 enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0;
4864
4865 if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0)
4866 snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal");
4867 else if (strncmp(securityType, "WPA", strlen("WPA")) == 0)
4868 snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal");
4869 else if (strncmp(securityType, "11i", strlen("11i")) == 0)
4870 snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal");
4871 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4872
4873 return RETURN_OK;
4874#endif
4875}
4876
4877INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
4878{
4879 char securityType[32];
4880 char authMode[32];
4881
4882 //store settings and wait for wifi up to apply
4883 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
4884 if(!encMode)
4885 return RETURN_ERR;
4886
4887 printf("%s: apIndex %d, encMode %s\n",__func__, apIndex, encMode);
4888 if (strcmp(encMode, "None")==0)
4889 {
4890 strcpy(securityType,"None");
4891 strcpy(authMode,"None");
4892 }
4893 else if (strcmp(encMode, "WPA-WPA2-Personal")==0)
4894 {
4895 strcpy(securityType,"WPAand11i");
4896 strcpy(authMode,"PSKAuthentication");
4897 }
4898 else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0)
4899 {
4900 strcpy(securityType,"WPAand11i");
4901 strcpy(authMode,"EAPAuthentication");
4902 }
4903 else if (strcmp(encMode, "WPA-Personal")==0)
4904 {
4905 strcpy(securityType,"WPA");
4906 strcpy(authMode,"PSKAuthentication");
4907 }
4908 else if (strcmp(encMode, "WPA-Enterprise")==0)
4909 {
4910 strcpy(securityType,"WPA");
4911 strcpy(authMode,"EAPAuthentication");
4912 }
4913 else if (strcmp(encMode, "WPA2-Personal")==0)
4914 {
4915 strcpy(securityType,"11i");
4916 strcpy(authMode,"PSKAuthentication");
4917 }
4918 else if (strcmp(encMode, "WPA2-Enterprise")==0)
4919 {
4920 strcpy(securityType,"11i");
4921 strcpy(authMode,"EAPAuthentication");
4922 }
4923 else
4924 {
4925 strcpy(securityType,"None");
4926 strcpy(authMode,"None");
4927 }
4928 wifi_setApBeaconType(apIndex, securityType);
4929 wifi_setApBasicAuthenticationMode(apIndex, authMode);
4930 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
4931
4932 return RETURN_OK;
4933}
4934
4935
4936//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
4937// output_string must be pre-allocated as 64 character string by caller
4938// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
4939INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
4940{
4941 char buf[16];
4942 char config_file[MAX_BUF_SIZE] = {0};
4943
4944 if(output_string==NULL)
4945 return RETURN_ERR;
4946
4947 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4948 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
4949
4950 if(strcmp(buf,"0")==0)
4951 {
4952 printf("wpa_mode is %s ......... \n",buf);
4953 return RETURN_ERR;
4954 }
4955
4956 wifi_dbg_printf("\nFunc=%s\n",__func__);
4957 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4958 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
4959 wifi_dbg_printf("\noutput_string=%s\n",output_string);
4960
4961 return RETURN_OK;
4962}
4963
4964// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
4965// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
4966INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
4967{
4968 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
4969 struct params params={'\0'};
4970 int ret;
4971 char config_file[MAX_BUF_SIZE] = {0};
4972
4973 if(NULL == preSharedKey)
4974 return RETURN_ERR;
4975
4976 params.name = "wpa_passphrase";
4977
4978 if(strlen(preSharedKey)<8 || strlen(preSharedKey)>63)
4979 {
4980 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
4981 return RETURN_ERR;
4982 }
4983 params.value = preSharedKey;
4984 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
4985 ret = wifi_hostapdWrite(config_file, &params, 1);
4986 if(!ret)
4987 ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
4988 return ret;
4989 //TODO: call hostapd_cli for dynamic_config_control
4990}
4991
4992//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
4993// outputs the passphrase, maximum 63 characters
4994INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
4995{
4996 char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
4997
4998 wifi_dbg_printf("\nFunc=%s\n",__func__);
4999 if (NULL == output_string)
5000 return RETURN_ERR;
5001
5002 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5003 wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
5004 if(strcmp(buf,"0")==0)
5005 {
5006 printf("wpa_mode is %s ......... \n",buf);
5007 return RETURN_ERR;
5008 }
5009
5010 wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
5011 wifi_dbg_printf("\noutput_string=%s\n",output_string);
5012
5013 return RETURN_OK;
5014}
5015
5016// sets the passphrase enviornment variable, max 63 characters
5017INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
5018{
5019 //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
5020 struct params params={'\0'};
5021 char config_file[MAX_BUF_SIZE] = {0};
5022 int ret;
5023
5024 if(NULL == passPhrase)
5025 return RETURN_ERR;
5026
5027 if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
5028 {
5029 wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
5030 return RETURN_ERR;
5031 }
5032 params.name = "wpa_passphrase";
5033 params.value = passPhrase;
5034 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
5035 ret=wifi_hostapdWrite(config_file,&params,1);
5036 if(!ret)
5037 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5038
5039 return ret;
5040}
5041
5042//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.
5043INT wifi_setApSecurityReset(INT apIndex)
5044{
5045 //apply instantly
5046 return RETURN_ERR;
5047}
5048
5049//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).
5050INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
5051{
5052 if(!IP_output || !Port_output || !RadiusSecret_output)
5053 return RETURN_ERR;
5054 snprintf(IP_output, 64, "75.56.77.78");
5055 *Port_output = 123;
5056 snprintf(RadiusSecret_output, 64, "12345678");
5057
5058 return RETURN_OK;
5059}
5060
5061INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
5062{
5063 //store the paramters, and apply instantly
5064 return RETURN_ERR;
5065}
5066
5067INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
5068{
5069 if(!IP_output || !Port_output || !RadiusSecret_output)
5070 return RETURN_ERR;
5071 snprintf(IP_output, 64, "75.56.77.78");
5072 *Port_output = 123;
5073 snprintf(RadiusSecret_output, 64, "12345678");
5074 return RETURN_OK;
5075}
5076
5077INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
5078{
5079 //store the paramters, and apply instantly
5080 return RETURN_ERR;
5081}
5082
5083//RadiusSettings
5084INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
5085{
5086 if(!output)
5087 return RETURN_ERR;
5088
5089 output->RadiusServerRetries = 3; //Number of retries for Radius requests.
5090 output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
5091 output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
5092 output->PMKCaching = FALSE; //Enable or disable caching of PMK.
5093 output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
5094 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.
5095 output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
5096 output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
5097 output->QuietPeriodAfterFailedAuthentication = 5; //The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it.
5098 //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.
5099
5100 return RETURN_OK;
5101}
5102
5103INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
5104{
5105 //store the paramters, and apply instantly
5106 return RETURN_ERR;
5107}
5108
5109//Device.WiFi.AccessPoint.{i}.WPS.Enable
5110//Enables or disables WPS functionality for this access point.
5111// outputs the WPS enable state of this ap in output_bool
5112INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
5113{
5114 char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value;
5115 if(!output_bool || !(apIndex==0 || apIndex==1))
5116 return RETURN_ERR;
5117 sprintf(cmd,"hostapd_cli -i %s%d get_config | grep wps_state | cut -d '=' -f2", AP_PREFIX, apIndex);
5118 _syscmd(cmd, buf, sizeof(buf));
5119 if(strstr(buf, "configured"))
5120 *output_bool=TRUE;
5121 else
5122 *output_bool=FALSE;
5123
5124 return RETURN_OK;
5125}
5126
5127//Device.WiFi.AccessPoint.{i}.WPS.Enable
5128// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
5129INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
5130{
5131 char config_file[MAX_BUF_SIZE] = {0};
5132 struct params params;
5133
5134 if(!(apIndex==0 || apIndex==1))
5135 return RETURN_ERR;
5136 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5137 //store the paramters, and wait for wifi up to apply
5138 params.name = "wps_state";
5139 params.value = enable ? "2":"0";
5140
5141 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5142 wifi_hostapdWrite(config_file, &params, 1);
5143 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5144 wifi_reloadAp(apIndex);
5145
5146 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5147 return RETURN_OK;
5148}
5149
5150//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
5151INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
5152{
5153 if(!output)
5154 return RETURN_ERR;
5155 snprintf(output, 128, "PushButton,PIN");
5156 return RETURN_OK;
5157}
5158
5159//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
5160//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.
5161// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
5162INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
5163{
5164 if(!output)
5165 return RETURN_ERR;
5166 snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
5167
5168 return RETURN_OK;
5169}
5170
5171//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
5172// 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
5173INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
5174{
5175 //apply instantly. No setting need to be stored.
5176 char methods[MAX_BUF_SIZE], *token, *next_token;
5177 char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
5178 struct params params;
5179
5180 if(!methodString || !(apIndex==0 || apIndex==1))
5181 return RETURN_ERR;
5182 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5183 //store the paramters, and wait for wifi up to apply
5184
5185 snprintf(methods, sizeof(methods), "%s", methodString);
5186 for(token=methods; *token; token=next_token)
5187 {
5188 strtok_r(token, ",", &next_token);
5189 if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
5190 snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
5191 else if(*token=='E')
5192 {
5193 if(!strcmp(methods, "Ethernet"))
5194 snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
5195 else if(!strcmp(methods, "ExternalNFCToken"))
5196 snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
5197 else
5198 printf("%s: Unknown WpsConfigMethod\n", __func__);
5199 }
5200 else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
5201 snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
5202 else if(*token=='N' && !strcmp(token, "NFCInterface"))
5203 snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
5204 else if(*token=='P' )
5205 {
5206 if(!strcmp(token, "PushButton"))
5207 snprintf(config_methods, sizeof(config_methods), "%s ", "virtual_push_button");
5208 else if(!strcmp(token, "PIN"))
5209 snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
5210 else
5211 printf("%s: Unknown WpsConfigMethod\n", __func__);
5212 }
5213 else
5214 printf("%s: Unknown WpsConfigMethod\n", __func__);
5215 }
5216 params.name = "config_methods";
5217 params.value = config_methods;
5218 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5219 wifi_hostapdWrite(config_file, &params, 1);
5220 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5221 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5222
5223 return RETURN_OK;
5224}
5225
5226// outputs the pin value, ulong_pin must be allocated by the caller
5227INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
5228{
5229 char buf[MAX_BUF_SIZE] = {0};
5230 char cmd[MAX_CMD_SIZE] = {0};
5231
5232 if(!output_ulong || !(apIndex==0 || apIndex==1))
5233 return RETURN_ERR;
5234 snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
5235 _syscmd(cmd, buf, sizeof(buf));
5236 if(strlen(buf) > 0)
5237 *output_ulong=strtoul(buf, NULL, 10);
5238
5239 return RETURN_OK;
5240}
5241
5242// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
5243INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
5244{
5245 //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
5246 char ap_pin[16] = {0};
5247 char buf[MAX_BUF_SIZE] = {0};
5248 char config_file[MAX_BUF_SIZE] = {0};
5249 ULONG prev_pin = 0;
5250 struct params params;
5251
5252 if(!(apIndex==0 || apIndex==1))
5253 return RETURN_ERR;
5254 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5255 snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
5256 params.name = "ap_pin";
5257 params.value = ap_pin;
5258 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
5259 wifi_hostapdWrite(config_file, &params, 1);
5260 wifi_hostapdProcessUpdate(apIndex, &params, 1);
5261 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5262
5263 return RETURN_OK;
5264}
5265
5266// Output string is either Not configured or Configured, max 32 characters
5267INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
5268{
5269 char cmd[MAX_CMD_SIZE];
5270 char buf[MAX_BUF_SIZE]={0};
5271
5272 if(!output_string || !(apIndex==0 || apIndex==1))
5273 return RETURN_ERR;
5274 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5275 snprintf(output_string, 32, "Not configured");
5276 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d get_config | grep wps_state | cut -d'=' -f2", AP_PREFIX, apIndex);
5277 _syscmd(cmd, buf, sizeof(buf));
5278
developer348e3d92022-09-13 14:48:41 +08005279 if(!strncmp(buf, "configured", 10))
developer06a01d92022-09-07 16:32:39 +08005280 snprintf(output_string, 32, "Configured");
5281 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5282
5283 return RETURN_OK;
5284}
5285
5286// sets the WPS pin for this AP
5287INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
5288{
5289 char cmd[MAX_CMD_SIZE];
5290 char buf[MAX_BUF_SIZE]={0};
5291 BOOL enable;
5292
5293 if(!(apIndex==0 || apIndex==1))
5294 return RETURN_ERR;
5295 wifi_getApEnable(apIndex, &enable);
5296 if (!enable)
5297 return RETURN_ERR;
5298 wifi_getApWpsEnable(apIndex, &enable);
5299 if (!enable)
5300 return RETURN_ERR;
5301
5302 snprintf(cmd, 64, "hostapd_cli -i%s%d wps_pin any %s", AP_PREFIX, apIndex, pin);
5303 _syscmd(cmd, buf, sizeof(buf));
5304 if((strstr(buf, "OK"))!=NULL)
5305 return RETURN_OK;
5306
5307 return RETURN_ERR;
5308}
5309
5310// This function is called when the WPS push button has been pressed for this AP
5311INT wifi_setApWpsButtonPush(INT apIndex)
5312{
5313 char cmd[MAX_CMD_SIZE];
5314 char buf[MAX_BUF_SIZE]={0};
5315 BOOL enable=FALSE;
5316
5317 if(!(apIndex==0 || apIndex==1))
5318 return RETURN_ERR;
5319 wifi_getApEnable(apIndex, &enable);
5320 if (!enable)
5321 return RETURN_ERR;
5322
5323 wifi_getApWpsEnable(apIndex, &enable);
5324 if (!enable)
5325 return RETURN_ERR;
5326
5327 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s%d wps_cancel; hostapd_cli -i%s%d wps_pbc", AP_PREFIX, apIndex, AP_PREFIX, apIndex);
5328 _syscmd(cmd, buf, sizeof(buf));
5329
5330 if((strstr(buf, "OK"))!=NULL)
5331 return RETURN_OK;
5332 return RETURN_ERR;
5333}
5334
5335// cancels WPS mode for this AP
5336INT wifi_cancelApWPS(INT apIndex)
5337{
5338 char cmd[MAX_CMD_SIZE];
5339 char buf[MAX_BUF_SIZE]={0};
5340
5341 if(!(apIndex==0 || apIndex==1))
5342 return RETURN_ERR;
5343 snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s%d wps_cancel", AP_PREFIX, apIndex);
5344 _syscmd(cmd,buf, sizeof(buf));
5345
5346 if((strstr(buf, "OK"))!=NULL)
5347 return RETURN_OK;
5348 return RETURN_ERR;
5349}
5350
5351//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
5352//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
5353INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
5354{
5355 FILE *f;
5356 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
5357 char cmd[256], buf[2048];
5358 char *param , *value, *line=NULL;
5359 size_t len = 0;
5360 ssize_t nread;
5361 wifi_associated_dev_t *dev=NULL;
5362
5363 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5364 *associated_dev_array = NULL;
5365 sprintf(cmd, "hostapd_cli -i%s%d all_sta | grep AUTHORIZED | wc -l", AP_PREFIX, apIndex);
5366 _syscmd(cmd,buf,sizeof(buf));
5367 *output_array_size = atoi(buf);
5368
5369 if (*output_array_size <= 0)
5370 return RETURN_OK;
5371
5372 dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
5373 *associated_dev_array = dev;
5374 sprintf(cmd, "hostapd_cli -i%s%d all_sta > /tmp/connected_devices.txt" , AP_PREFIX, apIndex);
5375 _syscmd(cmd,buf,sizeof(buf));
5376 f = fopen("/tmp/connected_devices.txt", "r");
5377 if (f==NULL)
5378 {
5379 *output_array_size=0;
5380 return RETURN_ERR;
5381 }
5382 while ((nread = getline(&line, &len, f)) != -1)
5383 {
5384 param = strtok(line,"=");
5385 value = strtok(NULL,"=");
5386
5387 if( strcmp("flags",param) == 0 )
5388 {
5389 value[strlen(value)-1]='\0';
5390 if(strstr (value,"AUTHORIZED") != NULL )
5391 {
5392 dev[auth_temp].cli_AuthenticationState = 1;
5393 dev[auth_temp].cli_Active = 1;
5394 auth_temp++;
5395 read_flag=1;
5396 }
5397 }
5398 if(read_flag==1)
5399 {
5400 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
5401 {
5402 value[strlen(value)-1]='\0';
5403 sscanf(value, "%x:%x:%x:%x:%x:%x",
5404 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
5405 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
5406 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
5407 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
5408 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
5409 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
5410 mac_temp++;
5411 read_flag=0;
5412 }
5413 }
5414 }
5415 *output_array_size = auth_temp;
5416 auth_temp=0;
5417 mac_temp=0;
5418 free(line);
5419 fclose(f);
5420 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5421 return RETURN_OK;
5422}
5423
5424#define MACADDRESS_SIZE 6
5425
5426INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
5427{
5428 FILE *fp = NULL;
5429 char str[MAX_BUF_SIZE] = {0};
5430 int wificlientindex = 0 ;
5431 int count = 0;
5432 int signalstrength = 0;
5433 int arr[MACADDRESS_SIZE] = {0};
5434 unsigned char mac[MACADDRESS_SIZE] = {0};
5435 UINT wifi_count = 0;
5436 char virtual_interface_name[MAX_BUF_SIZE] = {0};
5437 char pipeCmd[MAX_CMD_SIZE] = {0};
5438
5439 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5440 *output_array_size = 0;
5441 *associated_dev_array = NULL;
5442
5443 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
5444 fp = popen(pipeCmd, "r");
5445 if (fp == NULL)
5446 {
5447 printf("Failed to run command inside function %s\n",__FUNCTION__ );
5448 return RETURN_ERR;
5449 }
5450
5451 /* Read the output a line at a time - output it. */
5452 fgets(str, sizeof(str)-1, fp);
5453 wifi_count = (unsigned int) atoi ( str );
5454 *output_array_size = wifi_count;
5455 printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
5456 pclose(fp);
5457
5458 if(wifi_count == 0)
5459 {
5460 return RETURN_OK;
5461 }
5462 else
5463 {
5464 wifi_associated_dev3_t* temp = NULL;
5465 temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
5466 if(temp == NULL)
5467 {
5468 printf("Error Statement. Insufficient memory \n");
5469 return RETURN_ERR;
5470 }
5471
5472 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
5473 system(pipeCmd);
5474 memset(pipeCmd,0,sizeof(pipeCmd));
5475 if(apIndex == 0)
5476 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
5477 else if(apIndex == 1)
5478 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
5479 system(pipeCmd);
5480
5481 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
5482 if(fp == NULL)
5483 {
5484 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
5485 return RETURN_ERR;
5486 }
5487 fclose(fp);
5488
5489 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2", interface_name);
5490 fp = popen(pipeCmd, "r");
5491 if(fp)
5492 {
5493 for(count =0 ; count < wifi_count; count++)
5494 {
5495 fgets(str, MAX_BUF_SIZE, fp);
5496 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
5497 {
5498 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
5499 {
5500 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
5501
5502 }
5503 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
5504 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]);
5505 }
5506 temp[count].cli_AuthenticationState = 1; //TODO
5507 temp[count].cli_Active = 1; //TODO
5508 }
5509 pclose(fp);
5510 }
5511
5512 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt", interface_name);
5513 fp = popen(pipeCmd, "r");
5514 if(fp)
5515 {
5516 pclose(fp);
5517 }
5518 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
5519 if(fp)
5520 {
5521 for(count =0 ; count < wifi_count ;count++)
5522 {
5523 fgets(str, MAX_BUF_SIZE, fp);
5524 signalstrength = atoi(str);
5525 temp[count].cli_SignalStrength = signalstrength;
5526 temp[count].cli_RSSI = signalstrength;
5527 temp[count].cli_SNR = signalstrength + 95;
5528 }
5529 pclose(fp);
5530 }
5531
5532
5533 if((apIndex == 0) || (apIndex == 4))
5534 {
5535 for(count =0 ; count < wifi_count ;count++)
5536 {
5537 strcpy(temp[count].cli_OperatingStandard,"g");
5538 strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz");
5539 }
5540
5541 //BytesSent
5542 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt", interface_name);
5543 fp = popen(pipeCmd, "r");
5544 if(fp)
5545 {
5546 pclose(fp);
5547 }
5548 fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r");
5549 if(fp)
5550 {
5551 for (count = 0; count < wifi_count; count++)
5552 {
5553 fgets(str, MAX_BUF_SIZE, fp);
5554 temp[count].cli_BytesSent = strtoul(str, NULL, 10);
5555 }
5556 pclose(fp);
5557 }
5558
5559 //BytesReceived
5560 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt", interface_name);
5561 fp = popen(pipeCmd, "r");
5562 if (fp)
5563 {
5564 pclose(fp);
5565 }
5566 fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r");
5567 if (fp)
5568 {
5569 for (count = 0; count < wifi_count; count++)
5570 {
5571 fgets(str, MAX_BUF_SIZE, fp);
5572 temp[count].cli_BytesReceived = strtoul(str, NULL, 10);
5573 }
5574 pclose(fp);
5575 }
5576
5577 //PacketsSent
5578 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt", interface_name);
5579 fp = popen(pipeCmd, "r");
5580 if (fp)
5581 {
5582 pclose(fp);
5583 }
5584
5585 fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r");
5586 if (fp)
5587 {
5588 for (count = 0; count < wifi_count; count++)
5589 {
5590 fgets(str, MAX_BUF_SIZE, fp);
5591 temp[count].cli_PacketsSent = strtoul(str, NULL, 10);
5592 }
5593 pclose(fp);
5594 }
5595
5596 //PacketsReceived
5597 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt", interface_name);
5598 fp = popen(pipeCmd, "r");
5599 if (fp)
5600 {
5601 pclose(fp);
5602 }
5603 fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r");
5604 if (fp)
5605 {
5606 for (count = 0; count < wifi_count; count++)
5607 {
5608 fgets(str, MAX_BUF_SIZE, fp);
5609 temp[count].cli_PacketsReceived = strtoul(str, NULL, 10);
5610 }
5611 pclose(fp);
5612 }
5613
5614 //ErrorsSent
5615 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt", interface_name);
5616 fp = popen(pipeCmd, "r");
5617 if (fp)
5618 {
5619 pclose(fp);
5620 }
5621 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
5622 if (fp)
5623 {
5624 for (count = 0; count < wifi_count; count++)
5625 {
5626 fgets(str, MAX_BUF_SIZE, fp);
5627 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
5628 }
5629 pclose(fp);
5630 }
5631
5632 //ErrorsSent
5633 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt", interface_name);
5634 fp = popen(pipeCmd, "r");
5635 if (fp)
5636 {
5637 pclose(fp);
5638 }
5639 fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r");
5640 if (fp)
5641 {
5642 for (count = 0; count < wifi_count; count++)
5643 {
5644 fgets(str, MAX_BUF_SIZE, fp);
5645 temp[count].cli_ErrorsSent = strtoul(str, NULL, 10);
5646 }
5647 pclose(fp);
5648 }
5649
5650 //LastDataDownlinkRate
5651 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt", interface_name);
5652 fp = popen(pipeCmd, "r");
5653 if (fp)
5654 {
5655 pclose(fp);
5656 }
5657 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
5658 if (fp)
5659 {
5660 for (count = 0; count < wifi_count; count++)
5661 {
5662 fgets(str, MAX_BUF_SIZE, fp);
5663 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
5664 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
5665 }
5666 pclose(fp);
5667 }
5668
5669 //LastDataUplinkRate
5670 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt", interface_name);
5671 fp = popen(pipeCmd, "r");
5672 if (fp)
5673 {
5674 pclose(fp);
5675 }
5676 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
5677 if (fp)
5678 {
5679 for (count = 0; count < wifi_count; count++)
5680 {
5681 fgets(str, MAX_BUF_SIZE, fp);
5682 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
5683 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
5684 }
5685 pclose(fp);
5686 }
5687
5688 }
5689 else if ((apIndex == 1) || (apIndex == 5))
5690 {
5691 for (count = 0; count < wifi_count; count++)
5692 {
5693 strcpy(temp[count].cli_OperatingStandard, "a");
5694 strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz");
5695 temp[count].cli_BytesSent = 0;
5696 temp[count].cli_BytesReceived = 0;
5697 temp[count].cli_LastDataUplinkRate = 0;
5698 temp[count].cli_LastDataDownlinkRate = 0;
5699 temp[count].cli_PacketsSent = 0;
5700 temp[count].cli_PacketsReceived = 0;
5701 temp[count].cli_ErrorsSent = 0;
5702 }
5703 }
5704
5705 for (count = 0; count < wifi_count; count++)
5706 {
5707 temp[count].cli_Retransmissions = 0;
5708 temp[count].cli_DataFramesSentAck = 0;
5709 temp[count].cli_DataFramesSentNoAck = 0;
5710 temp[count].cli_MinRSSI = 0;
5711 temp[count].cli_MaxRSSI = 0;
5712 strncpy(temp[count].cli_InterferenceSources, "", 64);
5713 memset(temp[count].cli_IPAddress, 0, 64);
5714 temp[count].cli_RetransCount = 0;
5715 temp[count].cli_FailedRetransCount = 0;
5716 temp[count].cli_RetryCount = 0;
5717 temp[count].cli_MultipleRetryCount = 0;
5718 }
5719 *associated_dev_array = temp;
5720 }
5721 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5722 return RETURN_OK;
5723}
5724
5725int wifihal_interfacestatus(CHAR *wifi_status,CHAR *interface_name)
5726{
5727 FILE *fp = NULL;
5728 char path[512] = {0},status[MAX_BUF_SIZE] = {0};
5729 char cmd[MAX_CMD_SIZE];
5730 int count = 0;
5731
5732 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5733 sprintf(cmd, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4", interface_name);
5734 fp = popen(cmd,"r");
5735 if(fp == NULL)
5736 {
5737 printf("Failed to run command in Function %s\n",__FUNCTION__);
5738 return 0;
5739 }
5740 if(fgets(path, sizeof(path)-1, fp) != NULL)
5741 {
5742 for(count=0;path[count]!='\n';count++)
5743 status[count]=path[count];
5744 status[count]='\0';
5745 }
5746 strcpy(wifi_status,status);
5747 pclose(fp);
5748 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5749 return RETURN_OK;
5750}
5751
5752/* #define HOSTAPD_STA_PARAM_ENTRIES 29
5753struct hostapd_sta_param {
5754 char key[50];
5755 char value[100];
5756}
5757
5758static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){
5759 int i = 0;
5760
5761 while(i<HOSTAPD_STA_PARAM_ENTRIES) {
5762 if (strncmp(params[i].key,key,50) == 0){
5763 return &params[i].value;
5764 }
5765 i++;
5766 }
5767 return NULL;
5768
5769} */
5770
5771static unsigned int count_occurences(const char *buf, const char *word)
5772{
5773 unsigned int n = 0;
5774 char *ptr = strstr(buf, word);
5775
5776 while (ptr++) {
5777 n++;
5778 ptr = strstr(ptr, word);
5779 }
5780
5781 wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word);
5782 return n;
5783}
5784
5785static const char *get_line_from_str_buf(const char *buf, char *line)
5786{
5787 int i;
5788 int n = strlen(buf);
5789
5790 for (i = 0; i < n; i++) {
5791 line[i] = buf[i];
5792 if (buf[i] == '\n') {
5793 line[i] = '\0';
5794 return &buf[i + 1];
5795 }
5796 }
5797
5798 return NULL;
5799}
5800
5801INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
5802{
5803 unsigned int assoc_cnt = 0;
5804 char interface_name[50] = {0};
5805 char buf[MAX_BUF_SIZE * 50]= {'\0'}; // Increase this buffer if more fields are added to 'iw dev' output filter
5806 char cmd[MAX_CMD_SIZE] = {'\0'};
5807 char line[256] = {'\0'};
5808 int i = 0;
5809 int ret = 0;
5810 const char *ptr = NULL;
5811 char *key = NULL;
5812 char *val = NULL;
5813 wifi_associated_dev3_t *temp = NULL;
5814 int rssi;
5815
5816 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5817
5818 if (wifi_getApName(apIndex, interface_name) != RETURN_OK) {
5819 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
5820 return RETURN_ERR;
5821 }
5822
5823 // Example filtered output of 'iw dev' command:
5824 // Station 0a:69:72:10:d2:fa (on wifi0)
5825 // signal avg:-67 [-71, -71] dBm
5826 // Station 28:c2:1f:25:5f:99 (on wifi0)
5827 // signal avg:-67 [-71, -70] dBm
5828 if (sprintf(cmd,"iw dev %s station dump | tr -d '\\t' | grep 'Station\\|signal avg'", interface_name) < 0) {
5829 wifi_dbg_printf("%s: failed to build iw dev command for %s\n", __FUNCTION__, interface_name);
5830 return RETURN_ERR;
5831 }
5832
5833 ret = _syscmd(cmd, buf, sizeof(buf));
5834 if (ret == RETURN_ERR) {
5835 wifi_dbg_printf("%s: failed to execute '%s' for %s\n", __FUNCTION__, cmd, interface_name);
5836 return RETURN_ERR;
5837 }
5838
5839 *output_array_size = count_occurences(buf, "Station");
5840 if (*output_array_size == 0) return RETURN_OK;
5841
5842 temp = calloc(*output_array_size, sizeof(wifi_associated_dev3_t));
5843 if (temp == NULL) {
5844 wifi_dbg_printf("%s: failed to allocate dev array for %s\n", __FUNCTION__, interface_name);
5845 return RETURN_ERR;
5846 }
5847 *associated_dev_array = temp;
5848
5849 wifi_dbg_printf("%s: array_size = %u\n", __FUNCTION__, *output_array_size);
5850 ptr = get_line_from_str_buf(buf, line);
5851 i = -1;
5852 while (ptr) {
5853 if (strstr(line, "Station")) {
5854 i++;
5855 key = strtok(line, " ");
5856 val = strtok(NULL, " ");
5857 if (sscanf(val, "%02x:%02x:%02x:%02x:%02x:%02x",
5858 &temp[i].cli_MACAddress[0],
5859 &temp[i].cli_MACAddress[1],
5860 &temp[i].cli_MACAddress[2],
5861 &temp[i].cli_MACAddress[3],
5862 &temp[i].cli_MACAddress[4],
5863 &temp[i].cli_MACAddress[5]) != MACADDRESS_SIZE) {
5864 wifi_dbg_printf("%s: failed to parse MAC of client connected to %s\n", __FUNCTION__, interface_name);
5865 free(*associated_dev_array);
5866 return RETURN_ERR;
5867 }
5868 }
5869 else if (i < 0) {
5870 ptr = get_line_from_str_buf(ptr, line);
5871 continue; // We didn't detect 'station' entry yet
5872 }
5873 else if (strstr(line, "signal avg")) {
5874 key = strtok(line, ":");
5875 val = strtok(NULL, " ");
5876 if (sscanf(val, "%d", &rssi) <= 0 ) {
5877 wifi_dbg_printf("%s: failed to parse RSSI of client connected to %s\n", __FUNCTION__, interface_name);
5878 free(*associated_dev_array);
5879 return RETURN_ERR;
5880 }
5881 temp[i].cli_RSSI = rssi;
5882 temp[i].cli_SNR = 95 + rssi; // We use constant -95 noise floor
5883 }
5884 // Here other fields can be parsed if added to filter of 'iw dev' command
5885
5886 ptr = get_line_from_str_buf(ptr, line);
5887 };
5888
5889 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
5890
5891 return RETURN_OK;
5892}
5893
5894#if 0
5895//To-do
5896INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
5897{
5898 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
5899
5900 //Using different approach to get required WiFi Parameters from system available commands
5901#if 0
5902 FILE *f;
5903 int read_flag=0, auth_temp=0, mac_temp=0,i=0;
5904 char cmd[256], buf[2048];
5905 char *param , *value, *line=NULL;
5906 size_t len = 0;
5907 ssize_t nread;
5908 wifi_associated_dev3_t *dev=NULL;
5909 *associated_dev_array = NULL;
5910 sprintf(cmd, "hostapd_cli -i%s%d all_sta | grep AUTHORIZED | wc -l", AP_PREFIX, apIndex);
5911 _syscmd(cmd,buf,sizeof(buf));
5912 *output_array_size = atoi(buf);
5913
5914 if (*output_array_size <= 0)
5915 return RETURN_OK;
5916
5917 dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t));
5918 *associated_dev_array = dev;
5919 sprintf(cmd, "hostapd_cli -i%s%d all_sta > /tmp/connected_devices.txt", AP_PREFIX, apIndex);
5920 _syscmd(cmd,buf,sizeof(buf));
5921 f = fopen("/tmp/connected_devices.txt", "r");
5922 if (f==NULL)
5923 {
5924 *output_array_size=0;
5925 return RETURN_ERR;
5926 }
5927 while ((nread = getline(&line, &len, f)) != -1)
5928 {
5929 param = strtok(line,"=");
5930 value = strtok(NULL,"=");
5931
5932 if( strcmp("flags",param) == 0 )
5933 {
5934 value[strlen(value)-1]='\0';
5935 if(strstr (value,"AUTHORIZED") != NULL )
5936 {
5937 dev[auth_temp].cli_AuthenticationState = 1;
5938 dev[auth_temp].cli_Active = 1;
5939 auth_temp++;
5940 read_flag=1;
5941 }
5942 }
5943 if(read_flag==1)
5944 {
5945 if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
5946 {
5947 value[strlen(value)-1]='\0';
5948 sscanf(value, "%x:%x:%x:%x:%x:%x",
5949 (unsigned int *)&dev[mac_temp].cli_MACAddress[0],
5950 (unsigned int *)&dev[mac_temp].cli_MACAddress[1],
5951 (unsigned int *)&dev[mac_temp].cli_MACAddress[2],
5952 (unsigned int *)&dev[mac_temp].cli_MACAddress[3],
5953 (unsigned int *)&dev[mac_temp].cli_MACAddress[4],
5954 (unsigned int *)&dev[mac_temp].cli_MACAddress[5] );
5955
5956 }
5957 else if( strcmp("rx_packets",param) == 0 )
5958 {
5959 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived));
5960 }
5961
5962 else if( strcmp("tx_packets",param) == 0 )
5963 {
5964 sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent));
5965 }
5966
5967 else if( strcmp("rx_bytes",param) == 0 )
5968 {
5969 sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived));
5970 }
5971
5972 else if( strcmp("tx_bytes",param) == 0 )
5973 {
5974 sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent));
5975 mac_temp++;
5976 read_flag=0;
5977 }
5978 }
5979 }
5980
5981 *output_array_size = auth_temp;
5982 auth_temp=0;
5983 mac_temp=0;
5984 free(line);
5985 fclose(f);
5986#endif
5987 char interface_name[MAX_BUF_SIZE] = {0};
5988 char wifi_status[MAX_BUF_SIZE] = {0};
5989 char hostapdconf[MAX_BUF_SIZE] = {0};
5990
5991 wifi_associated_dev3_t *dev_array = NULL;
5992 ULONG wifi_count = 0;
5993
5994 *associated_dev_array = NULL;
5995 *output_array_size = 0;
5996
5997 printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex);
5998 //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI.
5999 {
6000 sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex);
6001
6002 GetInterfaceName(interface_name, hostapdconf);
6003
6004 if(strlen(interface_name) > 1)
6005 {
6006 wifihal_interfacestatus(wifi_status,interface_name);
6007 if(strcmp(wifi_status,"RUNNING") == 0)
6008 {
6009 wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count);
6010
6011 *associated_dev_array = dev_array;
6012 *output_array_size = wifi_count;
6013 }
6014 else
6015 {
6016 *associated_dev_array = NULL;
6017 }
6018 }
6019 }
6020
6021 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6022 return RETURN_OK;
6023}
6024#endif
6025
6026/* getIPAddress function */
6027/**
6028* @description Returning IpAddress of the Matched String
6029*
6030* @param
6031* @str Having MacAddress
6032* @ipaddr Having ipaddr
6033* @return The status of the operation
6034* @retval RETURN_OK if successful
6035* @retval RETURN_ERR if any error is detected
6036*
6037*/
6038
6039INT getIPAddress(char *str,char *ipaddr)
6040{
6041 FILE *fp = NULL;
6042 char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
6043 int LeaseTime = 0,ret = 0;
6044 if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
6045 {
6046 return RETURN_ERR;
6047 }
6048
6049 while ( fgets(buf, sizeof(buf), fp)!= NULL )
6050 {
6051 /*
6052 Sample:sss
6053 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
6054 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
6055 */
6056 ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
6057 &(LeaseTime),
6058 phyAddr,
6059 ipAddr,
6060 hostName
6061 );
6062 if(ret != 4)
6063 continue;
6064 if(strcmp(str,phyAddr) == 0)
6065 strcpy(ipaddr,ipAddr);
6066 }
6067 return RETURN_OK;
6068}
6069
6070/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
6071/**
6072* @description Returning Inactive wireless connected clients informations
6073*
6074* @param
6075* @filename Holding private_wifi 2g/5g content files
6076* @associated_dev_array Having inactiv wireless clients informations
6077* @output_array_size Returning Inactive wireless counts
6078* @return The status of the operation
6079* @retval RETURN_OK if successful
6080* @retval RETURN_ERR if any error is detected
6081*
6082*/
6083
6084INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
6085{
6086 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6087 int count = 0,maccount = 0,i = 0,wificlientindex = 0;
6088 FILE *fp = NULL;
6089 int arr[MACADDRESS_SIZE] = {0};
6090 unsigned char mac[MACADDRESS_SIZE] = {0};
6091 char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
6092 sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename);
6093 fp = popen(buf,"r");
6094 if(fp == NULL)
6095 return RETURN_ERR;
6096 else
6097 {
6098 fgets(path,sizeof(path),fp);
6099 maccount = atoi(path);
6100 }
6101 pclose(fp);
6102 *output_array_size = maccount;
6103 wifi_associated_dev3_t* temp = NULL;
6104 temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
6105 *associated_dev_array = temp;
6106 if(temp == NULL)
6107 {
6108 printf("Error Statement. Insufficient memory \n");
6109 return RETURN_ERR;
6110 }
6111 memset(buf,0,sizeof(buf));
6112 sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
6113 fp = popen(buf,"r");
6114 for(count = 0; count < maccount ; count++)
6115 {
6116 fgets(path,sizeof(path),fp);
6117 for(i = 0; path[i]!='\n';i++)
6118 str[i]=path[i];
6119 str[i]='\0';
6120 getIPAddress(str,ipaddr);
6121 memset(buf,0,sizeof(buf));
6122 if(strlen(ipaddr) > 0)
6123 {
6124 sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr);
6125 if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info
6126 {
6127 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
6128 {
6129 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
6130 {
6131 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
6132
6133 }
6134 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
6135 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]);
6136 }
6137 temp[count].cli_AuthenticationState = 0; //TODO
6138 temp[count].cli_Active = 0; //TODO
6139 temp[count].cli_SignalStrength = 0;
6140 }
6141 else //Active wireless clients info
6142 {
6143 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
6144 {
6145 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
6146 {
6147 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
6148
6149 }
6150 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
6151 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]);
6152 }
6153 temp[count].cli_Active = 1;
6154 }
6155 }
6156 memset(ipaddr,0,sizeof(ipaddr));
6157 }
6158 pclose(fp);
6159 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6160 return RETURN_OK;
6161}
6162//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
6163//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
6164//To get Band Steering Capability
6165INT wifi_getBandSteeringCapability(BOOL *support)
6166{
6167 *support = FALSE;
6168 return RETURN_OK;
6169}
6170
6171
6172//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
6173//To get Band Steering enable status
6174INT wifi_getBandSteeringEnable(BOOL *enable)
6175{
6176 *enable = FALSE;
6177 return RETURN_OK;
6178}
6179
6180//To turn on/off Band steering
6181INT wifi_setBandSteeringEnable(BOOL enable)
6182{
6183 return RETURN_OK;
6184}
6185
6186//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
6187//To get Band Steering AP group
6188INT wifi_getBandSteeringApGroup(char *output_ApGroup)
6189{
6190 if (NULL == output_ApGroup)
6191 return RETURN_ERR;
6192
6193 strcpy(output_ApGroup, "1,2");
6194 return RETURN_OK;
6195}
6196
6197//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
6198//to set and read the band steering BandUtilizationThreshold parameters
6199INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
6200{
6201 return RETURN_ERR;
6202}
6203
6204INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
6205{
6206 return RETURN_ERR;
6207}
6208
6209//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
6210//to set and read the band steering RSSIThreshold parameters
6211INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
6212{
6213 return RETURN_ERR;
6214}
6215
6216INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
6217{
6218 return RETURN_ERR;
6219}
6220
6221
6222//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
6223//to set and read the band steering physical modulation rate threshold parameters
6224INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
6225{
6226 //If chip is not support, return -1
6227 return RETURN_ERR;
6228}
6229
6230INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
6231{
6232 //If chip is not support, return -1
6233 return RETURN_ERR;
6234}
6235
6236//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
6237//to set and read the inactivity time (in seconds) for steering under overload condition
6238INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
6239{
6240 return RETURN_ERR;
6241}
6242
6243INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
6244{
6245 return RETURN_ERR;
6246}
6247
6248//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
6249//to set and read the inactivity time (in seconds) for steering under Idle condition
6250INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
6251{
6252 return RETURN_ERR;
6253}
6254
6255INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
6256{
6257 return RETURN_ERR;
6258}
6259
6260//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
6261//pClientMAC[64]
6262//pSourceSSIDIndex[64]
6263//pDestSSIDIndex[64]
6264//pSteeringReason[256]
6265INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
6266{
6267 //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
6268 *pSteeringTime=time(NULL);
6269 *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose)
6270 return RETURN_OK;
6271}
6272
6273INT wifi_ifConfigDown(INT apIndex)
6274{
6275 INT status = RETURN_OK;
6276 char cmd[64];
6277
6278 snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex);
6279 printf("%s: %s\n", __func__, cmd);
6280 system(cmd);
6281
6282 return status;
6283}
6284
6285INT wifi_ifConfigUp(INT apIndex)
6286{
6287 char cmd[128];
6288 char buf[1024];
6289
6290 snprintf(cmd, sizeof(cmd), "ifconfig %s%d up 2>/dev/null", AP_PREFIX, apIndex);
6291 _syscmd(cmd, buf, sizeof(buf));
6292 return 0;
6293}
6294
6295//>> Deprecated. Replace with wifi_applyRadioSettings
6296INT wifi_pushBridgeInfo(INT apIndex)
6297{
6298 char ip[32];
6299 char subnet[32];
6300 char bridge[32];
6301 int vlanId;
6302 char cmd[128];
6303 char buf[1024];
6304
6305 wifi_getApBridgeInfo(apIndex,bridge,ip,subnet);
6306 wifi_getApVlanID(apIndex,&vlanId);
6307
6308 snprintf(cmd, sizeof(cmd), "cfgVlan %s%d %s %d %s ", AP_PREFIX, apIndex, bridge, vlanId, ip);
6309 _syscmd(cmd,buf, sizeof(buf));
6310
6311 return 0;
6312}
6313
6314INT wifi_pushChannel(INT radioIndex, UINT channel)
6315{
6316 char cmd[128];
6317 char buf[1024];
6318 int apIndex;
6319
6320 apIndex=(radioIndex==0)?0:1;
6321 snprintf(cmd, sizeof(cmd), "iwconfig %s%d freq %d",AP_PREFIX, apIndex,channel);
6322 _syscmd(cmd,buf, sizeof(buf));
6323
6324 return 0;
6325}
6326
6327INT wifi_pushChannelMode(INT radioIndex)
6328{
6329 //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
6330 return RETURN_ERR;
6331}
6332
6333INT wifi_pushDefaultValues(INT radioIndex)
6334{
6335 //Apply Comcast specified default radio settings instantly
6336 //AMPDU=1
6337 //AMPDUFrames=32
6338 //AMPDULim=50000
6339 //txqueuelen=1000
6340
6341 return RETURN_ERR;
6342}
6343
6344INT wifi_pushTxChainMask(INT radioIndex)
6345{
6346 //Apply default TxChainMask instantly
6347 return RETURN_ERR;
6348}
6349
6350INT wifi_pushRxChainMask(INT radioIndex)
6351{
6352 //Apply default RxChainMask instantly
6353 return RETURN_ERR;
6354}
6355
6356INT wifi_pushSSID(INT apIndex, CHAR *ssid)
6357{
6358 INT status;
6359
6360 status = wifi_setSSIDName(apIndex,ssid);
6361 wifi_setApEnable(apIndex,FALSE);
6362 wifi_setApEnable(apIndex,TRUE);
6363
6364 return status;
6365}
6366
6367INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
6368{
6369 //Apply default Ssid Advertisement instantly
6370 return RETURN_ERR;
6371}
6372
6373INT wifi_getRadioUpTime(INT radioIndex, ULONG *output)
6374{
6375 INT status = RETURN_ERR;
6376 *output = 0;
6377 return RETURN_ERR;
6378}
6379
6380INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
6381{
6382 return RETURN_OK;
6383}
6384
6385INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
6386{
6387 return RETURN_OK;
6388}
6389
6390//To-do
6391INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
6392{
developereb199ae2022-09-13 14:04:27 +08006393 char output[16]={'\0'};
6394 char config_file[MAX_BUF_SIZE] = {0};
6395
6396 if (!output_string)
6397 return RETURN_ERR;
6398
6399 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6400 wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
6401
6402 if (strlen(output) == 0)
6403 snprintf(output_string, 64, "Disabled");
6404 else if (strncmp(output, "0", 1) == 0)
6405 snprintf(output_string, 64, "Disabled");
6406 else if (strncmp(output, "1", 1) == 0)
6407 snprintf(output_string, 64, "Optional");
6408 else if (strncmp(output, "2", 1) == 0)
6409 snprintf(output_string, 64, "Required");
6410 else {
6411 wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output);
6412 return RETURN_ERR;
6413 }
6414
6415 wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output);
developer06a01d92022-09-07 16:32:39 +08006416 return RETURN_OK;
6417}
6418INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
6419{
developereb199ae2022-09-13 14:04:27 +08006420 char str[MAX_BUF_SIZE]={'\0'};
6421 char cmd[MAX_CMD_SIZE]={'\0'};
6422 struct params params;
6423 char config_file[MAX_BUF_SIZE] = {0};
6424
6425 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6426 if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
6427 return RETURN_ERR;
6428
6429 params.name = "ieee80211w";
6430 if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0)
6431 params.value = "0";
6432 else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
6433 params.value = "1";
6434 else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
6435 params.value = "2";
6436 else{
6437 wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__);
6438 return RETURN_ERR;
6439 }
6440 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
6441 wifi_hostapdWrite(config_file, &params, 1);
6442 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
developer06a01d92022-09-07 16:32:39 +08006443 return RETURN_OK;
6444}
6445INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
6446{
6447 char output[16]={'\0'};
6448 char config_file[MAX_BUF_SIZE] = {0};
6449
6450 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6451 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex);
6452 wifi_hostapdRead(config_file,"channel",output,sizeof(output));
6453
6454 *output_bool = (strncmp(output, "0", 1)==0) ? TRUE : FALSE;
6455 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
6456
6457 return RETURN_OK;
6458}
6459
6460INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
6461{
6462 return RETURN_OK;
6463}
6464
6465INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
6466{
6467 return RETURN_OK;
6468}
6469
6470INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
6471{
6472 return RETURN_OK;
6473}
6474
6475INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
6476{
6477 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6478 char config_file[MAX_BUF_SIZE] = {0};
6479
6480 if (NULL == output)
6481 return RETURN_ERR;
6482 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
6483 wifi_hostapdRead(config_file,"hw_mode",output,64);
6484
6485 if(strcmp(output,"b")==0)
6486 sprintf(output, "%s", "1,2,5.5,11");
6487 else if (strcmp(output,"a")==0)
6488 sprintf(output, "%s", "6,9,11,12,18,24,36,48,54");
6489 else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0))
6490 sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
6491
6492 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6493 return RETURN_OK;
6494}
6495
6496INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
6497{
6498 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6499 char *temp;
6500 char temp_output[128];
6501 char temp_TransmitRates[128];
6502 char config_file[MAX_BUF_SIZE] = {0};
6503
6504 if (NULL == output)
6505 return RETURN_ERR;
6506
6507 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
6508 wifi_hostapdRead(config_file,"supported_rates",output,64);
6509
6510 strcpy(temp_TransmitRates,output);
6511 strcpy(temp_output,"");
6512 temp = strtok(temp_TransmitRates," ");
6513 while(temp!=NULL)
6514 {
6515 temp[strlen(temp)-1]=0;
6516 if((temp[0]=='5') && (temp[1]=='\0'))
6517 {
6518 temp="5.5";
6519 }
6520 strcat(temp_output,temp);
6521 temp = strtok(NULL," ");
6522 if(temp!=NULL)
6523 {
6524 strcat(temp_output,",");
6525 }
6526 }
6527 strcpy(output,temp_output);
6528 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6529
6530 return RETURN_OK;
6531}
6532
6533INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
6534{
6535 return RETURN_OK;
6536}
6537
6538
6539INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
6540{
6541 int i=0;
6542 char *temp;
6543 char temp1[128];
6544 char temp_output[128];
6545 char temp_TransmitRates[128];
6546 struct params params={'\0'};
6547 char config_file[MAX_BUF_SIZE] = {0};
6548
6549 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6550 if(NULL == output)
6551 return RETURN_ERR;
6552
6553 strcpy(temp_TransmitRates,output);
6554
6555 for(i=0;i<strlen(temp_TransmitRates);i++)
6556 {
6557 if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) | (temp_TransmitRates[i]==' ') | (temp_TransmitRates[i]=='.'))
6558 {
6559 continue;
6560 }
6561 else
6562 {
6563 return RETURN_ERR;
6564 }
6565 }
6566 strcpy(temp_output,"");
6567 temp = strtok(temp_TransmitRates," ");
6568 while(temp!=NULL)
6569 {
6570 strcpy(temp1,temp);
6571 if(wlanIndex==1)
6572 {
6573 if((strcmp(temp,"1")==0) | (strcmp(temp,"2")==0) | (strcmp(temp,"5.5")==0))
6574 {
6575 return RETURN_ERR;
6576 }
6577 }
6578
6579 if(strcmp(temp,"5.5")==0)
6580 {
6581 strcpy(temp1,"55");
6582 }
6583 else
6584 {
6585 strcat(temp1,"0");
6586 }
6587 strcat(temp_output,temp1);
6588 temp = strtok(NULL," ");
6589 if(temp!=NULL)
6590 {
6591 strcat(temp_output," ");
6592 }
6593 }
6594 strcpy(output,temp_output);
6595
6596
6597 params.name = "supported_rates";
6598 params.value = output;
6599
6600 wifi_dbg_printf("\n%s:",__func__);
6601 wifi_dbg_printf("params.value=%s\n",params.value);
6602 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex);
6603 wifi_hostapdWrite(config_file,&params,1);
6604 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6605
6606 return RETURN_OK;
6607}
6608
6609
6610static char *sncopy(char *dst, int dst_sz, const char *src)
6611{
6612 if (src && dst && dst_sz > 0) {
6613 strncpy(dst, src, dst_sz);
6614 dst[dst_sz - 1] = '\0';
6615 }
6616 return dst;
6617}
6618
6619static int util_get_sec_chan_offset(int channel, const char* ht_mode)
6620{
6621 if (0 == strcmp(ht_mode, "HT40") ||
6622 0 == strcmp(ht_mode, "HT80") ||
6623 0 == strcmp(ht_mode, "HT160")) {
6624 switch (channel) {
6625 case 1 ... 7:
6626 case 36:
6627 case 44:
6628 case 52:
6629 case 60:
6630 case 100:
6631 case 108:
6632 case 116:
6633 case 124:
6634 case 132:
6635 case 140:
6636 case 149:
6637 case 157:
6638 return 1;
6639 case 8 ... 13:
6640 case 40:
6641 case 48:
6642 case 56:
6643 case 64:
6644 case 104:
6645 case 112:
6646 case 120:
6647 case 128:
6648 case 136:
6649 case 144:
6650 case 153:
6651 case 161:
6652 return -1;
6653 default:
6654 return -EINVAL;
6655 }
6656 }
6657
6658 return -EINVAL;
6659}
6660
6661static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
6662{
6663 if (NULL == hw_mode) return;
6664
6665 if (0 == strcmp(hw_mode, "ac"))
6666 sncopy(bw_mode, bw_mode_len, "ht vht");
6667
6668 if (0 == strcmp(hw_mode, "n"))
6669 sncopy(bw_mode, bw_mode_len, "ht");
6670
6671 return;
6672}
6673
6674static int util_chan_to_freq(int chan)
6675{
6676 if (chan == 14)
6677 return 2484;
6678 else if (chan < 14)
6679 return 2407 + chan * 5;
6680 else if (chan >= 182 && chan <= 196)
6681 return 4000 + chan * 5;
6682 else
6683 return 5000 + chan * 5;
6684 return 0;
6685}
6686
6687const int *util_unii_5g_chan2list(int chan, int width)
6688{
6689 static const int lists[] = {
6690 // <width>, <chan1>, <chan2>..., 0,
6691 20, 36, 0,
6692 20, 40, 0,
6693 20, 44, 0,
6694 20, 48, 0,
6695 20, 52, 0,
6696 20, 56, 0,
6697 20, 60, 0,
6698 20, 64, 0,
6699 20, 100, 0,
6700 20, 104, 0,
6701 20, 108, 0,
6702 20, 112, 0,
6703 20, 116, 0,
6704 20, 120, 0,
6705 20, 124, 0,
6706 20, 128, 0,
6707 20, 132, 0,
6708 20, 136, 0,
6709 20, 140, 0,
6710 20, 144, 0,
6711 20, 149, 0,
6712 20, 153, 0,
6713 20, 157, 0,
6714 20, 161, 0,
6715 20, 165, 0,
6716 40, 36, 40, 0,
6717 40, 44, 48, 0,
6718 40, 52, 56, 0,
6719 40, 60, 64, 0,
6720 40, 100, 104, 0,
6721 40, 108, 112, 0,
6722 40, 116, 120, 0,
6723 40, 124, 128, 0,
6724 40, 132, 136, 0,
6725 40, 140, 144, 0,
6726 40, 149, 153, 0,
6727 40, 157, 161, 0,
6728 80, 36, 40, 44, 48, 0,
6729 80, 52, 56, 60, 64, 0,
6730 80, 100, 104, 108, 112, 0,
6731 80, 116, 120, 124, 128, 0,
6732 80, 132, 136, 140, 144, 0,
6733 80, 149, 153, 157, 161, 0,
6734 160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
6735 160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
6736 -1 // final delimiter
6737 };
6738 const int *start;
6739 const int *p;
6740
6741 for (p = lists; *p != -1; p++) {
6742 if (*p == width) {
6743 for (start = ++p; *p != 0; p++) {
6744 if (*p == chan)
6745 return start;
6746 }
6747 }
6748 // move to the end of channel list of given width
6749 while (*p != 0) {
6750 p++;
6751 }
6752 }
6753
6754 return NULL;
6755}
6756
6757static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
6758{
6759 if (NULL == ht_mode)
6760 return 0;
6761
6762 const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
6763 const int *chans = util_unii_5g_chan2list(channel, width);
6764 int sum = 0;
6765 int cnt = 0;
6766
6767 if (NULL == chans)
6768 return 0;
6769
6770 while (*chans) {
6771 sum += *chans;
6772 cnt++;
6773 chans++;
6774 }
6775 return sum / cnt;
6776}
6777
6778static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
6779{
6780 BOOL onlyG, onlyN, onlyA;
6781 CHAR tmp[64];
6782 int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
6783 if (ret == RETURN_OK) {
6784 sncopy(hw_mode, hw_mode_size, tmp);
6785 }
6786 return ret;
6787}
6788
6789INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
6790{
6791 // Sample commands:
6792 // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
6793 // hostapd_cli -i wifi0 chan_switch 30 2437
6794 char cmd[MAX_CMD_SIZE] = {0};
6795 char buf[MAX_BUF_SIZE] = {0};
6796 int freq = 0, ret = 0;
6797 char center_freq1_str[32] = ""; // center_freq1=%d
6798 char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
6799 char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
6800 char hw_mode[16] = ""; // n|ac
6801 char bw_mode[16] = ""; // ht|ht vht
6802 char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
6803 int sec_chan_offset;
6804 int width;
6805
6806 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6807
6808 freq = util_chan_to_freq(channel);
6809
6810 // Get radio mode HT20|HT40|HT80 etc.
6811 width = channel_width_MHz > 20 ? channel_width_MHz : 20;
6812 snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
6813 // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
6814 sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
6815 if (sec_chan_offset != -EINVAL)
6816 snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
6817
6818
6819 // Provide bandwith if specified
6820 if (channel_width_MHz > 20) {
6821 // Select bandwidth mode from hardware n --> ht | ac --> ht vht
6822 util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
6823 util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
6824
6825 snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
6826 }
6827
6828 int center_chan = 0;
6829 if (channel_width_MHz > 20) {
6830 center_chan = util_unii_5g_centerfreq(ht_mode, channel);
6831 if (center_chan > 0) {
6832 int center_freq1 = util_chan_to_freq(center_chan);
6833 if (center_freq1)
6834 snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
6835 }
6836 }
6837
6838 {
6839 // Only the first AP, other are hanging on the same radio
6840 int apIndex = radioIndex;
6841 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d chan_switch %d %d %s %s %s",
6842 AP_PREFIX, apIndex, csa_beacon_count, freq,
6843 sec_chan_offset_str, center_freq1_str, opt_chan_info_str);
6844 wifi_dbg_printf("execute: '%s'\n", cmd);
6845 ret = _syscmd(cmd, buf, sizeof(buf));
6846 }
6847
6848 wifi_setRadioChannel(radioIndex, channel);
6849
6850 char *ext_str = "None";
6851 if (sec_chan_offset == 1) ext_str = "Above";
6852 else if (sec_chan_offset == -1) ext_str = "Below";
6853 wifi_setRadioExtChannel(radioIndex, ext_str);
6854
6855 wifi_setRadioCenterChannel(radioIndex, center_chan);
6856
6857 char mhz_str[16];
6858 snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
6859 wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
6860
6861 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
6862
6863 return RETURN_OK;
6864}
6865
6866INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
6867{
6868 char cmd[1024] = {0};
6869 char buf[1024] = {0};
6870 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
6871 wifi_neighbor_ap2_t *scan_array = NULL;
6872 int scan_count=0;
6873 int i =0;
6874 int freq=0;
6875 size_t len=0;
6876 FILE *f = NULL;
6877 ssize_t read = 0;
6878 char *line =NULL;
6879 char radio_ifname[64];
6880 char secondary_chan[64];
6881 int vht_channel_width = 0;
6882
6883 if(wifi_getRadioIfName(radio_index,radio_ifname)!=RETURN_OK)
6884 return RETURN_ERR;
6885
6886 /* sched_start is not supported on open source ath9k ath10k firmware
6887 * Using active scan as a workaround */
6888 sprintf(cmd,"iw dev %s scan |grep '^BSS\\|SSID:\\|freq:\\|signal:\\|HT operation:\\|secondary channel offset:\\|* channel width:'", radio_ifname);
6889 if((f = popen(cmd, "r")) == NULL) {
6890 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
6891 return RETURN_ERR;
6892 }
6893 read = getline(&line, &len, f);
6894 while (read != -1) {
6895 if(strncmp(line,"BSS",3) == 0) {
6896 i = scan_count;
6897 scan_count++;
6898 scan_array = realloc(scan_array,sizeof(wifi_neighbor_ap2_t)*scan_count);
6899 memset(&(scan_array[i]),0, sizeof(wifi_neighbor_ap2_t));
6900 sscanf(line,"BSS %17s", scan_array[i].ap_BSSID);
6901
6902 read = getline(&line, &len, f);
6903 sscanf(line," freq: %d", &freq);
6904 scan_array[i].ap_Channel = ieee80211_frequency_to_channel(freq);
6905
6906 read = getline(&line, &len, f);
6907 sscanf(line," signal: %d", &(scan_array[i].ap_SignalStrength));
6908
6909 read = getline(&line, &len, f);
6910 sscanf(line," SSID: %s", scan_array[i].ap_SSID);
6911 wifi_dbg_printf("%s:Discovered BSS %s, %d, %d , %s\n", __func__, scan_array[i].ap_BSSID, scan_array[i].ap_Channel,scan_array[i].ap_SignalStrength, scan_array[i].ap_SSID);
6912 read = getline(&line, &len, f);
6913 if(strncmp(line,"BSS",3)==0) {
6914 // No HT and no VHT => 20Mhz
6915 snprintf(scan_array[i].ap_OperatingChannelBandwidth, sizeof(scan_array[i].ap_OperatingChannelBandwidth), "11%s", radio_index%1 ? "A": "G");
6916 wifi_dbg_printf("%s: ap_OperatingChannelBandwidth = '%s'\n", __func__, scan_array[i].ap_OperatingChannelBandwidth);
6917 continue;
6918 }
6919 if(strncmp(line," HT operation:",14)!= 0) {
6920 wifi_dbg_printf("HT output parsing error (%s)\n", line);
6921 goto output_error;
6922 }
6923
6924 read = getline(&line, &len, f);
6925 sscanf(line," * secondary channel offset: %s", &secondary_chan);
6926
6927 if(!strcmp(secondary_chan, "no")) {
6928 //20Mhz
6929 snprintf(scan_array[i].ap_OperatingChannelBandwidth, sizeof(scan_array[i].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
6930 }
6931
6932 if(!strcmp(secondary_chan, "above")) {
6933 //40Mhz +
6934 snprintf(scan_array[i].ap_OperatingChannelBandwidth, sizeof(scan_array[i].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
6935 }
6936
6937 if(!strcmp(secondary_chan, "below")) {
6938 //40Mhz -
6939 snprintf(scan_array[i].ap_OperatingChannelBandwidth, sizeof(scan_array[i].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
6940 }
6941
6942
6943 read = getline(&line, &len, f);
6944 if(strncmp(line," VHT operation:",15) !=0) {
6945 wifi_dbg_printf("%s: ap_OperatingChannelBandwidth = '%s'\n", __func__, scan_array[i].ap_OperatingChannelBandwidth);
6946 // No VHT
6947 continue;
6948 }
6949 read = getline(&line, &len, f);
6950 sscanf(line," * channel width: %d", &vht_channel_width);
6951 if(vht_channel_width == 1) {
6952 snprintf(scan_array[i].ap_OperatingChannelBandwidth, sizeof(scan_array[i].ap_OperatingChannelBandwidth), "11AC_VHT80");
6953 } else {
6954 snprintf(scan_array[i].ap_OperatingChannelBandwidth, sizeof(scan_array[i].ap_OperatingChannelBandwidth), "11AC_VHT40");
6955 }
6956
6957 }
6958 wifi_dbg_printf("%s: ap_OperatingChannelBandwidth = '%s'\n", __func__, scan_array[i].ap_OperatingChannelBandwidth);
6959 read = getline(&line, &len, f);
6960 }
6961 wifi_dbg_printf("%s:Counted BSS: %d\n",__func__, scan_count);
6962 *output_array_size = scan_count;
6963 *neighbor_ap_array = scan_array;
6964 free(line);
6965 pclose(f);
6966 return RETURN_OK;
6967
6968output_error:
6969 pclose(f);
6970 free(line);
6971 free(scan_array);
6972 return RETURN_ERR;
6973}
6974INT wifi_getApAssociatedDeviceStats(
6975 INT apIndex,
6976 mac_address_t *clientMacAddress,
6977 wifi_associated_dev_stats_t *associated_dev_stats,
6978 u64 *handle)
6979{
6980 wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
6981 char interface_name[50] = {0};
6982 char cmd[1024] = {0};
6983 char mac_str[18] = {0};
6984 char *key = NULL;
6985 char *val = NULL;
6986 FILE *f = NULL;
6987 char *line = NULL;
6988 size_t len = 0;
6989 ssize_t read = 0;
6990
6991 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
6992 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
6993 return RETURN_ERR;
6994 }
6995
6996 sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]);
6997 sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
6998 if((f = popen(cmd, "r")) == NULL) {
6999 wifi_dbg_printf("%s: popen %s error\n", __func__, cmd);
7000 return RETURN_ERR;
7001 }
7002
7003 while ((read = getline(&line, &len, f)) != -1) {
7004 key = strtok(line,":");
7005 val = strtok(NULL,":");
7006
7007 if(!strncmp(key,"rx bytes",8))
7008 sscanf(val, "%llu", &dev_stats->cli_rx_bytes);
7009 if(!strncmp(key,"tx bytes",8))
7010 sscanf(val, "%llu", &dev_stats->cli_tx_bytes);
7011 if(!strncmp(key,"rx packets",10))
7012 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
7013 if(!strncmp(key,"tx packets",10))
7014 sscanf(val, "%llu", &dev_stats->cli_tx_frames);
7015 if(!strncmp(key,"tx retries",10))
7016 sscanf(val, "%llu", &dev_stats->cli_tx_retries);
7017 if(!strncmp(key,"tx failed",9))
7018 sscanf(val, "%llu", &dev_stats->cli_tx_errors);
7019 if(!strncmp(key,"rx drop misc",13))
7020 sscanf(val, "%llu", &dev_stats->cli_rx_errors);
7021 if(!strncmp(key,"rx bitrate",10)) {
7022 val = strtok(val, " ");
7023 sscanf(val, "%lf", &dev_stats->cli_rx_rate);
7024 }
7025 if(!strncmp(key,"tx bitrate",10)) {
7026 val = strtok(val, " ");
7027 sscanf(val, "%lf", &dev_stats->cli_tx_rate);
7028 }
7029 }
7030 free(line);
7031 pclose(f);
7032 return RETURN_OK;
7033}
7034
7035INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
7036{
7037 char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0};
7038
7039 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7040 if (NULL == output_string)
7041 return RETURN_ERR;
7042
7043 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\n'", AP_PREFIX,apIndex);
7044 _syscmd(cmd, buf, sizeof(buf));
7045
7046 //size of SSID name restricted to value less than 32 bytes
7047 snprintf(output_string, 32, "%s", buf);
7048 WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
7049
7050 return RETURN_OK;
7051}
7052
7053INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
7054{
7055 //char cmd[MAX_CMD_SIZE] = {0};
7056 char config_file[MAX_BUF_SIZE] = {0};
7057 char buf[32] = {0};
7058
7059 if (!output_filterMode)
7060 return RETURN_ERR;
7061
7062 //snprintf(cmd, sizeof(cmd), "syscfg get %dblockall", apIndex);
7063 //_syscmd(cmd, buf, sizeof(buf));
7064 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
7065 wifi_hostapdRead(config_file, "macaddr_acl", buf, sizeof(buf));
developer10adcc12022-09-13 14:39:17 +08007066 if(strlen(buf) == 0) {
7067 *output_filterMode = 0;
7068 }
7069 else {
7070 int macaddr_acl_mode = strtol(buf, NULL, 10);
7071 if (macaddr_acl_mode == 1) {
7072 *output_filterMode = 1;
7073 } else if (macaddr_acl_mode == 0) {
7074 wifi_hostapdRead(config_file, "deny_mac_file", buf, sizeof(buf));
7075 if (strlen(buf) == 0) {
7076 *output_filterMode = 0;
7077 } else {
7078 *output_filterMode = 2;
7079 }
7080 } else {
7081 return RETURN_ERR;
7082 }
7083 }
developer06a01d92022-09-07 16:32:39 +08007084
7085 return RETURN_OK;
7086}
7087
7088INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
7089{
7090 FILE *fp = NULL;
7091 char str[MAX_BUF_SIZE] = {0};
7092 int wificlientindex = 0 ;
7093 int count = 0;
7094 int signalstrength = 0;
7095 int arr[MACADDRESS_SIZE] = {0};
7096 unsigned char mac[MACADDRESS_SIZE] = {0};
7097 UINT wifi_count = 0;
7098 char virtual_interface_name[MAX_BUF_SIZE] = {0};
7099 char pipeCmd[MAX_CMD_SIZE] = {0};
7100
7101 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7102 *output_array_size = 0;
7103 *associated_dev_array = NULL;
7104 char interface_name[50] = {0};
7105
7106 if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
7107 wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__);
7108 return RETURN_ERR;
7109 }
7110
7111 sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
7112 fp = popen(pipeCmd, "r");
7113 if (fp == NULL)
7114 {
7115 printf("Failed to run command inside function %s\n",__FUNCTION__ );
7116 return RETURN_ERR;
7117 }
7118
7119 /* Read the output a line at a time - output it. */
7120 fgets(str, sizeof(str)-1, fp);
7121 wifi_count = (unsigned int) atoi ( str );
7122 *output_array_size = wifi_count;
7123 wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex);
7124 pclose(fp);
7125
7126 if(wifi_count == 0)
7127 {
7128 return RETURN_OK;
7129 }
7130 else
7131 {
7132 wifi_associated_dev2_t* temp = NULL;
7133 temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
7134 *associated_dev_array = temp;
7135 if(temp == NULL)
7136 {
7137 printf("Error Statement. Insufficient memory \n");
7138 return RETURN_ERR;
7139 }
7140
7141 snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
7142 system(pipeCmd);
7143
7144 fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
7145 if(fp == NULL)
7146 {
7147 printf("/tmp/AssociatedDevice_Stats.txt not exists \n");
7148 return RETURN_ERR;
7149 }
7150 fclose(fp);
7151
7152 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2", interface_name);
7153 fp = popen(pipeCmd, "r");
7154 if(fp)
7155 {
7156 for(count =0 ; count < wifi_count; count++)
7157 {
7158 fgets(str, MAX_BUF_SIZE, fp);
7159 if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
7160 {
7161 for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
7162 {
7163 mac[wificlientindex] = (unsigned char) arr[wificlientindex];
7164
7165 }
7166 memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
7167 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]);
7168 }
7169 temp[count].cli_AuthenticationState = 1; //TODO
7170 temp[count].cli_Active = 1; //TODO
7171 }
7172 pclose(fp);
7173 }
7174
7175 //Updating RSSI per client
7176 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt", interface_name);
7177 fp = popen(pipeCmd, "r");
7178 if(fp)
7179 {
7180 pclose(fp);
7181 }
7182 fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r");
7183 if(fp)
7184 {
7185 for(count =0 ; count < wifi_count ;count++)
7186 {
7187 fgets(str, MAX_BUF_SIZE, fp);
7188 signalstrength = atoi(str);
7189 temp[count].cli_RSSI = signalstrength;
7190 }
7191 pclose(fp);
7192 }
7193
7194
7195 //LastDataDownlinkRate
7196 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt", interface_name);
7197 fp = popen(pipeCmd, "r");
7198 if (fp)
7199 {
7200 pclose(fp);
7201 }
7202 fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r");
7203 if (fp)
7204 {
7205 for (count = 0; count < wifi_count; count++)
7206 {
7207 fgets(str, MAX_BUF_SIZE, fp);
7208 temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10);
7209 temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
7210 }
7211 pclose(fp);
7212 }
7213
7214 //LastDataUplinkRate
7215 sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt", interface_name);
7216 fp = popen(pipeCmd, "r");
7217 if (fp)
7218 {
7219 pclose(fp);
7220 }
7221 fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r");
7222 if (fp)
7223 {
7224 for (count = 0; count < wifi_count; count++)
7225 {
7226 fgets(str, MAX_BUF_SIZE, fp);
7227 temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10);
7228 temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
7229 }
7230 pclose(fp);
7231 }
7232 }
7233 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7234 return RETURN_OK;
7235
7236}
7237
7238INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
7239{
7240#if 0
7241 /*char buf[1024] = {0};
7242 sprintf(cmd, "ifconfig %s%d ", AP_PREFIX, ssidIndex);
7243 _syscmd(cmd, buf, sizeof(buf));*/
7244
7245 output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters.
7246 output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters.
7247 output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface.
7248 output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface.
7249
7250 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.
7251 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].
7252 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].
7253 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].
7254 output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012].
7255 output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac.
7256
7257 output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors.
7258 output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
7259 output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol.
7260 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.
7261 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.
7262 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.
7263 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.
7264 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.
7265 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.
7266 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.
7267 output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol.
7268#endif
7269
7270 FILE *fp = NULL;
7271 char HConf_file[MAX_BUF_SIZE] = {'\0'};
7272 char interface_name[50] = {0};
7273 char pipeCmd[MAX_CMD_SIZE] = {0};
7274 char str[MAX_BUF_SIZE] = {0};
7275 wifi_ssidTrafficStats2_t *out = output_struct;
7276
7277 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7278 if (!output_struct)
7279 return RETURN_ERR;
7280
7281 if (ssidIndex >= 4)
7282 return RETURN_ERR;
7283
7284 sprintf(HConf_file,"%s%d%s","/nvram/hostapd",ssidIndex,".conf");
7285 GetInterfaceName(interface_name,HConf_file);
7286 sprintf(pipeCmd,"%s%s%s","cat /proc/net/dev | grep ",interface_name," | tr -s ' ' | cut -d ' ' -f11 | tr -d '\n'");
7287 fp = popen(pipeCmd, "r");
7288 fgets(str, MAX_BUF_SIZE,fp);
7289 out->ssid_BytesSent = atol(str);
7290 pclose(fp);
7291
7292 sprintf(pipeCmd,"%s%s%s","cat /proc/net/dev | grep ",interface_name," | tr -s ' ' | cut -d ' ' -f3 | tr -d '\n'");
7293 fp = popen(pipeCmd, "r");
7294 fgets(str, MAX_BUF_SIZE,fp);
7295 out->ssid_BytesReceived = atol(str);
7296 pclose(fp);
7297
7298 sprintf(pipeCmd,"%s%s%s","cat /proc/net/dev | grep ",interface_name," | tr -s ' ' | cut -d ' ' -f12 | tr -d '\n'");
7299 fp = popen(pipeCmd, "r");
7300 fgets(str, MAX_BUF_SIZE,fp);
7301 out->ssid_PacketsSent = atol(str);
7302 pclose(fp);
7303
7304 sprintf(pipeCmd,"%s%s%s","cat /proc/net/dev | grep ",interface_name," | tr -s ' ' | cut -d ' ' -f4 | tr -d '\n'");
7305 fp = popen(pipeCmd, "r");
7306 fgets(str, MAX_BUF_SIZE,fp);
7307 out->ssid_PacketsReceived = atol(str);
7308 pclose(fp);
7309 /*
7310 //TODO:
7311 out->ssid_UnicastPacketsSent = uni->ims_tx_data_packets;
7312 out->ssid_UnicastPacketsReceived = uni->ims_rx_data_packets;
7313 out->ssid_MulticastPacketsSent = multi->ims_tx_data_packets - multi->ims_tx_bcast_data_packets;
7314 out->ssid_MulticastPacketsReceived = multi->ims_rx_data_packets - multi->ims_rx_bcast_data_packets;
7315 out->ssid_BroadcastPacketsSent = multi->ims_tx_bcast_data_packets;
7316 out->ssid_BroadcastPacketsRecevied = multi->ims_rx_bcast_data_packets;
7317 */
7318 return RETURN_OK;
7319}
7320
7321//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).
7322INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
7323{
7324 char output_val[16]={'\0'};
7325 char config_file[MAX_BUF_SIZE] = {0};
7326
7327 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7328 if (!output)
7329 return RETURN_ERR;
7330 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7331 wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val));
7332
7333 if( strcmp(output_val,"1") == 0 )
7334 *output = TRUE;
7335 else
7336 *output = FALSE;
7337 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7338
7339 return RETURN_OK;
7340}
7341
7342INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
7343{
7344 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
7345 char str[MAX_BUF_SIZE]={'\0'};
7346 char string[MAX_BUF_SIZE]={'\0'};
7347 char cmd[MAX_CMD_SIZE]={'\0'};
7348 char *ch;
7349 char config_file[MAX_BUF_SIZE] = {0};
7350 struct params params;
7351
7352 if(enable == TRUE)
7353 strcpy(string,"1");
7354 else
7355 strcpy(string,"0");
7356
7357 params.name = "ap_isolate";
7358 params.value = string;
7359
7360 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7361 wifi_hostapdWrite(config_file,&params,1);
7362 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
7363
7364 return RETURN_OK;
7365}
7366
7367INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
7368{
7369 if (NULL == output_dBm)
7370 return RETURN_ERR;
7371
7372 *output_dBm = 0;
7373 return RETURN_OK;
7374}
7375
7376INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
7377{
7378 return RETURN_OK;
7379}
7380INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
7381{
7382 return RETURN_OK;
7383}
7384INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
7385{
7386 return RETURN_OK;
7387}
7388INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
7389{
7390 return RETURN_OK;
7391}
7392INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
7393{
7394 return RETURN_OK;
7395}
7396INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
7397{
7398 char config_file[MAX_BUF_SIZE] = {0};
7399 struct params list;
7400
7401 list.name = "bss_transition";
7402 list.value = activate?"1":"0";
7403 snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
7404 wifi_hostapdWrite(config_file, &list, 1);
7405
7406 return RETURN_OK;
7407}
7408wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
7409
7410void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
7411{
7412 return;
7413}
7414
7415INT wifi_setApCsaDeauth(INT apIndex, INT mode)
7416{
7417 // TODO Implement me!
7418 return RETURN_OK;
7419}
7420
7421INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
7422{
7423 // TODO Implement me!
7424 return RETURN_OK;
7425}
7426
7427INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
7428{
7429 // TODO Implement me!
7430 //Apply wifi_pushRadioChannel() instantly
7431 return RETURN_ERR;
7432}
7433
7434INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
7435{
7436 // TODO Implement me!
7437 return RETURN_OK;
7438}
7439
7440#ifdef HAL_NETLINK_IMPL
7441static int tidStats_callback(struct nl_msg *msg, void *arg) {
7442 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7443 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7444 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
7445 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
7446 int rem , tid_index = 0;
7447
7448 wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
7449 wifi_associated_dev_tid_entry_t *stats_entry;
7450
7451 static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
7452 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
7453 };
7454 static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
7455 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
7456 };
7457
7458 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
7459 genlmsg_attrlen(gnlh, 0), NULL);
7460
7461
7462 if (!tb[NL80211_ATTR_STA_INFO]) {
7463 fprintf(stderr, "station stats missing!\n");
7464 return NL_SKIP;
7465 }
7466
7467 if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
7468 tb[NL80211_ATTR_STA_INFO],
7469 stats_policy)) {
7470 fprintf(stderr, "failed to parse nested attributes!\n");
7471 return NL_SKIP;
7472 }
7473
7474 nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
7475 {
7476 stats_entry = &out->tid_array[tid_index];
7477
7478 stats_entry->tid = tid_index;
7479 stats_entry->ac = _tid_ac_index_get[tid_index];
7480
7481 if(sinfo[NL80211_STA_INFO_TID_STATS])
7482 {
7483 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
7484 printf("failed to parse nested stats attributes!");
7485 return NL_SKIP;
7486 }
7487 }
7488 if(stats_info[NL80211_TID_STATS_TX_MSDU])
7489 stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
7490
7491 if(tid_index < (PS_MAX_TID - 1))
7492 tid_index++;
7493 }
7494 //ToDo: sum_time_ms, ewma_time_ms
7495 return NL_SKIP;
7496}
7497#endif
7498
7499INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle)
7500{
7501#ifdef HAL_NETLINK_IMPL
7502 Netlink nl;
7503 char if_name[10];
7504
7505 snprintf(if_name, sizeof(if_name), "%s%d", AP_PREFIX, radioIndex);
7506
7507 nl.id = initSock80211(&nl);
7508
7509 if (nl.id < 0) {
7510 fprintf(stderr, "Error initializing netlink \n");
7511 return -1;
7512 }
7513
7514 struct nl_msg* msg = nlmsg_alloc();
7515
7516 if (!msg) {
7517 fprintf(stderr, "Failed to allocate netlink message.\n");
7518 nlfree(&nl);
7519 return -2;
7520 }
7521
7522 genlmsg_put(msg,
7523 NL_AUTO_PORT,
7524 NL_AUTO_SEQ,
7525 nl.id,
7526 0,
7527 0,
7528 NL80211_CMD_GET_STATION,
7529 0);
7530
7531 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
7532 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
7533 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
7534 nl_send_auto(nl.socket, msg);
7535 nl_recvmsgs(nl.socket, nl.cb);
7536 nlmsg_free(msg);
7537 nlfree(&nl);
7538 return RETURN_OK;
7539#else
7540//iw implementation
7541#define TID_STATS_FILE "/tmp/tid_stats_file.txt"
7542#define TOTAL_MAX_LINES 50
7543
7544 char buf[256] = {'\0'}; /* or other suitable maximum line size */
7545 char if_name[10];
7546 FILE *fp=NULL;
7547 char pipeCmd[1024]= {'\0'};
7548 int lines,tid_index=0;
7549 char mac_addr[20] = {'\0'};
7550
7551 wifi_associated_dev_tid_entry_t *stats_entry;
7552
7553 snprintf(if_name, sizeof(if_name), "%s%d", AP_PREFIX, radioIndex);
7554 strcpy(mac_addr,clientMacAddress);
7555
7556 snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name);
7557 fp= popen(pipeCmd,"r");
7558 if(fp == NULL)
7559 {
7560 perror("popen for station dump failed\n");
7561 return RETURN_ERR;
7562 }
7563 pclose(fp);
7564
7565 snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1");
7566 fp=popen(pipeCmd,"r");
7567 if(fp == NULL)
7568 {
7569 perror("popen for grep station failed\n");
7570 return RETURN_ERR;
7571 }
7572 else if(fgets(buf,sizeof(buf),fp) != NULL)
7573 lines=atoi(buf);
7574 else
7575 {
7576 pclose(fp);
7577 fprintf(stderr,"No devices are connected \n");
7578 return RETURN_ERR;
7579 }
7580 pclose(fp);
7581
7582 if(lines == 1)
7583 lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output
7584
7585 for(tid_index=0; tid_index<PS_MAX_TID; tid_index++)
7586 {
7587 stats_entry = &tid_stats->tid_array[tid_index];
7588 stats_entry->tid = tid_index;
7589
7590 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);
7591
7592 fp=popen(pipeCmd,"r");
7593 if(fp ==NULL)
7594 {
7595 perror("Failed to read from tid file \n");
7596 return RETURN_ERR;
7597 }
7598 else if(fgets(buf,sizeof(buf),fp) != NULL)
7599 stats_entry->num_msdus = atol(buf);
7600
7601 pclose(fp);
7602 stats_entry->ac = _tid_ac_index_get[tid_index];
7603// TODO:
7604// ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus
7605// ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval
7606 }
7607 return RETURN_OK;
7608#endif
7609}
7610
7611
7612INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
7613{
7614 // TODO Implement me!
7615 return RETURN_OK;
7616}
7617
7618
7619INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
7620{
7621 // TODO Implement me!
7622 return RETURN_ERR;
7623}
7624
7625INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
7626{
7627 // TODO Implement me!
7628 return RETURN_ERR;
7629}
7630
7631INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
7632{
7633 // TODO Implement me!
7634 return RETURN_ERR;
7635}
7636
7637INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
7638{
7639 // TODO Implement me!
7640 return RETURN_ERR;
7641}
7642
7643INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
7644{
7645 // TODO Implement me!
7646 return RETURN_ERR;
7647}
7648
7649INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
7650{
7651 // TODO Implement me!
7652 return RETURN_ERR;
7653}
7654
7655INT wifi_steering_eventUnregister(void)
7656{
7657 // TODO Implement me!
7658 return RETURN_ERR;
7659}
7660
7661INT wifi_delApAclDevices(INT apIndex)
7662{
7663#if 0
7664 char cmd[MAX_BUF_SIZE] = {0};
7665 char buf[MAX_BUF_SIZE] = {0};
7666
7667 /* Not reset proof solution */
7668 snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s%d accept_acl CLEAR", AP_PREFIX, apIndex);
7669 if(_syscmd(cmd,buf,sizeof(buf)))
7670 return RETURN_ERR;
7671#endif
7672 char fname[100];
7673 FILE *fp;
7674
7675 snprintf(fname, sizeof(fname), "%s%d", ACL_PREFIX, apIndex);
7676 fp = fopen(fname, "w");
7677 if (!fp) {
7678 return RETURN_ERR;
7679 }
7680 fclose(fp);
7681
7682 return RETURN_OK;
7683}
7684
7685#ifdef HAL_NETLINK_IMPL
7686static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
7687 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7688 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7689 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
7690 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
7691 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
7692 char mac_addr[20],dev[20];
7693
7694 nla_parse(tb,
7695 NL80211_ATTR_MAX,
7696 genlmsg_attrdata(gnlh, 0),
7697 genlmsg_attrlen(gnlh, 0),
7698 NULL);
7699
7700 if(!tb[NL80211_ATTR_STA_INFO]) {
7701 fprintf(stderr, "sta stats missing!\n");
7702 return NL_SKIP;
7703 }
7704
7705 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
7706 fprintf(stderr, "failed to parse nested attributes!\n");
7707 return NL_SKIP;
7708 }
7709 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
7710
7711 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
7712
7713 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
7714 fprintf(stderr, "failed to parse nested rate attributes!");
7715 return NL_SKIP;
7716 }
7717
7718 if(sinfo[NL80211_STA_INFO_TID_STATS])
7719 {
7720 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
7721 printf("failed to parse nested stats attributes!");
7722 return NL_SKIP;
7723 }
7724 }
7725
7726 if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
7727 {
7728 printf("Type is VHT\n");
7729 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
7730 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
7731
7732 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
7733 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
7734 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
7735 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
7736 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
7737 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
7738 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
7739 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
7740 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
7741 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
7742 }
7743 else
7744 {
7745 printf(" OFDM or CCK \n");
7746 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
7747 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
7748 }
7749
7750 if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
7751 if(rinfo[NL80211_RATE_INFO_MCS])
7752 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
7753 }
7754 if(sinfo[NL80211_STA_INFO_RX_BYTES64])
7755 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
7756 else if (sinfo[NL80211_STA_INFO_RX_BYTES])
7757 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
7758
7759 if(stats_info[NL80211_TID_STATS_RX_MSDU])
7760 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
7761
7762 if (sinfo[NL80211_STA_INFO_SIGNAL])
7763 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
7764 //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
7765 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
7766 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
7767 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
7768 //rssi_array need to be filled
7769 return NL_SKIP;
7770}
7771#endif
7772
7773INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
7774{
7775#ifdef HAL_NETLINK_IMPL
7776 Netlink nl;
7777 char if_name[10];
7778
7779 *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
7780
7781 if (*output_array_size <= 0)
7782 return RETURN_OK;
7783
7784 snprintf(if_name, sizeof(if_name), "%s%d", AP_PREFIX, radioIndex);
7785 nl.id = initSock80211(&nl);
7786
7787 if (nl.id < 0) {
7788 fprintf(stderr, "Error initializing netlink \n");
7789 return 0;
7790 }
7791
7792 struct nl_msg* msg = nlmsg_alloc();
7793
7794 if (!msg) {
7795 fprintf(stderr, "Failed to allocate netlink message.\n");
7796 nlfree(&nl);
7797 return 0;
7798 }
7799
7800 genlmsg_put(msg,
7801 NL_AUTO_PORT,
7802 NL_AUTO_SEQ,
7803 nl.id,
7804 0,
7805 0,
7806 NL80211_CMD_GET_STATION,
7807 0);
7808
7809 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
7810 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
7811 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
7812 nl_send_auto(nl.socket, msg);
7813 nl_recvmsgs(nl.socket, nl.cb);
7814 nlmsg_free(msg);
7815 nlfree(&nl);
7816 return RETURN_OK;
7817#else
7818 //TODO Implement me
7819 return RETURN_OK;
7820#endif
7821}
7822
7823#ifdef HAL_NETLINK_IMPL
7824static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
7825 struct nlattr *tb[NL80211_ATTR_MAX + 1];
7826 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
7827 struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
7828 struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1];
7829 struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
7830 char mac_addr[20],dev[20];
7831
7832 nla_parse(tb,
7833 NL80211_ATTR_MAX,
7834 genlmsg_attrdata(gnlh, 0),
7835 genlmsg_attrlen(gnlh, 0),
7836 NULL);
7837
7838 if(!tb[NL80211_ATTR_STA_INFO]) {
7839 fprintf(stderr, "sta stats missing!\n");
7840 return NL_SKIP;
7841 }
7842
7843 if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
7844 fprintf(stderr, "failed to parse nested attributes!\n");
7845 return NL_SKIP;
7846 }
7847
7848 mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
7849
7850 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
7851
7852 if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
7853 fprintf(stderr, "failed to parse nested rate attributes!");
7854 return NL_SKIP;
7855 }
7856
7857 if(sinfo[NL80211_STA_INFO_TID_STATS])
7858 {
7859 if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
7860 printf("failed to parse nested stats attributes!");
7861 return NL_SKIP;
7862 }
7863 }
7864 if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
7865 {
7866 printf("Type is VHT\n");
7867 if(rinfo[NL80211_RATE_INFO_VHT_NSS])
7868 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
7869
7870 if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
7871 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
7872 if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
7873 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
7874 if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
7875 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
7876 if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
7877 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
7878 if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
7879 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
7880 }
7881 else
7882 {
7883 printf(" OFDM or CCK \n");
7884 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
7885 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
7886 }
7887
7888 if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
7889 if(rinfo[NL80211_RATE_INFO_MCS])
7890 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
7891 }
7892
7893 if(sinfo[NL80211_STA_INFO_TX_BYTES64])
7894 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
7895 else if (sinfo[NL80211_STA_INFO_TX_BYTES])
7896 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
7897
7898 //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink
7899 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
7900 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
7901
7902 if(stats_info[NL80211_TID_STATS_TX_MSDU])
7903 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
7904
7905 if(sinfo[NL80211_STA_INFO_TX_RETRIES])
7906 ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
7907
7908 if(sinfo[NL80211_STA_INFO_TX_FAILED])
7909 ((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]);
7910
7911 return NL_SKIP;
7912}
7913#endif
7914
7915INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle)
7916{
7917#ifdef HAL_NETLINK_IMPL
7918 Netlink nl;
7919 char if_name[10];
7920
7921 *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
7922
7923 if (*output_array_size <= 0)
7924 return RETURN_OK;
7925
7926 snprintf(if_name, sizeof(if_name), "%s%d", AP_PREFIX, radioIndex);
7927
7928 nl.id = initSock80211(&nl);
7929
7930 if(nl.id < 0) {
7931 fprintf(stderr, "Error initializing netlink \n");
7932 return 0;
7933 }
7934
7935 struct nl_msg* msg = nlmsg_alloc();
7936
7937 if(!msg) {
7938 fprintf(stderr, "Failed to allocate netlink message.\n");
7939 nlfree(&nl);
7940 return 0;
7941 }
7942
7943 genlmsg_put(msg,
7944 NL_AUTO_PORT,
7945 NL_AUTO_SEQ,
7946 nl.id,
7947 0,
7948 0,
7949 NL80211_CMD_GET_STATION,
7950 0);
7951
7952 nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
7953 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
7954 nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
7955 nl_send_auto(nl.socket, msg);
7956 nl_recvmsgs(nl.socket, nl.cb);
7957 nlmsg_free(msg);
7958 nlfree(&nl);
7959 return RETURN_OK;
7960#else
7961 //TODO Implement me
7962 return RETURN_OK;
7963#endif
7964}
7965
7966INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
7967{
7968 // TODO Implement me!
7969 char buf[MAX_BUF_SIZE] = {0};
7970 char config_file[MAX_BUF_SIZE] = {0};
7971
7972 snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
7973 wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
7974 *activate = (strncmp("1",buf,1) == 0);
7975
7976 return RETURN_OK;
7977}
7978
7979INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
7980{
7981 char config_file[MAX_BUF_SIZE] = {0};
7982 struct params list;
7983
7984 list.name = "rrm_neighbor_report";
7985 list.value = activate?"1":"0";
7986 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7987 wifi_hostapdWrite(config_file, &list, 1);
7988
7989 return RETURN_OK;
7990}
7991
7992INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
7993{
7994 char buf[32] = {0};
7995 char config_file[MAX_BUF_SIZE] = {0};
7996
7997 sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex);
7998 wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
7999 *activate = (strncmp("1",buf,1) == 0);
8000
8001 return RETURN_OK;
8002}
8003#undef HAL_NETLINK_IMPL
8004#ifdef HAL_NETLINK_IMPL
8005static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
8006 struct nlattr *tb[NL80211_ATTR_MAX + 1];
8007 struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
8008 struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
8009 char dev[20];
8010 int freq =0 ;
8011 static int i=0;
8012
8013 wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
8014
8015 static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
8016 };
8017
8018 nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
8019
8020 if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
8021
8022 if (!tb[NL80211_ATTR_SURVEY_INFO]) {
8023 fprintf(stderr, "survey data missing!\n");
8024 return NL_SKIP;
8025 }
8026
8027 if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
8028 {
8029 fprintf(stderr, "failed to parse nested attributes!\n");
8030 return NL_SKIP;
8031 }
8032
8033
8034 if(out[0].array_size == 1 )
8035 {
8036 if(sinfo[NL80211_SURVEY_INFO_IN_USE])
8037 {
8038 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
8039 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
8040 out[0].ch_number = ieee80211_frequency_to_channel(freq);
8041
8042 if (sinfo[NL80211_SURVEY_INFO_NOISE])
8043 out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
8044 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
8045 out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
8046 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
8047 out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
8048 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
8049 out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
8050 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
8051 out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
8052 if (sinfo[NL80211_SURVEY_INFO_TIME])
8053 out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
8054 return NL_STOP;
8055 }
8056 }
8057 else
8058 {
8059 if ( i <= out[0].array_size )
8060 {
8061 if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
8062 freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
8063 out[i].ch_number = ieee80211_frequency_to_channel(freq);
8064
8065 if (sinfo[NL80211_SURVEY_INFO_NOISE])
8066 out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
8067 if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
8068 out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
8069 if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
8070 out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
8071 if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
8072 out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
8073 if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
8074 out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
8075 if (sinfo[NL80211_SURVEY_INFO_TIME])
8076 out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
8077 }
8078 }
8079
8080 i++;
8081 return NL_SKIP;
8082}
8083#endif
8084
8085static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
8086{
8087 char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE];
8088 FILE *fp;
8089
8090 if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
8091 {
8092 printf("Creating Frequency-Channel Map\n");
8093 system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
8094 }
8095 snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel);
8096 if((fp = popen(command, "r")))
8097 {
8098 fgets(output, sizeof(output), fp);
8099 *freqMHz = atoi(output);
8100 fclose(fp);
8101 }
8102
8103 return 0;
8104}
8105
8106static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz)
8107{
8108 int freqMHz = -1;
8109 char cmd[MAX_CMD_SIZE] = {'\0'};
8110
8111 ieee80211_channel_to_frequency(channel, &freqMHz);
8112 if (freqMHz == -1) {
8113 wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel);
8114 return -1;
8115 }
8116
8117 if (sprintf(cmd,"iw dev %s%d survey dump | grep -A5 %d | tr -d '\\t'", RADIO_PREFIX, radioIndex, freqMHz) < 0) {
8118 wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__,
8119 radioIndex, freqMHz);
8120 return -1;
8121 }
8122
8123 if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) {
8124 wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex);
8125 return -1;
8126 }
8127
8128 return 0;
8129}
8130
8131static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
8132{
8133 const char *ptr = buf;
8134 char *key = NULL;
8135 char *val = NULL;
8136 char line[256] = { '\0' };
8137
8138 while (ptr = get_line_from_str_buf(ptr, line)) {
8139 if (strstr(line, "Frequency")) continue;
8140
8141 key = strtok(line, ":");
8142 val = strtok(NULL, " ");
8143 wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val);
8144
8145 if (!strcmp(key, "noise")) {
8146 sscanf(val, "%d", &stats->ch_noise);
8147 if (stats->ch_noise == 0) {
8148 // Workaround for missing noise information.
8149 // Assume -95 for 2.4G and -103 for 5G
8150 if (radioIndex == 0) stats->ch_noise = -95;
8151 if (radioIndex == 1) stats->ch_noise = -103;
8152 }
8153 }
8154 else if (!strcmp(key, "channel active time")) {
8155 sscanf(val, "%llu", &stats->ch_utilization_total);
8156 }
8157 else if (!strcmp(key, "channel busy time")) {
8158 sscanf(val, "%llu", &stats->ch_utilization_busy);
8159 }
8160 else if (!strcmp(key, "channel receive time")) {
8161 sscanf(val, "%llu", &stats->ch_utilization_busy_rx);
8162 }
8163 else if (!strcmp(key, "channel transmit time")) {
8164 sscanf(val, "%llu", &stats->ch_utilization_busy_tx);
8165 }
8166 };
8167
8168 return 0;
8169}
8170
8171INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
8172{
8173 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
8174#ifdef HAL_NETLINK_IMPL
8175 Netlink nl;
8176 wifi_channelStats_t_loc local[array_size];
8177 char if_name[10];
8178
8179 local[0].array_size = array_size;
8180
8181 snprintf(if_name, sizeof(if_name), "%s%d", AP_PREFIX, radioIndex);
8182
8183 nl.id = initSock80211(&nl);
8184
8185 if (nl.id < 0) {
8186 fprintf(stderr, "Error initializing netlink \n");
8187 return -1;
8188 }
8189
8190 struct nl_msg* msg = nlmsg_alloc();
8191
8192 if (!msg) {
8193 fprintf(stderr, "Failed to allocate netlink message.\n");
8194 nlfree(&nl);
8195 return -2;
8196 }
8197
8198 genlmsg_put(msg,
8199 NL_AUTO_PORT,
8200 NL_AUTO_SEQ,
8201 nl.id,
8202 0,
8203 NLM_F_DUMP,
8204 NL80211_CMD_GET_SURVEY,
8205 0);
8206
8207 nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
8208 nl_send_auto(nl.socket, msg);
8209 nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
8210 nl_recvmsgs(nl.socket, nl.cb);
8211 nlmsg_free(msg);
8212 nlfree(&nl);
8213 //Copying the Values
8214 for(int i=0;i<array_size;i++)
8215 {
8216 input_output_channelStats_array[i].ch_number = local[i].ch_number;
8217 input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
8218 input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
8219 input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
8220 input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
8221 input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
8222 input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
8223 //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
8224 }
8225#else
8226 ULONG channel = 0;
8227 int i;
8228 int number_of_channels = array_size;
8229 char buf[512];
8230 INT ret;
8231 wifi_channelStats_t tmp_stats;
8232
8233 if (number_of_channels == 0) {
8234 if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
8235 wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex);
8236 return RETURN_ERR;
8237 }
8238 number_of_channels = 1;
8239 input_output_channelStats_array[0].ch_number = channel;
8240 }
8241
8242 for (i = 0; i < number_of_channels; i++) {
8243
8244 input_output_channelStats_array[i].ch_noise = 0;
8245 input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
8246 input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
8247 input_output_channelStats_array[i].ch_utilization_busy = 0;
8248 input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
8249 input_output_channelStats_array[i].ch_utilization_total = 0;
8250
8251 memset(buf, 0, sizeof(buf));
8252 if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
8253 return RETURN_ERR;
8254 }
8255 if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
8256 wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex);
8257 return RETURN_ERR;
8258 }
8259
8260 // XXX: fake missing 'self' counter which is not available in iw survey output
8261 // the 'self' counter (a.k.a 'bss') requires Linux Kernel update
8262 input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
8263
8264 input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
8265 input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
8266 input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
8267 input_output_channelStats_array[i].ch_utilization_busy *= 1000;
8268 input_output_channelStats_array[i].ch_utilization_total *= 1000;
8269
8270 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",
8271 __func__,
8272 input_output_channelStats_array[i].ch_number,
8273 input_output_channelStats_array[i].ch_noise,
8274 input_output_channelStats_array[i].ch_utilization_total,
8275 input_output_channelStats_array[i].ch_utilization_busy,
8276 input_output_channelStats_array[i].ch_utilization_busy_rx,
8277 input_output_channelStats_array[i].ch_utilization_busy_tx,
8278 input_output_channelStats_array[i].ch_utilization_busy_self,
8279 input_output_channelStats_array[i].ch_utilization_busy_ext);
8280 }
8281#endif
8282 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
8283 return RETURN_OK;
8284}
8285#define HAL_NETLINK_IMPL
8286
8287/* Hostapd events */
8288
8289#ifndef container_of
8290#define offset_of(st, m) ((size_t)&(((st *)0)->m))
8291#define container_of(ptr, type, member) \
8292 ((type *)((char *)ptr - offset_of(type, member)))
8293#endif /* container_of */
8294
8295struct ctrl {
8296 char sockpath[128];
8297 char sockdir[128];
8298 char bss[IFNAMSIZ];
8299 char reply[4096];
8300 int ssid_index;
8301 void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
8302 void (*overrun)(struct ctrl *ctrl);
8303 struct wpa_ctrl *wpa;
8304 unsigned int ovfl;
8305 size_t reply_len;
8306 int initialized;
8307 ev_timer retry;
8308 ev_timer watchdog;
8309 ev_stat stat;
8310 ev_io io;
8311};
8312static wifi_newApAssociatedDevice_callback clients_connect_cb;
8313static wifi_apDisassociatedDevice_callback clients_disconnect_cb;
8314static struct ctrl wpa_ctrl[MAX_APS];
8315static int initialized;
8316
8317static unsigned int ctrl_get_drops(struct ctrl *ctrl)
8318{
8319 char cbuf[256] = {};
8320 struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
8321 struct cmsghdr *cmsg;
8322 unsigned int ovfl = ctrl->ovfl;
8323 unsigned int drop;
8324
8325 recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT);
8326 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
8327 if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
8328 ovfl = *(unsigned int *)CMSG_DATA(cmsg);
8329
8330 drop = ovfl - ctrl->ovfl;
8331 ctrl->ovfl = ovfl;
8332
8333 return drop;
8334}
8335
8336static void ctrl_close(struct ctrl *ctrl)
8337{
8338 if (ctrl->io.cb)
8339 ev_io_stop(EV_DEFAULT_ &ctrl->io);
8340 if (ctrl->retry.cb)
8341 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
8342 if (!ctrl->wpa)
8343 return;
8344
8345 wpa_ctrl_detach(ctrl->wpa);
8346 wpa_ctrl_close(ctrl->wpa);
8347 ctrl->wpa = NULL;
8348 printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
8349}
8350
8351static void ctrl_process(struct ctrl *ctrl)
8352{
8353 const char *str;
8354 int drops;
8355 int level;
8356 int err;
8357
8358 /* Example events:
8359 *
8360 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
8361 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
8362 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
8363 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
8364 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
8365 */
8366 if (!(str = index(ctrl->reply, '>')))
8367 return;
8368 if (sscanf(ctrl->reply, "<%d>", &level) != 1)
8369 return;
8370
8371 str++;
8372
8373 if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
8374 if (!(str = index(ctrl->reply, ' ')))
8375 return;
8376 wifi_associated_dev_t sta;
8377 memset(&sta, 0, sizeof(sta));
8378
8379 sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
8380 &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
8381 &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]);
8382
8383 sta.cli_Active=true;
8384
8385 (clients_connect_cb)(ctrl->ssid_index, &sta);
8386 goto handled;
8387 }
8388
8389 if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
8390 if (!(str = index(ctrl->reply, ' ')))
8391 return;
8392
8393 (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0);
8394 goto handled;
8395 }
8396
8397 if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
8398 printf("CTRL_WPA: handle TERMINATING event\n");
8399 goto retry;
8400 }
8401
8402 if (strncmp("AP-DISABLED", str, 11) == 0) {
8403 printf("CTRL_WPA: handle AP-DISABLED\n");
8404 goto retry;
8405 }
8406
8407 printf("Event not supported!!\n");
8408
8409handled:
8410
8411 if ((drops = ctrl_get_drops(ctrl))) {
8412 printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
8413 if (ctrl->overrun)
8414 ctrl->overrun(ctrl);
8415 }
8416
8417 return;
8418
8419retry:
8420 printf("WPA_CTRL: closing\n");
8421 ctrl_close(ctrl);
8422 printf("WPA_CTRL: retrying from ctrl prcoess\n");
8423 ev_timer_again(EV_DEFAULT_ &ctrl->retry);
8424}
8425
8426static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
8427{
8428 struct ctrl *ctrl = container_of(io, struct ctrl, io);
8429 int err;
8430
8431 memset(ctrl->reply, 0, sizeof(ctrl->reply));
8432 ctrl->reply_len = sizeof(ctrl->reply) - 1;
8433 err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
8434 ctrl->reply[ctrl->reply_len] = 0;
8435 if (err < 0) {
8436 if (errno == EAGAIN || errno == EWOULDBLOCK)
8437 return;
8438 ctrl_close(ctrl);
8439 ev_timer_again(EV_A_ &ctrl->retry);
8440 return;
8441 }
8442
8443 ctrl_process(ctrl);
8444}
8445
8446static int ctrl_open(struct ctrl *ctrl)
8447{
8448 int fd;
8449
8450 if (ctrl->wpa)
8451 return 0;
8452
8453 ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
8454 if (!ctrl->wpa)
8455 goto err;
8456
8457 if (wpa_ctrl_attach(ctrl->wpa) < 0)
8458 goto err_close;
8459
8460 fd = wpa_ctrl_get_fd(ctrl->wpa);
8461 if (fd < 0)
8462 goto err_detach;
8463
8464 if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
8465 goto err_detach;
8466
8467 ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
8468 ev_io_start(EV_DEFAULT_ &ctrl->io);
8469
8470 return 0;
8471
8472err_detach:
8473 wpa_ctrl_detach(ctrl->wpa);
8474err_close:
8475 wpa_ctrl_close(ctrl->wpa);
8476err:
8477 ctrl->wpa = NULL;
8478 return -1;
8479}
8480
8481static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
8482{
8483 struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
8484
8485 printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
8486 ctrl_open(ctrl);
8487}
8488
8489static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
8490{
8491 struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
8492
8493 printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
8494 if (ctrl_open(ctrl) == 0) {
8495 printf("WPA_CTRL: retry successful\n");
8496 ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
8497 }
8498}
8499
8500int ctrl_enable(struct ctrl *ctrl)
8501{
8502 if (ctrl->wpa)
8503 return 0;
8504
8505 if (!ctrl->stat.cb) {
8506 ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
8507 ev_stat_start(EV_DEFAULT_ &ctrl->stat);
8508 }
8509
8510 if (!ctrl->retry.cb) {
8511 ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
8512 }
8513
8514 return ctrl_open(ctrl);
8515}
8516
8517static void
8518ctrl_msg_cb(char *buf, size_t len)
8519{
8520 struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
8521
8522 printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf);
8523 ctrl_process(ctrl);
8524}
8525
8526static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
8527{
8528 int err;
8529
8530 if (!ctrl->wpa)
8531 return -1;
8532 if (*reply_len < 2)
8533 return -1;
8534
8535 (*reply_len)--;
8536 ctrl->reply_len = sizeof(ctrl->reply);
8537 err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
8538 printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
8539 if (err < 0)
8540 return err;
8541
8542 if (ctrl->reply_len > *reply_len)
8543 ctrl->reply_len = *reply_len;
8544
8545 *reply_len = ctrl->reply_len;
8546 memcpy(reply, ctrl->reply, *reply_len);
8547 reply[*reply_len - 1] = 0;
8548 printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
8549 return 0;
8550}
8551
8552static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
8553{
8554 const char *pong = "PONG";
8555 const char *ping = "PING";
8556 char reply[1024];
8557 size_t len = sizeof(reply);
8558 int err;
8559 ULONG s, snum;
8560 INT ret;
8561 BOOL status;
8562
8563 printf("WPA_CTRL: watchdog cb\n");
8564
8565 ret = wifi_getSSIDNumberOfEntries(&snum);
8566 if (ret != RETURN_OK) {
8567 printf("%s: failed to get SSID count", __func__);
8568 return;
8569 }
8570
8571 if (snum > MAX_APS) {
8572 printf("more ssid than supported! %lu\n", snum);
8573 return;
8574 }
8575
8576 for (s = 0; s < snum; s++) {
8577 if (wifi_getApEnable(s, &status) != RETURN_OK) {
8578 printf("%s: failed to get AP Enable for index: %d\n", __func__, s);
8579 continue;
8580 }
8581 if (status == false) continue;
8582
8583 memset(reply, 0, sizeof(reply));
8584 len = sizeof(reply);
8585 printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
8586 err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
8587 if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
8588 continue;
8589
8590 printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
8591 ctrl_close(&wpa_ctrl[s]);
8592 printf("WPA_CTRL: ev_timer_again %d\n", s);
8593 ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry);
8594 }
8595}
8596
8597static int init_wpa()
8598{
8599 int ret = 0, i = 0;
8600 ULONG s, snum;
8601
8602 ret = wifi_getSSIDNumberOfEntries(&snum);
8603 if (ret != RETURN_OK) {
8604 printf("%s: failed to get SSID count", __func__);
8605 return RETURN_ERR;
8606 }
8607
8608 if (snum > MAX_APS) {
8609 printf("more ssid than supported! %lu\n", snum);
8610 return RETURN_ERR;
8611 }
8612
8613 for (s = 0; s < snum; s++) {
8614 memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
8615 sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s);
8616 wpa_ctrl[s].ssid_index = s;
8617 ctrl_enable(&wpa_ctrl[s]);
8618 }
8619
8620 ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
8621 ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog);
8622
8623 initialized = 1;
8624 printf("WPA_CTRL: initialized\n");
8625
8626 return RETURN_OK;
8627}
8628
8629void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
8630{
8631 clients_connect_cb = callback_proc;
8632 if (!initialized)
8633 init_wpa();
8634}
8635
8636void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
8637{
8638 clients_disconnect_cb = callback_proc;
8639 if (!initialized)
8640 init_wpa();
8641}
8642
8643INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
8644{
8645 // TODO Implement me!
8646 return RETURN_ERR;
8647}
8648
8649INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
8650{
8651 // TODO Implement me!
8652 return RETURN_ERR;
8653}
8654
8655INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
8656{
8657 int i;
8658 char cmd[256];
8659 char channel_numbers_buf[256];
8660 char dfs_state_buf[256];
8661 char line[256];
8662 const char *ptr;
8663
8664 memset(cmd, 0, sizeof(cmd));
8665 memset(channel_numbers_buf, 0, sizeof(channel_numbers_buf));
8666 memset(line, 0, sizeof(line));
8667 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
8668 memset(outputMap, 0, outputMapSize); // all unused entries should be zero
8669
8670 if (radioIndex == 0) { // 2.4G - all allowed
8671 if (outputMapSize < 11) {
8672 wifi_dbg_printf("%s: outputMapSize too small (%d)\n", __FUNCTION__, outputMapSize);
8673 return RETURN_ERR;
8674 }
8675
8676 for (i = 0; i < 11; i++) {
8677 outputMap[i].ch_number = i + 1;
8678 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
8679 }
8680
8681 return RETURN_OK;
8682 }
8683
8684 if (radioIndex == 1) { // 5G
8685// Example output of iw list:
8686//
8687// Frequencies:
8688// * 5180 MHz [36] (17.0 dBm)
8689// * 5200 MHz [40] (17.0 dBm)
8690// * 5220 MHz [44] (17.0 dBm)
8691// * 5240 MHz [48] (17.0 dBm)
8692// * 5260 MHz [52] (23.0 dBm) (radar detection)
8693// DFS state: usable (for 78930 sec)
8694// DFS CAC time: 60000 ms
8695// * 5280 MHz [56] (23.0 dBm) (radar detection)
8696// DFS state: usable (for 78930 sec)
8697// DFS CAC time: 60000 ms
8698// * 5300 MHz [60] (23.0 dBm) (radar detection)
8699// DFS state: usable (for 78930 sec)
8700// DFS CAC time: 60000 ms
8701// * 5320 MHz [64] (23.0 dBm) (radar detection)
8702// DFS state: usable (for 78930 sec)
8703// DFS CAC time: 60000 ms
8704// * 5500 MHz [100] (disabled)
8705// * 5520 MHz [104] (disabled)
8706// * 5540 MHz [108] (disabled)
8707// * 5560 MHz [112] (disabled)
8708//
8709// Below command should fetch channel numbers of each enabled channel in 5GHz band:
8710 if (sprintf(cmd,"iw list | grep MHz | tr -d '\\t' | grep -v disabled | tr -d '*' | grep '^ 5' | awk '{print $3}' | tr -d '[]'") < 0) {
8711 wifi_dbg_printf("%s: failed to build iw list command\n", __FUNCTION__);
8712 return RETURN_ERR;
8713 }
8714
8715 if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) {
8716 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
8717 return RETURN_ERR;
8718 }
8719
8720 ptr = channel_numbers_buf;
8721 i = 0;
8722 while (ptr = get_line_from_str_buf(ptr, line)) {
8723 if (i >= outputMapSize) {
8724 wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__);
8725 return RETURN_ERR;
8726 }
8727 sscanf(line, "%d", &outputMap[i].ch_number);
8728
8729 memset(cmd, 0, sizeof(cmd));
8730 // Below command should fetch string for DFS state (usable, available or unavailable)
8731 // Example line: "DFS state: usable (for 78930 sec)"
8732 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) {
8733 wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__);
8734 return RETURN_ERR;
8735 }
8736
8737 memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
8738 if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) {
8739 wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd);
8740 return RETURN_ERR;
8741 }
8742
8743 wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf);
8744
8745 if (!strcmp(dfs_state_buf, "usable")) {
8746 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
8747 } else if (!strcmp(dfs_state_buf, "available")) {
8748 outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
8749 } else if (!strcmp(dfs_state_buf, "unavailable")) {
8750 outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
8751 } else {
8752 outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
8753 }
8754 i++;
8755 }
8756
8757 return RETURN_OK;
8758 }
8759
8760 wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex);
8761 return RETURN_ERR;
8762}
8763
8764INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
8765{
8766 // TODO Implement me!
8767 return RETURN_ERR;
8768}
8769
8770INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
8771{
8772 return RETURN_OK;
8773}
8774
8775INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
8776{
8777 // TODO Implement me!
8778 return RETURN_ERR;
8779}
8780
8781INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
8782{
8783 // TODO API refrence Implementaion is present on RPI hal
8784 return RETURN_ERR;
8785}
8786
8787INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
8788{
8789 //TO-Do Implement this
8790 txpwr_pcntg = 0;
8791 return RETURN_OK;
8792}
8793
8794INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
8795{
8796 //Zero-wait DFS not supported
8797 return RETURN_ERR;
8798}
8799
8800INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
8801{
8802 //Zero-wait DFS not supported
8803 return RETURN_ERR;
8804}
8805
8806INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
8807{
8808 *supported = false;
8809 return RETURN_OK;
8810}
8811
8812/* multi-psk support */
8813INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
8814{
8815 char cmd[256];
8816
8817 sprintf(cmd, "hostapd_cli -i %s%d sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
8818 AP_PREFIX,
8819 apIndex,
8820 mac[0],
8821 mac[1],
8822 mac[2],
8823 mac[3],
8824 mac[4],
8825 mac[5]
8826 );
8827 printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
8828 _syscmd(cmd, key->wifi_keyId, 64);
8829
8830
8831 return RETURN_OK;
8832}
8833
8834INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
8835{
8836 FILE *fd = NULL;
8837 char fname[100];
8838 char cmd[128] = {0};
8839 char out[64] = {0};
8840 wifi_key_multi_psk_t * key = NULL;
8841 if(keysNumber < 0)
8842 return RETURN_ERR;
8843
8844 snprintf(fname, sizeof(fname), "/tmp/hostapd%d.psk", apIndex);
8845 fd = fopen(fname, "w");
8846 if (!fd) {
8847 return RETURN_ERR;
8848 }
8849 key= (wifi_key_multi_psk_t *) keys;
8850 for(int i=0; i<keysNumber; ++i, key++) {
8851 fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
8852 }
8853 fclose(fd);
8854
8855 //reload file
8856 sprintf(cmd, "hostapd_cli -i%s%d raw RELOAD_WPA_PSK", AP_PREFIX, apIndex);
8857 _syscmd(cmd, out, 64);
8858 return RETURN_OK;
8859}
8860
8861INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
8862{
8863 FILE *fd = NULL;
8864 char fname[100];
8865 char * line = NULL;
8866 char * pos = NULL;
8867 size_t len = 0;
8868 ssize_t read = 0;
8869 INT ret = RETURN_OK;
8870 wifi_key_multi_psk_t *keys_it = NULL;
8871
8872 if (keysNumber < 1) {
8873 return RETURN_ERR;
8874 }
8875
8876 snprintf(fname, sizeof(fname), "/tmp/hostapd%d.psk", apIndex);
8877 fd = fopen(fname, "r");
8878 if (!fd) {
8879 return RETURN_ERR;
8880 }
8881
8882 if (keys == NULL) {
8883 ret = RETURN_ERR;
8884 goto close;
8885 }
8886
8887 keys_it = keys;
8888 while ((read = getline(&line, &len, fd)) != -1) {
8889 //Strip trailing new line if present
8890 if (read > 0 && line[read-1] == '\n') {
8891 line[read-1] = '\0';
8892 }
8893
8894 if(strcmp(line,"keyid=")) {
8895 sscanf(line, "keyid=%s", &(keys_it->wifi_keyId));
8896 if (!(pos = index(line, ' '))) {
8897 ret = RETURN_ERR;
8898 goto close;
8899 }
8900 pos++;
8901 //Here should be 00:00:00:00:00:00
8902 if (!(strcmp(pos,"00:00:00:00:00:00"))) {
8903 printf("Not supported MAC: %s\n", pos);
8904 }
8905 if (!(pos = index(pos, ' '))) {
8906 ret = RETURN_ERR;
8907 goto close;
8908 }
8909 pos++;
8910
8911 //The rest is PSK
8912 snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
8913 keys_it++;
8914
8915 if(--keysNumber <= 0)
8916 break;
8917 }
8918 }
8919
8920close:
8921 free(line);
8922 fclose(fd);
8923 return ret;
8924}
8925/* end of multi-psk support */
8926
8927INT wifi_setNeighborReports(UINT apIndex,
8928 UINT numNeighborReports,
8929 wifi_NeighborReport_t *neighborReports)
8930{
8931 char cmd[256] = { 0 };
8932 char hex_bssid[13] = { 0 };
8933 char bssid[18] = { 0 };
8934 char nr[256] = { 0 };
8935 char ssid[256];
8936 char hex_ssid[256];
8937 INT ret;
8938
8939 /*rmeove all neighbors*/
8940 wifi_dbg_printf("\n[%s]: removing all neighbors from %s%d",__func__,AP_PREFIX,apIndex);
8941 sprintf(cmd, "hostapd_cli show_neighbor -i %s%d | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s%d",AP_PREFIX,apIndex,AP_PREFIX,apIndex);
8942 system(cmd);
8943
8944 for(unsigned int i = 0; i < numNeighborReports; i++)
8945 {
8946 memset(ssid, 0, sizeof(ssid));
8947 ret = wifi_getSSIDName(apIndex, ssid);
8948 if (ret != RETURN_OK)
8949 return RETURN_ERR;
8950
8951 memset(hex_ssid, 0, sizeof(hex_ssid));
8952 for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 )
8953 sprintf(hex_ssid + k,"%02x", ssid[j]);
8954
8955 snprintf(hex_bssid, sizeof(hex_bssid),
8956 "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
8957 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
8958 snprintf(bssid, sizeof(bssid),
8959 "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
8960 neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
8961
8962 snprintf(nr, sizeof(nr),
8963 "%s" // bssid
8964 "%02hhx%02hhx%02hhx%02hhx" // bssid_info
8965 "%02hhx" // operclass
8966 "%02hhx" // channel
8967 "%02hhx", // phy_mode
8968 hex_bssid,
8969 neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
8970 (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
8971 neighborReports[i].opClass,
8972 neighborReports[i].channel,
8973 neighborReports[i].phyTable);
8974
8975 snprintf(cmd, sizeof(cmd),
8976 "hostapd_cli set_neighbor "
8977 "%s " // bssid
8978 "ssid=%s " // ssid
8979 "nr=%s " // nr
8980 "-i %s%d",
8981 bssid,hex_ssid,nr,AP_PREFIX,apIndex);
8982
8983 if (WEXITSTATUS(system(cmd)) != 0)
8984 {
8985 wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd);
8986 }
8987 }
8988
8989 return RETURN_OK;
8990}
8991
8992INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
8993{
8994 return RETURN_OK;
8995}
8996
8997#ifdef _WIFI_HAL_TEST_
8998int main(int argc,char **argv)
8999{
9000 int index;
9001 INT ret=0;
9002 char buf[1024]="";
9003
9004 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9005 if(argc<3)
9006 {
9007 if(argc==2)
9008 {
9009 if(!strcmp(argv[1], "init"))
9010 return wifi_init();
9011 if(!strcmp(argv[1], "reset"))
9012 return wifi_reset();
9013 if(!strcmp(argv[1], "wifi_getHalVersion"))
9014 {
9015 char buffer[64];
9016 if(wifi_getHalVersion(buffer)==RETURN_OK)
9017 printf("Version: %s\n", buffer);
9018 else
9019 printf("Error in wifi_getHalVersion\n");
9020 return RETURN_OK;
9021 }
9022 }
9023 printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
9024 exit(-1);
9025 }
9026
9027 index = atoi(argv[2]);
9028 if(strstr(argv[1], "wifi_getApName")!=NULL)
9029 {
9030 wifi_getApName(index,buf);
9031 printf("Ap name is %s \n",buf);
9032 return 0;
9033 }
9034 if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
9035 {
9036 BOOL b = FALSE;
9037 BOOL *output_bool = &b;
9038 wifi_getRadioAutoChannelEnable(index,output_bool);
9039 printf("Channel enabled = %d \n",b);
9040 return 0;
9041 }
9042 if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
9043 {
9044 wifi_getApWpaEncryptionMode(index,buf);
9045 printf("encryption enabled = %s\n",buf);
9046 return 0;
9047 }
9048 if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
9049 {
9050 BOOL b = FALSE;
9051 BOOL *output_bool = &b;
9052 wifi_getApSsidAdvertisementEnable(index,output_bool);
9053 printf("advertisment enabled = %d\n",b);
9054 return 0;
9055 }
9056 if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
9057 {
9058 if(argc <= 3 )
9059 {
9060 printf("Insufficient arguments \n");
9061 exit(-1);
9062 }
9063
9064 char sta[20] = {'\0'};
9065 ULLONG handle= 0;
9066 strcpy(sta,argv[3]);
9067 mac_address_t st;
9068 mac_addr_aton(st,sta);
9069
9070 wifi_associated_dev_tid_stats_t tid_stats;
9071 wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
9072 for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
9073 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);
9074 }
9075
9076 if(strstr(argv[1], "getApEnable")!=NULL) {
9077 BOOL enable;
9078 ret=wifi_getApEnable(index, &enable);
9079 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
9080 }
9081 else if(strstr(argv[1], "setApEnable")!=NULL) {
9082 BOOL enable = atoi(argv[3]);
9083 ret=wifi_setApEnable(index, enable);
9084 printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
9085 }
9086 else if(strstr(argv[1], "getApStatus")!=NULL) {
9087 char status[64];
9088 ret=wifi_getApStatus(index, status);
9089 printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
9090 }
9091 else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
9092 {
9093 wifi_getSSIDNameStatus(index,buf);
9094 printf("%s %d: active ssid : %s\n",argv[1], index,buf);
9095 return 0;
9096 }
9097 else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
9098 wifi_ssidTrafficStats2_t stats={0};
9099 ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
9100 printf("%s %d: returns %d\n", argv[1], index, ret);
9101 printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent);
9102 printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived);
9103 printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent);
9104 printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived);
9105 printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount);
9106 printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount);
9107 printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount);
9108 printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount);
9109 printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount);
9110 printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
9111 printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent);
9112 printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived);
9113 printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent);
9114 printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived);
9115 printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent);
9116 printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived);
9117 printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent);
9118 printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived);
9119 printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent);
9120 printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied);
9121 printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived);
9122 }
9123 else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
9124 wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
9125 UINT array_size=0;
9126 UINT i=0;
9127 ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
9128 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
9129 for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
9130 printf(" neighbor %d:\n", i);
9131 printf(" ap_SSID =%s\n", pt->ap_SSID);
9132 printf(" ap_BSSID =%s\n", pt->ap_BSSID);
9133 printf(" ap_Mode =%s\n", pt->ap_Mode);
9134 printf(" ap_Channel =%d\n", pt->ap_Channel);
9135 printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength);
9136 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
9137 printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode);
9138 printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards);
9139 printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards);
9140 printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth);
9141 printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
9142 printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod);
9143 printf(" ap_Noise =%d\n", pt->ap_Noise);
9144 printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates);
9145 printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates);
9146 printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod);
9147 printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization);
9148 }
9149 if(neighbor_ap_array)
9150 free(neighbor_ap_array); //make sure to free the list
9151 }
9152 else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
9153 wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
9154 UINT array_size=0;
9155 UINT i=0;
9156 ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
9157 printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
9158 for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
9159 printf(" associated_dev %d:\n", i);
9160 printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard);
9161 printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth);
9162 printf(" cli_SNR =%d\n", pt->cli_SNR);
9163 printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources);
9164 printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck);
9165 printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck);
9166 printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent);
9167 printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived);
9168 printf(" cli_RSSI =%d\n", pt->cli_RSSI);
9169 printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI);
9170 printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI);
9171 printf(" cli_Disassociations =%d\n", pt->cli_Disassociations);
9172 printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
9173 }
9174 if(associated_dev_array)
9175 free(associated_dev_array); //make sure to free the list
9176 }
9177
9178 if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
9179 {
9180#define MAX_ARRAY_SIZE 64
9181 int i, array_size;
9182 char *p, *ch_str;
9183 wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
9184
9185 if(argc != 5)
9186 {
9187 printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
9188 exit(-1);
9189 }
9190 memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
9191
9192 for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
9193 {
9194 strtok_r(ch_str, ",", &p);
9195 input_output_channelStats_array[i].ch_number = atoi(ch_str);
9196 }
9197 wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
9198 if(!array_size)
9199 array_size=1;//Need to print current channel statistics
9200 for(i=0; i<array_size; i++)
9201 printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
9202 ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
9203 ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
9204 input_output_channelStats_array[i].ch_number,\
9205 input_output_channelStats_array[i].ch_noise,\
9206 input_output_channelStats_array[i].ch_utilization_busy_rx,\
9207 input_output_channelStats_array[i].ch_utilization_busy_tx,\
9208 input_output_channelStats_array[i].ch_utilization_busy,\
9209 input_output_channelStats_array[i].ch_utilization_busy_ext,\
9210 input_output_channelStats_array[i].ch_utilization_total);
9211 }
9212
9213 if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
9214 {
9215 if(argc <= 3 )
9216 {
9217 printf("Insufficient arguments \n");
9218 exit(-1);
9219 }
9220 char mac_addr[20] = {'\0'};
9221 wifi_device_t output_struct;
9222 int dev_index = atoi(argv[3]);
9223
9224 wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
9225 mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
9226 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);
9227 }
9228
9229 if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
9230 {
9231 if (argc <= 3)
9232 {
9233 printf("Insufficient arguments\n");
9234 exit(-1);
9235 }
9236 char args[256];
9237 wifi_NeighborReport_t *neighborReports;
9238
9239 neighborReports = calloc(argc - 2, sizeof(neighborReports));
9240 if (!neighborReports)
9241 {
9242 printf("Failed to allocate memory");
9243 exit(-1);
9244 }
9245
9246 for (int i = 3; i < argc; ++i)
9247 {
9248 char *val;
9249 int j = 0;
9250 memset(args, 0, sizeof(args));
9251 strncpy(args, argv[i], sizeof(args));
9252 val = strtok(args, ";");
9253 while (val != NULL)
9254 {
9255 if (j == 0)
9256 {
9257 mac_addr_aton(neighborReports[i - 3].bssid, val);
9258 } else if (j == 1)
9259 {
9260 neighborReports[i - 3].info = strtol(val, NULL, 16);
9261 } else if (j == 2)
9262 {
9263 neighborReports[i - 3].opClass = strtol(val, NULL, 16);
9264 } else if (j == 3)
9265 {
9266 neighborReports[i - 3].channel = strtol(val, NULL, 16);
9267 } else if (j == 4)
9268 {
9269 neighborReports[i - 3].phyTable = strtol(val, NULL, 16);
9270 } else {
9271 printf("Insufficient arguments]n\n");
9272 exit(-1);
9273 }
9274 val = strtok(NULL, ";");
9275 j++;
9276 }
9277 }
9278
9279 INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
9280 if (ret != RETURN_OK)
9281 {
9282 printf("wifi_setNeighborReports ret = %d", ret);
9283 exit(-1);
9284 }
9285 }
9286 if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
9287 {
9288 if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
9289 printf("%s.\n", buf);
9290 else
9291 printf("Error returned\n");
9292 }
9293 if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
9294 {
9295 if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
9296 printf("%s.\n", buf);
9297 else
9298 printf("Error returned\n");
9299 }
9300 if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
9301 {
9302 if (argc <= 2)
9303 {
9304 printf("Insufficient arguments\n");
9305 exit(-1);
9306 }
9307 char buf[64]= {'\0'};
9308 wifi_getRadioOperatingChannelBandwidth(index,buf);
9309 printf("Current bandwidth is %s \n",buf);
9310 return 0;
9311 }
9312 if(strstr(argv[1],"pushRadioChannel2")!=NULL)
9313 {
9314 if (argc <= 5)
9315 {
9316 printf("Insufficient arguments\n");
9317 exit(-1);
9318 }
9319 UINT channel = atoi(argv[3]);
9320 UINT width = atoi(argv[4]);
9321 UINT beacon = atoi(argv[5]);
9322 INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
9323 printf("Result = %d", ret);
9324 }
9325
9326 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9327 return 0;
9328}
9329
9330#endif
9331
9332#ifdef WIFI_HAL_VERSION_3
9333
9334INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
9335{
9336 // The only par-radio parameter is a channel number, however there's a 'dynamic' API
9337 // to change it ("wifi_pushRadioChannel2()") that is used instead.
9338 return RETURN_OK;
9339}
9340
9341INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
9342{
9343 INT ret;
9344 char band[128];
9345 ULONG channel;
9346 BOOL enabled;
9347 char buf[256];
9348
9349 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9350 printf("Entering %s index = %d\n", __func__, (int)index);
9351
9352 ret = wifi_getRadioEnable(index, &enabled);
9353 if (ret != RETURN_OK)
9354 {
9355 printf("%s: cannot get enabled state for radio index %d\n", __func__,
9356 index);
9357 return RETURN_ERR;
9358 }
9359 operationParam->enable = enabled;
9360
9361 memset(band, 0, sizeof(band));
9362 ret = wifi_getRadioOperatingFrequencyBand(index, band);
9363 if (ret != RETURN_OK)
9364 {
9365 printf("%s: cannot get radio band for radio index %d\n", __func__, index);
9366 return RETURN_ERR;
9367 }
9368
9369 if (!strcmp(band, "2.4GHz"))
9370 {
9371 operationParam->band = WIFI_FREQUENCY_2_4_BAND;
9372 operationParam->variant = WIFI_80211_VARIANT_N;
9373 }
9374 else if (!strcmp(band, "5GHz"))
9375 {
9376 operationParam->band = WIFI_FREQUENCY_5_BAND;
9377 operationParam->variant = WIFI_80211_VARIANT_AC;
9378 }
9379 else
9380 {
9381 printf("%s: cannot decode band for radio index %d ('%s')\n", __func__, index,
9382 band);
9383 }
9384
9385 memset(buf, 0, sizeof(buf));
9386 ret = wifi_getRadioOperatingChannelBandwidth(index, buf); // XXX: handle errors
9387 // XXX: only handle 20/40/80 modes for now
9388 if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
9389 else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
9390 else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
9391 else
9392 {
9393 printf("%s: Unknown HT mode: '%s'\n", __func__, buf);
9394 operationParam->channelWidth = 0;
9395 }
9396
9397 ret = wifi_getRadioChannel(index, &channel);
9398 if (ret != RETURN_OK)
9399 {
9400 printf("%s: Failed to get channel number for radio index %d\n", __func__, index);
9401 channel = 0;
9402 }
9403 operationParam->channel = channel;
9404 operationParam->csa_beacon_count = 15; // XXX: hardcoded for now
9405
9406 operationParam->countryCode = wifi_countrycode_US; // XXX: hardcoded for now
9407
9408 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9409 return RETURN_OK;
9410}
9411
9412static int array_index_to_vap_index(UINT radioIndex, int arrayIndex)
9413{
9414 if (radioIndex != 0 && radioIndex != 1)
9415 {
9416 printf("%s: Wrong radio index (%d)\n", __func__, index);
9417 return -1;
9418 }
9419
9420 // XXX: hardcode vap indexes for now (0,1 - home, 2,3 - backhaul 6,7 - onboard)
9421 // XXX : assumed radioIndex for 2.4 is 0 radioIndex for 5G is 1
9422
9423 return (arrayIndex * 2) + radioIndex;
9424}
9425
9426INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
9427{
9428 INT ret;
9429 int i;
9430 BOOL enabled = false;
9431 char buf[256];
9432 wifi_secur_list *secur_item;
9433 int vap_index;
9434 INT mode;
9435 map->num_vaps = 5; // XXX: this is a hack. For both radio let's support 5 vaps for now
9436
9437 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9438 printf("Entering %s index = %d\n", __func__, (int)index);
9439
9440 map->vap_array[index].radio_index = index;
9441 for (i = 0; i < 5; i++)
9442 {
9443 vap_index = array_index_to_vap_index(index, i);
9444 if (vap_index < 0)
9445 {
9446 return RETURN_ERR;
9447 }
9448
9449 strncpy(map->vap_array[i].bridge_name, "brlan0", sizeof(map->vap_array[i].bridge_name) - 1);
9450
9451 map->vap_array[i].vap_index = vap_index;
9452
9453 memset(buf, 0, sizeof(buf));
9454 wifi_getApName(vap_index, buf); // XXX: error handling
9455 strncpy(map->vap_array[i].vap_name, buf, sizeof(map->vap_array[i].vap_name) - 1);
9456
9457 ret = wifi_getSSIDEnable(vap_index, &enabled);
9458 if (ret != RETURN_OK)
9459 {
9460 printf("%s: failed to get SSIDEnable for index %d\n", __func__, i);
9461 return RETURN_ERR;
9462 }
9463 map->vap_array[i].u.bss_info.enabled = enabled;
9464
9465 memset(buf, 0, sizeof(buf));
9466 wifi_getBaseBSSID(vap_index, buf);
9467 sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
9468 &map->vap_array[i].u.bss_info.bssid[0],
9469 &map->vap_array[i].u.bss_info.bssid[1],
9470 &map->vap_array[i].u.bss_info.bssid[2],
9471 &map->vap_array[i].u.bss_info.bssid[3],
9472 &map->vap_array[i].u.bss_info.bssid[4],
9473 &map->vap_array[i].u.bss_info.bssid[5]); // XXX: handle error
9474
9475 wifi_getApSsidAdvertisementEnable(vap_index, &enabled); // XXX: error handling
9476 map->vap_array[i].u.bss_info.showSsid = enabled;
9477
9478 wifi_getApMacAddressControlMode(vap_index, &mode); // XXX: handle errors
9479 if (mode == 0) map->vap_array[i].u.bss_info.mac_filter_enable = false;
9480 else map->vap_array[i].u.bss_info.mac_filter_enable = true;
9481
9482 if (mode == 1) map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
9483 else if (mode == 2) map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list; // XXX: handle wrong mode
9484
9485 memset(buf, 0, sizeof(buf));
9486 wifi_getSSIDNameStatus(vap_index, buf); // XXX: error handling
9487 strncpy(map->vap_array[i].u.bss_info.ssid, buf, sizeof(map->vap_array[i].u.bss_info.ssid) - 1);
9488
9489 wifi_getApSecurityModeEnabled(vap_index, buf);
9490
9491 if (!(secur_item = wifi_get_item_by_str(ARRAY_AND_SIZE(map_security), buf)))
9492 {
9493 printf("%s: ssid_index %d: Failed to decode security mode (%s)\n", __func__, vap_index, buf);
9494 return RETURN_ERR;
9495 }
9496 map->vap_array[i].u.bss_info.security.mode = secur_item->key;
9497
9498 memset(buf, 0, sizeof(buf));
9499 wifi_getApSecurityKeyPassphrase(vap_index, buf); // XXX: error handling
9500 strncpy(map->vap_array[i].u.bss_info.security.u.key.key, buf, sizeof(map->vap_array[i].u.bss_info.security.u.key.key) - 1);
9501
9502 wifi_getNeighborReportActivation(vap_index, &enabled); // XXX: error handling
9503 map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
9504
9505 wifi_getBSSTransitionActivation(vap_index, &enabled); // XXX: error handling
9506 map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
9507
9508 wifi_getApIsolationEnable(vap_index, &enabled);
9509 map->vap_array[i].u.bss_info.isolation = enabled;
9510 }
9511 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9512 return RETURN_OK;
9513}
9514
9515INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
9516{
9517 unsigned int i;
9518 wifi_vap_info_t *vap_info = NULL;
9519 int acl_mode;
9520 char *sec_str = NULL;
9521
9522 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9523 printf("Entering %s index = %d\n", __func__, (int)index);
9524 for (i = 0; i < map->num_vaps; i++)
9525 {
9526 vap_info = &map->vap_array[i];
9527 printf("Create VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i);
9528
9529 if (vap_info->u.bss_info.mac_filter_enable == false) acl_mode = 0;
9530 else
9531 {
9532 if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list) acl_mode = 2;
9533 else acl_mode = 1;
9534 }
9535 wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode); // XXX: handle errors
9536 wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid); // XXX: handle errors
9537 wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid); // XXX: handle errors
9538
9539 sec_str = wifi_get_str_by_key(ARRAY_AND_SIZE(map_security), vap_info->u.bss_info.security.mode);
9540 if (sec_str)
9541 {
9542 wifi_setApSecurityModeEnabled(vap_info->vap_index, sec_str); // XXX: handle errors
9543 }
9544 else
9545 {
9546 printf("Cannot map security mode: %d\n", (int)vap_info->u.bss_info.security.mode);
9547 }
9548
9549 wifi_setApSecurityKeyPassphrase(vap_info->vap_index, vap_info->u.bss_info.security.u.key.key); // XXX: handle errors, handle radius
9550 wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
9551
9552 wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated); // XXX: handle errors
9553 wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated); // XXX: handle errors
9554
9555 printf("Calling wifi_applySSIDSettings for index: %d\n", vap_info->vap_index);
9556
9557 wifi_setSSIDEnable(vap_info->vap_index, vap_info->u.bss_info.enabled); // XXX: handle errors
9558 wifi_applySSIDSettings(vap_info->vap_index); // XXX: handle errors, don't call if no changes.
9559 }
9560 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9561 return RETURN_OK;
9562}
9563
9564int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
9565{
9566 char *token, *next;
9567 const char s[2] = ",";
9568 int count =0;
9569
9570 /* get the first token */
9571 token = strtok_r(pchannels, s, &next);
9572
9573 /* walk through other tokens */
9574 while( token != NULL && count < MAX_CHANNELS) {
9575 chlistptr->channels_list[count++] = atoi(token);
9576 token = strtok_r(NULL, s, &next);
9577 }
9578
9579 return count;
9580}
9581
9582static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
9583{
9584 INT status;
9585 wifi_channels_list_t *chlistp;
9586 CHAR output_string[64];
9587 CHAR pchannels[128];
9588
9589 if(rcap == NULL)
9590 {
9591 return RETURN_ERR;
9592 }
9593
9594 rcap->numSupportedFreqBand = 1;
9595 if (1 == radioIndex)
9596 rcap->band[0] = WIFI_FREQUENCY_5_BAND;
9597 else
9598 rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
9599
9600
9601 chlistp = &(rcap->channel_list[0]);
9602 memset(pchannels, 0, sizeof(pchannels));
9603
9604 /* possible number of radio channels */
9605 status = wifi_getRadioPossibleChannels(radioIndex, pchannels);
9606 {
9607 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels);
9608 }
9609 /* Number of channels and list*/
9610 chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
9611
9612 /* autoChannelSupported */
9613 /* always ON with wifi_getRadioAutoChannelSupported */
9614 rcap->autoChannelSupported = TRUE;
9615
9616 /* DCSSupported */
9617 /* always ON with wifi_getRadioDCSSupported */
9618 rcap->DCSSupported = TRUE;
9619
9620 /* zeroDFSSupported - TBD */
9621 rcap->zeroDFSSupported = FALSE;
9622
9623 /* Supported Country List*/
9624 memset(output_string, 0, sizeof(output_string));
9625 status = wifi_getRadioCountryCode(radioIndex, output_string);
9626 if( status != 0 ) {
9627 printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string);
9628 return RETURN_ERR;
9629 } else {
9630 printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string);
9631 }
9632 if(!strcmp(output_string,"US")){
9633 rcap->countrySupported[0] = wifi_countrycode_US;
9634 rcap->countrySupported[1] = wifi_countrycode_CA;
9635 } else if (!strcmp(output_string,"CA")) {
9636 rcap->countrySupported[0] = wifi_countrycode_CA;
9637 rcap->countrySupported[1] = wifi_countrycode_US;
9638 } else {
9639 printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string);
9640 }
9641
9642 rcap->numcountrySupported = 2;
9643
9644 /* csi */
9645 rcap->csi.maxDevices = 8;
9646 rcap->csi.soudingFrameSupported = TRUE;
9647
9648 snprintf(rcap->ifaceName, 64, "wlan%d", radioIndex);
9649
9650 /* channelWidth - all supported bandwidths */
9651 int i=0;
9652 rcap->channelWidth[i] = 0;
9653 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
9654 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
9655 WIFI_CHANNELBANDWIDTH_40MHZ);
9656
9657 }
9658 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) {
9659 rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
9660 WIFI_CHANNELBANDWIDTH_40MHZ |
9661 WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
9662 }
9663
9664
9665 /* mode - all supported variants */
9666 // rcap->mode[i] = WIFI_80211_VARIANT_H;
9667 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
9668 rcap->mode[i] = (WIFI_80211_VARIANT_N);
9669 }
9670 else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
9671 rcap->mode[i] = ( WIFI_80211_VARIANT_AC );
9672 }
9673 rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
9674 ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
9675
9676 /* supportedBitRate - all supported bitrates */
9677 rcap->supportedBitRate[i] = 0;
9678 if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
9679 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
9680 WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
9681 }
9682 else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) {
9683 rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
9684 WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
9685 WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
9686 }
9687
9688
9689 rcap->transmitPowerSupported_list[i].numberOfElements = 5;
9690 rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
9691 rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
9692 rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
9693 rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
9694 rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
9695 rcap->cipherSupported = 0;
9696 rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
9697 rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO;
9698
9699 return RETURN_OK;
9700}
9701
9702INT wifi_getHalCapability(wifi_hal_capability_t *cap)
9703{
9704 INT status, radioIndex;
9705 char cmd[MAX_BUF_SIZE], output[MAX_BUF_SIZE];
9706 int iter = 0;
9707 unsigned int j;
9708 wifi_interface_name_idex_map_t *iface_info;
9709
9710 WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
9711
9712 memset(cap, 0, sizeof(wifi_hal_capability_t));
9713
9714 /* version */
9715 cap->version.major = WIFI_HAL_MAJOR_VERSION;
9716 cap->version.minor = WIFI_HAL_MINOR_VERSION;
9717
9718 /* number of radios platform property */
9719 snprintf(cmd, sizeof(cmd), "ls -d /sys/class/net/wlan* | wc -l");
9720 _syscmd(cmd, output, sizeof(output));
9721 cap->wifi_prop.numRadios = atoi(output);
9722
9723 for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
9724 {
9725 status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
9726 if (status != 0) {
9727 printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex);
9728 return RETURN_ERR;
9729 }
9730
9731 for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
9732 {
9733 if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO)
9734 {
9735 printf("%s: to many vaps for index map (%d)\n", __func__, iter);
9736 return RETURN_ERR;
9737 }
9738 iface_info = &cap->wifi_prop.interface_map[iter];
9739 iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
9740 iface_info->rdk_radio_index = radioIndex;
9741 memset(output, 0, sizeof(output));
9742 if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK)
9743 {
9744 strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
9745 }
9746 // TODO: bridge name
9747 // TODO: vlan id
9748 // TODO: primary
9749 iface_info->index = array_index_to_vap_index(radioIndex, j);
9750 memset(output, 0, sizeof(output));
9751 if (iface_info >= 0 && wifi_getApName(iface_info->index, output) == RETURN_OK)
9752 {
9753 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
9754 }
9755 iter++;
9756 }
9757 }
9758
9759 cap->BandSteeringSupported = FALSE;
9760 WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
9761 return RETURN_OK;
9762}
9763
9764INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
9765{
9766 //TODO
9767 return RETURN_OK;
9768}
9769
9770INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
9771{
9772 //TODO
9773 return RETURN_OK;
9774}
9775
9776#endif /* WIFI_HAL_VERSION_3 */
9777
9778#ifdef WIFI_HAL_VERSION_3_PHASE2
9779INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
9780{
9781 return RETURN_OK;
9782}
9783#else
9784INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
9785{
9786 char cmd[128];
9787 BOOL status = false;
9788
9789 if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
9790 return RETURN_ERR;
9791
9792 output_buf[0] = '\0';
9793
9794 wifi_getApEnable(ap_index,&status);
9795 if (!status)
9796 return RETURN_OK;
9797
9798 sprintf(cmd, "hostapd_cli -i %s%d list_sta | tr '\\n' ',' | sed 's/.$//'", AP_PREFIX, ap_index);
9799 _syscmd(cmd, output_buf, output_buf_size);
9800
9801 return RETURN_OK;
9802}
9803#endif
developer2f513ab2022-09-13 14:26:06 +08009804
9805INT wifi_getProxyArp(INT apIndex, BOOL *enable)
9806{
9807 char output[16]={'\0'};
9808 char config_file[MAX_BUF_SIZE] = {0};
9809
9810 if (!enable)
9811 return RETURN_ERR;
9812
9813 sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex);
9814 wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
9815
9816 if (strlen(output) == 0)
9817 *enable = FALSE;
9818 else if (strncmp(output, "1", 1) == 0)
9819 *enable = TRUE;
9820 else
9821 *enable = FALSE;
9822
9823 wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output);
9824 return RETURN_OK;
9825}