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