developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1 | /* |
| 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: |
| 31 | Copyright (c) 2007, 2008 Johannes Berg |
| 32 | Copyright (c) 2007 Andy Lutomirski |
| 33 | Copyright (c) 2007 Mike Kershaw |
| 34 | Copyright (c) 2008-2009 Luis R. Rodriguez |
| 35 | Licensed under the ISC license |
| 36 | */ |
developer | da1ed69 | 2022-09-13 13:59:20 +0800 | [diff] [blame] | 37 | #define MTK_IMPL |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 38 | #define HAL_NETLINK_IMPL |
| 39 | #define _GNU_SOURCE /* needed for strcasestr */ |
| 40 | |
| 41 | #include <stdio.h> |
| 42 | #include <stdlib.h> |
| 43 | #include <unistd.h> |
| 44 | #include <string.h> |
| 45 | #include <fcntl.h> |
| 46 | #include <stdbool.h> |
| 47 | #include "wifi_hal.h" |
| 48 | |
| 49 | #ifdef HAL_NETLINK_IMPL |
| 50 | #include <errno.h> |
| 51 | #include <netlink/attr.h> |
| 52 | #include <netlink/netlink.h> |
| 53 | #include <netlink/genl/genl.h> |
| 54 | #include <netlink/genl/family.h> |
| 55 | #include <netlink/genl/ctrl.h> |
| 56 | #include <linux/nl80211.h> |
| 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" |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 71 | #define ACL_PREFIX "/nvram/hostapd-acl" |
| 72 | #define DENY_PREFIX "/nvram/hostapd-deny" |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 73 | //#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention |
| 74 | #define SOCK_PREFIX "/var/run/hostapd/wifi" |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 75 | #define VAP_STATUS_FILE "/nvram/vap-status" |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 76 | #define ESSID_FILE "/tmp/essid" |
developer | 247302b | 2022-10-06 15:03:00 +0800 | [diff] [blame] | 77 | #define GUARD_INTERVAL_FILE "/nvram/guard-interval" |
developer | a748dcf | 2022-09-13 15:56:48 +0800 | [diff] [blame] | 78 | #define CHANNEL_STATS_FILE "/tmp/channel_stats" |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 79 | #define DFS_ENABLE_FILE "/nvram/dfs_enable.txt" |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 80 | #define VLAN_FILE "/nvram/hostapd.vlan" |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 81 | #define PSK_FILE "/nvram/hostapd" |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 82 | #define CHAIN_MASK_FILE "/tmp/chain_mask" |
developer | 54e6b9f | 2022-09-28 14:41:20 +0800 | [diff] [blame] | 83 | #define AMSDU_FILE "/tmp/AMSDU" |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 84 | #define MCS_FILE "/tmp/MCS" |
developer | 6daeb3f | 2022-09-30 13:36:39 +0800 | [diff] [blame] | 85 | #define NOACK_MAP_FILE "/tmp/NoAckMap" |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 86 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 87 | #define DRIVER_2GHZ "ath9k" |
| 88 | #define DRIVER_5GHZ "ath10k_pci" |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 89 | #define BRIDGE_NAME "brlan0" |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 90 | |
| 91 | /* |
| 92 | MAX_APS - Number of all AP available in system |
| 93 | 2x Home AP |
| 94 | 2x Backhaul AP |
| 95 | 2x Guest AP |
| 96 | 2x Secure Onboard AP |
| 97 | 2x Service AP |
| 98 | |
| 99 | */ |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 100 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 101 | |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 102 | #define MAX_APS MAX_NUM_RADIOS*5 |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 103 | #ifndef AP_PREFIX |
| 104 | #define AP_PREFIX "wifi" |
| 105 | #endif |
| 106 | |
| 107 | #ifndef RADIO_PREFIX |
| 108 | #define RADIO_PREFIX "wlan" |
| 109 | #endif |
| 110 | |
| 111 | #define MAX_BUF_SIZE 128 |
| 112 | #define MAX_CMD_SIZE 1024 |
developer | 0947e1a | 2022-09-13 14:15:25 +0800 | [diff] [blame] | 113 | #define MAX_ASSOCIATED_STA_NUM 2007 |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 114 | |
| 115 | //Uncomment to enable debug logs |
| 116 | //#define WIFI_DEBUG |
| 117 | |
| 118 | #ifdef WIFI_DEBUG |
| 119 | #define wifi_dbg_printf printf |
| 120 | #define WIFI_ENTRY_EXIT_DEBUG printf |
| 121 | #else |
| 122 | #define wifi_dbg_printf(format, args...) printf("") |
| 123 | #define WIFI_ENTRY_EXIT_DEBUG(format, args...) printf("") |
| 124 | #endif |
| 125 | |
| 126 | #define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g |
| 127 | #define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g |
| 128 | #define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g |
| 129 | #define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g |
| 130 | #define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf" |
| 131 | #define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf" |
| 132 | #define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf" |
| 133 | #define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf" |
| 134 | #define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg" |
| 135 | #define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s" |
| 136 | |
developer | 4fb0b92 | 2022-09-30 14:29:09 +0800 | [diff] [blame] | 137 | #define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]" |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 138 | |
| 139 | #define BW_FNAME "/nvram/bw_file.txt" |
| 140 | |
| 141 | #define PS_MAX_TID 16 |
| 142 | |
| 143 | static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = { |
| 144 | WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */ |
| 145 | WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */ |
| 146 | WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */ |
| 147 | WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */ |
| 148 | WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */ |
| 149 | WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */ |
| 150 | WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */ |
| 151 | WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */ |
| 152 | WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */ |
| 153 | WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */ |
| 154 | WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */ |
| 155 | WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */ |
| 156 | WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */ |
| 157 | WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */ |
| 158 | WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */ |
| 159 | WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */ |
| 160 | }; |
| 161 | |
| 162 | typedef unsigned long long u64; |
| 163 | |
| 164 | /* Enum to define WiFi Bands */ |
| 165 | typedef enum |
| 166 | { |
| 167 | band_invalid = -1, |
| 168 | band_2_4 = 0, |
| 169 | band_5 = 1, |
developer | c707e97 | 2022-09-13 15:38:02 +0800 | [diff] [blame] | 170 | band_6 = 2, |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 171 | } wifi_band; |
| 172 | |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 173 | typedef enum { |
| 174 | WIFI_MODE_A = 0x01, |
| 175 | WIFI_MODE_B = 0x02, |
| 176 | WIFI_MODE_G = 0x04, |
| 177 | WIFI_MODE_N = 0x08, |
| 178 | WIFI_MODE_AC = 0x10, |
| 179 | WIFI_MODE_AX = 0x20, |
| 180 | } wifi_ieee80211_Mode; |
| 181 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 182 | #ifdef WIFI_HAL_VERSION_3 |
| 183 | |
| 184 | // Return number of elements in array |
| 185 | #ifndef ARRAY_SIZE |
| 186 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) |
| 187 | #endif /* ARRAY_SIZE */ |
| 188 | |
| 189 | #ifndef ARRAY_AND_SIZE |
| 190 | #define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x) |
| 191 | #endif /* ARRAY_AND_SIZE */ |
| 192 | |
| 193 | #define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str} |
| 194 | |
| 195 | typedef struct { |
| 196 | int32_t value; |
| 197 | int32_t param; |
| 198 | intptr_t key; |
| 199 | intptr_t data; |
| 200 | } wifi_secur_list; |
| 201 | |
| 202 | wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key); |
| 203 | wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str); |
| 204 | char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 205 | static int ieee80211_channel_to_frequency(int channel, int *freqMHz); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 206 | |
| 207 | static wifi_secur_list map_security[] = |
| 208 | { |
| 209 | WIFI_ITEM_STR(wifi_security_mode_none, "None"), |
| 210 | WIFI_ITEM_STR(wifi_security_mode_wep_64, "WEP-64"), |
| 211 | WIFI_ITEM_STR(wifi_security_mode_wep_128, "WEP-128"), |
| 212 | WIFI_ITEM_STR(wifi_security_mode_wpa_personal, "WPA-Personal"), |
| 213 | WIFI_ITEM_STR(wifi_security_mode_wpa_enterprise, "WPA-Enterprise"), |
| 214 | WIFI_ITEM_STR(wifi_security_mode_wpa2_personal, "WPA2-Personal"), |
| 215 | WIFI_ITEM_STR(wifi_security_mode_wpa2_enterprise, "WPA2-Enterprise"), |
| 216 | WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_personal, "WPA-WPA2-Personal"), |
developer | c083031 | 2022-10-13 13:22:36 +0800 | [diff] [blame] | 217 | WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_enterprise, "WPA-WPA2-Enterprise"), |
| 218 | WIFI_ITEM_STR(wifi_security_mode_wpa3_personal, "WPA3-Personal"), |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 219 | WIFI_ITEM_STR(wifi_security_mode_wpa3_transition, "WPA3-Personal-Transition"), |
developer | c083031 | 2022-10-13 13:22:36 +0800 | [diff] [blame] | 220 | WIFI_ITEM_STR(wifi_security_mode_wpa3_enterprise, "WPA3-Enterprise") |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 221 | }; |
| 222 | |
| 223 | wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key) |
| 224 | { |
| 225 | wifi_secur_list *item; |
| 226 | int i; |
| 227 | |
| 228 | for (item = list,i = 0;i < list_sz; item++, i++) { |
| 229 | if ((int)(item->key) == key) { |
| 230 | return item; |
| 231 | } |
| 232 | } |
| 233 | |
| 234 | return NULL; |
| 235 | } |
| 236 | |
| 237 | char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key) |
| 238 | { |
| 239 | wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key); |
| 240 | |
| 241 | if (!item) { |
| 242 | return ""; |
| 243 | } |
| 244 | |
| 245 | return (char *)(item->data); |
| 246 | } |
| 247 | |
| 248 | wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str) |
| 249 | { |
| 250 | wifi_secur_list *item; |
| 251 | int i; |
| 252 | |
| 253 | for (item = list,i = 0;i < list_sz; item++, i++) { |
| 254 | if (strcmp((char *)(item->data), str) == 0) { |
| 255 | return item; |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | return NULL; |
| 260 | } |
| 261 | #endif /* WIFI_HAL_VERSION_3 */ |
| 262 | |
| 263 | #ifdef HAL_NETLINK_IMPL |
| 264 | typedef struct { |
| 265 | int id; |
| 266 | struct nl_sock* socket; |
| 267 | struct nl_cb* cb; |
| 268 | } Netlink; |
| 269 | |
| 270 | static int mac_addr_aton(unsigned char *mac_addr, char *arg) |
| 271 | { |
| 272 | unsigned int mac_addr_int[6]={}; |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 273 | sscanf(arg, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int+0, mac_addr_int+1, mac_addr_int+2, mac_addr_int+3, mac_addr_int+4, mac_addr_int+5); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 274 | mac_addr[0] = mac_addr_int[0]; |
| 275 | mac_addr[1] = mac_addr_int[1]; |
| 276 | mac_addr[2] = mac_addr_int[2]; |
| 277 | mac_addr[3] = mac_addr_int[3]; |
| 278 | mac_addr[4] = mac_addr_int[4]; |
| 279 | mac_addr[5] = mac_addr_int[5]; |
| 280 | return 0; |
| 281 | } |
| 282 | |
| 283 | static void mac_addr_ntoa(char *mac_addr, unsigned char *arg) |
| 284 | { |
| 285 | unsigned int mac_addr_int[6]={}; |
| 286 | mac_addr_int[0] = arg[0]; |
| 287 | mac_addr_int[1] = arg[1]; |
| 288 | mac_addr_int[2] = arg[2]; |
| 289 | mac_addr_int[3] = arg[3]; |
| 290 | mac_addr_int[4] = arg[4]; |
| 291 | mac_addr_int[5] = arg[5]; |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 292 | snprintf(mac_addr, 20, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int[0], mac_addr_int[1],mac_addr_int[2],mac_addr_int[3],mac_addr_int[4],mac_addr_int[5]); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 293 | return; |
| 294 | } |
| 295 | |
| 296 | static int ieee80211_frequency_to_channel(int freq) |
| 297 | { |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 298 | /* see 802.11-2007 17.3.8.3.2 and Annex J */ |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 299 | if (freq == 2484) |
| 300 | return 14; |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 301 | /* see 802.11ax D6.1 27.3.23.2 and Annex E */ |
| 302 | else if (freq == 5935) |
| 303 | return 2; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 304 | else if (freq < 2484) |
| 305 | return (freq - 2407) / 5; |
| 306 | else if (freq >= 4910 && freq <= 4980) |
| 307 | return (freq - 4000) / 5; |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 308 | else if (freq < 5950) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 309 | return (freq - 5000) / 5; |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 310 | else if (freq <= 45000) /* DMG band lower limit */ |
| 311 | /* see 802.11ax D6.1 27.3.23.2 */ |
| 312 | return (freq - 5950) / 5; |
| 313 | else if (freq >= 58320 && freq <= 70200) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 314 | return (freq - 56160) / 2160; |
| 315 | else |
| 316 | return 0; |
| 317 | } |
| 318 | |
| 319 | static int initSock80211(Netlink* nl) { |
| 320 | nl->socket = nl_socket_alloc(); |
| 321 | if (!nl->socket) { |
| 322 | fprintf(stderr, "Failing to allocate the sock\n"); |
| 323 | return -ENOMEM; |
| 324 | } |
| 325 | |
| 326 | nl_socket_set_buffer_size(nl->socket, 8192, 8192); |
| 327 | |
| 328 | if (genl_connect(nl->socket)) { |
| 329 | fprintf(stderr, "Failed to connect\n"); |
| 330 | nl_close(nl->socket); |
| 331 | nl_socket_free(nl->socket); |
| 332 | return -ENOLINK; |
| 333 | } |
| 334 | |
| 335 | nl->id = genl_ctrl_resolve(nl->socket, "nl80211"); |
| 336 | if (nl->id< 0) { |
| 337 | fprintf(stderr, "interface not found.\n"); |
| 338 | nl_close(nl->socket); |
| 339 | nl_socket_free(nl->socket); |
| 340 | return -ENOENT; |
| 341 | } |
| 342 | |
| 343 | nl->cb = nl_cb_alloc(NL_CB_DEFAULT); |
| 344 | if ((!nl->cb)) { |
| 345 | fprintf(stderr, "Failed to allocate netlink callback.\n"); |
| 346 | nl_close(nl->socket); |
| 347 | nl_socket_free(nl->socket); |
| 348 | return ENOMEM; |
| 349 | } |
| 350 | |
| 351 | return nl->id; |
| 352 | } |
| 353 | |
| 354 | static int nlfree(Netlink *nl) |
| 355 | { |
| 356 | nl_cb_put(nl->cb); |
| 357 | nl_close(nl->socket); |
| 358 | nl_socket_free(nl->socket); |
| 359 | return 0; |
| 360 | } |
| 361 | |
| 362 | static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { |
| 363 | [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED }, |
| 364 | [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED }, |
| 365 | [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED } |
| 366 | }; |
| 367 | |
| 368 | static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { |
| 369 | }; |
| 370 | |
| 371 | static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = { |
| 372 | }; |
| 373 | |
| 374 | typedef struct _wifi_channelStats_loc { |
| 375 | INT array_size; |
| 376 | INT ch_number; |
| 377 | BOOL ch_in_pool; |
| 378 | INT ch_noise; |
| 379 | BOOL ch_radar_noise; |
| 380 | INT ch_max_80211_rssi; |
| 381 | INT ch_non_80211_noise; |
| 382 | INT ch_utilization; |
| 383 | ULLONG ch_utilization_total; |
| 384 | ULLONG ch_utilization_busy; |
| 385 | ULLONG ch_utilization_busy_tx; |
| 386 | ULLONG ch_utilization_busy_rx; |
| 387 | ULLONG ch_utilization_busy_self; |
| 388 | ULLONG ch_utilization_busy_ext; |
| 389 | } wifi_channelStats_t_loc; |
| 390 | |
| 391 | typedef struct wifi_device_info { |
| 392 | INT wifi_devIndex; |
| 393 | UCHAR wifi_devMacAddress[6]; |
| 394 | CHAR wifi_devIPAddress[64]; |
| 395 | BOOL wifi_devAssociatedDeviceAuthentiationState; |
| 396 | INT wifi_devSignalStrength; |
| 397 | INT wifi_devTxRate; |
| 398 | INT wifi_devRxRate; |
| 399 | } wifi_device_info_t; |
| 400 | |
| 401 | #endif |
| 402 | |
| 403 | //For 5g Alias Interfaces |
| 404 | static BOOL priv_flag = TRUE; |
| 405 | static BOOL pub_flag = TRUE; |
| 406 | static BOOL Radio_flag = TRUE; |
| 407 | //wifi_setApBeaconRate(1, beaconRate); |
| 408 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 409 | BOOL multiple_set = FALSE; |
| 410 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 411 | struct params |
| 412 | { |
| 413 | char * name; |
| 414 | char * value; |
| 415 | }; |
| 416 | |
| 417 | static int _syscmd(char *cmd, char *retBuf, int retBufSize) |
| 418 | { |
| 419 | FILE *f; |
| 420 | char *ptr = retBuf; |
| 421 | int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0; |
| 422 | |
| 423 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 424 | if((f = popen(cmd, "r")) == NULL) { |
| 425 | fprintf(stderr,"\npopen %s error\n", cmd); |
| 426 | return RETURN_ERR; |
| 427 | } |
| 428 | |
| 429 | while(!feof(f)) |
| 430 | { |
| 431 | *ptr = 0; |
| 432 | if(bufSize>=128) { |
| 433 | bufbytes=128; |
| 434 | } else { |
| 435 | bufbytes=bufSize-1; |
| 436 | } |
| 437 | |
| 438 | fgets(ptr,bufbytes,f); |
| 439 | readbytes=strlen(ptr); |
| 440 | |
| 441 | if(!readbytes) |
| 442 | break; |
| 443 | |
| 444 | bufSize-=readbytes; |
| 445 | ptr += readbytes; |
| 446 | } |
| 447 | cmd_ret = pclose(f); |
| 448 | retBuf[retBufSize-1]=0; |
| 449 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 450 | |
| 451 | return cmd_ret >> 8; |
| 452 | } |
| 453 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 454 | INT radio_index_to_phy(int radioIndex) |
| 455 | { |
| 456 | char cmd[128] = {0}; |
| 457 | char buf[64] = {0}; |
| 458 | int phyIndex = 0; |
| 459 | snprintf(cmd, sizeof(cmd), "ls /tmp | grep wifi%d | cut -d '-' -f1 | tr -d '\n'", radioIndex); |
| 460 | _syscmd(cmd, buf, sizeof(buf)); |
| 461 | |
| 462 | if (strlen(buf) == 0 || strstr(buf, "phy") == NULL) { |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 463 | fprintf(stderr, "%s: failed to get phy index with: %d\n", __func__, radioIndex); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 464 | return RETURN_ERR; |
| 465 | } |
| 466 | sscanf(buf, "phy%d", &phyIndex); |
| 467 | |
| 468 | return phyIndex; |
| 469 | } |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 470 | |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 471 | INT wifi_getMaxRadioNumber(INT *max_radio_num) |
| 472 | { |
| 473 | char cmd[64] = {0}; |
| 474 | char buf[4] = {0}; |
| 475 | |
| 476 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 477 | |
| 478 | snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l"); |
| 479 | _syscmd(cmd, buf, sizeof(buf)); |
| 480 | *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10); |
| 481 | |
| 482 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 483 | |
| 484 | return RETURN_OK; |
| 485 | } |
| 486 | |
| 487 | wifi_band wifi_index_to_band(int apIndex) |
developer | c707e97 | 2022-09-13 15:38:02 +0800 | [diff] [blame] | 488 | { |
| 489 | char cmd[128] = {0}; |
| 490 | char buf[64] = {0}; |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 491 | int nl80211_band = 0; |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 492 | int i = 0; |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 493 | int phyIndex = 0; |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 494 | int radioIndex = 0; |
| 495 | int max_radio_num = 0; |
developer | c707e97 | 2022-09-13 15:38:02 +0800 | [diff] [blame] | 496 | wifi_band band = band_invalid; |
| 497 | |
| 498 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 499 | |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 500 | wifi_getMaxRadioNumber(&max_radio_num); |
| 501 | radioIndex = apIndex % max_radio_num; |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 502 | phyIndex = radio_index_to_phy(radioIndex); |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 503 | while(i < 10){ |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 504 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex); |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 505 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 506 | nl80211_band = strtol(buf, NULL, 10); |
| 507 | if (nl80211_band == 1) |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 508 | band = band_2_4; |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 509 | else if (nl80211_band == 2) |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 510 | band = band_5; |
developer | 026ac9e | 2022-11-07 13:46:24 +0800 | [diff] [blame] | 511 | else if (nl80211_band == 4) // band == 3 is 60GHz |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 512 | band = band_6; |
| 513 | |
| 514 | if(band != band_invalid) |
| 515 | break; |
| 516 | |
| 517 | i++; |
| 518 | sleep(1); |
| 519 | } |
developer | c707e97 | 2022-09-13 15:38:02 +0800 | [diff] [blame] | 520 | |
| 521 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 522 | return band; |
| 523 | } |
| 524 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 525 | static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size) |
| 526 | { |
| 527 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 528 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 529 | int ret = 0; |
| 530 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 531 | sprintf(cmd, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file, param); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 532 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 533 | if ((ret != 0) && (strlen(buf) == 0)) |
| 534 | return -1; |
| 535 | snprintf(output, output_size, "%s", buf); |
| 536 | |
| 537 | return 0; |
| 538 | } |
| 539 | |
| 540 | static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count) |
| 541 | { |
| 542 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 543 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 544 | |
| 545 | for(int i=0;i<item_count;i++) |
| 546 | { |
| 547 | wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf)); |
| 548 | if (strlen(buf) == 0) //Insert |
| 549 | snprintf(cmd, sizeof(cmd), "echo \"%s=%s\" >> %s", list[i].name, list[i].value, conf_file); |
| 550 | else //Update |
| 551 | snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file); |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 552 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 553 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 554 | return -1; |
| 555 | } |
| 556 | |
| 557 | return 0; |
| 558 | } |
| 559 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 560 | //For Getting Current Interface Name from corresponding hostapd configuration |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 561 | static int wifi_GetInterfaceName(int apIndex, char *interface_name) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 562 | { |
| 563 | char config_file[128] = {0}; |
| 564 | |
| 565 | if (interface_name == NULL) |
| 566 | return RETURN_ERR; |
| 567 | |
| 568 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 569 | |
| 570 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 571 | wifi_hostapdRead(config_file, "interface", interface_name, 16); |
| 572 | if (strlen(interface_name) == 0) |
| 573 | return RETURN_ERR; |
| 574 | |
| 575 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 576 | return RETURN_OK; |
| 577 | } |
| 578 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 579 | // wifi agent will call this function, do not change the parameter |
| 580 | void GetInterfaceName(char *interface_name, char *conf_file) |
| 581 | { |
| 582 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 583 | wifi_hostapdRead(conf_file,"interface",interface_name, IF_NAME_SIZE); |
| 584 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 585 | } |
| 586 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 587 | static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count) |
| 588 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 589 | char interface_name[16] = {0}; |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 590 | if (multiple_set == TRUE) |
| 591 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 592 | char cmd[MAX_CMD_SIZE]="", output[32]=""; |
| 593 | FILE *fp; |
| 594 | int i; |
| 595 | //NOTE RELOAD should be done in ApplySSIDSettings |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 596 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 597 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 598 | for(i=0; i<item_count; i++, list++) |
| 599 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 600 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 601 | if((fp = popen(cmd, "r"))==NULL) |
| 602 | { |
| 603 | perror("popen failed"); |
| 604 | return -1; |
| 605 | } |
| 606 | if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) |
| 607 | { |
| 608 | pclose(fp); |
| 609 | perror("fgets failed"); |
| 610 | return -1; |
| 611 | } |
| 612 | pclose(fp); |
| 613 | } |
| 614 | return 0; |
| 615 | } |
| 616 | |
| 617 | static int wifi_reloadAp(int apIndex) |
| 618 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 619 | char interface_name[16] = {0}; |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 620 | if (multiple_set == TRUE) |
| 621 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 622 | char cmd[MAX_CMD_SIZE]=""; |
| 623 | char buf[MAX_BUF_SIZE]=""; |
| 624 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 625 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 626 | return RETURN_ERR; |
| 627 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 628 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 629 | return RETURN_ERR; |
| 630 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 631 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 632 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 633 | return RETURN_ERR; |
| 634 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 635 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 636 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 637 | return RETURN_ERR; |
| 638 | |
| 639 | return RETURN_OK; |
| 640 | } |
| 641 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 642 | INT File_Reading(CHAR *file, char *Value) |
| 643 | { |
| 644 | FILE *fp = NULL; |
| 645 | char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0}; |
| 646 | int count = 0; |
| 647 | |
| 648 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 649 | fp = popen(file,"r"); |
| 650 | if(fp == NULL) |
| 651 | return RETURN_ERR; |
| 652 | |
| 653 | if(fgets(buf,sizeof(buf) -1,fp) != NULL) |
| 654 | { |
| 655 | for(count=0;buf[count]!='\n';count++) |
| 656 | copy_buf[count]=buf[count]; |
| 657 | copy_buf[count]='\0'; |
| 658 | } |
| 659 | strcpy(Value,copy_buf); |
| 660 | pclose(fp); |
| 661 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 662 | |
| 663 | return RETURN_OK; |
| 664 | } |
| 665 | |
| 666 | void wifi_RestartHostapd_2G() |
| 667 | { |
| 668 | int Public2GApIndex = 4; |
| 669 | |
| 670 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 671 | wifi_setApEnable(Public2GApIndex, FALSE); |
| 672 | wifi_setApEnable(Public2GApIndex, TRUE); |
| 673 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 674 | } |
| 675 | |
| 676 | void wifi_RestartHostapd_5G() |
| 677 | { |
| 678 | int Public5GApIndex = 5; |
| 679 | |
| 680 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 681 | wifi_setApEnable(Public5GApIndex, FALSE); |
| 682 | wifi_setApEnable(Public5GApIndex, TRUE); |
| 683 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 684 | } |
| 685 | |
| 686 | void wifi_RestartPrivateWifi_2G() |
| 687 | { |
| 688 | int PrivateApIndex = 0; |
| 689 | |
| 690 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 691 | wifi_setApEnable(PrivateApIndex, FALSE); |
| 692 | wifi_setApEnable(PrivateApIndex, TRUE); |
| 693 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 694 | } |
| 695 | |
| 696 | void wifi_RestartPrivateWifi_5G() |
| 697 | { |
| 698 | int Private5GApIndex = 1; |
| 699 | |
| 700 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 701 | wifi_setApEnable(Private5GApIndex, FALSE); |
| 702 | wifi_setApEnable(Private5GApIndex, TRUE); |
| 703 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 704 | } |
| 705 | |
| 706 | static int writeBandWidth(int radioIndex,char *bw_value) |
| 707 | { |
| 708 | char buf[MAX_BUF_SIZE]; |
| 709 | char cmd[MAX_CMD_SIZE]; |
| 710 | |
| 711 | snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME); |
| 712 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 713 | { |
| 714 | snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME); |
| 715 | _syscmd(cmd, buf, sizeof(buf)); |
| 716 | return RETURN_OK; |
| 717 | } |
| 718 | |
| 719 | sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME); |
| 720 | _syscmd(cmd,buf,sizeof(buf)); |
| 721 | return RETURN_OK; |
| 722 | } |
| 723 | |
| 724 | static int readBandWidth(int radioIndex,char *bw_value) |
| 725 | { |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 726 | char buf[MAX_BUF_SIZE] = {0}; |
| 727 | char cmd[MAX_CMD_SIZE] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 728 | sprintf(cmd,"grep 'SET_BW%d=' %s | sed 's/^.*=//'",radioIndex,BW_FNAME); |
| 729 | _syscmd(cmd,buf,sizeof(buf)); |
| 730 | if(NULL!=strstr(buf,"20MHz")) |
| 731 | { |
| 732 | strcpy(bw_value,"20MHz"); |
| 733 | } |
| 734 | else if(NULL!=strstr(buf,"40MHz")) |
| 735 | { |
| 736 | strcpy(bw_value,"40MHz"); |
| 737 | } |
| 738 | else if(NULL!=strstr(buf,"80MHz")) |
| 739 | { |
| 740 | strcpy(bw_value,"80MHz"); |
| 741 | } |
| 742 | else |
| 743 | { |
| 744 | return RETURN_ERR; |
| 745 | } |
| 746 | return RETURN_OK; |
| 747 | } |
| 748 | |
developer | 264159b | 2022-11-02 09:41:35 +0800 | [diff] [blame] | 749 | // Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps" |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 750 | INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate) |
| 751 | { |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 752 | struct params params={'\0'}; |
| 753 | char config_file[MAX_BUF_SIZE] = {0}; |
| 754 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 755 | |
| 756 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 757 | // Copy the numeric value |
developer | 264159b | 2022-11-02 09:41:35 +0800 | [diff] [blame] | 758 | if (strlen (beaconRate) >= 5) { |
| 759 | strncpy(buf, beaconRate, strlen(beaconRate) - 4); |
| 760 | buf[strlen(beaconRate) - 4] = '\0'; |
| 761 | } else if (strlen(beaconRate) > 0) |
| 762 | strcpy(buf, beaconRate); |
| 763 | else |
| 764 | return RETURN_ERR; |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 765 | |
| 766 | params.name = "beacon_rate"; |
| 767 | // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10. |
| 768 | if (strncmp(buf, "5.5", 3) == 0) { |
| 769 | snprintf(buf, sizeof(buf), "55"); |
| 770 | params.value = buf; |
| 771 | } else { |
| 772 | strcat(buf, "0"); |
| 773 | params.value = buf; |
| 774 | } |
| 775 | |
| 776 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 777 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 778 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 779 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 780 | |
| 781 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 782 | } |
| 783 | |
| 784 | INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate) |
| 785 | { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 786 | char config_file[128] = {'\0'}; |
| 787 | char temp_output[128] = {'\0'}; |
| 788 | char buf[128] = {'\0'}; |
| 789 | char cmd[128] = {'\0'}; |
| 790 | int rate = 0; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 791 | int phyId = 0; |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 792 | |
| 793 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 794 | if (NULL == beaconRate) |
| 795 | return RETURN_ERR; |
| 796 | |
| 797 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 798 | wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf)); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 799 | phyId = radio_index_to_phy(radioIndex); |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 800 | // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10. |
| 801 | if(strlen(buf) > 0) { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 802 | if (strncmp(buf, "55", 2) == 0) |
| 803 | snprintf(temp_output, sizeof(temp_output), "5.5Mbps"); |
| 804 | else { |
| 805 | rate = strtol(buf, NULL, 10)/10; |
| 806 | snprintf(temp_output, sizeof(temp_output), "%dMbps", rate); |
| 807 | } |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 808 | } else { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 809 | // config not set, so we would use lowest rate as default |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 810 | sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 811 | _syscmd(cmd, buf, sizeof(buf)); |
| 812 | snprintf(temp_output, sizeof(temp_output), "%sMbps", buf); |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 813 | } |
| 814 | strncpy(beaconRate, temp_output, sizeof(temp_output)); |
| 815 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 816 | |
| 817 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 818 | } |
| 819 | |
| 820 | INT wifi_setLED(INT radioIndex, BOOL enable) |
| 821 | { |
| 822 | return 0; |
| 823 | } |
| 824 | INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds) |
| 825 | { |
| 826 | return RETURN_OK; |
| 827 | } |
| 828 | /********************************************************************************** |
| 829 | * |
| 830 | * Wifi Subsystem level function prototypes |
| 831 | * |
| 832 | **********************************************************************************/ |
| 833 | //--------------------------------------------------------------------------------------------------- |
| 834 | //Wifi system api |
| 835 | //Get the wifi hal version in string, eg "2.0.0". WIFI_HAL_MAJOR_VERSION.WIFI_HAL_MINOR_VERSION.WIFI_HAL_MAINTENANCE_VERSION |
| 836 | INT wifi_getHalVersion(CHAR *output_string) //RDKB |
| 837 | { |
| 838 | if(!output_string) |
| 839 | return RETURN_ERR; |
| 840 | snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION); |
| 841 | |
| 842 | return RETURN_OK; |
| 843 | } |
| 844 | |
| 845 | |
| 846 | /* wifi_factoryReset() function */ |
| 847 | /** |
| 848 | * @description Clears internal variables to implement a factory reset of the Wi-Fi |
| 849 | * subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements. |
| 850 | * |
| 851 | * @param None |
| 852 | * |
| 853 | * @return The status of the operation. |
| 854 | * @retval RETURN_OK if successful. |
| 855 | * @retval RETURN_ERR if any error is detected |
| 856 | * |
| 857 | * @execution Synchronous |
| 858 | * @sideeffect None |
| 859 | * |
| 860 | * @note This function must not suspend and must not invoke any blocking system |
| 861 | * calls. It should probably just send a message to a driver event handler task. |
| 862 | * |
| 863 | */ |
| 864 | INT wifi_factoryReset() |
| 865 | { |
| 866 | char cmd[128]; |
| 867 | |
| 868 | /*delete running hostapd conf files*/ |
| 869 | wifi_dbg_printf("\n[%s]: deleting hostapd conf file %s and %s",__func__,HOSTAPD_CONF_0,HOSTAPD_CONF_1); |
| 870 | sprintf(cmd, "rm -rf %s %s",HOSTAPD_CONF_0,HOSTAPD_CONF_1); |
| 871 | system(cmd); |
| 872 | system("systemctl restart hostapd.service"); |
| 873 | |
| 874 | return RETURN_OK; |
| 875 | } |
| 876 | |
| 877 | /* wifi_factoryResetRadios() function */ |
| 878 | /** |
| 879 | * @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. |
| 880 | * |
| 881 | * @param None |
| 882 | * @return The status of the operation |
| 883 | * @retval RETURN_OK if successful |
| 884 | * @retval RETURN_ERR if any error is detected |
| 885 | * |
| 886 | * @execution Synchronous |
| 887 | * |
| 888 | * @sideeffect None |
| 889 | * |
| 890 | * @note This function must not suspend and must not invoke any blocking system |
| 891 | * calls. It should probably just send a message to a driver event handler task. |
| 892 | * |
| 893 | */ |
| 894 | INT wifi_factoryResetRadios() |
| 895 | { |
| 896 | if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1))) |
| 897 | return RETURN_OK; |
| 898 | |
| 899 | return RETURN_ERR; |
| 900 | } |
| 901 | |
| 902 | |
| 903 | /* wifi_factoryResetRadio() function */ |
| 904 | /** |
| 905 | * @description Restore selected radio parameters without touching access point parameters |
| 906 | * |
| 907 | * @param radioIndex - Index of Wi-Fi Radio channel |
| 908 | * |
| 909 | * @return The status of the operation. |
| 910 | * @retval RETURN_OK if successful. |
| 911 | * @retval RETURN_ERR if any error is detected |
| 912 | * |
| 913 | * @execution Synchronous. |
| 914 | * @sideeffect None. |
| 915 | * |
| 916 | * @note This function must not suspend and must not invoke any blocking system |
| 917 | * calls. It should probably just send a message to a driver event handler task. |
| 918 | * |
| 919 | */ |
| 920 | INT wifi_factoryResetRadio(int radioIndex) //RDKB |
| 921 | { |
developer | 5ff7f5f | 2022-09-13 15:12:16 +0800 | [diff] [blame] | 922 | system("systemctl stop hostapd.service"); |
| 923 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 924 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 925 | if(radioIndex == 0) |
developer | 5ff7f5f | 2022-09-13 15:12:16 +0800 | [diff] [blame] | 926 | system("rm /nvram/hostapd0.conf"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 927 | else if(radioIndex == 1) |
developer | 5ff7f5f | 2022-09-13 15:12:16 +0800 | [diff] [blame] | 928 | system("rm /nvram/hostapd1.conf"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 929 | else |
| 930 | return RETURN_ERR; |
| 931 | |
developer | 5ff7f5f | 2022-09-13 15:12:16 +0800 | [diff] [blame] | 932 | system("systemctl start hostapd.service"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 933 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 934 | return RETURN_OK; |
| 935 | } |
| 936 | |
| 937 | /* wifi_initRadio() function */ |
| 938 | /** |
| 939 | * Description: This function call initializes the specified radio. |
| 940 | * Implementation specifics may dictate the functionality since |
| 941 | * different hardware implementations may have different initilization requirements. |
| 942 | * Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT |
| 943 | * |
| 944 | * @return The status of the operation. |
| 945 | * @retval RETURN_OK if successful. |
| 946 | * @retval RETURN_ERR if any error is detected |
| 947 | * |
| 948 | * @execution Synchronous. |
| 949 | * @sideeffect None. |
| 950 | * |
| 951 | * @note This function must not suspend and must not invoke any blocking system |
| 952 | * calls. It should probably just send a message to a driver event handler task. |
| 953 | * |
| 954 | */ |
| 955 | INT wifi_initRadio(INT radioIndex) |
| 956 | { |
| 957 | //TODO: Initializes the wifi subsystem (for specified radio) |
| 958 | return RETURN_OK; |
| 959 | } |
| 960 | void macfilter_init() |
| 961 | { |
| 962 | char count[4]={'\0'}; |
| 963 | char buf[253]={'\0'}; |
| 964 | char tmp[19]={'\0'}; |
| 965 | int dev_count,block,mac_entry=0; |
| 966 | char res[4]={'\0'}; |
| 967 | char acl_file_path[64] = {'\0'}; |
| 968 | FILE *fp = NULL; |
| 969 | int index=0; |
| 970 | char iface[10]={'\0'}; |
| 971 | char config_file[MAX_BUF_SIZE] = {0}; |
| 972 | |
| 973 | |
| 974 | sprintf(acl_file_path,"/tmp/mac_filter.sh"); |
| 975 | |
| 976 | fp=fopen(acl_file_path,"w+"); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 977 | if (fp == NULL) { |
| 978 | fprintf(stderr, "%s: failed to open file %s.\n", __func__, acl_file_path); |
| 979 | return RETURN_ERR; |
| 980 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 981 | sprintf(buf,"#!/bin/sh \n"); |
| 982 | fprintf(fp,"%s\n",buf); |
| 983 | |
| 984 | system("chmod 0777 /tmp/mac_filter.sh"); |
| 985 | |
| 986 | for(index=0;index<=1;index++) |
| 987 | { |
| 988 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index); |
| 989 | wifi_hostapdRead(config_file, "interface", iface, sizeof(iface)); |
| 990 | sprintf(buf,"syscfg get %dcountfilter",index); |
| 991 | _syscmd(buf,count,sizeof(count)); |
| 992 | mac_entry=atoi(count); |
| 993 | |
| 994 | sprintf(buf,"syscfg get %dblockall",index); |
| 995 | _syscmd(buf,res,sizeof(res)); |
| 996 | block = atoi(res); |
| 997 | |
| 998 | //Allow only those macs mentioned in ACL |
| 999 | if(block==1) |
| 1000 | { |
| 1001 | sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index); |
| 1002 | fprintf(fp,"%s\n",buf); |
| 1003 | for(dev_count=1;dev_count<=mac_entry;dev_count++) |
| 1004 | { |
| 1005 | sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count); |
| 1006 | _syscmd(buf,tmp,sizeof(tmp)); |
| 1007 | fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp); |
| 1008 | sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp); |
| 1009 | fprintf(fp,"%s\n",buf); |
| 1010 | } |
| 1011 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp); |
| 1012 | fprintf(fp,"%s\n",buf); |
| 1013 | } |
| 1014 | |
| 1015 | //Block all the macs mentioned in ACL |
| 1016 | else if(block==2) |
| 1017 | { |
| 1018 | sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index); |
| 1019 | fprintf(fp,"%s\n",buf); |
| 1020 | |
| 1021 | for(dev_count=1;dev_count<=mac_entry;dev_count++) |
| 1022 | { |
| 1023 | sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count); |
| 1024 | _syscmd(buf,tmp,sizeof(tmp)); |
| 1025 | fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp); |
| 1026 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp); |
| 1027 | fprintf(fp,"%s\n",buf); |
| 1028 | } |
| 1029 | } |
| 1030 | } |
| 1031 | fclose(fp); |
| 1032 | } |
| 1033 | |
| 1034 | // Initializes the wifi subsystem (all radios) |
| 1035 | INT wifi_init() //RDKB |
| 1036 | { |
| 1037 | char interface[MAX_BUF_SIZE]={'\0'}; |
| 1038 | char bridge_name[MAX_BUF_SIZE]={'\0'}; |
| 1039 | INT len=0; |
| 1040 | |
| 1041 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1042 | //Not intitializing macfilter for Turris-Omnia Platform for now |
| 1043 | //macfilter_init(); |
| 1044 | |
| 1045 | system("/usr/sbin/iw reg set US"); |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 1046 | // system("systemctl start hostapd.service"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1047 | sleep(2);//sleep to wait for hostapd to start |
| 1048 | |
| 1049 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1050 | |
| 1051 | return RETURN_OK; |
| 1052 | } |
| 1053 | |
| 1054 | /* wifi_reset() function */ |
| 1055 | /** |
| 1056 | * Description: Resets the Wifi subsystem. This includes reset of all AP varibles. |
| 1057 | * Implementation specifics may dictate what is actualy reset since |
| 1058 | * different hardware implementations may have different requirements. |
| 1059 | * Parameters : None |
| 1060 | * |
| 1061 | * @return The status of the operation. |
| 1062 | * @retval RETURN_OK if successful. |
| 1063 | * @retval RETURN_ERR if any error is detected |
| 1064 | * |
| 1065 | * @execution Synchronous. |
| 1066 | * @sideeffect None. |
| 1067 | * |
| 1068 | * @note This function must not suspend and must not invoke any blocking system |
| 1069 | * calls. It should probably just send a message to a driver event handler task. |
| 1070 | * |
| 1071 | */ |
| 1072 | INT wifi_reset() |
| 1073 | { |
| 1074 | //TODO: resets the wifi subsystem, deletes all APs |
developer | b222b21 | 2022-09-13 14:01:01 +0800 | [diff] [blame] | 1075 | system("systemctl stop hostapd.service"); |
| 1076 | sleep(2); |
| 1077 | system("systemctl start hostapd.service"); |
| 1078 | sleep(5); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1079 | return RETURN_OK; |
| 1080 | } |
| 1081 | |
| 1082 | /* wifi_down() function */ |
| 1083 | /** |
| 1084 | * @description Turns off transmit power for the entire Wifi subsystem, for all radios. |
| 1085 | * Implementation specifics may dictate some functionality since |
| 1086 | * different hardware implementations may have different requirements. |
| 1087 | * |
| 1088 | * @param None |
| 1089 | * |
| 1090 | * @return The status of the operation |
| 1091 | * @retval RETURN_OK if successful |
| 1092 | * @retval RETURN_ERR if any error is detected |
| 1093 | * |
| 1094 | * @execution Synchronous |
| 1095 | * @sideeffect None |
| 1096 | * |
| 1097 | * @note This function must not suspend and must not invoke any blocking system |
| 1098 | * calls. It should probably just send a message to a driver event handler task. |
| 1099 | * |
| 1100 | */ |
| 1101 | INT wifi_down() |
| 1102 | { |
| 1103 | //TODO: turns off transmit power for the entire Wifi subsystem, for all radios |
developer | b222b21 | 2022-09-13 14:01:01 +0800 | [diff] [blame] | 1104 | system("systemctl stop hostapd.service"); |
| 1105 | sleep(2); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1106 | return RETURN_OK; |
| 1107 | } |
| 1108 | |
| 1109 | |
| 1110 | /* wifi_createInitialConfigFiles() function */ |
| 1111 | /** |
| 1112 | * @description This function creates wifi configuration files. The format |
| 1113 | * and content of these files are implementation dependent. This function call is |
| 1114 | * used to trigger this task if necessary. Some implementations may not need this |
| 1115 | * function. If an implementation does not need to create config files the function call can |
| 1116 | * do nothing and return RETURN_OK. |
| 1117 | * |
| 1118 | * @param None |
| 1119 | * |
| 1120 | * @return The status of the operation |
| 1121 | * @retval RETURN_OK if successful |
| 1122 | * @retval RETURN_ERR if any error is detected |
| 1123 | * |
| 1124 | * @execution Synchronous |
| 1125 | * @sideeffect None |
| 1126 | * |
| 1127 | * @note This function must not suspend and must not invoke any blocking system |
| 1128 | * calls. It should probably just send a message to a driver event handler task. |
| 1129 | * |
| 1130 | */ |
| 1131 | INT wifi_createInitialConfigFiles() |
| 1132 | { |
| 1133 | //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) |
| 1134 | return RETURN_OK; |
| 1135 | } |
| 1136 | |
| 1137 | // outputs the country code to a max 64 character string |
| 1138 | INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string) |
| 1139 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1140 | char interface_name[16] = {0}; |
developer | 7543b3b | 2022-09-13 13:47:17 +0800 | [diff] [blame] | 1141 | char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 1142 | if(!output_string || (radioIndex >= MAX_NUM_RADIOS)) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1143 | return RETURN_ERR; |
developer | 7543b3b | 2022-09-13 13:47:17 +0800 | [diff] [blame] | 1144 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 1145 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1146 | return RETURN_ERR; |
| 1147 | sprintf(cmd,"hostapd_cli -i %s status driver | grep country | cut -d '=' -f2", interface_name); |
developer | 7543b3b | 2022-09-13 13:47:17 +0800 | [diff] [blame] | 1148 | _syscmd(cmd, buf, sizeof(buf)); |
| 1149 | if(strlen(buf) > 0) |
| 1150 | snprintf(output_string, 64, "%s", buf); |
| 1151 | else |
| 1152 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1153 | |
| 1154 | return RETURN_OK; |
| 1155 | } |
| 1156 | |
| 1157 | INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode) |
| 1158 | { |
| 1159 | //Set wifi config. Wait for wifi reset to apply |
developer | 7543b3b | 2022-09-13 13:47:17 +0800 | [diff] [blame] | 1160 | char str[MAX_BUF_SIZE]={'\0'}; |
| 1161 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 1162 | struct params params; |
| 1163 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1164 | |
| 1165 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1166 | if(NULL == CountryCode || strlen(CountryCode) >= 32 ) |
| 1167 | return RETURN_ERR; |
| 1168 | |
developer | b86c6f3 | 2022-10-07 14:34:58 +0800 | [diff] [blame] | 1169 | if (strlen(CountryCode) == 0) |
| 1170 | strcpy(CountryCode, "US"); |
| 1171 | |
developer | 7543b3b | 2022-09-13 13:47:17 +0800 | [diff] [blame] | 1172 | params.name = "country_code"; |
| 1173 | params.value = CountryCode; |
| 1174 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, radioIndex); |
| 1175 | int ret = wifi_hostapdWrite(config_file, ¶ms, 1); |
| 1176 | if (ret) { |
| 1177 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n" |
| 1178 | ,__func__, ret); |
| 1179 | } |
| 1180 | |
| 1181 | ret = wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 1182 | if (ret) { |
| 1183 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n" |
| 1184 | ,__func__, ret); |
| 1185 | } |
developer | 7543b3b | 2022-09-13 13:47:17 +0800 | [diff] [blame] | 1186 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1187 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1188 | return RETURN_OK; |
| 1189 | } |
| 1190 | |
developer | a748dcf | 2022-09-13 15:56:48 +0800 | [diff] [blame] | 1191 | INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2) |
| 1192 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1193 | char interface_name[16] = {0}; |
developer | a748dcf | 2022-09-13 15:56:48 +0800 | [diff] [blame] | 1194 | char channel_util_file[64] = {0}; |
| 1195 | char cmd[128] = {0}; |
| 1196 | char buf[128] = {0}; |
| 1197 | char line[128] = {0}; |
| 1198 | char *param = NULL, *value = NULL; |
| 1199 | int read = 0; |
| 1200 | unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0; |
| 1201 | unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0; |
| 1202 | size_t len = 0; |
| 1203 | FILE *f = NULL; |
| 1204 | |
| 1205 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1206 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 1207 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1208 | return RETURN_ERR; |
| 1209 | snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name); |
developer | a748dcf | 2022-09-13 15:56:48 +0800 | [diff] [blame] | 1210 | _syscmd(cmd, buf, sizeof(buf)); |
| 1211 | outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10); |
| 1212 | |
| 1213 | memset(cmd, 0, sizeof(cmd)); |
| 1214 | memset(buf, 0, sizeof(buf)); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1215 | snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name); |
developer | a748dcf | 2022-09-13 15:56:48 +0800 | [diff] [blame] | 1216 | if ((f = popen(cmd, "r")) == NULL) { |
| 1217 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 1218 | return RETURN_ERR; |
| 1219 | } |
| 1220 | |
| 1221 | read = getline(&line, &len, f); |
| 1222 | while (read != -1) { |
| 1223 | param = strtok(line, ":\t"); |
| 1224 | value = strtok(NULL, " "); |
| 1225 | if(strstr(param, "frequency") != NULL) { |
| 1226 | outputChannelStats2->ch_Frequency = strtol(value, NULL, 10); |
| 1227 | } |
| 1228 | if(strstr(param, "noise") != NULL) { |
| 1229 | outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10); |
| 1230 | outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10); |
| 1231 | } |
| 1232 | if(strstr(param, "channel active time") != NULL) { |
| 1233 | ActiveTime = strtol(value, NULL, 10); |
| 1234 | } |
| 1235 | if(strstr(param, "channel busy time") != NULL) { |
| 1236 | BusyTime = strtol(value, NULL, 10); |
| 1237 | } |
| 1238 | if(strstr(param, "channel transmit time") != NULL) { |
| 1239 | TransmitTime = strtol(value, NULL, 10); |
| 1240 | } |
| 1241 | read = getline(&line, &len, f); |
| 1242 | } |
| 1243 | pclose(f); |
| 1244 | |
| 1245 | // The file should store the last active, busy and transmit time |
| 1246 | snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex); |
| 1247 | f = fopen(channel_util_file, "r"); |
| 1248 | if (f != NULL) { |
| 1249 | read = getline(&line, &len, f); |
| 1250 | preActiveTime = strtol(line, NULL, 10); |
| 1251 | read = getline(&line, &len, f); |
| 1252 | preBusyTime = strtol(line, NULL, 10); |
| 1253 | read = getline(&line, &len, f); |
| 1254 | preTransmitTime = strtol(line, NULL, 10); |
| 1255 | fclose(f); |
| 1256 | } |
| 1257 | |
| 1258 | outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime); |
| 1259 | outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime); |
| 1260 | |
| 1261 | f = fopen(channel_util_file, "w"); |
| 1262 | if (f != NULL) { |
| 1263 | fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime); |
| 1264 | fclose(f); |
| 1265 | } |
| 1266 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1267 | return RETURN_OK; |
| 1268 | } |
| 1269 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1270 | /********************************************************************************** |
| 1271 | * |
| 1272 | * Wifi radio level function prototypes |
| 1273 | * |
| 1274 | **********************************************************************************/ |
| 1275 | |
| 1276 | //Get the total number of radios in this wifi subsystem |
| 1277 | INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181 |
| 1278 | { |
| 1279 | if (NULL == output) |
| 1280 | return RETURN_ERR; |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 1281 | *output = MAX_NUM_RADIOS; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1282 | |
| 1283 | return RETURN_OK; |
| 1284 | } |
| 1285 | |
| 1286 | //Get the total number of SSID entries in this wifi subsystem |
| 1287 | INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181 |
| 1288 | { |
| 1289 | if (NULL == output) |
| 1290 | return RETURN_ERR; |
| 1291 | *output = MAX_APS; |
| 1292 | |
| 1293 | return RETURN_OK; |
| 1294 | } |
| 1295 | |
| 1296 | //Get the Radio enable config parameter |
| 1297 | INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB |
| 1298 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1299 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1300 | char interface_path[MAX_CMD_SIZE] = {0}; |
| 1301 | FILE *fp = NULL; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1302 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1303 | |
| 1304 | if (NULL == output_bool) |
| 1305 | return RETURN_ERR; |
| 1306 | |
| 1307 | *output_bool = FALSE; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 1308 | if (radioIndex >= MAX_NUM_RADIOS)// Target has two wifi radios |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1309 | return RETURN_ERR; |
| 1310 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1311 | phyId = radio_index_to_phy(radioIndex); |
| 1312 | |
| 1313 | snprintf(interface_path, sizeof(interface_path), "/sys/class/net/%s%d/address", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1314 | fp = fopen(interface_path, "r"); |
developer | cf48e48 | 2022-09-13 14:49:50 +0800 | [diff] [blame] | 1315 | if(!fp) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1316 | { |
developer | cf48e48 | 2022-09-13 14:49:50 +0800 | [diff] [blame] | 1317 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1318 | } |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1319 | fclose(fp); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1320 | //TODO: check if hostapd with config is running |
developer | cf48e48 | 2022-09-13 14:49:50 +0800 | [diff] [blame] | 1321 | char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 1322 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1323 | return RETURN_ERR; |
| 1324 | sprintf(cmd, "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name); |
developer | cf48e48 | 2022-09-13 14:49:50 +0800 | [diff] [blame] | 1325 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1326 | |
developer | cf48e48 | 2022-09-13 14:49:50 +0800 | [diff] [blame] | 1327 | if(strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 || strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) |
| 1328 | *output_bool = TRUE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1329 | return RETURN_OK; |
| 1330 | } |
| 1331 | |
| 1332 | INT wifi_setRadioEnable(INT radioIndex, BOOL enable) |
| 1333 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1334 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1335 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1336 | char buf[MAX_CMD_SIZE] = {0}; |
| 1337 | int apIndex, ret; |
| 1338 | FILE *fp = NULL; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1339 | int max_radio_num = 0; |
| 1340 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1341 | |
| 1342 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1343 | |
| 1344 | phyId = radio_index_to_phy(radioIndex); |
| 1345 | |
| 1346 | wifi_getMaxRadioNumber(&max_radio_num); |
| 1347 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 1348 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1349 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1350 | if(enable==FALSE) |
| 1351 | { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1352 | for(apIndex=radioIndex; apIndex<MAX_APS; apIndex+=max_radio_num) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1353 | { |
| 1354 | //Detaching %s%d from hostapd daemon |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1355 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1356 | _syscmd(cmd, buf, sizeof(buf)); |
| 1357 | if(strncmp(buf, "OK", 2)) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1358 | fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name); |
| 1359 | snprintf(cmd, sizeof(cmd), "iw %s del", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1360 | _syscmd(cmd, buf, sizeof(buf)); |
| 1361 | } |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1362 | snprintf(cmd, sizeof(cmd), "ifconfig %s%d down 2>&1", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1363 | _syscmd(cmd, buf, sizeof(buf)); |
| 1364 | if(strlen(buf)) |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1365 | fprintf(stderr, "Could not shut down the radio interface: %s%d", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1366 | } |
| 1367 | else |
| 1368 | { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1369 | snprintf(cmd, sizeof(cmd), "ifconfig %s%d up 2>&1", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1370 | _syscmd(cmd, buf, sizeof(buf)); |
| 1371 | if(strlen(buf)) |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1372 | fprintf(stderr, "Could not up the radio interface: %s%d", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1373 | sleep(1); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1374 | |
| 1375 | for(apIndex=radioIndex; apIndex<MAX_APS; apIndex+=max_radio_num) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1376 | { |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 1377 | snprintf(cmd, sizeof(cmd), "iw phy%d interface add %s type __ap", phyId, interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1378 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 1379 | if ( ret == RETURN_ERR) |
| 1380 | { |
| 1381 | fprintf(stderr, "VAP interface creation failed\n"); |
| 1382 | continue; |
| 1383 | } |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1384 | snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1385 | _syscmd(cmd, buf, sizeof(buf)); |
| 1386 | if(*buf == '1') |
| 1387 | { |
| 1388 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf", |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1389 | phyId, apIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1390 | _syscmd(cmd, buf, sizeof(buf)); |
| 1391 | if(strncmp(buf, "OK", 2)) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1392 | fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1393 | } |
| 1394 | } |
| 1395 | } |
| 1396 | |
| 1397 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1398 | return RETURN_OK; |
| 1399 | } |
| 1400 | |
| 1401 | //Get the Radio enable status |
| 1402 | INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB |
| 1403 | { |
| 1404 | if (NULL == output_bool) |
| 1405 | return RETURN_ERR; |
| 1406 | |
| 1407 | return wifi_getRadioEnable(radioIndex, output_bool); |
| 1408 | } |
| 1409 | |
| 1410 | //Get the Radio Interface name from platform, eg "wlan0" |
| 1411 | INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181 |
| 1412 | { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1413 | int phyId = 0; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 1414 | if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1415 | return RETURN_ERR; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1416 | phyId = radio_index_to_phy(radioIndex); |
| 1417 | snprintf(output_string, 64, "%s%d", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1418 | |
| 1419 | return RETURN_OK; |
| 1420 | } |
| 1421 | |
| 1422 | //Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s" |
| 1423 | //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. |
| 1424 | INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB |
| 1425 | { |
developer | bcc556a | 2022-09-22 20:02:45 +0800 | [diff] [blame] | 1426 | // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)" |
| 1427 | // For max bit rate, we should always choose the best MCS |
| 1428 | char mode[64] = {0}; |
developer | dbbd678 | 2022-12-16 14:26:20 +0800 | [diff] [blame] | 1429 | char channel_bandwidth_str[64] = {0}; |
developer | bcc556a | 2022-09-22 20:02:45 +0800 | [diff] [blame] | 1430 | char *tmp = NULL; |
| 1431 | UINT mode_map = 0; |
| 1432 | UINT num_subcarrier = 0; |
| 1433 | UINT code_bits = 0; |
| 1434 | float code_rate = 0; // use max code rate |
| 1435 | int NSS = 0; |
| 1436 | UINT Symbol_duration = 0; |
| 1437 | UINT GI_duration = 0; |
| 1438 | wifi_band band = band_invalid; |
| 1439 | wifi_guard_interval_t gi = wifi_guard_interval_auto; |
| 1440 | BOOL enable = FALSE; |
| 1441 | float bit_rate = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1442 | |
| 1443 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1444 | if (NULL == output_string) |
| 1445 | return RETURN_ERR; |
| 1446 | |
developer | bcc556a | 2022-09-22 20:02:45 +0800 | [diff] [blame] | 1447 | wifi_getRadioEnable(radioIndex, &enable); |
| 1448 | if (enable == FALSE) { |
| 1449 | snprintf(output_string, 64, "0 Mb/s"); |
| 1450 | return RETURN_OK; |
| 1451 | } |
| 1452 | |
| 1453 | if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) { |
| 1454 | fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__); |
| 1455 | return RETURN_ERR; |
| 1456 | } |
| 1457 | |
| 1458 | if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) { |
| 1459 | fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__); |
| 1460 | return RETURN_ERR; |
| 1461 | } |
| 1462 | |
| 1463 | if (gi == wifi_guard_interval_3200) |
| 1464 | GI_duration = 32; |
| 1465 | else if (gi == wifi_guard_interval_1600) |
| 1466 | GI_duration = 16; |
| 1467 | else if (gi == wifi_guard_interval_800) |
| 1468 | GI_duration = 8; |
| 1469 | else // auto, 400 |
| 1470 | GI_duration = 4; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1471 | |
developer | bcc556a | 2022-09-22 20:02:45 +0800 | [diff] [blame] | 1472 | if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) { |
| 1473 | fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__); |
| 1474 | return RETURN_ERR; |
| 1475 | } |
| 1476 | |
| 1477 | if (strstr(channel_bandwidth_str, "80+80") != NULL) |
| 1478 | strcpy(channel_bandwidth_str, "160"); |
| 1479 | |
| 1480 | if (mode_map & WIFI_MODE_AX) { |
| 1481 | if (strstr(channel_bandwidth_str, "160") != NULL) |
| 1482 | num_subcarrier = 1960; |
| 1483 | else if (strstr(channel_bandwidth_str, "80") != NULL) |
| 1484 | num_subcarrier = 980; |
| 1485 | else if (strstr(channel_bandwidth_str, "40") != NULL) |
| 1486 | num_subcarrier = 468; |
| 1487 | else if (strstr(channel_bandwidth_str, "20") != NULL) |
| 1488 | num_subcarrier = 234; |
| 1489 | code_bits = 10; |
| 1490 | code_rate = (float)5/6; |
| 1491 | Symbol_duration = 128; |
| 1492 | } else if (mode_map & WIFI_MODE_AC) { |
| 1493 | if (strstr(channel_bandwidth_str, "160") != NULL) |
| 1494 | num_subcarrier = 468; |
| 1495 | else if (strstr(channel_bandwidth_str, "80") != NULL) |
| 1496 | num_subcarrier = 234; |
| 1497 | else if (strstr(channel_bandwidth_str, "40") != NULL) |
| 1498 | num_subcarrier = 108; |
| 1499 | else if (strstr(channel_bandwidth_str, "20") != NULL) |
| 1500 | num_subcarrier = 52; |
| 1501 | code_bits = 8; |
| 1502 | code_rate = (float)5/6; |
| 1503 | Symbol_duration = 32; |
| 1504 | } else if (mode_map & WIFI_MODE_N) { |
| 1505 | if (strstr(channel_bandwidth_str, "160") != NULL) |
| 1506 | num_subcarrier = 468; |
| 1507 | else if (strstr(channel_bandwidth_str, "80") != NULL) |
| 1508 | num_subcarrier = 234; |
| 1509 | else if (strstr(channel_bandwidth_str, "40") != NULL) |
| 1510 | num_subcarrier = 108; |
| 1511 | else if (strstr(channel_bandwidth_str, "20") != NULL) |
| 1512 | num_subcarrier = 52; |
| 1513 | code_bits = 6; |
| 1514 | code_rate = (float)3/4; |
| 1515 | Symbol_duration = 32; |
| 1516 | } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) { |
| 1517 | // mode b must run with mode g, so we output mode g bitrate in 2.4 G. |
| 1518 | snprintf(output_string, 64, "65 Mb/s"); |
| 1519 | return RETURN_OK; |
| 1520 | } else { |
| 1521 | snprintf(output_string, 64, "0 Mb/s"); |
| 1522 | return RETURN_OK; |
| 1523 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1524 | |
developer | bcc556a | 2022-09-22 20:02:45 +0800 | [diff] [blame] | 1525 | // Spatial streams |
| 1526 | if (wifi_getRadioTxChainMask(radioIndex, &NSS) != RETURN_OK) { |
| 1527 | fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__); |
| 1528 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1529 | } |
developer | bcc556a | 2022-09-22 20:02:45 +0800 | [diff] [blame] | 1530 | |
| 1531 | // multiple 10 is to align duration unit (0.1 us) |
| 1532 | bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10; |
| 1533 | snprintf(output_string, 64, "%.1f Mb/s", bit_rate); |
| 1534 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1535 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1536 | |
| 1537 | return RETURN_OK; |
| 1538 | } |
| 1539 | #if 0 |
| 1540 | INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB |
| 1541 | { |
| 1542 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1543 | char cmd[64]; |
| 1544 | char buf[1024]; |
| 1545 | int apIndex; |
| 1546 | |
| 1547 | if (NULL == output_string) |
| 1548 | return RETURN_ERR; |
| 1549 | |
| 1550 | apIndex=(radioIndex==0)?0:1; |
| 1551 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 1552 | snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1553 | _syscmd(cmd,buf, sizeof(buf)); |
| 1554 | |
| 1555 | snprintf(output_string, 64, "%s", buf); |
| 1556 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1557 | return RETURN_OK; |
| 1558 | } |
| 1559 | #endif |
| 1560 | |
| 1561 | |
| 1562 | //Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz" |
| 1563 | //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. |
| 1564 | INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB |
| 1565 | { |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1566 | wifi_band band = band_invalid; |
| 1567 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1568 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1569 | if (NULL == output_string) |
| 1570 | return RETURN_ERR; |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1571 | |
| 1572 | band = wifi_index_to_band(radioIndex); |
| 1573 | |
| 1574 | memset(output_string, 0, 10); |
| 1575 | if (band == band_2_4) |
| 1576 | strcpy(output_string, "2.4GHz"); |
| 1577 | else if (band == band_5) |
| 1578 | strcpy(output_string, "5GHz"); |
| 1579 | else if (band == band_6) |
| 1580 | strcpy(output_string, "6GHz"); |
| 1581 | else |
| 1582 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1583 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1584 | |
| 1585 | return RETURN_OK; |
| 1586 | #if 0 |
| 1587 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 1588 | char str[MAX_BUF_SIZE]={'\0'}; |
| 1589 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 1590 | char *ch=NULL; |
| 1591 | char *ch2=NULL; |
| 1592 | |
| 1593 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1594 | if (NULL == output_string) |
| 1595 | return RETURN_ERR; |
| 1596 | |
| 1597 | |
| 1598 | sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 1599 | |
| 1600 | if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR) |
| 1601 | { |
| 1602 | printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1603 | return RETURN_ERR; |
| 1604 | } |
| 1605 | ch=strchr(buf,'\n'); |
| 1606 | *ch='\0'; |
| 1607 | ch=strchr(buf,'='); |
| 1608 | if(ch==NULL) |
| 1609 | return RETURN_ERR; |
| 1610 | |
| 1611 | |
| 1612 | ch++; |
| 1613 | |
| 1614 | /* prepend 0 for channel with single digit. for ex, 6 would be 06 */ |
| 1615 | strcpy(buf,"0"); |
| 1616 | if(strlen(ch) == 1) |
| 1617 | ch=strcat(buf,ch); |
| 1618 | |
| 1619 | |
| 1620 | sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 1621 | |
| 1622 | if(_syscmd(cmd,str,64) == RETURN_ERR) |
| 1623 | { |
| 1624 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1625 | return RETURN_ERR; |
| 1626 | } |
| 1627 | |
| 1628 | |
| 1629 | ch2=strchr(str,'\n'); |
| 1630 | //replace \n with \0 |
| 1631 | *ch2='\0'; |
| 1632 | ch2=strchr(str,'='); |
| 1633 | if(ch2==NULL) |
| 1634 | { |
| 1635 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1636 | return RETURN_ERR; |
| 1637 | } |
| 1638 | else |
| 1639 | wifi_dbg_printf("%s",ch2+1); |
| 1640 | |
| 1641 | |
| 1642 | ch2++; |
| 1643 | |
| 1644 | |
| 1645 | sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch); |
| 1646 | |
| 1647 | memset(buf,'\0',sizeof(buf)); |
| 1648 | if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR) |
| 1649 | { |
| 1650 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1651 | return RETURN_ERR; |
| 1652 | } |
| 1653 | if (strstr(buf,"2.4") != NULL ) |
| 1654 | strcpy(output_string,"2.4GHz"); |
| 1655 | else if(strstr(buf,"5.") != NULL ) |
| 1656 | strcpy(output_string,"5GHz"); |
| 1657 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1658 | |
| 1659 | return RETURN_OK; |
| 1660 | #endif |
| 1661 | } |
| 1662 | |
| 1663 | //Get the frequency band at which the radio is operating, eg: "2.4GHz" |
| 1664 | //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. |
| 1665 | INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181 |
| 1666 | { |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 1667 | wifi_band band = band_invalid; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1668 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1669 | if (NULL == output_string) |
| 1670 | return RETURN_ERR; |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 1671 | band = wifi_index_to_band(radioIndex); |
| 1672 | |
| 1673 | if (band == band_2_4) |
| 1674 | snprintf(output_string, 64, "2.4GHz"); |
| 1675 | else if (band == band_5) |
| 1676 | snprintf(output_string, 64, "5GHz"); |
| 1677 | else if (band == band_6) |
| 1678 | snprintf(output_string, 64, "6GHz"); |
| 1679 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1680 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1681 | |
| 1682 | return RETURN_OK; |
| 1683 | #if 0 |
| 1684 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1685 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 1686 | char str[MAX_BUF_SIZE]={'\0'}; |
| 1687 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 1688 | char *ch=NULL; |
| 1689 | char *ch2=NULL; |
| 1690 | char ch1[5]="0"; |
| 1691 | |
| 1692 | sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 1693 | |
| 1694 | if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR) |
| 1695 | { |
| 1696 | printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1697 | return RETURN_ERR; |
| 1698 | } |
| 1699 | |
| 1700 | ch=strchr(buf,'\n'); |
| 1701 | *ch='\0'; |
| 1702 | ch=strchr(buf,'='); |
| 1703 | if(ch==NULL) |
| 1704 | return RETURN_ERR; |
| 1705 | ch++; |
| 1706 | |
| 1707 | if(strlen(ch)==1) |
| 1708 | { |
| 1709 | strcat(ch1,ch); |
| 1710 | |
| 1711 | } |
| 1712 | else |
| 1713 | { |
| 1714 | strcpy(ch1,ch); |
| 1715 | } |
| 1716 | |
| 1717 | |
| 1718 | |
| 1719 | sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 1720 | if(_syscmd(cmd,str,64) == RETURN_ERR) |
| 1721 | { |
| 1722 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1723 | return RETURN_ERR; |
| 1724 | } |
| 1725 | |
| 1726 | |
| 1727 | ch2=strchr(str,'\n'); |
| 1728 | //replace \n with \0 |
| 1729 | *ch2='\0'; |
| 1730 | ch2=strchr(str,'='); |
| 1731 | if(ch2==NULL) |
| 1732 | { |
| 1733 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1734 | return RETURN_ERR; |
| 1735 | } |
| 1736 | else |
| 1737 | wifi_dbg_printf("%s",ch2+1); |
| 1738 | ch2++; |
| 1739 | |
| 1740 | |
| 1741 | sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1); |
| 1742 | memset(buf,'\0',sizeof(buf)); |
| 1743 | if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR) |
| 1744 | { |
| 1745 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 1746 | return RETURN_ERR; |
| 1747 | } |
| 1748 | |
| 1749 | |
| 1750 | if(strstr(buf,"2.4")!=NULL) |
| 1751 | { |
| 1752 | strcpy(output_string,"2.4GHz"); |
| 1753 | } |
| 1754 | if(strstr(buf,"5.")!=NULL) |
| 1755 | { |
| 1756 | strcpy(output_string,"5GHz"); |
| 1757 | } |
| 1758 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1759 | return RETURN_OK; |
| 1760 | #endif |
| 1761 | } |
| 1762 | |
| 1763 | //Get the Supported Radio Mode. eg: "b,g,n"; "n,ac" |
| 1764 | //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. |
| 1765 | INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181 |
| 1766 | { |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1767 | char cmd[128]={0}; |
| 1768 | char buf[128]={0}; |
| 1769 | char temp_output[128] = {0}; |
| 1770 | wifi_band band; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1771 | int phyId = 0; |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1772 | |
| 1773 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1774 | if (NULL == output_string) |
| 1775 | return RETURN_ERR; |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1776 | |
| 1777 | band = wifi_index_to_band(radioIndex); |
| 1778 | if (band == band_2_4) { |
| 1779 | strcat(temp_output, "b,g,"); |
| 1780 | } else if (band == band_5) { |
| 1781 | strcat(temp_output, "a,"); |
| 1782 | } |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1783 | phyId = radio_index_to_phy(radioIndex); |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1784 | // ht capabilities |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1785 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep '[^PHY|MAC|VHT].Capabilities' | head -n 1 | cut -d ':' -f2 | sed 's/^.//' | tr -d '\\n'", phyId); |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1786 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 8f8f017 | 2022-10-26 14:24:43 +0800 | [diff] [blame] | 1787 | if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) { |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1788 | strcat(temp_output, "n,"); |
| 1789 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1790 | |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1791 | // vht capabilities |
| 1792 | if (band == band_5) { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1793 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId); |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1794 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 8f8f017 | 2022-10-26 14:24:43 +0800 | [diff] [blame] | 1795 | if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) { |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1796 | strcat(temp_output, "ac,"); |
| 1797 | } |
| 1798 | } |
| 1799 | |
| 1800 | // he capabilities |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 1801 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'HE MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId); |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1802 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 8f8f017 | 2022-10-26 14:24:43 +0800 | [diff] [blame] | 1803 | if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) { |
developer | 963da0c | 2022-09-13 15:58:27 +0800 | [diff] [blame] | 1804 | strcat(temp_output, "ax,"); |
| 1805 | } |
| 1806 | |
| 1807 | // Remove the last comma |
| 1808 | if (strlen(temp_output) != 0) |
| 1809 | temp_output[strlen(temp_output)-1] = '\0'; |
| 1810 | strncpy(output_string, temp_output, strlen(temp_output)); |
| 1811 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1812 | return RETURN_OK; |
| 1813 | } |
| 1814 | |
| 1815 | //Get the radio operating mode, and pure mode flag. eg: "ac" |
| 1816 | //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. |
| 1817 | INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB |
| 1818 | { |
| 1819 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1820 | if (NULL == output_string) |
| 1821 | return RETURN_ERR; |
| 1822 | |
| 1823 | if (radioIndex == 0) { |
| 1824 | snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others |
| 1825 | *gOnly = FALSE; |
| 1826 | *nOnly = TRUE; |
| 1827 | *acOnly = FALSE; |
| 1828 | } else { |
| 1829 | snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac" |
| 1830 | *gOnly = FALSE; |
| 1831 | *nOnly = FALSE; |
| 1832 | *acOnly = FALSE; |
| 1833 | } |
| 1834 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1835 | |
| 1836 | return RETURN_OK; |
| 1837 | #if 0 |
| 1838 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1839 | char buf[64] = {0}; |
| 1840 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1841 | |
| 1842 | if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly)) |
| 1843 | return RETURN_ERR; |
| 1844 | |
| 1845 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 1846 | wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf)); |
| 1847 | |
| 1848 | wifi_dbg_printf("\nhw_mode=%s\n",buf); |
| 1849 | if (strlen(buf) == 0) |
| 1850 | { |
| 1851 | wifi_dbg_printf("\nwifi_hostapdRead returned none\n"); |
| 1852 | return RETURN_ERR; |
| 1853 | } |
| 1854 | if(strcmp(buf,"g")==0) |
| 1855 | { |
| 1856 | wifi_dbg_printf("\nG\n"); |
| 1857 | *gOnly=TRUE; |
| 1858 | *nOnly=FALSE; |
| 1859 | *acOnly=FALSE; |
| 1860 | } |
| 1861 | else if(strcmp(buf,"n")==0) |
| 1862 | { |
| 1863 | wifi_dbg_printf("\nN\n"); |
| 1864 | *gOnly=FALSE; |
| 1865 | *nOnly=TRUE; |
| 1866 | *acOnly=FALSE; |
| 1867 | } |
| 1868 | else if(strcmp(buf,"ac")==0) |
| 1869 | { |
| 1870 | wifi_dbg_printf("\nac\n"); |
| 1871 | *gOnly=FALSE; |
| 1872 | *nOnly=FALSE; |
| 1873 | *acOnly=TRUE; |
| 1874 | } |
| 1875 | /* hostapd-5G.conf has "a" as hw_mode */ |
| 1876 | else if(strcmp(buf,"a")==0) |
| 1877 | { |
| 1878 | wifi_dbg_printf("\na\n"); |
| 1879 | *gOnly=FALSE; |
| 1880 | *nOnly=FALSE; |
| 1881 | *acOnly=FALSE; |
| 1882 | } |
| 1883 | else |
| 1884 | wifi_dbg_printf("\nInvalid Mode %s\n", buf); |
| 1885 | |
| 1886 | //for a,n mode |
| 1887 | if(radioIndex == 1) |
| 1888 | { |
| 1889 | wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf)); |
| 1890 | if(strcmp(buf,"1")==0) |
| 1891 | { |
| 1892 | strncpy(output_string, "n", 1); |
| 1893 | *nOnly=FALSE; |
| 1894 | } |
| 1895 | } |
| 1896 | |
| 1897 | wifi_dbg_printf("\nReturning from getRadioStandard\n"); |
| 1898 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1899 | return RETURN_OK; |
| 1900 | #endif |
| 1901 | } |
| 1902 | |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 1903 | INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode) |
| 1904 | { |
| 1905 | char cmd[128] = {0}; |
| 1906 | char buf[64] = {0}; |
| 1907 | char config_file[64] = {0}; |
| 1908 | wifi_band band; |
| 1909 | |
| 1910 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1911 | if(NULL == output_string || NULL == pureMode) |
| 1912 | return RETURN_ERR; |
| 1913 | |
| 1914 | // grep all of the ieee80211 protocol config set to 1 |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 1915 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 1916 | snprintf(cmd, sizeof(cmd), "cat %s | grep -E \"ieee.*=1\" | cut -d '=' -f1 | tr -d 'ieee80211'", config_file); |
| 1917 | _syscmd(cmd, buf, sizeof(buf)); |
| 1918 | |
| 1919 | band = wifi_index_to_band(radioIndex); |
| 1920 | // puremode is a bit map |
| 1921 | *pureMode = 0; |
| 1922 | if (band == band_2_4) { |
| 1923 | strcat(output_string, "b,g"); |
| 1924 | *pureMode |= WIFI_MODE_B | WIFI_MODE_G; |
| 1925 | if (strstr(buf, "n") != NULL) { |
| 1926 | strcat(output_string, ",n"); |
| 1927 | *pureMode |= WIFI_MODE_N; |
| 1928 | } |
| 1929 | if (strstr(buf, "ax") != NULL) { |
| 1930 | strcat(output_string, ",ax"); |
| 1931 | *pureMode |= WIFI_MODE_AX; |
| 1932 | } |
| 1933 | } else if (band == band_5) { |
| 1934 | strcat(output_string, "a"); |
| 1935 | *pureMode |= WIFI_MODE_A; |
| 1936 | if (strstr(buf, "n") != NULL) { |
| 1937 | strcat(output_string, ",n"); |
| 1938 | *pureMode |= WIFI_MODE_N; |
| 1939 | } |
| 1940 | if (strstr(buf, "ac") != NULL) { |
| 1941 | strcat(output_string, ",ac"); |
| 1942 | *pureMode |= WIFI_MODE_AC; |
| 1943 | } |
| 1944 | if (strstr(buf, "ax") != NULL) { |
| 1945 | strcat(output_string, ",ax"); |
| 1946 | *pureMode |= WIFI_MODE_AX; |
| 1947 | } |
| 1948 | } else if (band == band_6) { |
| 1949 | if (strstr(buf, "ax") != NULL) { |
| 1950 | strcat(output_string, "ax"); |
| 1951 | *pureMode |= WIFI_MODE_AX; |
| 1952 | } |
| 1953 | } |
| 1954 | |
| 1955 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1956 | return RETURN_OK; |
| 1957 | } |
| 1958 | |
| 1959 | // Set the radio operating mode, and pure mode flag. |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 1960 | INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB |
| 1961 | { |
| 1962 | WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__); |
| 1963 | if (strcmp (channelMode,"11A") == 0) |
| 1964 | { |
| 1965 | writeBandWidth(radioIndex,"20MHz"); |
| 1966 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 1967 | printf("\nChannel Mode is 802.11a (5GHz)\n"); |
| 1968 | } |
| 1969 | else if (strcmp (channelMode,"11NAHT20") == 0) |
| 1970 | { |
| 1971 | writeBandWidth(radioIndex,"20MHz"); |
| 1972 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 1973 | printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n"); |
| 1974 | } |
| 1975 | else if (strcmp (channelMode,"11NAHT40PLUS") == 0) |
| 1976 | { |
| 1977 | writeBandWidth(radioIndex,"40MHz"); |
| 1978 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 1979 | printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n"); |
| 1980 | } |
| 1981 | else if (strcmp (channelMode,"11NAHT40MINUS") == 0) |
| 1982 | { |
| 1983 | writeBandWidth(radioIndex,"40MHz"); |
| 1984 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 1985 | printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n"); |
| 1986 | } |
| 1987 | else if (strcmp (channelMode,"11ACVHT20") == 0) |
| 1988 | { |
| 1989 | writeBandWidth(radioIndex,"20MHz"); |
| 1990 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 1991 | printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n"); |
| 1992 | } |
| 1993 | else if (strcmp (channelMode,"11ACVHT40PLUS") == 0) |
| 1994 | { |
| 1995 | writeBandWidth(radioIndex,"40MHz"); |
| 1996 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 1997 | printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n"); |
| 1998 | } |
| 1999 | else if (strcmp (channelMode,"11ACVHT40MINUS") == 0) |
| 2000 | { |
| 2001 | writeBandWidth(radioIndex,"40MHz"); |
| 2002 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 2003 | printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n"); |
| 2004 | } |
| 2005 | else if (strcmp (channelMode,"11ACVHT80") == 0) |
| 2006 | { |
| 2007 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz"); |
| 2008 | printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n"); |
| 2009 | } |
| 2010 | else if (strcmp (channelMode,"11ACVHT160") == 0) |
| 2011 | { |
| 2012 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz"); |
| 2013 | printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n"); |
| 2014 | } |
| 2015 | else if (strcmp (channelMode,"11B") == 0) |
| 2016 | { |
| 2017 | writeBandWidth(radioIndex,"20MHz"); |
| 2018 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 2019 | printf("\nChannel Mode is 802.11b(2.4GHz)\n"); |
| 2020 | } |
| 2021 | else if (strcmp (channelMode,"11G") == 0) |
| 2022 | { |
| 2023 | writeBandWidth(radioIndex,"20MHz"); |
| 2024 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 2025 | printf("\nChannel Mode is 802.11g(2.4GHz)\n"); |
| 2026 | } |
| 2027 | else if (strcmp (channelMode,"11NGHT20") == 0) |
| 2028 | { |
| 2029 | writeBandWidth(radioIndex,"20MHz"); |
| 2030 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 2031 | printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n"); |
| 2032 | } |
| 2033 | else if (strcmp (channelMode,"11NGHT40PLUS") == 0) |
| 2034 | { |
| 2035 | writeBandWidth(radioIndex,"40MHz"); |
| 2036 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 2037 | printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n"); |
| 2038 | } |
| 2039 | else if (strcmp (channelMode,"11NGHT40MINUS") == 0) |
| 2040 | { |
| 2041 | writeBandWidth(radioIndex,"40MHz"); |
| 2042 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 2043 | printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n"); |
| 2044 | } |
| 2045 | else |
| 2046 | { |
| 2047 | return RETURN_ERR; |
| 2048 | } |
| 2049 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2050 | |
| 2051 | return RETURN_OK; |
| 2052 | } |
| 2053 | |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 2054 | // Set the radio operating mode, and pure mode flag. |
| 2055 | INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode) |
| 2056 | { |
| 2057 | int num_hostapd_support_mode = 3; // n, ac, ax |
| 2058 | struct params list[num_hostapd_support_mode]; |
| 2059 | char config_file[64] = {0}; |
| 2060 | char bandwidth[16] = {0}; |
| 2061 | int mode_check_bit = 1 << 3; // n mode |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 2062 | |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 2063 | |
| 2064 | WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__); |
| 2065 | // Set radio mode |
| 2066 | list[0].name = "ieee80211n"; |
| 2067 | list[1].name = "ieee80211ac"; |
| 2068 | list[2].name = "ieee80211ax"; |
| 2069 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2070 | |
| 2071 | // check the bit map from n to ax, and set hostapd config |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 2072 | if (pureMode & WIFI_MODE_N) |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 2073 | list[0].value = "1"; |
| 2074 | else |
| 2075 | list[0].value = "0"; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 2076 | if (pureMode & WIFI_MODE_AC) |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 2077 | list[1].value = "1"; |
| 2078 | else |
| 2079 | list[1].value = "0"; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 2080 | if (pureMode & WIFI_MODE_AX) |
developer | db74438 | 2022-09-13 15:34:54 +0800 | [diff] [blame] | 2081 | list[2].value = "1"; |
| 2082 | else |
| 2083 | list[2].value = "0"; |
| 2084 | wifi_hostapdWrite(config_file, list, num_hostapd_support_mode); |
| 2085 | |
| 2086 | if (channelMode == NULL || strlen(channelMode) == 0) |
| 2087 | return RETURN_OK; |
| 2088 | // Set bandwidth |
| 2089 | if (strstr(channelMode, "40") != NULL) |
| 2090 | strcpy(bandwidth, "40MHz"); |
| 2091 | else if (strstr(channelMode, "80") != NULL) |
| 2092 | strcpy(bandwidth, "80MHz"); |
| 2093 | else if (strstr(channelMode, "160") != NULL) |
| 2094 | strcpy(bandwidth, "160MHz"); |
| 2095 | else // 11A, 11B, 11G.... |
| 2096 | strcpy(bandwidth, "20MHz"); |
| 2097 | |
| 2098 | writeBandWidth(radioIndex, bandwidth); |
| 2099 | wifi_setRadioOperatingChannelBandwidth(radioIndex, bandwidth); |
| 2100 | |
| 2101 | wifi_reloadAp(radioIndex); |
| 2102 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2103 | |
| 2104 | return RETURN_OK; |
| 2105 | } |
| 2106 | |
developer | 1d12ebf | 2022-10-04 15:13:38 +0800 | [diff] [blame] | 2107 | INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) { |
| 2108 | |
| 2109 | char config_file[64] = {0}; |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 2110 | char buf[64] = {0}; |
developer | 1d12ebf | 2022-10-04 15:13:38 +0800 | [diff] [blame] | 2111 | struct params params = {0}; |
| 2112 | wifi_band band = band_invalid; |
| 2113 | |
| 2114 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 2115 | |
| 2116 | band = wifi_index_to_band(radioIndex); |
developer | c9e88f3 | 2022-10-06 17:09:56 +0800 | [diff] [blame] | 2117 | |
| 2118 | if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6)) |
developer | 1d12ebf | 2022-10-04 15:13:38 +0800 | [diff] [blame] | 2119 | return RETURN_ERR; |
| 2120 | else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4) |
| 2121 | return RETURN_ERR; |
developer | c9e88f3 | 2022-10-06 17:09:56 +0800 | [diff] [blame] | 2122 | else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid) |
| 2123 | return RETURN_ERR; |
developer | 1d12ebf | 2022-10-04 15:13:38 +0800 | [diff] [blame] | 2124 | |
| 2125 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2126 | params.name = "hw_mode"; |
| 2127 | params.value = hw_mode; |
| 2128 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 2129 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 2130 | |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 2131 | if (band == band_2_4) { |
| 2132 | if (strncmp(hw_mode, "b", 1) == 0) { |
| 2133 | wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B); |
| 2134 | snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11"); |
| 2135 | wifi_setRadioOperationalDataTransmitRates(radioIndex, buf); |
| 2136 | snprintf(buf, sizeof(buf), "%s", "1,2"); |
| 2137 | wifi_setRadioBasicDataTransmitRates(radioIndex, buf); |
| 2138 | } else { |
| 2139 | // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?). |
| 2140 | |
| 2141 | snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54"); |
| 2142 | wifi_setRadioOperationalDataTransmitRates(radioIndex, buf); |
| 2143 | snprintf(buf, sizeof(buf), "%s", "6,12,24"); |
| 2144 | wifi_setRadioBasicDataTransmitRates(radioIndex, buf); |
| 2145 | } |
| 2146 | } |
| 2147 | |
developer | 1d12ebf | 2022-10-04 15:13:38 +0800 | [diff] [blame] | 2148 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2149 | return RETURN_OK; |
| 2150 | } |
| 2151 | |
developer | e8988ba | 2022-10-18 17:42:30 +0800 | [diff] [blame] | 2152 | INT wifi_setNoscan(INT radioIndex, CHAR *noscan) |
| 2153 | { |
| 2154 | char config_file[64] = {0}; |
| 2155 | struct params params = {0}; |
| 2156 | wifi_band band = band_invalid; |
| 2157 | |
| 2158 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 2159 | |
| 2160 | band = wifi_index_to_band(radioIndex); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 2161 | if (band != band_2_4) |
| 2162 | return RETURN_OK; |
developer | e8988ba | 2022-10-18 17:42:30 +0800 | [diff] [blame] | 2163 | |
| 2164 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2165 | params.name = "noscan"; |
| 2166 | params.value = noscan; |
| 2167 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 2168 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 2169 | |
| 2170 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2171 | return RETURN_OK; |
| 2172 | } |
| 2173 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2174 | //Get the list of supported channel. eg: "1-11" |
| 2175 | //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. |
| 2176 | INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB |
| 2177 | { |
developer | 6318ed5 | 2022-09-13 15:17:58 +0800 | [diff] [blame] | 2178 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2179 | if (NULL == output_string) |
| 2180 | return RETURN_ERR; |
developer | 6318ed5 | 2022-09-13 15:17:58 +0800 | [diff] [blame] | 2181 | char cmd[256] = {0}; |
| 2182 | char buf[128] = {0}; |
| 2183 | BOOL dfs_enable = false; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2184 | int phyId = 0; |
| 2185 | |
developer | 6318ed5 | 2022-09-13 15:17:58 +0800 | [diff] [blame] | 2186 | // Parse possible channel number and separate them with commas. |
| 2187 | wifi_getRadioDfsEnable(radioIndex, &dfs_enable); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2188 | phyId = radio_index_to_phy(radioIndex); |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2189 | // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency. |
developer | 6318ed5 | 2022-09-13 15:17:58 +0800 | [diff] [blame] | 2190 | if (dfs_enable) |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2191 | snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId); |
developer | 6318ed5 | 2022-09-13 15:17:58 +0800 | [diff] [blame] | 2192 | else |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2193 | snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'radar\\|no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId); |
developer | 6318ed5 | 2022-09-13 15:17:58 +0800 | [diff] [blame] | 2194 | |
| 2195 | _syscmd(cmd,buf,sizeof(buf)); |
| 2196 | strncpy(output_string, buf, sizeof(buf)); |
| 2197 | |
| 2198 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2199 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2200 | } |
| 2201 | |
| 2202 | //Get the list for used channel. eg: "1,6,9,11" |
| 2203 | //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. |
| 2204 | INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB |
| 2205 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 2206 | char interface_name[16] = {0}; |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 2207 | char cmd[128] = {0}; |
| 2208 | char buf[128] = {0}; |
| 2209 | char config_file[64] = {0}; |
| 2210 | int channel = 0; |
| 2211 | int freq = 0; |
| 2212 | int bandwidth = 0; |
| 2213 | int center_freq = 0; |
| 2214 | int center_channel = 0; |
| 2215 | int channel_delta = 0; |
| 2216 | wifi_band band = band_invalid; |
| 2217 | |
| 2218 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 2219 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2220 | if (NULL == output_string) |
| 2221 | return RETURN_ERR; |
| 2222 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 2223 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 2224 | return RETURN_ERR; |
| 2225 | sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name); |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 2226 | _syscmd(cmd, buf, sizeof(buf)); |
| 2227 | if (strlen(buf) == 0) { |
| 2228 | fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__); |
| 2229 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2230 | } |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 2231 | sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, ¢er_freq); |
| 2232 | |
| 2233 | if (bandwidth == 20) { |
| 2234 | snprintf(output_string, 256, "%d", channel); |
| 2235 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2236 | } |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 2237 | |
| 2238 | center_channel = ieee80211_frequency_to_channel(center_freq); |
| 2239 | |
| 2240 | band = wifi_index_to_band(radioIndex); |
| 2241 | if (band == band_2_4 && bandwidth == 40) { |
| 2242 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2243 | memset(buf, 0, sizeof(buf)); |
| 2244 | wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or - |
| 2245 | |
developer | f22724d | 2022-12-22 17:24:14 +0800 | [diff] [blame^] | 2246 | if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) { |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 2247 | snprintf(output_string, 256, "%d,%d", channel, channel+4); |
developer | f22724d | 2022-12-22 17:24:14 +0800 | [diff] [blame^] | 2248 | } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) { |
developer | f5745ee | 2022-10-05 16:09:53 +0800 | [diff] [blame] | 2249 | snprintf(output_string, 256, "%d,%d", channel-4, channel); |
| 2250 | } else { |
| 2251 | fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf); |
| 2252 | return RETURN_ERR; |
| 2253 | } |
| 2254 | } else if (band == band_5 || band == band_6){ |
| 2255 | // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel. |
| 2256 | // example: bandwidth 80: center is 42 (5210), channels are 36-48 (5170-5250). The delta should be 6. |
| 2257 | channel_delta = (bandwidth-20)/10; |
| 2258 | snprintf(output_string, 256, "%d-%d", (center_channel-channel_delta), (center_channel+channel_delta)); |
| 2259 | } else |
| 2260 | return RETURN_ERR; |
| 2261 | |
| 2262 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2263 | return RETURN_OK; |
| 2264 | } |
| 2265 | |
| 2266 | //Get the running channel number |
| 2267 | INT wifi_getRadioChannel(INT radioIndex,ULONG *output_ulong) //RDKB |
| 2268 | { |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 2269 | char channel_str[16] = {0}; |
| 2270 | char config_file[128] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2271 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 2272 | if (output_ulong == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2273 | return RETURN_ERR; |
| 2274 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 2275 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2276 | wifi_hostapdRead(config_file, "channel", channel_str, sizeof(channel_str)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2277 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 2278 | *output_ulong = strtoul(channel_str, NULL, 10); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2279 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2280 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2281 | } |
| 2282 | |
| 2283 | |
| 2284 | INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB |
| 2285 | { |
| 2286 | char cmd[1024] = {0}, buf[5] = {0}; |
developer | dbbd678 | 2022-12-16 14:26:20 +0800 | [diff] [blame] | 2287 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2288 | |
| 2289 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2290 | if (NULL == output_ulong) |
| 2291 | return RETURN_ERR; |
| 2292 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2293 | snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name); |
developer | dbbd678 | 2022-12-16 14:26:20 +0800 | [diff] [blame] | 2294 | if (wifi_getApName(apIndex,interface_name) != RETURN_OK) |
| 2295 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2296 | _syscmd(cmd,buf,sizeof(buf)); |
| 2297 | *output_ulong = (strlen(buf) >= 1)? atol(buf): 0; |
| 2298 | if (*output_ulong == 0) { |
| 2299 | return RETURN_ERR; |
| 2300 | } |
| 2301 | |
| 2302 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2303 | return RETURN_OK; |
| 2304 | } |
| 2305 | |
| 2306 | //Storing the previous channel value |
| 2307 | INT wifi_storeprevchanval(INT radioIndex) |
| 2308 | { |
| 2309 | char buf[256] = {0}; |
| 2310 | char output[4]={'\0'}; |
| 2311 | char config_file[MAX_BUF_SIZE] = {0}; |
| 2312 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
| 2313 | wifi_hostapdRead(config_file, "channel", output, sizeof(output)); |
| 2314 | if(radioIndex == 0) |
| 2315 | sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable"); |
| 2316 | else if(radioIndex == 1) |
| 2317 | sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable"); |
| 2318 | system(buf); |
| 2319 | Radio_flag = FALSE; |
| 2320 | return RETURN_OK; |
| 2321 | } |
| 2322 | |
| 2323 | //Set the running channel number |
| 2324 | INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only |
| 2325 | { |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2326 | // We only write hostapd config here |
| 2327 | char str_channel[8]={0}; |
| 2328 | char *list_channel; |
| 2329 | char config_file[128] = {0}; |
| 2330 | char possible_channels[256] = {0}; |
| 2331 | int max_radio_num = 0; |
| 2332 | struct params list = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2333 | |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2334 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2335 | |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2336 | // Check valid |
| 2337 | sprintf(str_channel, "%lu", channel); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2338 | |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2339 | wifi_getRadioPossibleChannels(radioIndex, possible_channels); |
| 2340 | list_channel = strtok(possible_channels, ","); |
| 2341 | while(true) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2342 | { |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2343 | if(list_channel == NULL) { // input not in the list |
| 2344 | fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel); |
| 2345 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2346 | } |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2347 | if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0) |
| 2348 | break; |
| 2349 | list_channel = strtok(NULL, ","); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2350 | } |
| 2351 | |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2352 | list.name = "channel"; |
| 2353 | list.value = str_channel; |
| 2354 | wifi_getMaxRadioNumber(&max_radio_num); |
| 2355 | for(int i=0; i<=MAX_APS/max_radio_num;i++) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2356 | { |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2357 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i)); |
| 2358 | wifi_hostapdWrite(config_file, &list, 1); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2359 | } |
| 2360 | |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2361 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2362 | return RETURN_OK; |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2363 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2364 | |
| 2365 | INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel) |
| 2366 | { |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2367 | struct params list[2]; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2368 | char str_idx[16]; |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2369 | char config_file[64]; |
| 2370 | int max_num_radios = 0; |
| 2371 | wifi_band band = band_invalid; |
| 2372 | |
| 2373 | band = wifi_index_to_band(radioIndex); |
| 2374 | if (band == band_2_4) |
| 2375 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2376 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 2377 | snprintf(str_idx, sizeof(str_idx), "%lu", channel); |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2378 | list[0].name = "vht_oper_centr_freq_seg0_idx"; |
| 2379 | list[0].value = str_idx; |
| 2380 | list[1].name = "he_oper_centr_freq_seg0_idx"; |
| 2381 | list[1].value = str_idx; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2382 | |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2383 | wifi_getMaxRadioNumber(&max_num_radios); |
| 2384 | for(int i=0; i<=MAX_APS/max_num_radios; i++) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2385 | { |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2386 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i)); |
| 2387 | if (band == band_6) |
| 2388 | wifi_hostapdWrite(config_file, &list[1], 1); |
| 2389 | else |
| 2390 | wifi_hostapdWrite(config_file, list, 2); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2391 | } |
| 2392 | |
| 2393 | return RETURN_OK; |
| 2394 | } |
| 2395 | |
| 2396 | //Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio |
| 2397 | //This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS)) |
| 2398 | INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB |
| 2399 | { |
| 2400 | //Set to wifi config only. Wait for wifi reset to apply. |
| 2401 | char buf[256] = {0}; |
| 2402 | char str_channel[256] = {0}; |
| 2403 | int count = 0; |
| 2404 | ULONG Value = 0; |
| 2405 | FILE *fp = NULL; |
| 2406 | if(enable == TRUE) |
| 2407 | { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2408 | wifi_setRadioChannel(radioIndex,Value); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2409 | } |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 2410 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2411 | } |
| 2412 | |
developer | 0b246d1 | 2022-09-30 15:24:20 +0800 | [diff] [blame] | 2413 | INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool) |
| 2414 | { |
| 2415 | if (output_bool == NULL) |
| 2416 | return RETURN_ERR; |
| 2417 | |
| 2418 | *output_bool = TRUE; |
| 2419 | |
| 2420 | return RETURN_OK; |
| 2421 | } |
| 2422 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2423 | INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB |
| 2424 | { |
| 2425 | if (NULL == output_bool) |
| 2426 | return RETURN_ERR; |
| 2427 | *output_bool=FALSE; |
| 2428 | return RETURN_OK; |
| 2429 | } |
| 2430 | |
| 2431 | INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB |
| 2432 | { |
| 2433 | if (NULL == output_bool) |
| 2434 | return RETURN_ERR; |
| 2435 | *output_bool=FALSE; |
| 2436 | return RETURN_OK; |
| 2437 | } |
| 2438 | |
| 2439 | INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB |
| 2440 | { |
| 2441 | //Set to wifi config only. Wait for wifi reset to apply. |
| 2442 | return RETURN_OK; |
| 2443 | } |
| 2444 | |
| 2445 | INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable) |
| 2446 | { |
| 2447 | return RETURN_OK; |
| 2448 | } |
| 2449 | |
| 2450 | INT wifi_factoryResetAP(int apIndex) |
| 2451 | { |
developer | 838cca9 | 2022-10-03 13:19:57 +0800 | [diff] [blame] | 2452 | char ap_config_file[64] = {0}; |
| 2453 | char cmd[128] = {0}; |
| 2454 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2455 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 838cca9 | 2022-10-03 13:19:57 +0800 | [diff] [blame] | 2456 | |
| 2457 | wifi_setApEnable(apIndex, FALSE); |
| 2458 | sprintf(ap_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 2459 | sprintf(cmd, "rm %s && sh /lib/rdk/hostapd-init.sh", ap_config_file); |
| 2460 | wifi_setApEnable(apIndex, TRUE); |
| 2461 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2462 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 838cca9 | 2022-10-03 13:19:57 +0800 | [diff] [blame] | 2463 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2464 | return RETURN_OK; |
| 2465 | } |
| 2466 | |
| 2467 | //To set Band Steering AP group |
| 2468 | //To-do |
| 2469 | INT wifi_setBandSteeringApGroup(char *ApGroup) |
| 2470 | { |
| 2471 | return RETURN_OK; |
| 2472 | } |
| 2473 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 2474 | INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval) |
| 2475 | { |
| 2476 | char config_file[128] = {'\0'}; |
| 2477 | char buf[128] = {'\0'}; |
| 2478 | |
| 2479 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2480 | if (dtimInterval == NULL) |
| 2481 | return RETURN_ERR; |
| 2482 | |
| 2483 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 2484 | wifi_hostapdRead(config_file, "dtime_period", buf, sizeof(buf)); |
| 2485 | |
| 2486 | if (strlen(buf) == 0) { |
| 2487 | *dtimInterval = 2; |
| 2488 | } else { |
| 2489 | *dtimInterval = strtoul(buf, NULL, 10); |
| 2490 | } |
| 2491 | |
| 2492 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2493 | return RETURN_OK; |
| 2494 | } |
| 2495 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2496 | INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval) |
| 2497 | { |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 2498 | struct params params={0}; |
| 2499 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 2500 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 2501 | |
| 2502 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2503 | if (dtimInterval < 1 || dtimInterval > 255) { |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 2504 | WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 2505 | return RETURN_ERR; |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 2506 | } |
| 2507 | |
| 2508 | params.name = "dtim_period"; |
| 2509 | snprintf(buf, sizeof(buf), "%d", dtimInterval); |
| 2510 | params.value = buf; |
| 2511 | |
| 2512 | sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex); |
| 2513 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 2514 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 2515 | |
| 2516 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2517 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2518 | } |
| 2519 | |
| 2520 | //Check if the driver support the Dfs |
| 2521 | INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181 |
| 2522 | { |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 2523 | wifi_band band = band_invalid; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2524 | if (NULL == output_bool) |
| 2525 | return RETURN_ERR; |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 2526 | *output_bool=FALSE; |
| 2527 | |
| 2528 | band = wifi_index_to_band(radioIndex); |
| 2529 | if (band == band_5) |
| 2530 | *output_bool = TRUE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2531 | return RETURN_OK; |
| 2532 | } |
| 2533 | |
| 2534 | //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. |
| 2535 | //The value of this parameter is a comma seperated list of channel number |
| 2536 | INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB |
| 2537 | { |
| 2538 | if (NULL == output_pool) |
| 2539 | return RETURN_ERR; |
| 2540 | if (radioIndex==1) |
| 2541 | return RETURN_OK;//TODO need to handle for 5GHz band, i think |
| 2542 | snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11"); |
| 2543 | |
| 2544 | return RETURN_OK; |
| 2545 | } |
| 2546 | |
| 2547 | INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB |
| 2548 | { |
| 2549 | //Set to wifi config. And apply instantly. |
| 2550 | return RETURN_OK; |
| 2551 | } |
| 2552 | |
| 2553 | INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds) |
| 2554 | { |
| 2555 | if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds) |
| 2556 | return RETURN_ERR; |
| 2557 | *output_interval_seconds=1800; |
| 2558 | *output_dwell_milliseconds=40; |
| 2559 | |
| 2560 | return RETURN_OK; |
| 2561 | } |
| 2562 | |
| 2563 | INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds) |
| 2564 | { |
| 2565 | //Set to wifi config. And apply instantly. |
| 2566 | return RETURN_OK; |
| 2567 | } |
| 2568 | |
developer | bfc1851 | 2022-10-05 17:54:28 +0800 | [diff] [blame] | 2569 | INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181 |
| 2570 | { |
| 2571 | if (output_bool == NULL) |
| 2572 | return RETURN_ERR; |
| 2573 | *output_bool = true; |
| 2574 | return RETURN_OK; |
| 2575 | } |
| 2576 | |
| 2577 | INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181 |
| 2578 | { |
| 2579 | return RETURN_OK; |
| 2580 | } |
| 2581 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2582 | //Get the Dfs enable status |
| 2583 | INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181 |
| 2584 | { |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2585 | char buf[16] = {0}; |
| 2586 | FILE *f = NULL; |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2587 | |
| 2588 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2589 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 2590 | if (output_bool == NULL) |
| 2591 | return RETURN_ERR; |
| 2592 | |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2593 | *output_bool = TRUE; // default |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2594 | f = fopen(DFS_ENABLE_FILE, "r"); |
| 2595 | if (f != NULL) { |
| 2596 | fgets(buf, 2, f); |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2597 | if (strncmp(buf, "0", 1) == 0) |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2598 | *output_bool = FALSE; |
| 2599 | fclose(f); |
| 2600 | } |
| 2601 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2602 | return RETURN_OK; |
| 2603 | } |
| 2604 | |
| 2605 | //Set the Dfs enable status |
| 2606 | INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181 |
| 2607 | { |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2608 | char config_file[128] = {0}; |
| 2609 | FILE *f = NULL; |
| 2610 | struct params params={0}; |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2611 | |
| 2612 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2613 | |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2614 | f = fopen(DFS_ENABLE_FILE, "w"); |
| 2615 | if (f == NULL) |
| 2616 | return RETURN_ERR; |
| 2617 | fprintf(f, "%d", enable); |
| 2618 | fclose(f); |
| 2619 | |
| 2620 | params.name = "acs_exclude_dfs"; |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2621 | params.value = enable?"0":"1"; |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2622 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2623 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 2624 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 2625 | |
| 2626 | wifi_setRadioIEEE80211hEnabled(radioIndex, enable); |
| 2627 | |
developer | 9964b5b | 2022-09-13 15:59:34 +0800 | [diff] [blame] | 2628 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 7698923 | 2022-10-04 14:13:19 +0800 | [diff] [blame] | 2629 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2630 | } |
| 2631 | |
| 2632 | //Check if the driver support the AutoChannelRefreshPeriod |
| 2633 | INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181 |
| 2634 | { |
| 2635 | if (NULL == output_bool) |
| 2636 | return RETURN_ERR; |
| 2637 | *output_bool=FALSE; //not support |
| 2638 | |
| 2639 | return RETURN_OK; |
| 2640 | } |
| 2641 | |
| 2642 | //Get the ACS refresh period in seconds |
| 2643 | INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181 |
| 2644 | { |
| 2645 | if (NULL == output_ulong) |
| 2646 | return RETURN_ERR; |
| 2647 | *output_ulong=300; |
| 2648 | |
| 2649 | return RETURN_OK; |
| 2650 | } |
| 2651 | |
| 2652 | //Set the ACS refresh period in seconds |
| 2653 | INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181 |
| 2654 | { |
| 2655 | return RETURN_ERR; |
| 2656 | } |
| 2657 | |
| 2658 | //Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160" |
| 2659 | //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. |
| 2660 | INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181 |
| 2661 | { |
developer | 7049003 | 2022-09-13 15:45:20 +0800 | [diff] [blame] | 2662 | char cmd[128] = {0}, buf[64] = {0}; |
| 2663 | char interface_name[64] = {0}; |
| 2664 | int ret = 0, len=0; |
| 2665 | BOOL radio_enable = FALSE; |
| 2666 | |
| 2667 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2668 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2669 | if (NULL == output_string) |
| 2670 | return RETURN_ERR; |
| 2671 | |
developer | 7049003 | 2022-09-13 15:45:20 +0800 | [diff] [blame] | 2672 | if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) |
| 2673 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2674 | |
developer | 7049003 | 2022-09-13 15:45:20 +0800 | [diff] [blame] | 2675 | if (radio_enable != TRUE) |
| 2676 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2677 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 2678 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 2679 | return RETURN_ERR; |
| 2680 | snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2681 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 2682 | len = strlen(buf); |
| 2683 | if((ret != 0) || (len == 0)) |
| 2684 | { |
| 2685 | WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__); |
| 2686 | return RETURN_ERR; |
| 2687 | } |
| 2688 | |
| 2689 | buf[len-1] = '\0'; |
| 2690 | snprintf(output_string, 64, "%sMHz", buf); |
| 2691 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2692 | |
| 2693 | #if 0 |
| 2694 | //TODO: revisit below implementation |
| 2695 | char output_buf[8]={0}; |
| 2696 | char bw_value[10]; |
| 2697 | char config_file[MAX_BUF_SIZE] = {0}; |
| 2698 | |
| 2699 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2700 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
| 2701 | wifi_hostapdRead(config_file, "vht_oper_chwidth", output_buf, sizeof(output_buf)); |
| 2702 | readBandWidth(radioIndex,bw_value); |
| 2703 | |
| 2704 | if(strstr (output_buf,"0") != NULL ) |
| 2705 | { |
| 2706 | strcpy(output_string,bw_value); |
| 2707 | } |
| 2708 | else if (strstr (output_buf,"1") != NULL) |
| 2709 | { |
| 2710 | strcpy(output_string,"80MHz"); |
| 2711 | } |
| 2712 | else if (strstr (output_buf,"2") != NULL) |
| 2713 | { |
| 2714 | strcpy(output_string,"160MHz"); |
| 2715 | } |
| 2716 | else if (strstr (output_buf,"3") != NULL) |
| 2717 | { |
| 2718 | strcpy(output_string,"80+80"); |
| 2719 | } |
| 2720 | else |
| 2721 | { |
| 2722 | strcpy(output_string,"Auto"); |
| 2723 | } |
| 2724 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2725 | #endif |
| 2726 | |
| 2727 | return RETURN_OK; |
| 2728 | } |
| 2729 | |
| 2730 | //Set the Operating Channel Bandwidth. |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2731 | INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2732 | { |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2733 | char config_file[128]; |
| 2734 | char set_value[16]; |
| 2735 | struct params params[2]; |
| 2736 | int max_radio_num = 0; |
| 2737 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2738 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2739 | |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2740 | if(NULL == bandwidth) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2741 | return RETURN_ERR; |
| 2742 | |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2743 | if(strstr(bandwidth,"80+80") != NULL) |
| 2744 | strcpy(set_value, "3"); |
| 2745 | else if(strstr(bandwidth,"160") != NULL) |
| 2746 | strcpy(set_value, "2"); |
| 2747 | else if(strstr(bandwidth,"80") != NULL) |
| 2748 | strcpy(set_value, "1"); |
| 2749 | else if(strstr(bandwidth,"20") != NULL || strstr(bandwidth,"40") != NULL) |
| 2750 | strcpy(set_value, "0"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2751 | else |
| 2752 | { |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2753 | fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2754 | return RETURN_ERR; |
| 2755 | } |
| 2756 | |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2757 | params[0].name = "vht_oper_chwidth"; |
| 2758 | params[0].value = set_value; |
| 2759 | params[1].name = "he_oper_chwidth"; |
| 2760 | params[1].value = set_value; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2761 | |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2762 | wifi_getMaxRadioNumber(&max_radio_num); |
| 2763 | for(int i=0; i<=MAX_APS/max_radio_num; i++) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2764 | { |
developer | f7a466e | 2022-09-29 11:55:56 +0800 | [diff] [blame] | 2765 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i)); |
| 2766 | wifi_hostapdWrite(config_file, params, 2); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2767 | } |
| 2768 | |
| 2769 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2770 | return RETURN_OK; |
| 2771 | } |
| 2772 | |
| 2773 | //Getting current radio extension channel |
| 2774 | INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value) |
| 2775 | { |
| 2776 | CHAR buf[150] = {0}; |
| 2777 | CHAR cmd[150] = {0}; |
| 2778 | sprintf(cmd,"%s%s%s","cat ",file," | grep -w ht_capab="); |
| 2779 | _syscmd(cmd, buf, sizeof(buf)); |
| 2780 | if(NULL != strstr(buf,"HT40+")) |
| 2781 | strcpy(Value,"AboveControlChannel"); |
| 2782 | else if(NULL != strstr(buf,"HT40-")) |
| 2783 | strcpy(Value,"BelowControlChannel"); |
| 2784 | return RETURN_OK; |
| 2785 | } |
| 2786 | |
| 2787 | //Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only) |
| 2788 | //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. |
| 2789 | INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181 |
| 2790 | { |
| 2791 | if (NULL == output_string) |
| 2792 | return RETURN_ERR; |
| 2793 | |
| 2794 | snprintf(output_string, 64, (radioIndex==0)?"":"BelowControlChannel"); |
| 2795 | #if 0 |
| 2796 | CHAR Value[100] = {0}; |
| 2797 | if (NULL == output_string) |
| 2798 | return RETURN_ERR; |
| 2799 | if(radioIndex == 0) |
| 2800 | strcpy(Value,"Auto"); //so far rpi(2G) supports upto 150Mbps (i,e 20MHZ) |
| 2801 | else if(radioIndex == 1)//so far rpi(5G) supports upto 300mbps (i,e 20MHz/40MHz) |
| 2802 | { |
| 2803 | wifi_getRadioOperatingChannelBandwidth(radioIndex,Value); |
| 2804 | if(strcmp(Value,"40MHz") == 0) |
| 2805 | wifi_halgetRadioExtChannel("/nvram/hostapd1.conf",Value); |
| 2806 | else |
| 2807 | strcpy(Value,"Auto"); |
| 2808 | } |
| 2809 | strcpy(output_string,Value); |
| 2810 | #endif |
| 2811 | |
| 2812 | return RETURN_OK; |
| 2813 | } |
| 2814 | |
| 2815 | //Set the extension channel. |
| 2816 | INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only |
| 2817 | { |
| 2818 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2819 | struct params params={'\0'}; |
| 2820 | char config_file[MAX_BUF_SIZE] = {0}; |
| 2821 | char ext_channel[127]={'\0'}; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2822 | int max_radio_num =0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2823 | params.name = "ht_capab"; |
| 2824 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2825 | if(NULL!= strstr(string,"Above")) |
| 2826 | strcpy(ext_channel, HOSTAPD_HT_CAPAB "[HT40+]"); |
| 2827 | else if(NULL!= strstr(string,"Below")) |
| 2828 | strcpy(ext_channel, HOSTAPD_HT_CAPAB "[HT40-]"); |
| 2829 | else |
| 2830 | strcpy(ext_channel, HOSTAPD_HT_CAPAB); |
| 2831 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2832 | |
| 2833 | params.value = ext_channel; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2834 | |
| 2835 | wifi_getMaxRadioNumber(&max_radio_num); |
| 2836 | for(int i=0; i<=MAX_APS/max_radio_num; i++) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2837 | { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 2838 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2839 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 2840 | } |
| 2841 | |
| 2842 | //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply. |
| 2843 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2844 | return RETURN_OK; |
| 2845 | } |
| 2846 | |
| 2847 | //Get the guard interval value. eg "400nsec" or "800nsec" |
| 2848 | //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. |
| 2849 | INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181 |
| 2850 | { |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 2851 | wifi_guard_interval_t GI; |
| 2852 | |
| 2853 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2854 | |
| 2855 | if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2856 | return RETURN_ERR; |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 2857 | |
| 2858 | if (GI == wifi_guard_interval_400) |
| 2859 | strcpy(output_string, "400nsec"); |
| 2860 | else if (GI == wifi_guard_interval_800) |
| 2861 | strcpy(output_string, "800nsec"); |
| 2862 | else if (GI == wifi_guard_interval_1600) |
| 2863 | strcpy(output_string, "1600nsec"); |
| 2864 | else if (GI == wifi_guard_interval_3200) |
| 2865 | strcpy(output_string, "3200nsec"); |
| 2866 | else |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 2867 | strcpy(output_string, "Auto"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2868 | |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 2869 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2870 | return RETURN_OK; |
| 2871 | } |
| 2872 | |
| 2873 | //Set the guard interval value. |
| 2874 | INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181 |
| 2875 | { |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 2876 | wifi_guard_interval_t GI; |
| 2877 | int ret = 0; |
| 2878 | |
| 2879 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2880 | |
| 2881 | if (strcmp(string, "400nsec") == 0) |
| 2882 | GI = wifi_guard_interval_400; |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 2883 | else if (strcmp(string , "800nsec") == 0) |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 2884 | GI = wifi_guard_interval_800; |
| 2885 | else if (strcmp(string , "1600nsec") == 0) |
| 2886 | GI = wifi_guard_interval_1600; |
| 2887 | else if (strcmp(string , "3200nsec") == 0) |
| 2888 | GI = wifi_guard_interval_3200; |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 2889 | else |
| 2890 | GI = wifi_guard_interval_auto; |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 2891 | |
| 2892 | ret = wifi_setGuardInterval(radioIndex, GI); |
| 2893 | |
| 2894 | if (ret == RETURN_ERR) { |
| 2895 | wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__); |
| 2896 | return RETURN_ERR; |
| 2897 | } |
| 2898 | |
| 2899 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2900 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2901 | } |
| 2902 | |
| 2903 | //Get the Modulation Coding Scheme index, eg: "-1", "1", "15" |
| 2904 | INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181 |
| 2905 | { |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 2906 | char buf[32]={0}; |
| 2907 | char mcs_file[64] = {0}; |
| 2908 | char cmd[64] = {0}; |
| 2909 | int mode_bitmap = 0; |
| 2910 | |
| 2911 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2912 | if(output_int == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2913 | return RETURN_ERR; |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 2914 | snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex); |
| 2915 | |
| 2916 | snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file); |
| 2917 | _syscmd(cmd, buf, sizeof(buf)); |
| 2918 | if (strlen(buf) > 0) |
| 2919 | *output_int = strtol(buf, NULL, 10); |
| 2920 | else { |
| 2921 | // output the max MCS for the current radio mode |
| 2922 | if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) { |
| 2923 | wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__); |
| 2924 | return RETURN_ERR; |
| 2925 | } |
| 2926 | if (mode_bitmap & WIFI_MODE_AX) { |
| 2927 | *output_int = 11; |
| 2928 | } else if (mode_bitmap & WIFI_MODE_AC) { |
| 2929 | *output_int = 9; |
| 2930 | } else if (mode_bitmap & WIFI_MODE_N) { |
| 2931 | *output_int = 7; |
| 2932 | } |
| 2933 | } |
| 2934 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2935 | |
| 2936 | return RETURN_OK; |
| 2937 | } |
| 2938 | |
| 2939 | //Set the Modulation Coding Scheme index |
| 2940 | INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181 |
| 2941 | { |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 2942 | // Only HE mode can specify MCS capability. We don't support MCS in HT mode, because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT). |
| 2943 | char config_file[64] = {0}; |
| 2944 | char set_value[16] = {0}; |
| 2945 | char mcs_file[32] = {0}; |
| 2946 | wifi_band band = band_invalid; |
| 2947 | struct params set_config = {0}; |
| 2948 | FILE *f = NULL; |
| 2949 | |
| 2950 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2951 | |
| 2952 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2953 | |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 2954 | // -1 means auto |
| 2955 | if (MCS > 15 || MCS < -1) { |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 2956 | fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS); |
| 2957 | return RETURN_ERR; |
| 2958 | } |
| 2959 | |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 2960 | if (MCS > 9 || MCS == -1) |
| 2961 | strcpy(set_value, "2"); |
| 2962 | else if (MCS > 7) |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 2963 | strcpy(set_value, "1"); |
| 2964 | else |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 2965 | strcpy(set_value, "0"); |
developer | f49437e | 2022-09-29 19:58:21 +0800 | [diff] [blame] | 2966 | |
| 2967 | set_config.name = "he_basic_mcs_nss_set"; |
| 2968 | set_config.value = set_value; |
| 2969 | |
| 2970 | wifi_hostapdWrite(config_file, &set_config, 1); |
| 2971 | wifi_hostapdProcessUpdate(radioIndex, &set_config, 1); |
| 2972 | |
| 2973 | // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not. |
| 2974 | snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex); |
| 2975 | f = fopen(mcs_file, "w"); |
| 2976 | if (f == NULL) { |
| 2977 | fprintf(stderr, "%s: fopen failed\n", __func__); |
| 2978 | return RETURN_ERR; |
| 2979 | } |
| 2980 | fprintf(f, "%d", MCS); |
| 2981 | fclose(f); |
| 2982 | |
| 2983 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2984 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2985 | } |
| 2986 | |
| 2987 | //Get supported Transmit Power list, eg : "0,25,50,75,100" |
| 2988 | //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. |
| 2989 | INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181 |
| 2990 | { |
| 2991 | if (NULL == output_list) |
| 2992 | return RETURN_ERR; |
| 2993 | snprintf(output_list, 64,"0,25,50,75,100"); |
| 2994 | return RETURN_OK; |
| 2995 | } |
| 2996 | |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 2997 | //Get current Transmit Power in dBm units. |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 2998 | //The transmite power level is in units of full power for this radio. |
| 2999 | INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB |
| 3000 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3001 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3002 | char cmd[128]={0}; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3003 | char buf[16]={0}; |
| 3004 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3005 | |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3006 | if(output_ulong == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3007 | return RETURN_ERR; |
| 3008 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3009 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3010 | return RETURN_ERR; |
| 3011 | snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3012 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3013 | |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3014 | *output_ulong = strtol(buf, NULL, 10); |
| 3015 | |
| 3016 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3017 | return RETURN_OK; |
| 3018 | } |
| 3019 | |
| 3020 | //Set Transmit Power |
| 3021 | //The transmite power level is in units of full power for this radio. |
| 3022 | INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB |
| 3023 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3024 | char interface_name[16] = {0}; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3025 | char *support; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3026 | char cmd[128]={0}; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3027 | char buf[128]={0}; |
| 3028 | char txpower_str[64] = {0}; |
| 3029 | int txpower = 0; |
| 3030 | int maximum_tx = 0; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 3031 | int phyId = 0; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3032 | |
| 3033 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3034 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3035 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3036 | return RETURN_ERR; |
| 3037 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3038 | _syscmd(cmd, buf, sizeof(buf)); |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3039 | maximum_tx = strtol(buf, NULL, 10); |
| 3040 | |
| 3041 | // Get the Tx power supported list and check that is the input in the list |
| 3042 | snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower); |
| 3043 | wifi_getRadioTransmitPowerSupported(radioIndex, buf); |
| 3044 | support = strtok(buf, ","); |
| 3045 | while(true) |
| 3046 | { |
| 3047 | if(support == NULL) { // input not in the list |
| 3048 | wifi_dbg_printf("Input value is invalid.\n"); |
| 3049 | return RETURN_ERR; |
| 3050 | } |
| 3051 | if (strncmp(txpower_str, support, strlen(support)) == 0) { |
| 3052 | break; |
| 3053 | } |
| 3054 | support = strtok(NULL, ","); |
| 3055 | } |
| 3056 | txpower = TransmitPower*maximum_tx/100; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 3057 | phyId = radio_index_to_phy(radioIndex); |
| 3058 | snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower); |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 3059 | _syscmd(cmd, buf, sizeof(buf)); |
| 3060 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3061 | |
| 3062 | return RETURN_OK; |
| 3063 | } |
| 3064 | |
| 3065 | //get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band |
| 3066 | INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181 |
| 3067 | { |
| 3068 | if (NULL == Supported) |
| 3069 | return RETURN_ERR; |
developer | 3885fec | 2022-09-13 15:13:47 +0800 | [diff] [blame] | 3070 | *Supported = TRUE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3071 | |
| 3072 | return RETURN_OK; |
| 3073 | } |
| 3074 | |
| 3075 | //Get 80211h feature enable |
| 3076 | INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181 |
| 3077 | { |
developer | 3885fec | 2022-09-13 15:13:47 +0800 | [diff] [blame] | 3078 | char buf[64]={'\0'}; |
| 3079 | char config_file[64] = {'\0'}; |
| 3080 | |
| 3081 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3082 | if(enable == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3083 | return RETURN_ERR; |
developer | 3885fec | 2022-09-13 15:13:47 +0800 | [diff] [blame] | 3084 | |
| 3085 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 3086 | wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3087 | |
developer | 3885fec | 2022-09-13 15:13:47 +0800 | [diff] [blame] | 3088 | if (strncmp(buf, "1", 1) == 0) |
| 3089 | *enable = TRUE; |
| 3090 | else |
| 3091 | *enable = FALSE; |
| 3092 | |
| 3093 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3094 | return RETURN_OK; |
| 3095 | } |
| 3096 | |
| 3097 | //Set 80211h feature enable |
| 3098 | INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181 |
| 3099 | { |
developer | 3885fec | 2022-09-13 15:13:47 +0800 | [diff] [blame] | 3100 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3101 | struct params params={'\0'}; |
| 3102 | char config_file[MAX_BUF_SIZE] = {0}; |
| 3103 | |
| 3104 | params.name = "ieee80211h"; |
| 3105 | |
| 3106 | if (enable) { |
| 3107 | params.value = "1"; |
| 3108 | } else { |
| 3109 | params.value = "0"; |
| 3110 | } |
| 3111 | |
| 3112 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 3113 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 3114 | |
| 3115 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 3116 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3117 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3118 | } |
| 3119 | |
| 3120 | //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. |
| 3121 | INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3 |
| 3122 | { |
| 3123 | if (NULL == output) |
| 3124 | return RETURN_ERR; |
| 3125 | *output=100; |
| 3126 | |
| 3127 | return RETURN_OK; |
| 3128 | } |
| 3129 | |
| 3130 | //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. |
| 3131 | INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3 |
| 3132 | { |
| 3133 | if (NULL == output) |
| 3134 | return RETURN_ERR; |
| 3135 | *output = -99; |
| 3136 | |
| 3137 | return RETURN_OK; |
| 3138 | } |
| 3139 | |
| 3140 | INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3 |
| 3141 | { |
| 3142 | return RETURN_ERR; |
| 3143 | } |
| 3144 | |
| 3145 | |
| 3146 | //Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012]. |
| 3147 | INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output) |
| 3148 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3149 | char interface_name[16] = {0}; |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 3150 | char cmd[MAX_BUF_SIZE]={'\0'}; |
| 3151 | char buf[MAX_CMD_SIZE]={'\0'}; |
| 3152 | |
| 3153 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3154 | if(output == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3155 | return RETURN_ERR; |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 3156 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3157 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3158 | return RETURN_ERR; |
| 3159 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name); |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 3160 | _syscmd(cmd, buf, sizeof(buf)); |
| 3161 | *output = atoi(buf); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3162 | |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 3163 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3164 | return RETURN_OK; |
| 3165 | } |
| 3166 | |
| 3167 | INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod) |
| 3168 | { |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 3169 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3170 | struct params params={'\0'}; |
| 3171 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 3172 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 3173 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 3174 | if (BeaconPeriod < 15 || BeaconPeriod > 65535) |
| 3175 | return RETURN_ERR; |
| 3176 | |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 3177 | params.name = "beacon_int"; |
| 3178 | snprintf(buf, sizeof(buf), "%u", BeaconPeriod); |
| 3179 | params.value = buf; |
| 3180 | |
| 3181 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 3182 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 3183 | |
| 3184 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 3185 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3186 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3187 | } |
| 3188 | |
| 3189 | //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. |
| 3190 | INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output) |
| 3191 | { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3192 | //TODO: need to revisit below implementation |
| 3193 | char *temp; |
developer | e9d0abd | 2022-09-13 15:40:57 +0800 | [diff] [blame] | 3194 | char temp_output[128] = {0}; |
| 3195 | char temp_TransmitRates[64] = {0}; |
| 3196 | char config_file[64] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3197 | |
| 3198 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3199 | if (NULL == output) |
| 3200 | return RETURN_ERR; |
| 3201 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
developer | e9d0abd | 2022-09-13 15:40:57 +0800 | [diff] [blame] | 3202 | wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64); |
| 3203 | |
| 3204 | if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate |
| 3205 | wifi_getRadioSupportedDataTransmitRates(radioIndex, output); |
| 3206 | } else { |
| 3207 | temp = strtok(temp_TransmitRates," "); |
| 3208 | while(temp!=NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3209 | { |
developer | e9d0abd | 2022-09-13 15:40:57 +0800 | [diff] [blame] | 3210 | // Convert 100 kbps to Mbps |
| 3211 | temp[strlen(temp)-1]=0; |
| 3212 | if((temp[0]=='5') && (temp[1]=='\0')) |
| 3213 | { |
| 3214 | temp="5.5"; |
| 3215 | } |
| 3216 | strcat(temp_output,temp); |
| 3217 | temp = strtok(NULL," "); |
| 3218 | if(temp!=NULL) |
| 3219 | { |
| 3220 | strcat(temp_output,","); |
| 3221 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3222 | } |
developer | e9d0abd | 2022-09-13 15:40:57 +0800 | [diff] [blame] | 3223 | strcpy(output,temp_output); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3224 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3225 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3226 | return RETURN_OK; |
| 3227 | } |
| 3228 | |
| 3229 | INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates) |
| 3230 | { |
| 3231 | char *temp; |
| 3232 | char temp1[128]; |
| 3233 | char temp_output[128]; |
| 3234 | char temp_TransmitRates[128]; |
| 3235 | char set[128]; |
| 3236 | char sub_set[128]; |
| 3237 | int set_count=0,subset_count=0; |
| 3238 | int set_index=0,subset_index=0; |
| 3239 | char *token; |
| 3240 | int flag=0, i=0; |
| 3241 | struct params params={'\0'}; |
| 3242 | char config_file[MAX_BUF_SIZE] = {0}; |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 3243 | wifi_band band = wifi_index_to_band(radioIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3244 | |
| 3245 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3246 | if(NULL == TransmitRates) |
| 3247 | return RETURN_ERR; |
| 3248 | strcpy(sub_set,TransmitRates); |
| 3249 | |
| 3250 | //Allow only supported Data transmit rate to be set |
| 3251 | wifi_getRadioSupportedDataTransmitRates(radioIndex,set); |
| 3252 | token = strtok(sub_set,","); |
| 3253 | while( token != NULL ) /* split the basic rate to be set, by comma */ |
| 3254 | { |
| 3255 | sub_set[subset_count]=atoi(token); |
| 3256 | subset_count++; |
| 3257 | token=strtok(NULL,","); |
| 3258 | } |
| 3259 | token=strtok(set,","); |
| 3260 | while(token!=NULL) /* split the supported rate by comma */ |
| 3261 | { |
| 3262 | set[set_count]=atoi(token); |
| 3263 | set_count++; |
| 3264 | token=strtok(NULL,","); |
| 3265 | } |
| 3266 | for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */ |
| 3267 | { |
| 3268 | for(set_index=0;set_index < set_count;set_index++) |
| 3269 | { |
| 3270 | flag=0; |
| 3271 | if(sub_set[subset_index]==set[set_index]) |
| 3272 | break; |
| 3273 | else |
| 3274 | flag=1; /* No match found */ |
| 3275 | } |
| 3276 | if(flag==1) |
| 3277 | return RETURN_ERR; //If value not found return Error |
| 3278 | } |
| 3279 | strcpy(temp_TransmitRates,TransmitRates); |
| 3280 | |
| 3281 | for(i=0;i<strlen(temp_TransmitRates);i++) |
| 3282 | { |
| 3283 | //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32)) |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 3284 | if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==',')) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3285 | { |
| 3286 | continue; |
| 3287 | } |
| 3288 | else |
| 3289 | { |
| 3290 | return RETURN_ERR; |
| 3291 | } |
| 3292 | } |
| 3293 | strcpy(temp_output,""); |
| 3294 | temp = strtok(temp_TransmitRates,","); |
| 3295 | while(temp!=NULL) |
| 3296 | { |
| 3297 | strcpy(temp1,temp); |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 3298 | if(band == band_5) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3299 | { |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 3300 | if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0)) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3301 | { |
| 3302 | return RETURN_ERR; |
| 3303 | } |
| 3304 | } |
| 3305 | |
| 3306 | if(strcmp(temp,"5.5")==0) |
| 3307 | { |
| 3308 | strcpy(temp1,"55"); |
| 3309 | } |
| 3310 | else |
| 3311 | { |
| 3312 | strcat(temp1,"0"); |
| 3313 | } |
| 3314 | strcat(temp_output,temp1); |
| 3315 | temp = strtok(NULL,","); |
| 3316 | if(temp!=NULL) |
| 3317 | { |
| 3318 | strcat(temp_output," "); |
| 3319 | } |
| 3320 | } |
| 3321 | strcpy(TransmitRates,temp_output); |
| 3322 | |
| 3323 | params.name= "basic_rates"; |
| 3324 | params.value =TransmitRates; |
| 3325 | |
| 3326 | wifi_dbg_printf("\n%s:",__func__); |
| 3327 | wifi_dbg_printf("\nparams.value=%s\n",params.value); |
| 3328 | wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates); |
| 3329 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
| 3330 | wifi_hostapdWrite(config_file,¶ms,1); |
| 3331 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3332 | return RETURN_OK; |
| 3333 | } |
| 3334 | |
| 3335 | //passing the hostapd configuration file and get the virtual interface of xfinity(2g) |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3336 | INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50]) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3337 | { |
| 3338 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3339 | FILE *fp = NULL; |
| 3340 | char path[256] = {0}, output_string[256] = {0}; |
| 3341 | int count = 0; |
| 3342 | char *interface = NULL; |
| 3343 | |
| 3344 | fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r"); |
| 3345 | if (fp == NULL) |
| 3346 | { |
| 3347 | printf("Failed to run command in Function %s\n", __FUNCTION__); |
| 3348 | return RETURN_ERR; |
| 3349 | } |
| 3350 | if (fgets(path, sizeof(path) - 1, fp) != NULL) |
| 3351 | { |
| 3352 | interface = strchr(path, '='); |
| 3353 | |
| 3354 | if (interface != NULL) |
| 3355 | { |
| 3356 | strcpy(output_string, interface + 1); |
| 3357 | for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++) |
| 3358 | interface_name[count] = output_string[count]; |
| 3359 | |
| 3360 | interface_name[count] = '\0'; |
| 3361 | } |
| 3362 | } |
| 3363 | pclose(fp); |
| 3364 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3365 | return RETURN_OK; |
| 3366 | } |
| 3367 | |
| 3368 | INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct) |
| 3369 | { |
| 3370 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3371 | output_struct->radio_BytesSent = 0; |
| 3372 | output_struct->radio_BytesReceived = 0; |
| 3373 | output_struct->radio_PacketsSent = 0; |
| 3374 | output_struct->radio_PacketsReceived = 0; |
| 3375 | output_struct->radio_ErrorsSent = 0; |
| 3376 | output_struct->radio_ErrorsReceived = 0; |
| 3377 | output_struct->radio_DiscardPacketsSent = 0; |
| 3378 | output_struct->radio_DiscardPacketsReceived = 0; |
| 3379 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3380 | return RETURN_OK; |
| 3381 | } |
| 3382 | |
| 3383 | |
| 3384 | INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats) |
| 3385 | { |
| 3386 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3387 | CHAR buf[MAX_CMD_SIZE] = {0}; |
| 3388 | CHAR Value[MAX_BUF_SIZE] = {0}; |
| 3389 | FILE *fp = NULL; |
| 3390 | |
| 3391 | if (ifname == NULL || strlen(ifname) <= 1) |
| 3392 | return RETURN_OK; |
| 3393 | |
| 3394 | snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname); |
| 3395 | system(buf); |
| 3396 | |
| 3397 | fp = fopen("/tmp/Radio_Stats.txt", "r"); |
| 3398 | if(fp == NULL) |
| 3399 | { |
| 3400 | printf("/tmp/Radio_Stats.txt not exists \n"); |
| 3401 | return RETURN_ERR; |
| 3402 | } |
| 3403 | fclose(fp); |
| 3404 | |
| 3405 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 3406 | File_Reading(buf, Value); |
| 3407 | pStats->radio_PacketsReceived = strtoul(Value, NULL, 10); |
| 3408 | |
| 3409 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 3410 | File_Reading(buf, Value); |
| 3411 | pStats->radio_PacketsSent = strtoul(Value, NULL, 10); |
| 3412 | |
| 3413 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 3414 | File_Reading(buf, Value); |
| 3415 | pStats->radio_BytesReceived = strtoul(Value, NULL, 10); |
| 3416 | |
| 3417 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 3418 | File_Reading(buf, Value); |
| 3419 | pStats->radio_BytesSent = strtoul(Value, NULL, 10); |
| 3420 | |
| 3421 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 3422 | File_Reading(buf, Value); |
| 3423 | pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10); |
| 3424 | |
| 3425 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 3426 | File_Reading(buf, Value); |
| 3427 | pStats->radio_ErrorsSent = strtoul(Value, NULL, 10); |
| 3428 | |
| 3429 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 3430 | File_Reading(buf, Value); |
| 3431 | pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10); |
| 3432 | |
| 3433 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 3434 | File_Reading(buf, Value); |
| 3435 | pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10); |
| 3436 | |
| 3437 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3438 | return RETURN_OK; |
| 3439 | } |
| 3440 | |
| 3441 | INT GetIfacestatus(CHAR *interface_name, CHAR *status) |
| 3442 | { |
| 3443 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3444 | CHAR buf[MAX_CMD_SIZE] = {0}; |
| 3445 | FILE *fp = NULL; |
| 3446 | INT count = 0; |
| 3447 | |
| 3448 | if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) |
| 3449 | { |
| 3450 | sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l"); |
| 3451 | File_Reading(buf, status); |
| 3452 | } |
| 3453 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3454 | return RETURN_OK; |
| 3455 | } |
| 3456 | |
| 3457 | //Get detail radio traffic static info |
| 3458 | INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181 |
| 3459 | { |
| 3460 | |
| 3461 | #if 0 |
| 3462 | //ifconfig radio_x |
| 3463 | output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters. |
| 3464 | output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters. |
| 3465 | output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface. |
| 3466 | output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface. |
| 3467 | |
| 3468 | output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors. |
| 3469 | output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol. |
| 3470 | 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. |
| 3471 | 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. |
| 3472 | |
| 3473 | output_struct->radio_PLCPErrorCount=0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error. |
| 3474 | 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]. |
| 3475 | output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error. |
| 3476 | 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. |
| 3477 | 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 |
| 3478 | 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 |
| 3479 | 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 |
| 3480 | 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 |
| 3481 | 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 |
| 3482 | |
| 3483 | 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 |
| 3484 | 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 |
| 3485 | 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 |
| 3486 | 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. |
| 3487 | |
| 3488 | return RETURN_OK; |
| 3489 | #endif |
| 3490 | |
developer | a91d99f | 2022-09-29 15:59:10 +0800 | [diff] [blame] | 3491 | CHAR interface_name[64] = {0}; |
developer | a91d99f | 2022-09-29 15:59:10 +0800 | [diff] [blame] | 3492 | BOOL iface_status = FALSE; |
| 3493 | wifi_radioTrafficStats2_t radioTrafficStats = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3494 | |
| 3495 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3496 | if (NULL == output_struct) |
| 3497 | return RETURN_ERR; |
| 3498 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3499 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | dbbd678 | 2022-12-16 14:26:20 +0800 | [diff] [blame] | 3500 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3501 | |
developer | a91d99f | 2022-09-29 15:59:10 +0800 | [diff] [blame] | 3502 | wifi_getApEnable(radioIndex, &iface_status); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3503 | |
developer | a91d99f | 2022-09-29 15:59:10 +0800 | [diff] [blame] | 3504 | if (iface_status == TRUE) |
| 3505 | wifi_halGetIfStats(interface_name, &radioTrafficStats); |
| 3506 | else |
| 3507 | wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0 |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3508 | |
developer | a91d99f | 2022-09-29 15:59:10 +0800 | [diff] [blame] | 3509 | output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent; |
| 3510 | output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived; |
| 3511 | output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent; |
| 3512 | output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived; |
| 3513 | output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent; |
| 3514 | output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived; |
| 3515 | output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent; |
| 3516 | output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3517 | |
| 3518 | output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error. |
| 3519 | 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]. |
| 3520 | output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error. |
| 3521 | 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. |
| 3522 | 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 |
| 3523 | 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 |
| 3524 | 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 |
| 3525 | 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 |
| 3526 | 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 |
| 3527 | |
| 3528 | 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 |
| 3529 | 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 |
| 3530 | 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 |
| 3531 | 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. |
| 3532 | |
| 3533 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3534 | |
| 3535 | return RETURN_OK; |
| 3536 | } |
| 3537 | |
| 3538 | //Set radio traffic static Measureing rules |
| 3539 | INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181 |
| 3540 | { |
| 3541 | //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 |
| 3542 | // Else, save the MeasuringRate and MeasuringInterval for future usage |
| 3543 | |
| 3544 | return RETURN_OK; |
| 3545 | } |
| 3546 | |
| 3547 | //To start or stop RadioTrafficStats |
| 3548 | INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable) |
| 3549 | { |
| 3550 | //zqiu: If the RadioTrafficStats process running |
| 3551 | // if(enable) |
| 3552 | // return RETURN_OK. |
| 3553 | // else |
| 3554 | // Stop RadioTrafficStats process |
| 3555 | // Else |
| 3556 | // if(enable) |
| 3557 | // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds |
| 3558 | // else |
| 3559 | // return RETURN_OK. |
| 3560 | |
| 3561 | return RETURN_OK; |
| 3562 | } |
| 3563 | |
| 3564 | //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 |
| 3565 | INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181 |
| 3566 | { |
| 3567 | //zqiu: Please ignor signalIndex. |
| 3568 | if (NULL == SignalLevel) |
| 3569 | return RETURN_ERR; |
| 3570 | *SignalLevel=(radioIndex==0)?-19:-19; |
| 3571 | |
| 3572 | return RETURN_OK; |
| 3573 | } |
| 3574 | |
| 3575 | //Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0) |
| 3576 | INT wifi_applyRadioSettings(INT radioIndex) |
| 3577 | { |
| 3578 | return RETURN_OK; |
| 3579 | } |
| 3580 | |
| 3581 | //Get the radio index assocated with this SSID entry |
| 3582 | INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex) |
| 3583 | { |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 3584 | if(NULL == radioIndex) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3585 | return RETURN_ERR; |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 3586 | int max_radio_num = 0; |
| 3587 | wifi_getMaxRadioNumber(&max_radio_num); |
| 3588 | *radioIndex = ssidIndex%max_radio_num; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3589 | return RETURN_OK; |
| 3590 | } |
| 3591 | |
| 3592 | //Device.WiFi.SSID.{i}.Enable |
| 3593 | //Get SSID enable configuration parameters (not the SSID enable status) |
| 3594 | INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181 |
| 3595 | { |
| 3596 | if (NULL == output_bool) |
| 3597 | return RETURN_ERR; |
| 3598 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3599 | return wifi_getApEnable(ssidIndex, output_bool); |
| 3600 | } |
| 3601 | |
| 3602 | //Device.WiFi.SSID.{i}.Enable |
| 3603 | //Set SSID enable configuration parameters |
| 3604 | INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181 |
| 3605 | { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3606 | return wifi_setApEnable(ssidIndex, enable); |
| 3607 | } |
| 3608 | |
| 3609 | //Device.WiFi.SSID.{i}.Status |
| 3610 | //Get the SSID enable status |
| 3611 | INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181 |
| 3612 | { |
| 3613 | char cmd[MAX_CMD_SIZE]={0}; |
| 3614 | char buf[MAX_BUF_SIZE]={0}; |
| 3615 | BOOL output_bool; |
| 3616 | |
| 3617 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3618 | if (NULL == output_string) |
| 3619 | return RETURN_ERR; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 3620 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3621 | wifi_getApEnable(ssidIndex,&output_bool); |
| 3622 | snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled"); |
| 3623 | |
| 3624 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3625 | return RETURN_OK; |
| 3626 | } |
| 3627 | |
| 3628 | // Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller. |
| 3629 | INT wifi_getSSIDName(INT apIndex, CHAR *output) |
| 3630 | { |
| 3631 | char config_file[MAX_BUF_SIZE] = {0}; |
| 3632 | |
| 3633 | if (NULL == output) |
| 3634 | return RETURN_ERR; |
| 3635 | |
| 3636 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 3637 | wifi_hostapdRead(config_file,"ssid",output,32); |
| 3638 | |
| 3639 | wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output); |
| 3640 | return RETURN_OK; |
| 3641 | } |
| 3642 | |
| 3643 | // Set a max 32 byte string and sets an internal variable to the SSID name |
| 3644 | INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string) |
| 3645 | { |
| 3646 | char str[MAX_BUF_SIZE]={'\0'}; |
| 3647 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 3648 | struct params params; |
| 3649 | char config_file[MAX_BUF_SIZE] = {0}; |
| 3650 | |
| 3651 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3652 | if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 ) |
| 3653 | return RETURN_ERR; |
| 3654 | |
| 3655 | params.name = "ssid"; |
| 3656 | params.value = ssid_string; |
| 3657 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 3658 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 3659 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 3660 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3661 | |
| 3662 | return RETURN_OK; |
| 3663 | } |
| 3664 | |
| 3665 | //Get the BSSID |
| 3666 | INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB |
| 3667 | { |
| 3668 | char cmd[MAX_CMD_SIZE]=""; |
| 3669 | |
| 3670 | if (NULL == output_string) |
| 3671 | return RETURN_ERR; |
| 3672 | |
| 3673 | if(ssidIndex >= 0 && ssidIndex < MAX_APS) |
| 3674 | { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 3675 | snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep bssid | cut -d '=' -f2 | tr -d '\n'", CONFIG_PREFIX, ssidIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3676 | _syscmd(cmd, output_string, 64); |
| 3677 | return RETURN_OK; |
| 3678 | } |
| 3679 | strncpy(output_string, "\0", 1); |
| 3680 | |
| 3681 | return RETURN_ERR; |
| 3682 | } |
| 3683 | |
| 3684 | //Get the MAC address associated with this Wifi SSID |
| 3685 | INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181 |
| 3686 | { |
| 3687 | wifi_getBaseBSSID(ssidIndex,output_string); |
| 3688 | return RETURN_OK; |
| 3689 | } |
| 3690 | |
| 3691 | //Get the basic SSID traffic static info |
| 3692 | //Apply SSID and AP (in the case of Acess Point devices) to the hardware |
| 3693 | //Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0) |
| 3694 | INT wifi_applySSIDSettings(INT ssidIndex) |
| 3695 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3696 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3697 | BOOL status = false; |
| 3698 | char cmd[MAX_CMD_SIZE] = {0}; |
| 3699 | char buf[MAX_CMD_SIZE] = {0}; |
| 3700 | int apIndex, ret; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 3701 | int max_radio_num = 0; |
| 3702 | int radioIndex = 0; |
| 3703 | |
| 3704 | wifi_getMaxRadioNumber(&max_radio_num); |
| 3705 | |
| 3706 | radioIndex = ssidIndex % max_radio_num; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3707 | |
| 3708 | wifi_getApEnable(ssidIndex,&status); |
| 3709 | // Do not apply when ssid index is disabled |
| 3710 | if (status == false) |
| 3711 | return RETURN_OK; |
| 3712 | |
| 3713 | /* Doing full remove and add for ssid Index |
| 3714 | * Not all hostapd options are supported with reload |
| 3715 | * for example macaddr_acl |
| 3716 | */ |
| 3717 | if(wifi_setApEnable(ssidIndex,false) != RETURN_OK) |
| 3718 | return RETURN_ERR; |
| 3719 | |
| 3720 | ret = wifi_setApEnable(ssidIndex,true); |
| 3721 | |
| 3722 | /* Workaround for hostapd issue with multiple bss definitions |
| 3723 | * when first created interface will be removed |
| 3724 | * then all vaps other vaps on same phy are removed |
| 3725 | * after calling setApEnable to false readd all enabled vaps */ |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 3726 | for(int i=0; i < MAX_APS/max_radio_num; i++) { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3727 | apIndex = max_radio_num*i+radioIndex; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3728 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3729 | return RETURN_ERR; |
| 3730 | snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3731 | _syscmd(cmd, buf, sizeof(buf)); |
| 3732 | if(*buf == '1') |
| 3733 | wifi_setApEnable(apIndex, true); |
| 3734 | } |
| 3735 | |
| 3736 | return ret; |
| 3737 | } |
| 3738 | |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3739 | struct channels_noise { |
| 3740 | int channel; |
| 3741 | int noise; |
| 3742 | }; |
| 3743 | |
| 3744 | // Return noise array for each channel |
| 3745 | int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num) |
| 3746 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3747 | char interface_name[16] = {0}; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3748 | FILE *f = NULL; |
| 3749 | char cmd[128] = {0}; |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3750 | char line[256] = {0}; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3751 | size_t len = 0; |
| 3752 | ssize_t read = 0; |
| 3753 | int tmp = 0, arr_index = -1; |
| 3754 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3755 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3756 | return RETURN_ERR; |
| 3757 | sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3758 | |
| 3759 | if ((f = popen(cmd, "r")) == NULL) { |
| 3760 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 3761 | return RETURN_ERR; |
| 3762 | } |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3763 | |
| 3764 | while(fgets(line, sizeof(line), f) != NULL) { |
| 3765 | if(arr_index < channels_num){ |
| 3766 | sscanf(line, "%d", &tmp); |
| 3767 | if (tmp > 0) { // channel frequency, the first line must be frequency |
| 3768 | arr_index++; |
| 3769 | channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp); |
| 3770 | } else { // noise |
| 3771 | channels_noise_arr[arr_index].noise = tmp; |
| 3772 | } |
| 3773 | }else{ |
| 3774 | break; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3775 | } |
| 3776 | } |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3777 | pclose(f); |
| 3778 | return RETURN_OK; |
| 3779 | } |
| 3780 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3781 | //Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list |
| 3782 | //HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array" |
| 3783 | INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181 |
| 3784 | { |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3785 | int index = -1; |
| 3786 | wifi_neighbor_ap2_t *scan_array = NULL; |
| 3787 | char cmd[256]={0}; |
| 3788 | char buf[128]={0}; |
| 3789 | char file_name[32] = {0}; |
| 3790 | char filter_SSID[32] = {0}; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3791 | char line[256] = {0}; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3792 | char interface_name[16] = {0}; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3793 | char *ret = NULL; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3794 | int freq=0; |
| 3795 | FILE *f = NULL; |
| 3796 | size_t len=0; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3797 | int channels_num = 0; |
| 3798 | int vht_channel_width = 0; |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3799 | int get_noise_ret = RETURN_ERR; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3800 | bool filter_enable = false; |
| 3801 | bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd. |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 3802 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3803 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3804 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3805 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 3806 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3807 | return RETURN_ERR; |
| 3808 | |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3809 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex); |
| 3810 | f = fopen(file_name, "r"); |
| 3811 | if (f != NULL) { |
| 3812 | fgets(filter_SSID, sizeof(file_name), f); |
| 3813 | if (strlen(filter_SSID) != 0) |
| 3814 | filter_enable = true; |
| 3815 | fclose(f); |
| 3816 | } |
| 3817 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 3818 | phyId = radio_index_to_phy(radioIndex); |
| 3819 | snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3820 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3821 | channels_num = strtol(buf, NULL, 10); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3822 | |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3823 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3824 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 3825 | sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \ |
| 3826 | // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3827 | fprintf(stderr, "cmd: %s\n", cmd); |
| 3828 | if ((f = popen(cmd, "r")) == NULL) { |
| 3829 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 3830 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3831 | } |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3832 | |
| 3833 | struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise)); |
| 3834 | get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num); |
| 3835 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3836 | ret = fgets(line, sizeof(line), f); |
| 3837 | while (ret != NULL) { |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3838 | if(strstr(line, "BSS") != NULL) { // new neighbor info |
| 3839 | // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag. |
| 3840 | // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop. |
| 3841 | // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS. |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3842 | |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3843 | if (!filter_BSS) { |
| 3844 | index++; |
| 3845 | wifi_neighbor_ap2_t *tmp; |
| 3846 | tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1)); |
| 3847 | if (tmp == NULL) { // no more memory to use |
| 3848 | index--; |
| 3849 | wifi_dbg_printf("%s: realloc failed\n", __func__); |
| 3850 | break; |
| 3851 | } |
| 3852 | scan_array = tmp; |
| 3853 | } |
| 3854 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 3855 | |
| 3856 | filter_BSS = false; |
| 3857 | sscanf(line, "BSS %17s", scan_array[index].ap_BSSID); |
| 3858 | strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure")); |
| 3859 | strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None")); |
| 3860 | strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None")); |
| 3861 | } else if (strstr(line, "freq") != NULL) { |
| 3862 | sscanf(line," freq: %d", &freq); |
| 3863 | scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq); |
| 3864 | |
| 3865 | if (freq >= 2412 && freq <= 2484) { |
| 3866 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")); |
| 3867 | strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g")); |
| 3868 | strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g")); |
| 3869 | } |
| 3870 | else if (freq >= 5160 && freq <= 5805) { |
| 3871 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")); |
| 3872 | strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a")); |
| 3873 | strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a")); |
| 3874 | } |
| 3875 | |
| 3876 | scan_array[index].ap_Noise = 0; |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3877 | if (get_noise_ret == RETURN_OK) { |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3878 | for (int i = 0; i < channels_num; i++) { |
| 3879 | if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) { |
| 3880 | scan_array[index].ap_Noise = channels_noise_arr[i].noise; |
| 3881 | break; |
| 3882 | } |
| 3883 | } |
| 3884 | } |
| 3885 | } else if (strstr(line, "beacon interval") != NULL) { |
| 3886 | sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)); |
| 3887 | } else if (strstr(line, "signal") != NULL) { |
| 3888 | sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)); |
| 3889 | } else if (strstr(line,"SSID") != NULL) { |
| 3890 | sscanf(line," SSID: %s", scan_array[index].ap_SSID); |
| 3891 | if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) { |
| 3892 | filter_BSS = true; |
| 3893 | } |
| 3894 | } else if (strstr(line, "Supported rates") != NULL) { |
| 3895 | char SRate[80] = {0}, *tmp = NULL; |
| 3896 | memset(buf, 0, sizeof(buf)); |
| 3897 | strcpy(SRate, line); |
| 3898 | tmp = strtok(SRate, ":"); |
| 3899 | tmp = strtok(NULL, ":"); |
| 3900 | strcpy(buf, tmp); |
| 3901 | memset(SRate, 0, sizeof(SRate)); |
| 3902 | |
| 3903 | tmp = strtok(buf, " \n"); |
| 3904 | while (tmp != NULL) { |
| 3905 | strcat(SRate, tmp); |
| 3906 | if (SRate[strlen(SRate) - 1] == '*') { |
| 3907 | SRate[strlen(SRate) - 1] = '\0'; |
| 3908 | } |
| 3909 | strcat(SRate, ","); |
| 3910 | |
| 3911 | tmp = strtok(NULL, " \n"); |
| 3912 | } |
| 3913 | SRate[strlen(SRate) - 1] = '\0'; |
| 3914 | strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate); |
| 3915 | } else if (strstr(line, "DTIM") != NULL) { |
| 3916 | sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf); |
| 3917 | } else if (strstr(line, "VHT capabilities") != NULL) { |
| 3918 | strcat(scan_array[index].ap_SupportedStandards, ",ac"); |
| 3919 | strcpy(scan_array[index].ap_OperatingStandards, "ac"); |
| 3920 | } else if (strstr(line, "HT capabilities") != NULL) { |
| 3921 | strcat(scan_array[index].ap_SupportedStandards, ",n"); |
| 3922 | strcpy(scan_array[index].ap_OperatingStandards, "n"); |
| 3923 | } else if (strstr(line, "VHT operation") != NULL) { |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3924 | ret = fgets(line, sizeof(line), f); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3925 | sscanf(line," * channel width: %d", &vht_channel_width); |
| 3926 | if(vht_channel_width == 1) { |
| 3927 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80"); |
| 3928 | } else { |
| 3929 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40"); |
| 3930 | } |
| 3931 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 3932 | continue; |
| 3933 | } else if (strstr(line, "HT operation") != NULL) { |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3934 | ret = fgets(line, sizeof(line), f); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3935 | sscanf(line," * secondary channel offset: %s", &buf); |
| 3936 | if (!strcmp(buf, "above")) { |
| 3937 | //40Mhz + |
| 3938 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G"); |
| 3939 | } |
| 3940 | else if (!strcmp(buf, "below")) { |
| 3941 | //40Mhz - |
| 3942 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G"); |
| 3943 | } else { |
| 3944 | //20Mhz |
| 3945 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G"); |
| 3946 | } |
| 3947 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 3948 | continue; |
| 3949 | } else if (strstr(line, "HE capabilities") != NULL) { |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3950 | strcat(scan_array[index].ap_SupportedStandards, ",ax"); |
| 3951 | strcpy(scan_array[index].ap_OperatingStandards, "ax"); |
| 3952 | ret = fgets(line, sizeof(line), f); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3953 | if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) { |
| 3954 | if (strstr(line, "HE40/2.4GHz") != NULL) |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3955 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS"); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3956 | else |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3957 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20"); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3958 | } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) { |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3959 | if (strstr(line, "HE80/5GHz") != NULL) { |
| 3960 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80"); |
| 3961 | ret = fgets(line, sizeof(line), f); |
| 3962 | } else |
| 3963 | continue; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3964 | if (strstr(line, "HE160/5GHz") != NULL) |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3965 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160"); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3966 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3967 | continue; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3968 | } else if (strstr(line, "WPA") != NULL) { |
| 3969 | strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA"); |
| 3970 | } else if (strstr(line, "RSN") != NULL) { |
| 3971 | strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN"); |
| 3972 | } else if (strstr(line, "Group cipher") != NULL) { |
| 3973 | sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode); |
| 3974 | if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) { |
| 3975 | strcpy(scan_array[index].ap_EncryptionMode, "AES"); |
| 3976 | } |
| 3977 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 3978 | ret = fgets(line, sizeof(line), f); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3979 | } |
| 3980 | |
| 3981 | if (!filter_BSS) { |
| 3982 | *output_array_size = index + 1; |
| 3983 | } else { |
| 3984 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 3985 | *output_array_size = index; |
| 3986 | } |
| 3987 | *neighbor_ap_array = scan_array; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3988 | pclose(f); |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 3989 | free(channels_noise_arr); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3990 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 3991 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 3992 | } |
| 3993 | |
| 3994 | //>> Deprecated: used for old RDKB code. |
| 3995 | INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct) |
| 3996 | { |
| 3997 | INT status = RETURN_ERR; |
| 3998 | |
| 3999 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4000 | output_struct->wifi_PLCPErrorCount = 0; |
| 4001 | output_struct->wifi_FCSErrorCount = 0; |
| 4002 | output_struct->wifi_InvalidMACCount = 0; |
| 4003 | output_struct->wifi_PacketsOtherReceived = 0; |
| 4004 | output_struct->wifi_Noise = 0; |
| 4005 | status = RETURN_OK; |
| 4006 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4007 | return status; |
| 4008 | } |
| 4009 | |
| 4010 | INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct) |
| 4011 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4012 | char interface_name[16] = {0}; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 4013 | char cmd[128] = {0}; |
| 4014 | char buf[1280] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4015 | char *pos = NULL; |
| 4016 | |
| 4017 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4018 | if (NULL == output_struct) |
| 4019 | return RETURN_ERR; |
| 4020 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4021 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4022 | return RETURN_ERR; |
| 4023 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4024 | memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t)); |
| 4025 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4026 | snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4027 | _syscmd(cmd, buf, sizeof(buf)); |
| 4028 | |
| 4029 | pos = buf; |
| 4030 | if ((pos = strstr(pos, "RX packets:")) == NULL) |
| 4031 | return RETURN_ERR; |
| 4032 | output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:")); |
| 4033 | |
| 4034 | if ((pos = strstr(pos, "TX packets:")) == NULL) |
| 4035 | return RETURN_ERR; |
| 4036 | output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:")); |
| 4037 | |
| 4038 | if ((pos = strstr(pos, "RX bytes:")) == NULL) |
| 4039 | return RETURN_ERR; |
| 4040 | output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:")); |
| 4041 | |
| 4042 | if ((pos = strstr(pos, "TX bytes:")) == NULL) |
| 4043 | return RETURN_ERR; |
| 4044 | output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:")); |
| 4045 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4046 | sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4047 | _syscmd(cmd, buf, sizeof(buf)); |
| 4048 | sscanf(buf, "%lu", &output_struct->wifi_Associations); |
| 4049 | |
| 4050 | #if 0 |
| 4051 | //TODO: need to revisit below implementation |
| 4052 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4053 | char interface_name[MAX_BUF_SIZE] = {0}; |
| 4054 | char interface_status[MAX_BUF_SIZE] = {0}; |
| 4055 | char Value[MAX_BUF_SIZE] = {0}; |
| 4056 | char buf[MAX_CMD_SIZE] = {0}; |
| 4057 | char cmd[MAX_CMD_SIZE] = {0}; |
| 4058 | FILE *fp = NULL; |
| 4059 | |
| 4060 | if (NULL == output_struct) { |
| 4061 | return RETURN_ERR; |
| 4062 | } |
| 4063 | |
| 4064 | memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t)); |
| 4065 | |
| 4066 | if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5)) |
| 4067 | { |
| 4068 | if(apIndex == 0) //private_wifi for 2.4G |
| 4069 | { |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4070 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4071 | } |
| 4072 | else if(apIndex == 1) //private_wifi for 5G |
| 4073 | { |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4074 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4075 | } |
| 4076 | else if(apIndex == 4) //public_wifi for 2.4G |
| 4077 | { |
| 4078 | sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss="); |
| 4079 | if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR) |
| 4080 | { |
| 4081 | return RETURN_ERR; |
| 4082 | } |
| 4083 | if(buf[0] == '#')//tp-link |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4084 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4085 | else//tenda |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4086 | wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4087 | } |
| 4088 | else if(apIndex == 5) //public_wifi for 5G |
| 4089 | { |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4090 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4091 | } |
| 4092 | |
| 4093 | GetIfacestatus(interface_name, interface_status); |
| 4094 | |
| 4095 | if(0 != strcmp(interface_status, "1")) |
| 4096 | return RETURN_ERR; |
| 4097 | |
| 4098 | snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name); |
| 4099 | system(cmd); |
| 4100 | |
| 4101 | fp = fopen("/tmp/SSID_Stats.txt", "r"); |
| 4102 | if(fp == NULL) |
| 4103 | { |
| 4104 | printf("/tmp/SSID_Stats.txt not exists \n"); |
| 4105 | return RETURN_ERR; |
| 4106 | } |
| 4107 | fclose(fp); |
| 4108 | |
| 4109 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 4110 | File_Reading(buf, Value); |
| 4111 | output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10); |
| 4112 | |
| 4113 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 4114 | File_Reading(buf, Value); |
| 4115 | output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10); |
| 4116 | |
| 4117 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 4118 | File_Reading(buf, Value); |
| 4119 | output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10); |
| 4120 | |
| 4121 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 4122 | File_Reading(buf, Value); |
| 4123 | output_struct->wifi_BytesSent = strtoul(Value, NULL, 10); |
| 4124 | |
| 4125 | /* There is no specific parameter from caller to associate the value wifi_Associations */ |
| 4126 | //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name); |
| 4127 | //_syscmd(cmd, buf, sizeof(buf)); |
| 4128 | //sscanf(buf,"%lu", &output_struct->wifi_Associations); |
| 4129 | } |
| 4130 | #endif |
| 4131 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4132 | return RETURN_OK; |
| 4133 | } |
| 4134 | |
| 4135 | INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct) |
| 4136 | { |
| 4137 | char interface_name[MAX_BUF_SIZE] = {0}; |
| 4138 | char interface_status[MAX_BUF_SIZE] = {0}; |
| 4139 | char Value[MAX_BUF_SIZE] = {0}; |
| 4140 | char buf[MAX_CMD_SIZE] = {0}; |
| 4141 | char cmd[MAX_CMD_SIZE] = {0}; |
| 4142 | FILE *fp = NULL; |
| 4143 | |
| 4144 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4145 | if (NULL == output_struct) |
| 4146 | return RETURN_ERR; |
| 4147 | |
| 4148 | memset(output_struct, 0, sizeof(wifi_trafficStats_t)); |
| 4149 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4150 | if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK) |
developer | dbbd678 | 2022-12-16 14:26:20 +0800 | [diff] [blame] | 4151 | return RETURN_ERR; |
| 4152 | GetIfacestatus(interface_name, interface_status); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4153 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4154 | if(0 != strcmp(interface_status, "1")) |
| 4155 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4156 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4157 | snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name); |
| 4158 | system(cmd); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4159 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4160 | fp = fopen("/tmp/SSID_Stats.txt", "r"); |
| 4161 | if(fp == NULL) |
| 4162 | { |
| 4163 | printf("/tmp/SSID_Stats.txt not exists \n"); |
| 4164 | return RETURN_ERR; |
| 4165 | } |
| 4166 | fclose(fp); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4167 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4168 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 4169 | File_Reading(buf, Value); |
| 4170 | output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4171 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4172 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 4173 | File_Reading(buf, Value); |
| 4174 | output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4175 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4176 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 4177 | File_Reading(buf, Value); |
| 4178 | output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4179 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4180 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 4181 | File_Reading(buf, Value); |
| 4182 | output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4183 | |
| 4184 | output_struct->wifi_UnicastPacketsSent = 0; |
| 4185 | output_struct->wifi_UnicastPacketsReceived = 0; |
| 4186 | output_struct->wifi_MulticastPacketsSent = 0; |
| 4187 | output_struct->wifi_MulticastPacketsReceived = 0; |
| 4188 | output_struct->wifi_BroadcastPacketsSent = 0; |
| 4189 | output_struct->wifi_BroadcastPacketsRecevied = 0; |
| 4190 | output_struct->wifi_UnknownPacketsReceived = 0; |
| 4191 | |
| 4192 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4193 | return RETURN_OK; |
| 4194 | } |
| 4195 | |
| 4196 | INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct) |
| 4197 | { |
| 4198 | INT status = RETURN_ERR; |
| 4199 | |
| 4200 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4201 | //Below values should get updated from hal |
| 4202 | output_struct->wifi_RetransCount=0; |
| 4203 | output_struct->wifi_FailedRetransCount=0; |
| 4204 | output_struct->wifi_RetryCount=0; |
| 4205 | output_struct->wifi_MultipleRetryCount=0; |
| 4206 | output_struct->wifi_ACKFailureCount=0; |
| 4207 | output_struct->wifi_AggregatedPacketCount=0; |
| 4208 | |
| 4209 | status = RETURN_OK; |
| 4210 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4211 | |
| 4212 | return status; |
| 4213 | } |
| 4214 | |
| 4215 | INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size) |
| 4216 | { |
| 4217 | INT status = RETURN_ERR; |
| 4218 | UINT index; |
| 4219 | wifi_neighbor_ap_t *pt=NULL; |
| 4220 | |
| 4221 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4222 | *output_array_size=2; |
| 4223 | //zqiu: HAL alloc the array and return to caller. Caller response to free it. |
| 4224 | *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size); |
| 4225 | for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) { |
| 4226 | strcpy(pt->ap_Radio,""); |
| 4227 | strcpy(pt->ap_SSID,""); |
| 4228 | strcpy(pt->ap_BSSID,""); |
| 4229 | strcpy(pt->ap_Mode,""); |
| 4230 | pt->ap_Channel=1; |
| 4231 | pt->ap_SignalStrength=0; |
| 4232 | strcpy(pt->ap_SecurityModeEnabled,""); |
| 4233 | strcpy(pt->ap_EncryptionMode,""); |
| 4234 | strcpy(pt->ap_OperatingFrequencyBand,""); |
| 4235 | strcpy(pt->ap_SupportedStandards,""); |
| 4236 | strcpy(pt->ap_OperatingStandards,""); |
| 4237 | strcpy(pt->ap_OperatingChannelBandwidth,""); |
| 4238 | pt->ap_BeaconPeriod=1; |
| 4239 | pt->ap_Noise=0; |
| 4240 | strcpy(pt->ap_BasicDataTransferRates,""); |
| 4241 | strcpy(pt->ap_SupportedDataTransferRates,""); |
| 4242 | pt->ap_DTIMPeriod=1; |
| 4243 | pt->ap_ChannelUtilization = 1; |
| 4244 | } |
| 4245 | |
| 4246 | status = RETURN_OK; |
| 4247 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4248 | |
| 4249 | return status; |
| 4250 | } |
| 4251 | |
| 4252 | //----------------- AP HAL ------------------------------- |
| 4253 | |
| 4254 | //>> Deprecated: used for old RDKB code. |
| 4255 | INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct) |
| 4256 | { |
| 4257 | if (NULL == output_ulong || NULL == output_struct) |
| 4258 | return RETURN_ERR; |
| 4259 | *output_ulong = 0; |
| 4260 | *output_struct = NULL; |
| 4261 | return RETURN_OK; |
| 4262 | } |
| 4263 | |
| 4264 | #ifdef HAL_NETLINK_IMPL |
| 4265 | static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) { |
| 4266 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 4267 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 4268 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 4269 | struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 4270 | char mac_addr[20]; |
| 4271 | static int count=0; |
| 4272 | int rate=0; |
| 4273 | |
| 4274 | wifi_device_info_t *out = (wifi_device_info_t*)arg; |
| 4275 | |
| 4276 | nla_parse(tb, |
| 4277 | NL80211_ATTR_MAX, |
| 4278 | genlmsg_attrdata(gnlh, 0), |
| 4279 | genlmsg_attrlen(gnlh, 0), |
| 4280 | NULL); |
| 4281 | |
| 4282 | if(!tb[NL80211_ATTR_STA_INFO]) { |
| 4283 | fprintf(stderr, "sta stats missing!\n"); |
| 4284 | return NL_SKIP; |
| 4285 | } |
| 4286 | |
| 4287 | |
| 4288 | if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) { |
| 4289 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 4290 | return NL_SKIP; |
| 4291 | } |
| 4292 | |
| 4293 | //devIndex starts from 1 |
| 4294 | if( ++count == out->wifi_devIndex ) |
| 4295 | { |
| 4296 | mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); |
| 4297 | //Getting the mac addrress |
| 4298 | mac_addr_aton(out->wifi_devMacAddress,mac_addr); |
| 4299 | |
| 4300 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { |
| 4301 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 4302 | return NL_SKIP; |
| 4303 | } |
| 4304 | |
| 4305 | if(sinfo[NL80211_STA_INFO_TX_BITRATE]) { |
| 4306 | if(rinfo[NL80211_RATE_INFO_BITRATE]) |
| 4307 | rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); |
| 4308 | out->wifi_devTxRate = rate/10; |
| 4309 | } |
| 4310 | |
| 4311 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) { |
| 4312 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 4313 | return NL_SKIP; |
| 4314 | } |
| 4315 | |
| 4316 | if(sinfo[NL80211_STA_INFO_RX_BITRATE]) { |
| 4317 | if(rinfo[NL80211_RATE_INFO_BITRATE]) |
| 4318 | rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); |
| 4319 | out->wifi_devRxRate = rate/10; |
| 4320 | } |
| 4321 | if(sinfo[NL80211_STA_INFO_SIGNAL_AVG]) |
| 4322 | out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]); |
| 4323 | |
| 4324 | out->wifi_devAssociatedDeviceAuthentiationState = 1; |
| 4325 | count = 0; //starts the count for next cycle |
| 4326 | return NL_STOP; |
| 4327 | } |
| 4328 | |
| 4329 | return NL_SKIP; |
| 4330 | |
| 4331 | } |
| 4332 | #endif |
| 4333 | |
| 4334 | INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct) |
| 4335 | { |
| 4336 | #ifdef HAL_NETLINK_IMPL |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 4337 | Netlink nl = {0}; |
| 4338 | char if_name[10] = {0}; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4339 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4340 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 4341 | wifi_device_info_t info = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4342 | info.wifi_devIndex = devIndex; |
| 4343 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4344 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4345 | return RETURN_ERR; |
| 4346 | |
| 4347 | snprintf(if_name,sizeof(if_name),"%s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4348 | |
| 4349 | nl.id = initSock80211(&nl); |
| 4350 | |
| 4351 | if (nl.id < 0) { |
| 4352 | fprintf(stderr, "Error initializing netlink \n"); |
| 4353 | return -1; |
| 4354 | } |
| 4355 | |
| 4356 | struct nl_msg* msg = nlmsg_alloc(); |
| 4357 | |
| 4358 | if (!msg) { |
| 4359 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 4360 | nlfree(&nl); |
| 4361 | return -2; |
| 4362 | } |
| 4363 | |
| 4364 | genlmsg_put(msg, |
| 4365 | NL_AUTO_PORT, |
| 4366 | NL_AUTO_SEQ, |
| 4367 | nl.id, |
| 4368 | 0, |
| 4369 | NLM_F_DUMP, |
| 4370 | NL80211_CMD_GET_STATION, |
| 4371 | 0); |
| 4372 | |
| 4373 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 4374 | nl_send_auto(nl.socket, msg); |
| 4375 | nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info); |
| 4376 | nl_recvmsgs(nl.socket, nl.cb); |
| 4377 | nlmsg_free(msg); |
| 4378 | nlfree(&nl); |
| 4379 | |
| 4380 | output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState; |
| 4381 | output_struct->wifi_devRxRate = info.wifi_devRxRate; |
| 4382 | output_struct->wifi_devTxRate = info.wifi_devTxRate; |
| 4383 | output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength; |
| 4384 | memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress)); |
| 4385 | return RETURN_OK; |
| 4386 | #else |
| 4387 | //iw utility to retrieve station information |
| 4388 | #define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt" |
| 4389 | #define SIGNALFILE "/tmp/wifi_signalstrength.txt" |
| 4390 | #define MACFILE "/tmp/wifi_AssoMac.txt" |
| 4391 | #define TXRATEFILE "/tmp/wifi_txrate.txt" |
| 4392 | #define RXRATEFILE "/tmp/wifi_rxrate.txt" |
| 4393 | FILE *file = NULL; |
| 4394 | char if_name[10] = {'\0'}; |
| 4395 | char pipeCmd[256] = {'\0'}; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 4396 | char line[256] = {0}; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4397 | char interface_name[16] = {0}; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 4398 | int count = 0, device = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4399 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4400 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4401 | return RETURN_ERR; |
| 4402 | |
| 4403 | snprintf(if_name,sizeof(if_name),"%s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4404 | |
| 4405 | sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name); |
| 4406 | file = popen(pipeCmd, "r"); |
| 4407 | |
| 4408 | if(file == NULL) |
| 4409 | return RETURN_ERR; //popen failed |
| 4410 | |
| 4411 | fgets(line, sizeof line, file); |
| 4412 | device = atoi(line); |
| 4413 | pclose(file); |
| 4414 | |
| 4415 | if(device == 0) |
| 4416 | return RETURN_ERR; //No devices are connected |
| 4417 | |
| 4418 | sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name); |
| 4419 | system(pipeCmd); |
| 4420 | |
| 4421 | system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE); |
| 4422 | |
| 4423 | system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE); |
| 4424 | |
| 4425 | system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE); |
| 4426 | |
| 4427 | system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE); |
| 4428 | |
| 4429 | //devIndex starts from 1, ++count |
| 4430 | if((file = fopen(SIGNALFILE, "r")) != NULL ) |
| 4431 | { |
| 4432 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 4433 | { |
| 4434 | if (++count == devIndex) |
| 4435 | { |
| 4436 | output_struct->wifi_devSignalStrength = atoi(line); |
| 4437 | break; |
| 4438 | } |
| 4439 | } |
| 4440 | fclose(file); |
| 4441 | } |
| 4442 | else |
| 4443 | fprintf(stderr,"fopen wifi_signalstrength.txt failed"); |
| 4444 | |
| 4445 | if((file = fopen(MACFILE, "r")) != NULL ) |
| 4446 | { |
| 4447 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 4448 | { |
| 4449 | if (++count == devIndex) |
| 4450 | { |
| 4451 | 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]); |
| 4452 | break; |
| 4453 | } |
| 4454 | } |
| 4455 | fclose(file); |
| 4456 | } |
| 4457 | else |
| 4458 | fprintf(stderr,"fopen wifi_AssoMac.txt failed"); |
| 4459 | |
| 4460 | if((file = fopen(TXRATEFILE, "r")) != NULL ) |
| 4461 | { |
| 4462 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 4463 | { |
| 4464 | if (++count == devIndex) |
| 4465 | { |
| 4466 | output_struct->wifi_devTxRate = atoi(line); |
| 4467 | break; |
| 4468 | } |
| 4469 | } |
| 4470 | fclose(file); |
| 4471 | } |
| 4472 | else |
| 4473 | fprintf(stderr,"fopen wifi_txrate.txt failed"); |
| 4474 | |
| 4475 | if((file = fopen(RXRATEFILE, "r")) != NULL) |
| 4476 | { |
| 4477 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 4478 | { |
| 4479 | if (++count == devIndex) |
| 4480 | { |
| 4481 | output_struct->wifi_devRxRate = atoi(line); |
| 4482 | break; |
| 4483 | } |
| 4484 | } |
| 4485 | fclose(file); |
| 4486 | } |
| 4487 | else |
| 4488 | fprintf(stderr,"fopen wifi_rxrate.txt failed"); |
| 4489 | |
| 4490 | output_struct->wifi_devAssociatedDeviceAuthentiationState = 1; |
| 4491 | |
| 4492 | return RETURN_OK; |
| 4493 | #endif |
| 4494 | } |
| 4495 | |
| 4496 | INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device) |
| 4497 | { |
| 4498 | if (NULL == device) |
| 4499 | return RETURN_ERR; |
| 4500 | return RETURN_OK; |
| 4501 | } |
| 4502 | //<< |
| 4503 | |
| 4504 | |
| 4505 | //--------------wifi_ap_hal----------------------------- |
| 4506 | //enables CTS protection for the radio used by this AP |
| 4507 | INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable) |
| 4508 | { |
| 4509 | //save config and Apply instantly |
| 4510 | return RETURN_ERR; |
| 4511 | } |
| 4512 | |
| 4513 | // enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap |
| 4514 | INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable) |
| 4515 | { |
developer | 463d39a | 2022-09-13 15:32:51 +0800 | [diff] [blame] | 4516 | char config_file[64] = {'\0'}; |
| 4517 | char buf[64] = {'\0'}; |
| 4518 | struct params list; |
| 4519 | |
| 4520 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4521 | list.name = "ht_coex"; |
| 4522 | snprintf(buf, sizeof(buf), "%d", enable); |
| 4523 | list.value = buf; |
| 4524 | |
| 4525 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 4526 | wifi_hostapdWrite(config_file, &list, 1); |
| 4527 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 4528 | |
| 4529 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4530 | |
| 4531 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4532 | } |
| 4533 | |
| 4534 | //P3 // sets the fragmentation threshold in bytes for the radio used by this ap |
| 4535 | INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold) |
| 4536 | { |
developer | ea4bcce | 2022-09-13 15:26:13 +0800 | [diff] [blame] | 4537 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 4538 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 4539 | struct params list; |
| 4540 | |
| 4541 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4542 | if (threshold < 256 || threshold > 2346 ) |
| 4543 | return RETURN_ERR; |
| 4544 | list.name = "fragm_threshold"; |
| 4545 | snprintf(buf, sizeof(buf), "%d", threshold); |
| 4546 | list.value = buf; |
| 4547 | |
| 4548 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 4549 | wifi_hostapdWrite(config_file, &list, 1); |
| 4550 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4551 | |
developer | ea4bcce | 2022-09-13 15:26:13 +0800 | [diff] [blame] | 4552 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4553 | |
| 4554 | return RETURN_OK; |
| 4555 | } |
| 4556 | |
| 4557 | // enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled |
| 4558 | INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable) |
| 4559 | { |
developer | 51a927d | 2022-09-13 15:42:22 +0800 | [diff] [blame] | 4560 | char config_file[64] = {'\0'}; |
| 4561 | char cmd[128] = {'\0'}; |
| 4562 | char buf[64] = {'\0'}; |
| 4563 | char stbc_config[16] = {'\0'}; |
| 4564 | wifi_band band; |
| 4565 | int iterator = 0; |
| 4566 | BOOL current_stbc = FALSE; |
| 4567 | |
| 4568 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4569 | |
| 4570 | band = wifi_index_to_band(radioIndex); |
| 4571 | if (band == band_invalid) |
| 4572 | return RETURN_ERR; |
| 4573 | |
| 4574 | if (band == band_2_4) |
| 4575 | iterator = 1; |
| 4576 | else if (band == band_5) |
| 4577 | iterator = 2; |
| 4578 | else |
| 4579 | return RETURN_OK; |
| 4580 | |
| 4581 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 4582 | |
| 4583 | // set ht and vht config |
| 4584 | for (int i = 0; i < iterator; i++) { |
| 4585 | memset(stbc_config, 0, sizeof(stbc_config)); |
| 4586 | memset(cmd, 0, sizeof(cmd)); |
| 4587 | memset(buf, 0, sizeof(buf)); |
| 4588 | snprintf(stbc_config, sizeof(stbc_config), "%sht_capab", (i == 0)?"":"v"); |
| 4589 | snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config); |
| 4590 | _syscmd(cmd, buf, sizeof(buf)); |
| 4591 | if (strlen(buf) != 0) |
| 4592 | current_stbc = TRUE; |
| 4593 | if (current_stbc == STBC_Enable) |
| 4594 | continue; |
| 4595 | |
| 4596 | if (STBC_Enable == TRUE) { |
| 4597 | // Append the STBC flags in capab config |
| 4598 | memset(cmd, 0, sizeof(cmd)); |
| 4599 | if (i == 0) |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 4600 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file); |
developer | 51a927d | 2022-09-13 15:42:22 +0800 | [diff] [blame] | 4601 | else |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 4602 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file); |
developer | 51a927d | 2022-09-13 15:42:22 +0800 | [diff] [blame] | 4603 | _syscmd(cmd, buf, sizeof(buf)); |
| 4604 | } else if (STBC_Enable == FALSE) { |
| 4605 | // Remove the STBC flags and remain other flags in capab |
| 4606 | memset(cmd, 0, sizeof(cmd)); |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 4607 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file); |
developer | 51a927d | 2022-09-13 15:42:22 +0800 | [diff] [blame] | 4608 | _syscmd(cmd, buf, sizeof(buf)); |
| 4609 | memset(cmd, 0, sizeof(cmd)); |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 4610 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file); |
developer | 51a927d | 2022-09-13 15:42:22 +0800 | [diff] [blame] | 4611 | _syscmd(cmd, buf, sizeof(buf)); |
| 4612 | } |
| 4613 | } |
| 4614 | |
| 4615 | wifi_reloadAp(radioIndex); |
| 4616 | |
| 4617 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4618 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4619 | } |
| 4620 | |
| 4621 | // outputs A-MSDU enable status, 0 == not enabled, 1 == enabled |
| 4622 | INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool) |
| 4623 | { |
developer | 54e6b9f | 2022-09-28 14:41:20 +0800 | [diff] [blame] | 4624 | char AMSDU_file_path[64] = {0}; |
| 4625 | |
| 4626 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4627 | |
| 4628 | if(output_bool == NULL) |
| 4629 | return RETURN_ERR; |
| 4630 | |
| 4631 | sprintf(AMSDU_file_path, "%s%d.txt", AMSDU_FILE, radioIndex); |
| 4632 | |
| 4633 | if (access(AMSDU_file_path, F_OK) == 0) |
| 4634 | *output_bool = TRUE; |
| 4635 | else |
| 4636 | *output_bool = FALSE; |
| 4637 | |
| 4638 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4639 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4640 | } |
| 4641 | |
| 4642 | // enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled |
| 4643 | INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable) |
| 4644 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4645 | char interface_name[16] = {0}; |
developer | 54e6b9f | 2022-09-28 14:41:20 +0800 | [diff] [blame] | 4646 | char cmd[64]={0}; |
| 4647 | char buf[64]={0}; |
| 4648 | char AMSDU_file_path[64] = {0}; |
| 4649 | |
| 4650 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4651 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4652 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4653 | return RETURN_ERR; |
| 4654 | sprintf(cmd, "mt76-vendor %s set ap_wireless amsdu=%d", interface_name, amsduEnable); |
developer | 54e6b9f | 2022-09-28 14:41:20 +0800 | [diff] [blame] | 4655 | _syscmd(cmd, buf, sizeof(buf)); |
| 4656 | |
| 4657 | sprintf(AMSDU_file_path, "%s%d.txt", AMSDU_FILE, radioIndex); |
| 4658 | memset(cmd, 0, sizeof(cmd)); |
| 4659 | if (amsduEnable == TRUE) |
| 4660 | sprintf(cmd, "touch %s", AMSDU_file_path); |
| 4661 | else |
| 4662 | sprintf(cmd, "rm %s 2> /dev/null", AMSDU_file_path); |
| 4663 | _syscmd(cmd, buf, sizeof(buf)); |
| 4664 | |
| 4665 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4666 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4667 | } |
| 4668 | |
| 4669 | //P2 // outputs the number of Tx streams |
| 4670 | INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int) |
| 4671 | { |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4672 | char buf[8] = {0}; |
| 4673 | char cmd[128] = {0}; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4674 | int phyId = 0; |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4675 | |
| 4676 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4677 | |
| 4678 | sprintf(cmd, "cat %s%d.txt 2> /dev/null", CHAIN_MASK_FILE, radioIndex); |
| 4679 | _syscmd(cmd, buf, sizeof(buf)); |
| 4680 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4681 | phyId = radio_index_to_phy(radioIndex); |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4682 | // if there is no record, output the max number of spatial streams |
| 4683 | if (strlen(buf) == 0) { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4684 | sprintf(cmd, "iw phy%d info | grep 'TX MCS and NSS set' -A8 | head -n8 | grep 'streams: MCS' | wc -l", phyId); |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4685 | _syscmd(cmd, buf, sizeof(buf)); |
| 4686 | } |
| 4687 | |
| 4688 | *output_int = (INT)strtol(buf, NULL, 10); |
| 4689 | |
| 4690 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4691 | |
| 4692 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4693 | } |
| 4694 | |
| 4695 | //P2 // sets the number of Tx streams to an enviornment variable |
| 4696 | INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams) |
| 4697 | { |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4698 | char cmd[128] = {0}; |
| 4699 | char buf[128] = {0}; |
| 4700 | char chain_mask_file[128] = {0}; |
| 4701 | FILE *f = NULL; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4702 | int phyId = 0; |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4703 | |
| 4704 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4705 | |
| 4706 | if (numStreams == 0) { |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 4707 | fprintf(stderr, "The mask did not support 0 (auto).\n"); |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4708 | return RETURN_ERR; |
| 4709 | } |
| 4710 | wifi_setRadioEnable(radioIndex, FALSE); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4711 | |
| 4712 | phyId = radio_index_to_phy(radioIndex); |
| 4713 | sprintf(cmd, "iw phy%d set antenna 0x%x 2>&1", phyId, numStreams); |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4714 | _syscmd(cmd, buf, sizeof(buf)); |
| 4715 | |
| 4716 | if (strlen(buf) > 0) { |
| 4717 | fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf); |
| 4718 | return RETURN_ERR; |
| 4719 | } |
| 4720 | wifi_setRadioEnable(radioIndex, TRUE); |
| 4721 | |
| 4722 | sprintf(chain_mask_file, "%s%d.txt", CHAIN_MASK_FILE, radioIndex); |
| 4723 | f = fopen(chain_mask_file, "w"); |
| 4724 | if (f == NULL) { |
| 4725 | fprintf(stderr, "%s: fopen failed.\n", __func__); |
| 4726 | return RETURN_ERR; |
| 4727 | } |
| 4728 | fprintf(f, "%d", numStreams); |
| 4729 | fclose(f); |
| 4730 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4731 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4732 | } |
| 4733 | |
| 4734 | //P2 // outputs the number of Rx streams |
| 4735 | INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int) |
| 4736 | { |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4737 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4738 | if (wifi_getRadioTxChainMask(radioIndex, output_int) == RETURN_ERR) { |
| 4739 | fprintf(stderr, "%s: wifi_getRadioTxChainMask return error.\n", __func__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4740 | return RETURN_ERR; |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4741 | } |
| 4742 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4743 | return RETURN_OK; |
| 4744 | } |
| 4745 | |
| 4746 | //P2 // sets the number of Rx streams to an enviornment variable |
| 4747 | INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams) |
| 4748 | { |
developer | 2de9769 | 2022-09-26 14:00:03 +0800 | [diff] [blame] | 4749 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4750 | if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) { |
| 4751 | fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__); |
| 4752 | return RETURN_ERR; |
| 4753 | } |
| 4754 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4755 | return RETURN_ERR; |
| 4756 | } |
| 4757 | |
| 4758 | //Get radio RDG enable setting |
| 4759 | INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool) |
| 4760 | { |
| 4761 | if (NULL == output_bool) |
| 4762 | return RETURN_ERR; |
| 4763 | *output_bool = TRUE; |
| 4764 | return RETURN_OK; |
| 4765 | } |
| 4766 | |
| 4767 | //Get radio RDG enable setting |
| 4768 | INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool) |
| 4769 | { |
| 4770 | if (NULL == output_bool) |
| 4771 | return RETURN_ERR; |
| 4772 | *output_bool = TRUE; |
| 4773 | return RETURN_OK; |
| 4774 | } |
| 4775 | |
| 4776 | //Set radio RDG enable setting |
| 4777 | INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable) |
| 4778 | { |
| 4779 | return RETURN_ERR; |
| 4780 | } |
| 4781 | |
| 4782 | //Get radio ADDBA enable setting |
| 4783 | INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool) |
| 4784 | { |
| 4785 | if (NULL == output_bool) |
| 4786 | return RETURN_ERR; |
| 4787 | *output_bool = TRUE; |
| 4788 | return RETURN_OK; |
| 4789 | } |
| 4790 | |
| 4791 | //Set radio ADDBA enable setting |
| 4792 | INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable) |
| 4793 | { |
| 4794 | return RETURN_ERR; |
| 4795 | } |
| 4796 | |
| 4797 | //Get radio auto block ack enable setting |
| 4798 | INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool) |
| 4799 | { |
| 4800 | if (NULL == output_bool) |
| 4801 | return RETURN_ERR; |
| 4802 | *output_bool = TRUE; |
| 4803 | return RETURN_OK; |
| 4804 | } |
| 4805 | |
| 4806 | //Set radio auto block ack enable setting |
| 4807 | INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable) |
| 4808 | { |
| 4809 | return RETURN_ERR; |
| 4810 | } |
| 4811 | |
| 4812 | //Get radio 11n pure mode enable support |
| 4813 | INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool) |
| 4814 | { |
| 4815 | if (NULL == output_bool) |
| 4816 | return RETURN_ERR; |
| 4817 | *output_bool = TRUE; |
| 4818 | return RETURN_OK; |
| 4819 | } |
| 4820 | |
| 4821 | //Get radio 11n pure mode enable setting |
| 4822 | INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool) |
| 4823 | { |
| 4824 | if (NULL == output_bool) |
| 4825 | return RETURN_ERR; |
| 4826 | *output_bool = TRUE; |
| 4827 | return RETURN_OK; |
| 4828 | } |
| 4829 | |
| 4830 | //Set radio 11n pure mode enable setting |
| 4831 | INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable) |
| 4832 | { |
| 4833 | return RETURN_ERR; |
| 4834 | } |
| 4835 | |
| 4836 | //Get radio IGMP snooping enable setting |
| 4837 | INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool) |
| 4838 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4839 | char interface_name[16] = {0}; |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4840 | char cmd[128]={0}; |
| 4841 | char buf[4]={0}; |
| 4842 | bool bridge = FALSE, mac80211 = FALSE; |
| 4843 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4844 | |
| 4845 | if(output_bool == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4846 | return RETURN_ERR; |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4847 | |
| 4848 | *output_bool = FALSE; |
| 4849 | |
| 4850 | snprintf(cmd, sizeof(cmd), "cat /sys/devices/virtual/net/%s/bridge/multicast_snooping", BRIDGE_NAME); |
| 4851 | _syscmd(cmd, buf, sizeof(buf)); |
| 4852 | if (strncmp(buf, "1", 1) == 0) |
| 4853 | bridge = TRUE; |
| 4854 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4855 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4856 | return RETURN_ERR; |
| 4857 | snprintf(cmd, sizeof(cmd), "cat /sys/devices/virtual/net/%s/brif/%s/multicast_to_unicast", BRIDGE_NAME, interface_name); |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4858 | _syscmd(cmd, buf, sizeof(buf)); |
| 4859 | if (strncmp(buf, "1", 1) == 0) |
| 4860 | mac80211 = TRUE; |
| 4861 | |
| 4862 | if (bridge && mac80211) |
| 4863 | *output_bool = TRUE; |
| 4864 | |
| 4865 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4866 | return RETURN_OK; |
| 4867 | } |
| 4868 | |
| 4869 | //Set radio IGMP snooping enable setting |
| 4870 | INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable) |
| 4871 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4872 | char interface_name[16] = {0}; |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4873 | char cmd[128]={0}; |
| 4874 | char buf[4]={0}; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 4875 | int max_num_radios =0; |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4876 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4877 | |
| 4878 | // bridge |
| 4879 | snprintf(cmd, sizeof(cmd), "echo %d > /sys/devices/virtual/net/%s/bridge/multicast_snooping", enable, BRIDGE_NAME); |
| 4880 | _syscmd(cmd, buf, sizeof(buf)); |
| 4881 | |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 4882 | wifi_getMaxRadioNumber(&max_num_radios); |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4883 | // mac80211 |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 4884 | for (int i = 0; i < max_num_radios; i++) { |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4885 | if (wifi_GetInterfaceName(i, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4886 | return RETURN_ERR; |
| 4887 | snprintf(cmd, sizeof(cmd), "echo %d > /sys/devices/virtual/net/%s/brif/%s/multicast_to_unicast", enable, BRIDGE_NAME, interface_name); |
developer | 81bf2ed | 2022-09-13 15:31:14 +0800 | [diff] [blame] | 4888 | _syscmd(cmd, buf, sizeof(buf)); |
| 4889 | } |
| 4890 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4891 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4892 | } |
| 4893 | |
| 4894 | //Get the Reset count of radio |
| 4895 | INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int) |
| 4896 | { |
| 4897 | if (NULL == output_int) |
| 4898 | return RETURN_ERR; |
| 4899 | *output_int = (radioIndex==0)? 1: 3; |
| 4900 | |
| 4901 | return RETURN_OK; |
| 4902 | } |
| 4903 | |
| 4904 | |
| 4905 | //--------------------------------------------------------------------------------------------------- |
| 4906 | // |
| 4907 | // Additional Wifi AP level APIs used for Access Point devices |
| 4908 | // |
| 4909 | //--------------------------------------------------------------------------------------------------- |
| 4910 | |
| 4911 | // creates a new ap and pushes these parameters to the hardware |
| 4912 | INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid) |
| 4913 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4914 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4915 | char buf[1024]; |
| 4916 | char cmd[128]; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4917 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4918 | |
| 4919 | if (NULL == essid) |
| 4920 | return RETURN_ERR; |
| 4921 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4922 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4923 | return RETURN_ERR; |
| 4924 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 4925 | phyId = radio_index_to_phy(radioIndex); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4926 | snprintf(cmd,sizeof(cmd), "wlanconfig %s create wlandev %s%d wlanmode ap", interface_name, RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4927 | _syscmd(cmd, buf, sizeof(buf)); |
| 4928 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4929 | snprintf(cmd,sizeof(cmd), "iwconfig %s essid %s mode master", interface_name, essid); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4930 | _syscmd(cmd, buf, sizeof(buf)); |
| 4931 | |
| 4932 | wifi_pushSsidAdvertisementEnable(apIndex, !hideSsid); |
| 4933 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4934 | snprintf(cmd,sizeof(cmd), "ifconfig %s txqueuelen 1000", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4935 | _syscmd(cmd, buf, sizeof(buf)); |
| 4936 | |
| 4937 | return RETURN_OK; |
| 4938 | } |
| 4939 | |
| 4940 | // deletes this ap entry on the hardware, clears all internal variables associaated with this ap |
| 4941 | INT wifi_deleteAp(INT apIndex) |
| 4942 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4943 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4944 | char buf[1024]; |
| 4945 | char cmd[128]; |
| 4946 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4947 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4948 | return RETURN_ERR; |
| 4949 | snprintf(cmd,sizeof(cmd), "wlanconfig %s destroy", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4950 | _syscmd(cmd, buf, sizeof(buf)); |
| 4951 | |
| 4952 | wifi_removeApSecVaribles(apIndex); |
| 4953 | |
| 4954 | return RETURN_OK; |
| 4955 | } |
| 4956 | |
| 4957 | // Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller |
| 4958 | INT wifi_getApName(INT apIndex, CHAR *output_string) |
| 4959 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4960 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4961 | if(NULL == output_string) |
| 4962 | return RETURN_ERR; |
| 4963 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4964 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | 67b8ee9 | 2022-12-20 10:48:43 +0800 | [diff] [blame] | 4965 | snprintf(output_string, 16, "%s%d", AP_PREFIX, apIndex); // For wifiagent generating data model. |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4966 | else |
| 4967 | snprintf(output_string, 16, "%s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4968 | return RETURN_OK; |
| 4969 | } |
| 4970 | |
| 4971 | // Outputs the index number in that corresponds to the SSID string |
| 4972 | INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int) |
| 4973 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4974 | char cmd [128] = {0}; |
| 4975 | char buf[32] = {0}; |
| 4976 | char *apIndex_str = NULL; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4977 | bool enable = FALSE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4978 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4979 | snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'", inputSsidString); |
| 4980 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 67b8ee9 | 2022-12-20 10:48:43 +0800 | [diff] [blame] | 4981 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 4982 | if (strlen(buf) != 0) { |
| 4983 | apIndex_str = strtok(buf, "\n"); |
| 4984 | *output_int = strtoul(apIndex_str, NULL, 10); |
| 4985 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4986 | } |
developer | 67b8ee9 | 2022-12-20 10:48:43 +0800 | [diff] [blame] | 4987 | |
| 4988 | // If interface name is not in hostapd config, the caller maybe wifi agent to generate data model. |
| 4989 | apIndex_str = strstr(inputSsidString, AP_PREFIX); |
| 4990 | if (apIndex_str) { |
| 4991 | sscanf(apIndex_str + strlen(AP_PREFIX), "%d", output_int); |
| 4992 | return RETURN_OK; |
| 4993 | } |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 4994 | *output_int = -1; |
| 4995 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 4996 | } |
| 4997 | |
| 4998 | INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int) |
| 4999 | { |
| 5000 | return wifi_getIndexFromName(inputSsidString, output_int); |
| 5001 | } |
| 5002 | |
| 5003 | // Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i" |
| 5004 | INT wifi_getApBeaconType(INT apIndex, CHAR *output_string) |
| 5005 | { |
| 5006 | char buf[MAX_BUF_SIZE] = {0}; |
| 5007 | char cmd[MAX_CMD_SIZE] = {0}; |
| 5008 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5009 | |
| 5010 | if(NULL == output_string) |
| 5011 | return RETURN_ERR; |
| 5012 | |
| 5013 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5014 | wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf)); |
| 5015 | if((strcmp(buf,"3")==0)) |
| 5016 | snprintf(output_string, 32, "WPAand11i"); |
| 5017 | else if((strcmp(buf,"2")==0)) |
| 5018 | snprintf(output_string, 32, "11i"); |
| 5019 | else if((strcmp(buf,"1")==0)) |
| 5020 | snprintf(output_string, 32, "WPA"); |
| 5021 | else |
| 5022 | snprintf(output_string, 32, "None"); |
| 5023 | |
| 5024 | return RETURN_OK; |
| 5025 | } |
| 5026 | |
| 5027 | // Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i" |
| 5028 | INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString) |
| 5029 | { |
| 5030 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5031 | struct params list; |
| 5032 | |
| 5033 | if (NULL == beaconTypeString) |
| 5034 | return RETURN_ERR; |
| 5035 | list.name = "wpa"; |
| 5036 | list.value = "0"; |
| 5037 | |
| 5038 | if((strcmp(beaconTypeString,"WPAand11i")==0)) |
| 5039 | list.value="3"; |
| 5040 | else if((strcmp(beaconTypeString,"11i")==0)) |
| 5041 | list.value="2"; |
| 5042 | else if((strcmp(beaconTypeString,"WPA")==0)) |
| 5043 | list.value="1"; |
| 5044 | |
| 5045 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5046 | wifi_hostapdWrite(config_file, &list, 1); |
| 5047 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 5048 | //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply |
| 5049 | return RETURN_OK; |
| 5050 | } |
| 5051 | |
| 5052 | // sets the beacon interval on the hardware for this AP |
| 5053 | INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval) |
| 5054 | { |
developer | 5f22249 | 2022-09-13 15:21:52 +0800 | [diff] [blame] | 5055 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5056 | struct params params={'\0'}; |
| 5057 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 5058 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 5059 | |
| 5060 | params.name = "beacon_int"; |
| 5061 | snprintf(buf, sizeof(buf), "%u", beaconInterval); |
| 5062 | params.value = buf; |
| 5063 | |
| 5064 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 5065 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5066 | |
| 5067 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5068 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5069 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5070 | } |
| 5071 | |
| 5072 | INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval) |
| 5073 | { |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 5074 | if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK) |
| 5075 | return RETURN_ERR; |
| 5076 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5077 | } |
| 5078 | |
| 5079 | // Get the packet size threshold supported. |
| 5080 | INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool) |
| 5081 | { |
| 5082 | //save config and apply instantly |
| 5083 | if (NULL == output_bool) |
| 5084 | return RETURN_ERR; |
developer | 514406b | 2022-12-05 17:20:21 +0800 | [diff] [blame] | 5085 | *output_bool = TRUE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5086 | return RETURN_OK; |
| 5087 | } |
| 5088 | |
| 5089 | // sets the packet size threshold in bytes to apply RTS/CTS backoff rules. |
| 5090 | INT wifi_setApRtsThreshold(INT apIndex, UINT threshold) |
| 5091 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5092 | char interface_name[16] = {0}; |
developer | 514406b | 2022-12-05 17:20:21 +0800 | [diff] [blame] | 5093 | char buf[16] = {0}; |
| 5094 | char config_file[128] = {0}; |
| 5095 | struct params param = {0}; |
| 5096 | |
| 5097 | if (threshold > 65535) { |
| 5098 | fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold); |
| 5099 | return RETURN_ERR; |
| 5100 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5101 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5102 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5103 | return RETURN_ERR; |
| 5104 | snprintf(config_file, sizeof(config_file), "%s.conf", interface_name); |
developer | 514406b | 2022-12-05 17:20:21 +0800 | [diff] [blame] | 5105 | snprintf(buf, sizeof(buf), "%u", threshold); |
| 5106 | param.name = "rts_threshold"; |
| 5107 | param.value = buf; |
| 5108 | wifi_hostapdWrite(config_file, ¶m, 1); |
| 5109 | wifi_hostapdProcessUpdate(apIndex, ¶m, 1); |
| 5110 | wifi_reloadAp(apIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5111 | |
| 5112 | return RETURN_OK; |
| 5113 | } |
| 5114 | |
| 5115 | // outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption" |
| 5116 | INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string) |
| 5117 | { |
| 5118 | if (NULL == output_string) |
| 5119 | return RETURN_ERR; |
| 5120 | snprintf(output_string, 32, "TKIPandAESEncryption"); |
| 5121 | return RETURN_OK; |
| 5122 | |
| 5123 | } |
| 5124 | |
| 5125 | // outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption" |
| 5126 | INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string) |
| 5127 | { |
| 5128 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 5129 | char *param_name = NULL; |
| 5130 | char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5131 | |
| 5132 | if(NULL == output_string) |
| 5133 | return RETURN_ERR; |
| 5134 | |
| 5135 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5136 | wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf)); |
| 5137 | |
| 5138 | if(strcmp(buf,"0")==0) |
| 5139 | { |
| 5140 | printf("%s: wpa_mode is %s ......... \n", __func__, buf); |
| 5141 | snprintf(output_string, 32, "None"); |
| 5142 | return RETURN_OK; |
| 5143 | } |
| 5144 | else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0)) |
| 5145 | param_name = "rsn_pairwise"; |
| 5146 | else if((strcmp(buf,"1")==0)) |
| 5147 | param_name = "wpa_pairwise"; |
| 5148 | else |
| 5149 | return RETURN_ERR; |
| 5150 | memset(output_string,'\0',32); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5151 | wifi_hostapdRead(config_file,param_name,output_string,32); |
developer | 78a1538 | 2022-11-02 10:57:40 +0800 | [diff] [blame] | 5152 | if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead. |
| 5153 | param_name = "wpa_pairwise"; |
| 5154 | memset(output_string, '\0', 32); |
| 5155 | wifi_hostapdRead(config_file, param_name, output_string, 32); |
| 5156 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5157 | wifi_dbg_printf("\n%s output_string=%s",__func__,output_string); |
| 5158 | |
| 5159 | if(strcmp(output_string,"TKIP") == 0) |
| 5160 | strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption")); |
| 5161 | else if(strcmp(output_string,"CCMP") == 0) |
| 5162 | strncpy(output_string,"AESEncryption", strlen("AESEncryption")); |
| 5163 | else if(strcmp(output_string,"TKIP CCMP") == 0) |
| 5164 | strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption")); |
| 5165 | |
| 5166 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5167 | return RETURN_OK; |
| 5168 | } |
| 5169 | |
| 5170 | // sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption" |
| 5171 | INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode) |
| 5172 | { |
| 5173 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5174 | struct params params={'\0'}; |
| 5175 | char output_string[32]; |
| 5176 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5177 | |
| 5178 | memset(output_string,'\0',32); |
| 5179 | wifi_getApWpaEncryptionMode(apIndex,output_string); |
| 5180 | |
| 5181 | if(strcmp(encMode, "TKIPEncryption") == 0) |
| 5182 | params.value = "TKIP"; |
| 5183 | else if(strcmp(encMode,"AESEncryption") == 0) |
| 5184 | params.value = "CCMP"; |
| 5185 | else if(strcmp(encMode,"TKIPandAESEncryption") == 0) |
| 5186 | params.value = "TKIP CCMP"; |
| 5187 | |
| 5188 | if((strcmp(output_string,"WPAand11i")==0)) |
| 5189 | { |
| 5190 | params.name = "wpa_pairwise"; |
| 5191 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5192 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5193 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5194 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 5195 | params.name = "rsn_pairwise"; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5196 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5197 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5198 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5199 | |
| 5200 | return RETURN_OK; |
| 5201 | } |
| 5202 | else if((strcmp(output_string,"11i")==0)) |
| 5203 | { |
| 5204 | params.name = "rsn_pairwise"; |
| 5205 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5206 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5207 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5208 | return RETURN_OK; |
| 5209 | } |
| 5210 | else if((strcmp(output_string,"WPA")==0)) |
| 5211 | { |
| 5212 | params.name = "wpa_pairwise"; |
| 5213 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5214 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5215 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5216 | return RETURN_OK; |
| 5217 | } |
| 5218 | |
| 5219 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5220 | return RETURN_OK; |
| 5221 | } |
| 5222 | |
| 5223 | // deletes internal security varable settings for this ap |
| 5224 | INT wifi_removeApSecVaribles(INT apIndex) |
| 5225 | { |
| 5226 | //TODO: remove the entry in hostapd config file |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5227 | //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5228 | //_syscmd(cmd, buf, sizeof(buf)); |
| 5229 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5230 | //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5231 | //_syscmd(cmd, buf, sizeof(buf)); |
| 5232 | return RETURN_ERR; |
| 5233 | } |
| 5234 | |
| 5235 | // changes the hardware settings to disable encryption on this ap |
| 5236 | INT wifi_disableApEncryption(INT apIndex) |
| 5237 | { |
| 5238 | //Apply instantly |
| 5239 | return RETURN_ERR; |
| 5240 | } |
| 5241 | |
| 5242 | // set the authorization mode on this ap |
| 5243 | // mode mapping as: 1: open, 2: shared, 4:auto |
| 5244 | INT wifi_setApAuthMode(INT apIndex, INT mode) |
| 5245 | { |
developer | af95c50 | 2022-09-13 16:18:22 +0800 | [diff] [blame] | 5246 | struct params params={0}; |
| 5247 | char config_file[64] = {0}; |
| 5248 | int ret; |
| 5249 | |
| 5250 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 5251 | |
| 5252 | wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode); |
| 5253 | params.name = "auth_algs"; |
| 5254 | |
| 5255 | if (mode & 1 && mode & 2) |
| 5256 | params.value = "3"; |
| 5257 | else if (mode & 2) |
| 5258 | params.value = "2"; |
| 5259 | else if (mode & 1) |
| 5260 | params.value = "1"; |
| 5261 | else |
| 5262 | params.value = "0"; |
| 5263 | |
| 5264 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 5265 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5266 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5267 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 5268 | |
| 5269 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5270 | } |
| 5271 | |
| 5272 | // sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication" |
| 5273 | INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode) |
| 5274 | { |
| 5275 | //save to wifi config, and wait for wifi restart to apply |
| 5276 | struct params params={'\0'}; |
| 5277 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5278 | int ret; |
| 5279 | |
| 5280 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5281 | if(authMode == NULL) |
| 5282 | return RETURN_ERR; |
| 5283 | |
| 5284 | wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode); |
| 5285 | params.name = "wpa_key_mgmt"; |
| 5286 | |
| 5287 | if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0)) |
| 5288 | params.value = "WPA-PSK"; |
| 5289 | else if(strcmp(authMode,"EAPAuthentication") == 0) |
| 5290 | params.value = "WPA-EAP"; |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 5291 | else if (strcmp(authMode, "SAEAuthentication") == 0) |
| 5292 | params.value = "SAE"; |
| 5293 | else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0) |
| 5294 | params.value = "WPA-EAP-SUITE-B-192"; |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 5295 | else if (strcmp(authMode, "PSK-SAEAuthentication") == 0) |
| 5296 | params.value = "WPA-PSK WPA-PSK-SHA256 SAE"; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5297 | else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None |
| 5298 | return RETURN_OK; //This is taken careof in beaconType |
| 5299 | |
| 5300 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5301 | ret=wifi_hostapdWrite(config_file,¶ms,1); |
| 5302 | if(!ret) |
| 5303 | ret=wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5304 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5305 | |
| 5306 | return ret; |
| 5307 | } |
| 5308 | |
| 5309 | // sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication" |
| 5310 | INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode) |
| 5311 | { |
| 5312 | //save to wifi config, and wait for wifi restart to apply |
| 5313 | char BeaconType[50] = {0}; |
| 5314 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5315 | |
| 5316 | *authMode = 0; |
| 5317 | wifi_getApBeaconType(apIndex,BeaconType); |
| 5318 | printf("%s____%s \n",__FUNCTION__,BeaconType); |
| 5319 | |
| 5320 | if(strcmp(BeaconType,"None") == 0) |
| 5321 | strcpy(authMode,"None"); |
| 5322 | else |
| 5323 | { |
| 5324 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5325 | wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32); |
| 5326 | wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode); |
| 5327 | if(strcmp(authMode,"WPA-PSK") == 0) |
| 5328 | strcpy(authMode,"SharedAuthentication"); |
| 5329 | else if(strcmp(authMode,"WPA-EAP") == 0) |
| 5330 | strcpy(authMode,"EAPAuthentication"); |
| 5331 | } |
| 5332 | |
| 5333 | return RETURN_OK; |
| 5334 | } |
| 5335 | |
| 5336 | // Outputs the number of stations associated per AP |
| 5337 | INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong) |
| 5338 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5339 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5340 | char cmd[128]={0}; |
| 5341 | char buf[128]={0}; |
| 5342 | BOOL status = false; |
| 5343 | |
| 5344 | if(apIndex > MAX_APS) |
| 5345 | return RETURN_ERR; |
| 5346 | |
| 5347 | wifi_getApEnable(apIndex,&status); |
| 5348 | if (!status) |
| 5349 | return RETURN_OK; |
| 5350 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5351 | //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5352 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5353 | return RETURN_ERR; |
| 5354 | sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5355 | _syscmd(cmd, buf, sizeof(buf)); |
| 5356 | sscanf(buf,"%lu", output_ulong); |
| 5357 | |
| 5358 | return RETURN_OK; |
| 5359 | } |
| 5360 | |
| 5361 | // manually removes any active wi-fi association with the device specified on this ap |
| 5362 | INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac) |
| 5363 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5364 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5365 | char buf[126]={'\0'}; |
| 5366 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5367 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5368 | return RETURN_ERR; |
| 5369 | sprintf(buf,"hostapd_cli -i%s disassociate %s", interface_name, client_mac); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5370 | system(buf); |
| 5371 | |
| 5372 | return RETURN_OK; |
| 5373 | } |
| 5374 | |
| 5375 | // outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex |
| 5376 | INT wifi_getApRadioIndex(INT apIndex, INT *output_int) |
| 5377 | { |
| 5378 | if(NULL == output_int) |
| 5379 | return RETURN_ERR; |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 5380 | int max_radio_num = 0; |
| 5381 | wifi_getMaxRadioNumber(&max_radio_num); |
| 5382 | *output_int = apIndex%max_radio_num; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5383 | return RETURN_OK; |
| 5384 | } |
| 5385 | |
| 5386 | // sets the radio index for the specific ap |
| 5387 | INT wifi_setApRadioIndex(INT apIndex, INT radioIndex) |
| 5388 | { |
| 5389 | //set to config only and wait for wifi reset to apply settings |
| 5390 | return RETURN_ERR; |
| 5391 | } |
| 5392 | |
| 5393 | // Get the ACL MAC list per AP |
| 5394 | INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size) |
| 5395 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5396 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5397 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 5398 | int ret = 0; |
| 5399 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5400 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5401 | return RETURN_ERR; |
| 5402 | sprintf(cmd, "hostapd_cli -i %s accept_acl SHOW | awk '{print $1}'", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5403 | ret = _syscmd(cmd,macArray,buf_size); |
| 5404 | if (ret != 0) |
| 5405 | return RETURN_ERR; |
| 5406 | |
| 5407 | return RETURN_OK; |
| 5408 | } |
| 5409 | |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5410 | INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size) |
| 5411 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5412 | char interface_name[16] = {0}; |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5413 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 5414 | int ret = 0; |
| 5415 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5416 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5417 | return RETURN_ERR; |
| 5418 | sprintf(cmd, "hostapd_cli -i %s deny_acl SHOW | awk '{print $1}'", interface_name); |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5419 | ret = _syscmd(cmd,macArray,buf_size); |
| 5420 | if (ret != 0) |
| 5421 | return RETURN_ERR; |
| 5422 | |
| 5423 | return RETURN_OK; |
| 5424 | } |
| 5425 | |
| 5426 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5427 | // Get the list of stations associated per AP |
| 5428 | INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size) |
| 5429 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5430 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5431 | char cmd[128]; |
| 5432 | |
| 5433 | if(apIndex > 3) //Currently supporting apIndex upto 3 |
| 5434 | return RETURN_ERR; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5435 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5436 | return RETURN_ERR; |
| 5437 | sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name); |
| 5438 | //sprintf(buf,"iw dev %s station dump | grep Station | cut -d ' ' -f2", interface_name);//alternate method |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5439 | _syscmd(cmd, macArray, buf_size); |
| 5440 | |
| 5441 | return RETURN_OK; |
| 5442 | } |
| 5443 | |
| 5444 | // adds the mac address to the filter list |
| 5445 | //DeviceMacAddress is in XX:XX:XX:XX:XX:XX format |
| 5446 | INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress) |
| 5447 | { |
| 5448 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 5449 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 5450 | |
| 5451 | #if 0 |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5452 | sprintf(cmd, "hostapd_cli -i %s accept_acl ADD_MAC %s", interface_name,DeviceMacAddress); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5453 | if(_syscmd(cmd,buf,sizeof(buf))) |
| 5454 | return RETURN_ERR; |
| 5455 | #endif |
| 5456 | sprintf(cmd, "echo '%s' >> %s%d", DeviceMacAddress, ACL_PREFIX, apIndex); |
| 5457 | if(_syscmd(cmd,buf,sizeof(buf))) |
| 5458 | return RETURN_ERR; |
| 5459 | |
| 5460 | return RETURN_OK; |
| 5461 | } |
| 5462 | |
| 5463 | // deletes the mac address from the filter list |
| 5464 | //DeviceMacAddress is in XX:XX:XX:XX:XX:XX format |
| 5465 | INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress) |
| 5466 | { |
| 5467 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 5468 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 5469 | |
| 5470 | #if 0 |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5471 | sprintf(cmd, "hostapd_cli -i %s accept_acl DEL_MAC %s", interface_name,DeviceMacAddress); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5472 | if(_syscmd(cmd,buf,sizeof(buf))) |
| 5473 | return RETURN_ERR; |
| 5474 | |
| 5475 | #endif |
| 5476 | sprintf(cmd, "sed -i '/%s/d' %s%d ", DeviceMacAddress, ACL_PREFIX, apIndex); |
| 5477 | if(_syscmd(cmd,buf,sizeof(buf))) |
| 5478 | return RETURN_ERR; |
| 5479 | |
| 5480 | return RETURN_OK; |
| 5481 | } |
| 5482 | |
| 5483 | // outputs the number of devices in the filter list |
| 5484 | INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint) |
| 5485 | { |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5486 | char cmd[MAX_BUF_SIZE]={0}; |
| 5487 | char buf[MAX_CMD_SIZE]={0}; |
| 5488 | |
| 5489 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5490 | if(output_uint == NULL) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5491 | return RETURN_ERR; |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5492 | |
| 5493 | snprintf(cmd, sizeof(cmd), "cat %s%d | wc -l | tr -d '\\n'", ACL_PREFIX, apIndex); |
| 5494 | _syscmd(cmd, buf, sizeof(buf)); |
| 5495 | |
| 5496 | *output_uint = atoi(buf); |
| 5497 | |
| 5498 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5499 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5500 | } |
| 5501 | |
| 5502 | INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface) |
| 5503 | { |
| 5504 | char cmd[128]={'\0'}; |
| 5505 | char buf[128]={'\0'}; |
| 5506 | |
| 5507 | if(strcmp(action,"DENY")==0) |
| 5508 | { |
| 5509 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac); |
| 5510 | system(buf); |
| 5511 | return RETURN_OK; |
| 5512 | } |
| 5513 | |
| 5514 | if(strcmp(action,"ALLOW")==0) |
| 5515 | { |
| 5516 | sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac); |
| 5517 | system(buf); |
| 5518 | return RETURN_OK; |
| 5519 | } |
| 5520 | |
| 5521 | return RETURN_ERR; |
| 5522 | |
| 5523 | } |
| 5524 | |
| 5525 | // enable kick for devices on acl black list |
| 5526 | INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable) |
| 5527 | { |
| 5528 | char aclArray[512] = {0}, *acl = NULL; |
| 5529 | char assocArray[512] = {0}, *asso = NULL; |
| 5530 | |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5531 | wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5532 | wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray)); |
| 5533 | |
| 5534 | // if there are no devices connected there is nothing to do |
| 5535 | if (strlen(assocArray) < 17) |
| 5536 | return RETURN_OK; |
| 5537 | |
| 5538 | if (enable == TRUE) |
| 5539 | { |
| 5540 | //kick off the MAC which is in ACL array (deny list) |
| 5541 | acl = strtok(aclArray, "\r\n"); |
| 5542 | while (acl != NULL) { |
| 5543 | if (strlen(acl) >= 17 && strcasestr(assocArray, acl)) |
| 5544 | wifi_kickApAssociatedDevice(apIndex, acl); |
| 5545 | |
| 5546 | acl = strtok(NULL, "\r\n"); |
| 5547 | } |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5548 | wifi_setApMacAddressControlMode(apIndex, 2); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5549 | } |
| 5550 | else |
| 5551 | { |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 5552 | wifi_setApMacAddressControlMode(apIndex, 0); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5553 | } |
| 5554 | |
| 5555 | #if 0 |
| 5556 | //TODO: need to revisit below implementation |
| 5557 | char aclArray[512]={0}, *acl=NULL; |
| 5558 | char assocArray[512]={0}, *asso=NULL; |
| 5559 | char buf[256]={'\0'}; |
| 5560 | char action[10]={'\0'}; |
| 5561 | FILE *fr=NULL; |
| 5562 | char interface[10]={'\0'}; |
| 5563 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5564 | |
| 5565 | wifi_getApAclDevices( apIndex, aclArray, sizeof(aclArray)); |
| 5566 | wifi_getApDevicesAssociated( apIndex, assocArray, sizeof(assocArray)); |
| 5567 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5568 | wifi_hostapdRead(config_file,"interface",interface,sizeof(interface)); |
| 5569 | |
| 5570 | sprintf(buf,"iptables -F WifiServices%d",apIndex); |
| 5571 | system(buf); |
| 5572 | sprintf(buf,"iptables -D INPUT -j WifiServices%d",apIndex); |
| 5573 | system(buf); |
| 5574 | sprintf(buf,"iptables -X WifiServices%d",apIndex); |
| 5575 | system(buf); |
| 5576 | sprintf(buf,"iptables -N WifiServices%d",apIndex); |
| 5577 | system(buf); |
| 5578 | sprintf(buf,"iptables -I INPUT 21 -j WifiServices%d",apIndex); |
| 5579 | system(buf); |
| 5580 | |
| 5581 | if ( enable == TRUE ) |
| 5582 | { |
| 5583 | int device_count=0; |
| 5584 | strcpy(action,"DENY"); |
| 5585 | //kick off the MAC which is in ACL array (deny list) |
| 5586 | acl = strtok (aclArray,","); |
| 5587 | while (acl != NULL) { |
| 5588 | if(strlen(acl)>=17) |
| 5589 | { |
| 5590 | apply_rules(apIndex, acl,action,interface); |
| 5591 | device_count++; |
| 5592 | //Register mac to be blocked ,in syscfg.db persistent storage |
| 5593 | sprintf(buf,"syscfg set %dmacfilter%d %s",apIndex,device_count,acl); |
| 5594 | system(buf); |
| 5595 | sprintf(buf,"syscfg set %dcountfilter %d",apIndex,device_count); |
| 5596 | system(buf); |
| 5597 | system("syscfg commit"); |
| 5598 | |
| 5599 | wifi_kickApAssociatedDevice(apIndex, acl); |
| 5600 | } |
| 5601 | acl = strtok (NULL, ","); |
| 5602 | } |
| 5603 | } |
| 5604 | else |
| 5605 | { |
| 5606 | int device_count=0; |
| 5607 | char cmdmac[20]={'\0'}; |
| 5608 | strcpy(action,"ALLOW"); |
| 5609 | //kick off the MAC which is not in ACL array (allow list) |
| 5610 | acl = strtok (aclArray,","); |
| 5611 | while (acl != NULL) { |
| 5612 | if(strlen(acl)>=17) |
| 5613 | { |
| 5614 | apply_rules(apIndex, acl,action,interface); |
| 5615 | device_count++; |
| 5616 | //Register mac to be Allowed ,in syscfg.db persistent storage |
| 5617 | sprintf(buf,"syscfg set %dmacfilter%d %s",apIndex,device_count,acl); |
| 5618 | system(buf); |
| 5619 | sprintf(buf,"syscfg set %dcountfilter %d",apIndex,device_count); |
| 5620 | system(buf); |
| 5621 | sprintf(cmdmac,"%s",acl); |
| 5622 | } |
| 5623 | acl = strtok (NULL, ","); |
| 5624 | } |
| 5625 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",apIndex,interface,cmdmac); |
| 5626 | system(buf); |
| 5627 | |
| 5628 | //Disconnect the mac which is not in ACL |
| 5629 | asso = strtok (assocArray,","); |
| 5630 | while (asso != NULL) { |
| 5631 | if(strlen(asso)>=17 && !strcasestr(aclArray, asso)) |
| 5632 | wifi_kickApAssociatedDevice(apIndex, asso); |
| 5633 | asso = strtok (NULL, ","); |
| 5634 | } |
| 5635 | } |
| 5636 | #endif |
| 5637 | return RETURN_OK; |
| 5638 | } |
| 5639 | |
| 5640 | INT wifi_setPreferPrivateConnection(BOOL enable) |
| 5641 | { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5642 | return RETURN_OK; |
| 5643 | } |
| 5644 | |
| 5645 | // sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist |
| 5646 | INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode) |
| 5647 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5648 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5649 | int items = 1; |
| 5650 | struct params list[2]; |
| 5651 | char buf[MAX_BUF_SIZE] = {0}; |
| 5652 | char config_file[MAX_BUF_SIZE] = {0}, acl_file[MAX_BUF_SIZE] = {0}; |
developer | 10adcc1 | 2022-09-13 14:39:17 +0800 | [diff] [blame] | 5653 | char deny_file[MAX_BUF_SIZE] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5654 | |
| 5655 | list[0].name = "macaddr_acl"; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5656 | |
developer | 10adcc1 | 2022-09-13 14:39:17 +0800 | [diff] [blame] | 5657 | if (filterMode == 0) { |
| 5658 | sprintf(buf, "%d", 0); |
| 5659 | list[0].value = buf; |
| 5660 | |
| 5661 | char cmd[128], rtn[128]; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5662 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5663 | return RETURN_ERR; |
| 5664 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s deny_acl CLEAR", interface_name); |
developer | 10adcc1 | 2022-09-13 14:39:17 +0800 | [diff] [blame] | 5665 | _syscmd(cmd, rtn, sizeof(rtn)); |
| 5666 | memset(cmd,0,sizeof(cmd)); |
| 5667 | // Delete deny_mac_file in hostapd configuration |
| 5668 | snprintf(cmd, sizeof(cmd), "sed -i '/deny_mac_file=/d' %s%d.conf ", CONFIG_PREFIX, apIndex); |
| 5669 | _syscmd(cmd, rtn, sizeof(rtn)); |
| 5670 | } |
| 5671 | else if (filterMode == 1) { |
| 5672 | sprintf(buf, "%d", filterMode); |
| 5673 | list[0].value = buf; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5674 | sprintf(acl_file,"%s%d",ACL_PREFIX,apIndex); |
| 5675 | list[1].name = "accept_mac_file"; |
| 5676 | list[1].value = acl_file; |
| 5677 | items = 2; |
developer | 10adcc1 | 2022-09-13 14:39:17 +0800 | [diff] [blame] | 5678 | } else if (filterMode == 2) { |
| 5679 | //TODO: deny_mac_file |
| 5680 | sprintf(buf, "%d", 0); |
| 5681 | list[0].value = buf; |
| 5682 | list[1].name = "deny_mac_file"; |
| 5683 | sprintf(deny_file,"%s%d", DENY_PREFIX,apIndex); |
| 5684 | list[1].value = deny_file; |
| 5685 | items = 2; |
| 5686 | } else { |
| 5687 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5688 | } |
developer | 10adcc1 | 2022-09-13 14:39:17 +0800 | [diff] [blame] | 5689 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5690 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5691 | wifi_hostapdWrite(config_file, list, items); |
| 5692 | |
| 5693 | return RETURN_OK; |
| 5694 | |
| 5695 | #if 0 |
| 5696 | if(apIndex==0 || apIndex==1) |
| 5697 | { |
| 5698 | //set the filtermode |
| 5699 | sprintf(buf,"syscfg set %dblockall %d",apIndex,filterMode); |
| 5700 | system(buf); |
| 5701 | system("syscfg commit"); |
| 5702 | |
| 5703 | if(filterMode==0) |
| 5704 | { |
| 5705 | sprintf(buf,"iptables -F WifiServices%d",apIndex); |
| 5706 | system(buf); |
| 5707 | return RETURN_OK; |
| 5708 | } |
| 5709 | } |
| 5710 | return RETURN_OK; |
| 5711 | #endif |
| 5712 | } |
| 5713 | |
| 5714 | // 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. |
| 5715 | INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled) |
| 5716 | { |
| 5717 | return RETURN_ERR; |
| 5718 | } |
| 5719 | |
| 5720 | // gets the vlan ID for this ap from an internal enviornment variable |
| 5721 | INT wifi_getApVlanID(INT apIndex, INT *output_int) |
| 5722 | { |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 5723 | if(apIndex==0) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5724 | { |
| 5725 | *output_int=100; |
| 5726 | return RETURN_OK; |
| 5727 | } |
| 5728 | |
| 5729 | return RETURN_ERR; |
| 5730 | } |
| 5731 | |
| 5732 | // sets the vlan ID for this ap to an internal enviornment variable |
| 5733 | INT wifi_setApVlanID(INT apIndex, INT vlanId) |
| 5734 | { |
| 5735 | //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) |
| 5736 | return RETURN_ERR; |
| 5737 | } |
| 5738 | |
| 5739 | // gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters, |
| 5740 | INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet) |
| 5741 | { |
| 5742 | snprintf(bridgeName, 32, "brlan0"); |
| 5743 | snprintf(IP, 32, "10.0.0.1"); |
| 5744 | snprintf(subnet, 32, "255.255.255.0"); |
| 5745 | |
| 5746 | return RETURN_OK; |
| 5747 | } |
| 5748 | |
| 5749 | //sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters |
| 5750 | INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet) |
| 5751 | { |
| 5752 | //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply. |
| 5753 | return RETURN_ERR; |
| 5754 | } |
| 5755 | |
| 5756 | // reset the vlan configuration for this ap |
| 5757 | INT wifi_resetApVlanCfg(INT apIndex) |
| 5758 | { |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5759 | char original_config_file[64] = {0}; |
| 5760 | char current_config_file[64] = {0}; |
| 5761 | char buf[64] = {0}; |
| 5762 | char cmd[64] = {0}; |
| 5763 | char vlan_file[64] = {0}; |
| 5764 | char vlan_tagged_interface[16] = {0}; |
| 5765 | char vlan_bridge[16] = {0}; |
| 5766 | char vlan_naming[16] = {0}; |
| 5767 | struct params list[4] = {0}; |
| 5768 | wifi_band band; |
| 5769 | |
| 5770 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5771 | |
| 5772 | band = wifi_index_to_band(apIndex); |
| 5773 | if (band == band_2_4) |
| 5774 | sprintf(original_config_file, "/etc/hostapd-2G.conf"); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 5775 | else if (band == band_5) |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5776 | sprintf(original_config_file, "/etc/hostapd-5G.conf"); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 5777 | else if (band == band_6) |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5778 | sprintf(original_config_file, "/etc/hostapd-6G.conf"); |
| 5779 | |
| 5780 | wifi_hostapdRead(original_config_file, "vlan_file", vlan_file, sizeof(vlan_file)); |
| 5781 | |
| 5782 | if (strlen(vlan_file) == 0) |
| 5783 | strcpy(vlan_file, VLAN_FILE); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5784 | |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5785 | // The file should exist or this vap would not work. |
| 5786 | if (access(vlan_file, F_OK) != 0) { |
| 5787 | sprintf(cmd, "touch %s", vlan_file); |
| 5788 | _syscmd(cmd, buf, sizeof(buf)); |
| 5789 | } |
| 5790 | list[0].name = "vlan_file"; |
| 5791 | list[0].value = vlan_file; |
| 5792 | |
| 5793 | wifi_hostapdRead(original_config_file, "vlan_tagged_interface", vlan_tagged_interface, sizeof(vlan_tagged_interface)); |
| 5794 | list[1].name = "vlan_tagged_interface"; |
| 5795 | list[1].value = vlan_tagged_interface; |
| 5796 | |
| 5797 | wifi_hostapdRead(original_config_file, "vlan_bridge", vlan_bridge, sizeof(vlan_bridge)); |
| 5798 | list[2].name = "vlan_bridge"; |
| 5799 | list[2].value = vlan_bridge; |
| 5800 | |
| 5801 | wifi_hostapdRead(original_config_file, "vlan_naming", vlan_naming, sizeof(vlan_naming)); |
| 5802 | list[3].name = "vlan_naming"; |
| 5803 | list[3].value = vlan_naming; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5804 | |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5805 | sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 5806 | wifi_hostapdWrite(current_config_file, list, 4); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5807 | //Reapply vlan settings |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5808 | // wifi_pushBridgeInfo(apIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5809 | |
developer | f5fef61 | 2022-09-20 19:38:26 +0800 | [diff] [blame] | 5810 | // restart this ap |
| 5811 | wifi_setApEnable(apIndex, FALSE); |
| 5812 | wifi_setApEnable(apIndex, TRUE); |
| 5813 | |
| 5814 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5815 | |
| 5816 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5817 | } |
| 5818 | |
| 5819 | // 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. |
| 5820 | INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg) |
| 5821 | { |
| 5822 | return RETURN_ERR; |
| 5823 | } |
| 5824 | |
| 5825 | // starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation |
| 5826 | INT wifi_startHostApd() |
| 5827 | { |
| 5828 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5829 | system("systemctl start hostapd.service"); |
| 5830 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5831 | return RETURN_OK; |
| 5832 | //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2"); |
| 5833 | } |
| 5834 | |
| 5835 | // stops hostapd |
| 5836 | INT wifi_stopHostApd() |
| 5837 | { |
| 5838 | char cmd[128] = {0}; |
| 5839 | char buf[128] = {0}; |
| 5840 | |
| 5841 | sprintf(cmd,"systemctl stop hostapd"); |
| 5842 | _syscmd(cmd, buf, sizeof(buf)); |
| 5843 | |
| 5844 | return RETURN_OK; |
| 5845 | } |
| 5846 | |
| 5847 | // restart hostapd dummy function |
| 5848 | INT wifi_restartHostApd() |
| 5849 | { |
| 5850 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5851 | system("systemctl restart hostapd-global"); |
| 5852 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5853 | |
| 5854 | return RETURN_OK; |
| 5855 | } |
| 5856 | |
| 5857 | static int align_hostapd_config(int index) |
| 5858 | { |
| 5859 | ULONG lval; |
| 5860 | wifi_getRadioChannel(index%2, &lval); |
| 5861 | wifi_setRadioChannel(index%2, lval); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 5862 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5863 | } |
| 5864 | |
| 5865 | // sets the AP enable status variable for the specified ap. |
| 5866 | INT wifi_setApEnable(INT apIndex, BOOL enable) |
| 5867 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5868 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5869 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5870 | char cmd[MAX_CMD_SIZE] = {0}; |
| 5871 | char buf[MAX_BUF_SIZE] = {0}; |
| 5872 | BOOL status; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 5873 | int max_radio_num = 0; |
| 5874 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5875 | |
| 5876 | wifi_getApEnable(apIndex,&status); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 5877 | |
| 5878 | wifi_getMaxRadioNumber(&max_radio_num); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5879 | if (enable == status) |
| 5880 | return RETURN_OK; |
| 5881 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5882 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5883 | return RETURN_ERR; |
| 5884 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5885 | if (enable == TRUE) { |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 5886 | int radioIndex = apIndex % max_radio_num; |
| 5887 | phyId = radio_index_to_phy(radioIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5888 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5889 | //Hostapd will bring up this interface |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5890 | sprintf(cmd, "hostapd_cli -i global raw REMOVE %s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5891 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 5892 | sprintf(cmd, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5893 | _syscmd(cmd, buf, sizeof(buf)); |
| 5894 | } |
| 5895 | else { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5896 | sprintf(cmd, "hostapd_cli -i global raw REMOVE %s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5897 | _syscmd(cmd, buf, sizeof(buf)); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5898 | sprintf(cmd, "ip link set %s down", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5899 | _syscmd(cmd, buf, sizeof(buf)); |
| 5900 | } |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 5901 | snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s", |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5902 | interface_name, interface_name, enable, VAP_STATUS_FILE); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5903 | _syscmd(cmd, buf, sizeof(buf)); |
| 5904 | //Wait for wifi up/down to apply |
| 5905 | return RETURN_OK; |
| 5906 | } |
| 5907 | |
| 5908 | // Outputs the setting of the internal variable that is set by wifi_setApEnable(). |
| 5909 | INT wifi_getApEnable(INT apIndex, BOOL *output_bool) |
| 5910 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5911 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5912 | char cmd[MAX_CMD_SIZE] = {'\0'}; |
| 5913 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 5914 | |
| 5915 | if((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS)) |
| 5916 | return RETURN_ERR; |
| 5917 | |
| 5918 | *output_bool = 0; |
| 5919 | |
| 5920 | if((apIndex >= 0) && (apIndex < MAX_APS))//Handling 6 APs |
| 5921 | { |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 5922 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 5923 | *output_bool = FALSE; |
| 5924 | return RETURN_OK; |
| 5925 | } |
| 5926 | sprintf(cmd, "ifconfig %s 2> /dev/null | grep UP", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5927 | *output_bool = _syscmd(cmd,buf,sizeof(buf))?0:1; |
| 5928 | } |
| 5929 | |
| 5930 | return RETURN_OK; |
| 5931 | } |
| 5932 | |
| 5933 | // Outputs the AP "Enabled" "Disabled" status from driver |
| 5934 | INT wifi_getApStatus(INT apIndex, CHAR *output_string) |
| 5935 | { |
| 5936 | char cmd[128] = {0}; |
| 5937 | char buf[128] = {0}; |
| 5938 | BOOL output_bool; |
| 5939 | |
| 5940 | if ( NULL == output_string) |
| 5941 | return RETURN_ERR; |
| 5942 | wifi_getApEnable(apIndex,&output_bool); |
| 5943 | |
| 5944 | if(output_bool == 1) |
| 5945 | snprintf(output_string, 32, "Up"); |
| 5946 | else |
| 5947 | snprintf(output_string, 32, "Disable"); |
| 5948 | |
| 5949 | return RETURN_OK; |
| 5950 | } |
| 5951 | |
| 5952 | //Indicates whether or not beacons include the SSID name. |
| 5953 | // outputs a 1 if SSID on the AP is enabled, else outputs 0 |
| 5954 | INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output) |
| 5955 | { |
| 5956 | //get the running status |
| 5957 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5958 | char buf[16] = {0}; |
| 5959 | |
| 5960 | if (!output) |
| 5961 | return RETURN_ERR; |
| 5962 | |
| 5963 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5964 | wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf)); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 5965 | // default is enable |
| 5966 | if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0) |
| 5967 | *output = TRUE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5968 | |
| 5969 | return RETURN_OK; |
| 5970 | } |
| 5971 | |
| 5972 | // sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable |
| 5973 | INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable) |
| 5974 | { |
| 5975 | //store the config, apply instantly |
| 5976 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5977 | struct params list; |
| 5978 | |
| 5979 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5980 | list.name = "ignore_broadcast_ssid"; |
| 5981 | list.value = enable?"0":"1"; |
| 5982 | |
| 5983 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5984 | wifi_hostapdWrite(config_file, &list, 1); |
| 5985 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 5986 | //TODO: call hostapd_cli for dynamic_config_control |
developer | 384f25c | 2022-09-13 14:41:20 +0800 | [diff] [blame] | 5987 | wifi_reloadAp(apIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 5988 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5989 | |
| 5990 | return RETURN_OK; |
| 5991 | } |
| 5992 | |
| 5993 | //The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit. |
| 5994 | INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint) |
| 5995 | { |
| 5996 | //get the running status |
| 5997 | if(!output_uint) |
| 5998 | return RETURN_ERR; |
| 5999 | *output_uint=16; |
| 6000 | return RETURN_OK; |
| 6001 | } |
| 6002 | |
| 6003 | INT wifi_setApRetryLimit(INT apIndex, UINT number) |
| 6004 | { |
| 6005 | //apply instantly |
| 6006 | return RETURN_ERR; |
| 6007 | } |
| 6008 | |
| 6009 | //Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC). |
| 6010 | INT wifi_getApWMMCapability(INT apIndex, BOOL *output) |
| 6011 | { |
| 6012 | if(!output) |
| 6013 | return RETURN_ERR; |
| 6014 | *output=TRUE; |
| 6015 | return RETURN_OK; |
| 6016 | } |
| 6017 | |
| 6018 | //Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support. |
| 6019 | INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output) |
| 6020 | { |
| 6021 | //get the running status from driver |
developer | 0b246d1 | 2022-09-30 15:24:20 +0800 | [diff] [blame] | 6022 | char cmd[128] = {0}; |
| 6023 | char buf[128] = {0}; |
| 6024 | int max_radio_num = 0, radioIndex = 0; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 6025 | int phyId = 0; |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6026 | |
developer | 0b246d1 | 2022-09-30 15:24:20 +0800 | [diff] [blame] | 6027 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6028 | |
developer | 0b246d1 | 2022-09-30 15:24:20 +0800 | [diff] [blame] | 6029 | wifi_getMaxRadioNumber(&max_radio_num); |
| 6030 | radioIndex = apIndex % max_radio_num; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 6031 | phyId = radio_index_to_phy(radioIndex); |
| 6032 | snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId); |
developer | 0b246d1 | 2022-09-30 15:24:20 +0800 | [diff] [blame] | 6033 | _syscmd(cmd,buf, sizeof(buf)); |
| 6034 | |
| 6035 | if (strlen(buf) > 0) |
| 6036 | *output = true; |
| 6037 | |
| 6038 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6039 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6040 | return RETURN_OK; |
| 6041 | } |
| 6042 | |
| 6043 | //Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames. |
| 6044 | INT wifi_getApWmmEnable(INT apIndex, BOOL *output) |
| 6045 | { |
| 6046 | //get the running status from driver |
| 6047 | if(!output) |
| 6048 | return RETURN_ERR; |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6049 | |
| 6050 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6051 | char buf[16] = {0}; |
| 6052 | |
| 6053 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6054 | wifi_hostapdRead(config_file, "wmm_enabled", buf, sizeof(buf)); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 6055 | if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0) |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6056 | *output = TRUE; |
| 6057 | else |
| 6058 | *output = FALSE; |
| 6059 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6060 | return RETURN_OK; |
| 6061 | } |
| 6062 | |
| 6063 | // enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0 |
| 6064 | INT wifi_setApWmmEnable(INT apIndex, BOOL enable) |
| 6065 | { |
| 6066 | //Save config and apply instantly. |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6067 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6068 | struct params list; |
| 6069 | |
| 6070 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6071 | list.name = "wmm_enabled"; |
| 6072 | list.value = enable?"1":"0"; |
| 6073 | |
| 6074 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6075 | wifi_hostapdWrite(config_file, &list, 1); |
| 6076 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 6077 | wifi_reloadAp(apIndex); |
| 6078 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6079 | |
| 6080 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6081 | } |
| 6082 | |
| 6083 | //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. |
| 6084 | INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output) |
| 6085 | { |
| 6086 | //get the running status from driver |
| 6087 | if(!output) |
| 6088 | return RETURN_ERR; |
developer | 97c720c | 2022-11-04 17:08:12 +0800 | [diff] [blame] | 6089 | |
| 6090 | char config_file[128] = {0}; |
| 6091 | char buf[16] = {0}; |
| 6092 | |
| 6093 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6094 | wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf)); |
| 6095 | if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0) |
| 6096 | *output = TRUE; |
| 6097 | else |
| 6098 | *output = FALSE; |
| 6099 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6100 | return RETURN_OK; |
| 6101 | } |
| 6102 | |
| 6103 | // enables/disables Automatic Power Save Delivery on the hardwarwe for this AP |
| 6104 | INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable) |
| 6105 | { |
| 6106 | //save config and apply instantly. |
developer | 3ab3804 | 2022-09-13 14:17:03 +0800 | [diff] [blame] | 6107 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6108 | struct params list; |
| 6109 | |
| 6110 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6111 | list.name = "uapsd_advertisement_enabled"; |
| 6112 | list.value = enable?"1":"0"; |
| 6113 | |
| 6114 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6115 | wifi_hostapdWrite(config_file, &list, 1); |
| 6116 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 6117 | wifi_reloadAp(apIndex); |
| 6118 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6119 | |
| 6120 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6121 | } |
| 6122 | |
developer | 6daeb3f | 2022-09-30 13:36:39 +0800 | [diff] [blame] | 6123 | // Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6124 | INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB |
| 6125 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6126 | char interface_name[16] = {0}; |
developer | 6daeb3f | 2022-09-30 13:36:39 +0800 | [diff] [blame] | 6127 | // assume class 0->BE, 1->BK, 2->VI, 3->VO |
| 6128 | char cmd[128] = {0}; |
| 6129 | char buf[128] = {0}; |
| 6130 | char ack_filepath[128] = {0}; |
| 6131 | uint16_t bitmap = 0; |
| 6132 | uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0}; |
| 6133 | FILE *f = NULL; |
| 6134 | |
| 6135 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 6136 | |
| 6137 | // Get current setting |
| 6138 | snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex); |
| 6139 | snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath); |
| 6140 | _syscmd(cmd, buf, sizeof(buf)); |
| 6141 | if (strlen(buf) > 0) |
| 6142 | bitmap = strtoul(buf, NULL, 10); |
| 6143 | |
| 6144 | bitmap = strtoul(buf, NULL, 10); |
| 6145 | |
| 6146 | if (ackPolicy == TRUE) { // True, unset this class |
| 6147 | bitmap &= ~class_map[class]; |
| 6148 | } else { // False, set this class |
| 6149 | bitmap |= class_map[class]; |
| 6150 | } |
| 6151 | |
| 6152 | f = fopen(ack_filepath, "w"); |
| 6153 | if (f == NULL) { |
| 6154 | fprintf(stderr, "%s: fopen failed\n", __func__); |
| 6155 | return RETURN_ERR; |
| 6156 | } |
| 6157 | fprintf(f, "%hu", bitmap); |
| 6158 | fclose(f); |
| 6159 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 6160 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6161 | return RETURN_ERR; |
| 6162 | snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap); |
developer | 6daeb3f | 2022-09-30 13:36:39 +0800 | [diff] [blame] | 6163 | _syscmd(cmd, buf, sizeof(buf)); |
| 6164 | |
| 6165 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 6166 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6167 | } |
| 6168 | |
| 6169 | //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. |
| 6170 | INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint) |
| 6171 | { |
| 6172 | //get the running status from driver |
| 6173 | if(!output_uint) |
| 6174 | return RETURN_ERR; |
developer | 0947e1a | 2022-09-13 14:15:25 +0800 | [diff] [blame] | 6175 | |
| 6176 | char output[16]={'\0'}; |
| 6177 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6178 | |
| 6179 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6180 | wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output)); |
| 6181 | if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM; |
| 6182 | else { |
| 6183 | int device_num = atoi(output); |
| 6184 | if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) { |
| 6185 | wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num); |
| 6186 | return RETURN_ERR; |
| 6187 | } |
| 6188 | else { |
| 6189 | *output_uint = device_num; |
| 6190 | } |
| 6191 | } |
| 6192 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6193 | return RETURN_OK; |
| 6194 | } |
| 6195 | |
| 6196 | INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number) |
| 6197 | { |
| 6198 | //store to wifi config, apply instantly |
developer | 0947e1a | 2022-09-13 14:15:25 +0800 | [diff] [blame] | 6199 | char str[MAX_BUF_SIZE]={'\0'}; |
| 6200 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 6201 | struct params params; |
| 6202 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6203 | |
| 6204 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 6205 | if (number > MAX_ASSOCIATED_STA_NUM) { |
developer | 0947e1a | 2022-09-13 14:15:25 +0800 | [diff] [blame] | 6206 | WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__); |
| 6207 | return RETURN_ERR; |
| 6208 | } |
| 6209 | sprintf(str, "%d", number); |
| 6210 | params.name = "max_num_sta"; |
| 6211 | params.value = str; |
| 6212 | |
| 6213 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex); |
| 6214 | int ret = wifi_hostapdWrite(config_file, ¶ms, 1); |
| 6215 | if (ret) { |
| 6216 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n" |
| 6217 | ,__func__, ret); |
| 6218 | } |
| 6219 | |
| 6220 | ret = wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 6221 | if (ret) { |
| 6222 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n" |
| 6223 | ,__func__, ret); |
| 6224 | } |
| 6225 | wifi_reloadAp(apIndex); |
| 6226 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6227 | |
| 6228 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6229 | } |
| 6230 | |
| 6231 | //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. |
| 6232 | INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint) |
| 6233 | { |
| 6234 | //get the current threshold |
| 6235 | if(!output_uint) |
| 6236 | return RETURN_ERR; |
developer | 0947e1a | 2022-09-13 14:15:25 +0800 | [diff] [blame] | 6237 | wifi_getApMaxAssociatedDevices(apIndex, output_uint); |
| 6238 | if (*output_uint == 0) |
| 6239 | *output_uint = 50; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6240 | return RETURN_OK; |
| 6241 | } |
| 6242 | |
| 6243 | INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold) |
| 6244 | { |
| 6245 | //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time |
developer | 0947e1a | 2022-09-13 14:15:25 +0800 | [diff] [blame] | 6246 | if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold)) |
| 6247 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6248 | return RETURN_ERR; |
| 6249 | } |
| 6250 | |
| 6251 | //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. |
| 6252 | INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint) |
| 6253 | { |
| 6254 | if(!output_uint) |
| 6255 | return RETURN_ERR; |
| 6256 | *output_uint = 3; |
| 6257 | return RETURN_OK; |
| 6258 | } |
| 6259 | |
| 6260 | //Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module. |
| 6261 | INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint) |
| 6262 | { |
| 6263 | if(!output_uint) |
| 6264 | return RETURN_ERR; |
| 6265 | *output_uint = 3; |
| 6266 | return RETURN_OK; |
| 6267 | } |
| 6268 | |
| 6269 | //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. |
| 6270 | INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds) |
| 6271 | { |
| 6272 | if(!output_in_seconds) |
| 6273 | return RETURN_ERR; |
| 6274 | *output_in_seconds = 0; |
| 6275 | return RETURN_OK; |
| 6276 | } |
| 6277 | |
| 6278 | //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 |
| 6279 | INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output) |
| 6280 | { |
| 6281 | if(!output || apIndex>=MAX_APS) |
| 6282 | return RETURN_ERR; |
| 6283 | //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise"); |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6284 | snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6285 | return RETURN_OK; |
| 6286 | } |
| 6287 | |
| 6288 | //The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled. |
| 6289 | INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output) |
| 6290 | { |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6291 | char config_file[128] = {0}; |
| 6292 | char wpa[16] = {0}; |
| 6293 | char key_mgmt[64] = {0}; |
| 6294 | char buf[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6295 | if (!output) |
| 6296 | return RETURN_ERR; |
| 6297 | |
| 6298 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6299 | wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6300 | |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6301 | strcpy(output, "None");//Copying "None" to output string for default case |
| 6302 | wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt)); |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 6303 | if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) { |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 6304 | if (!strcmp(wpa, "1")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6305 | snprintf(output, 32, "WPA-Personal"); |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 6306 | else if (!strcmp(wpa, "2")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6307 | snprintf(output, 32, "WPA2-Personal"); |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 6308 | else if (!strcmp(wpa, "3")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6309 | snprintf(output, 32, "WPA-WPA2-Personal"); |
| 6310 | |
| 6311 | } else if (strstr(key_mgmt, "WPA-EAP")) { |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 6312 | if (!strcmp(wpa, "1")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6313 | snprintf(output, 32, "WPA-Enterprise"); |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 6314 | else if (!strcmp(wpa, "2")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6315 | snprintf(output, 32, "WPA2-Enterprise"); |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 6316 | else if (!strcmp(wpa, "3")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6317 | snprintf(output, 32, "WPA-WPA2-Enterprise"); |
| 6318 | } else if (strstr(key_mgmt, "SAE")) { |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 6319 | if (strstr(key_mgmt, "WPA-PSK") == NULL) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6320 | snprintf(output, 32, "WPA3-Personal"); |
| 6321 | else |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 6322 | snprintf(output, 32, "WPA3-Personal-Transition"); |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6323 | } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) { |
| 6324 | snprintf(output, 32, "WPA3-Enterprise"); |
| 6325 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6326 | |
| 6327 | //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply |
| 6328 | return RETURN_OK; |
| 6329 | #if 0 |
| 6330 | //TODO: need to revisit below implementation |
| 6331 | char securityType[32], authMode[32]; |
| 6332 | int enterpriseMode=0; |
| 6333 | |
| 6334 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6335 | if(!output) |
| 6336 | return RETURN_ERR; |
| 6337 | |
| 6338 | wifi_getApBeaconType(apIndex, securityType); |
| 6339 | strcpy(output,"None");//By default, copying "None" to output string |
| 6340 | if (strncmp(securityType,"None", strlen("None")) == 0) |
| 6341 | return RETURN_OK; |
| 6342 | |
| 6343 | wifi_getApBasicAuthenticationMode(apIndex, authMode); |
| 6344 | enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0; |
| 6345 | |
| 6346 | if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0) |
| 6347 | snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal"); |
| 6348 | else if (strncmp(securityType, "WPA", strlen("WPA")) == 0) |
| 6349 | snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal"); |
| 6350 | else if (strncmp(securityType, "11i", strlen("11i")) == 0) |
| 6351 | snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal"); |
| 6352 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6353 | |
| 6354 | return RETURN_OK; |
| 6355 | #endif |
| 6356 | } |
| 6357 | |
| 6358 | INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode) |
| 6359 | { |
| 6360 | char securityType[32]; |
| 6361 | char authMode[32]; |
| 6362 | |
| 6363 | //store settings and wait for wifi up to apply |
| 6364 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6365 | if(!encMode) |
| 6366 | return RETURN_ERR; |
| 6367 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6368 | if (strcmp(encMode, "None")==0) |
| 6369 | { |
| 6370 | strcpy(securityType,"None"); |
| 6371 | strcpy(authMode,"None"); |
| 6372 | } |
| 6373 | else if (strcmp(encMode, "WPA-WPA2-Personal")==0) |
| 6374 | { |
| 6375 | strcpy(securityType,"WPAand11i"); |
| 6376 | strcpy(authMode,"PSKAuthentication"); |
| 6377 | } |
| 6378 | else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) |
| 6379 | { |
| 6380 | strcpy(securityType,"WPAand11i"); |
| 6381 | strcpy(authMode,"EAPAuthentication"); |
| 6382 | } |
| 6383 | else if (strcmp(encMode, "WPA-Personal")==0) |
| 6384 | { |
| 6385 | strcpy(securityType,"WPA"); |
| 6386 | strcpy(authMode,"PSKAuthentication"); |
| 6387 | } |
| 6388 | else if (strcmp(encMode, "WPA-Enterprise")==0) |
| 6389 | { |
| 6390 | strcpy(securityType,"WPA"); |
| 6391 | strcpy(authMode,"EAPAuthentication"); |
| 6392 | } |
| 6393 | else if (strcmp(encMode, "WPA2-Personal")==0) |
| 6394 | { |
| 6395 | strcpy(securityType,"11i"); |
| 6396 | strcpy(authMode,"PSKAuthentication"); |
| 6397 | } |
| 6398 | else if (strcmp(encMode, "WPA2-Enterprise")==0) |
| 6399 | { |
| 6400 | strcpy(securityType,"11i"); |
| 6401 | strcpy(authMode,"EAPAuthentication"); |
| 6402 | } |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6403 | else if (strcmp(encMode, "WPA3-Personal") == 0) |
| 6404 | { |
| 6405 | strcpy(securityType,"11i"); |
| 6406 | strcpy(authMode,"SAEAuthentication"); |
| 6407 | } |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 6408 | else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 6409 | { |
| 6410 | strcpy(securityType, "11i"); |
| 6411 | strcpy(authMode, "PSK-SAEAuthentication"); |
| 6412 | } |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 6413 | else if (strcmp(encMode, "WPA3-Enterprise") == 0) |
| 6414 | { |
| 6415 | strcpy(securityType,"11i"); |
| 6416 | strcpy(authMode,"EAP_192-bit_Authentication"); |
| 6417 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6418 | else |
| 6419 | { |
| 6420 | strcpy(securityType,"None"); |
| 6421 | strcpy(authMode,"None"); |
| 6422 | } |
| 6423 | wifi_setApBeaconType(apIndex, securityType); |
| 6424 | wifi_setApBasicAuthenticationMode(apIndex, authMode); |
| 6425 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6426 | |
| 6427 | return RETURN_OK; |
| 6428 | } |
| 6429 | |
| 6430 | |
| 6431 | //A literal PreSharedKey (PSK) expressed as a hexadecimal string. |
| 6432 | // output_string must be pre-allocated as 64 character string by caller |
| 6433 | // PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value |
| 6434 | INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string) |
| 6435 | { |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 6436 | char buf[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6437 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6438 | |
| 6439 | if(output_string==NULL) |
| 6440 | return RETURN_ERR; |
| 6441 | |
| 6442 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6443 | wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf)); |
| 6444 | |
| 6445 | if(strcmp(buf,"0")==0) |
| 6446 | { |
| 6447 | printf("wpa_mode is %s ......... \n",buf); |
| 6448 | return RETURN_ERR; |
| 6449 | } |
| 6450 | |
| 6451 | wifi_dbg_printf("\nFunc=%s\n",__func__); |
| 6452 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6453 | wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64); |
| 6454 | wifi_dbg_printf("\noutput_string=%s\n",output_string); |
| 6455 | |
| 6456 | return RETURN_OK; |
| 6457 | } |
| 6458 | |
| 6459 | // sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters |
| 6460 | // PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value |
| 6461 | INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey) |
| 6462 | { |
| 6463 | //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply |
| 6464 | struct params params={'\0'}; |
| 6465 | int ret; |
| 6466 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6467 | |
| 6468 | if(NULL == preSharedKey) |
| 6469 | return RETURN_ERR; |
| 6470 | |
| 6471 | params.name = "wpa_passphrase"; |
| 6472 | |
| 6473 | if(strlen(preSharedKey)<8 || strlen(preSharedKey)>63) |
| 6474 | { |
| 6475 | wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n"); |
| 6476 | return RETURN_ERR; |
| 6477 | } |
| 6478 | params.value = preSharedKey; |
| 6479 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6480 | ret = wifi_hostapdWrite(config_file, ¶ms, 1); |
| 6481 | if(!ret) |
| 6482 | ret = wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 6483 | return ret; |
| 6484 | //TODO: call hostapd_cli for dynamic_config_control |
| 6485 | } |
| 6486 | |
| 6487 | //A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes. |
| 6488 | // outputs the passphrase, maximum 63 characters |
| 6489 | INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string) |
| 6490 | { |
| 6491 | char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0}; |
| 6492 | |
| 6493 | wifi_dbg_printf("\nFunc=%s\n",__func__); |
| 6494 | if (NULL == output_string) |
| 6495 | return RETURN_ERR; |
| 6496 | |
| 6497 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6498 | wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf)); |
| 6499 | if(strcmp(buf,"0")==0) |
| 6500 | { |
| 6501 | printf("wpa_mode is %s ......... \n",buf); |
| 6502 | return RETURN_ERR; |
| 6503 | } |
| 6504 | |
| 6505 | wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64); |
| 6506 | wifi_dbg_printf("\noutput_string=%s\n",output_string); |
| 6507 | |
| 6508 | return RETURN_OK; |
| 6509 | } |
| 6510 | |
| 6511 | // sets the passphrase enviornment variable, max 63 characters |
| 6512 | INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase) |
| 6513 | { |
| 6514 | //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply |
| 6515 | struct params params={'\0'}; |
| 6516 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6517 | int ret; |
| 6518 | |
| 6519 | if(NULL == passPhrase) |
| 6520 | return RETURN_ERR; |
| 6521 | |
| 6522 | if(strlen(passPhrase)<8 || strlen(passPhrase)>63) |
| 6523 | { |
| 6524 | wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n"); |
| 6525 | return RETURN_ERR; |
| 6526 | } |
| 6527 | params.name = "wpa_passphrase"; |
| 6528 | params.value = passPhrase; |
| 6529 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 6530 | ret=wifi_hostapdWrite(config_file,¶ms,1); |
| 6531 | if(!ret) |
| 6532 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 6533 | |
| 6534 | return ret; |
| 6535 | } |
| 6536 | |
| 6537 | //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. |
| 6538 | INT wifi_setApSecurityReset(INT apIndex) |
| 6539 | { |
developer | 8d58398 | 2022-09-20 11:28:22 +0800 | [diff] [blame] | 6540 | char original_config_file[64] = {0}; |
| 6541 | char current_config_file[64] = {0}; |
| 6542 | char buf[64] = {0}; |
| 6543 | char cmd[64] = {0}; |
| 6544 | char wpa[4] = {0}; |
| 6545 | char wpa_psk[64] = {0}; |
| 6546 | char wpa_passphrase[64] = {0}; |
| 6547 | char wpa_psk_file[128] = {0}; |
| 6548 | char wpa_key_mgmt[64] = {0}; |
| 6549 | char wpa_pairwise[32] = {0}; |
| 6550 | wifi_band band; |
| 6551 | struct params list[6]; |
| 6552 | |
| 6553 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6554 | |
| 6555 | band = wifi_index_to_band(apIndex); |
| 6556 | if (band == band_2_4) |
| 6557 | sprintf(original_config_file, "/etc/hostapd-2G.conf"); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 6558 | else if (band == band_5) |
developer | 8d58398 | 2022-09-20 11:28:22 +0800 | [diff] [blame] | 6559 | sprintf(original_config_file, "/etc/hostapd-5G.conf"); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 6560 | else if (band == band_6) |
developer | 8d58398 | 2022-09-20 11:28:22 +0800 | [diff] [blame] | 6561 | sprintf(original_config_file, "/etc/hostapd-6G.conf"); |
| 6562 | else |
| 6563 | return RETURN_ERR; |
| 6564 | |
| 6565 | wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa)); |
| 6566 | list[0].name = "wpa"; |
| 6567 | list[0].value = wpa; |
| 6568 | |
| 6569 | wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk)); |
| 6570 | list[1].name = "wpa_psk"; |
| 6571 | list[1].value = wpa_psk; |
| 6572 | |
| 6573 | wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase)); |
| 6574 | list[2].name = "wpa_passphrase"; |
| 6575 | list[2].value = wpa_passphrase; |
| 6576 | |
| 6577 | wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file)); |
| 6578 | |
| 6579 | if (strlen(wpa_psk_file) == 0) |
| 6580 | strcpy(wpa_psk_file, PSK_FILE); |
| 6581 | |
| 6582 | if (access(wpa_psk_file, F_OK) != 0) { |
| 6583 | sprintf(cmd, "touch %s", wpa_psk_file); |
| 6584 | _syscmd(cmd, buf, sizeof(buf)); |
| 6585 | } |
| 6586 | list[3].name = "wpa_psk_file"; |
| 6587 | list[3].value = wpa_psk_file; |
| 6588 | |
| 6589 | wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt)); |
| 6590 | list[4].name = "wpa_key_mgmt"; |
| 6591 | list[4].value = wpa_key_mgmt; |
| 6592 | |
| 6593 | wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise)); |
| 6594 | list[5].name = "wpa_pairwise"; |
| 6595 | list[5].value = wpa_pairwise; |
| 6596 | |
| 6597 | sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6598 | wifi_hostapdWrite(current_config_file, list, 6); |
| 6599 | |
| 6600 | wifi_setApEnable(apIndex, FALSE); |
| 6601 | wifi_setApEnable(apIndex, TRUE); |
| 6602 | |
| 6603 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6604 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6605 | } |
| 6606 | |
| 6607 | //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). |
| 6608 | INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output) |
| 6609 | { |
developer | 8f2ddd5 | 2022-09-13 15:39:24 +0800 | [diff] [blame] | 6610 | char config_file[64] = {0}; |
| 6611 | char buf[64] = {0}; |
| 6612 | char cmd[256] = {0}; |
| 6613 | |
| 6614 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6615 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6616 | if(!IP_output || !Port_output || !RadiusSecret_output) |
| 6617 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6618 | |
developer | 8f2ddd5 | 2022-09-13 15:39:24 +0800 | [diff] [blame] | 6619 | // Read the first matched config |
| 6620 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6621 | sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file); |
| 6622 | _syscmd(cmd, buf, sizeof(buf)); |
| 6623 | strncpy(IP_output, buf, 64); |
| 6624 | |
| 6625 | memset(buf, 0, sizeof(buf)); |
| 6626 | sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file); |
| 6627 | _syscmd(cmd, buf, sizeof(buf)); |
| 6628 | *Port_output = atoi(buf); |
| 6629 | |
| 6630 | memset(buf, 0, sizeof(buf)); |
| 6631 | sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file); |
| 6632 | _syscmd(cmd, buf, sizeof(buf)); |
| 6633 | strncpy(RadiusSecret_output, buf, 64); |
| 6634 | |
| 6635 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6636 | return RETURN_OK; |
| 6637 | } |
| 6638 | |
| 6639 | INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret) |
| 6640 | { |
developer | 8f2ddd5 | 2022-09-13 15:39:24 +0800 | [diff] [blame] | 6641 | char config_file[64] = {0}; |
| 6642 | char port_str[8] = {0}; |
| 6643 | char cmd[256] = {0}; |
| 6644 | char buf[128] = {0}; |
| 6645 | |
| 6646 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6647 | |
| 6648 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6649 | |
| 6650 | snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file); |
| 6651 | _syscmd(cmd, buf, sizeof(buf)); |
| 6652 | memset(cmd, 0, sizeof(cmd)); |
| 6653 | |
| 6654 | snprintf(port_str, sizeof(port_str), "%d", port); |
| 6655 | if (strlen(buf) == 0) |
| 6656 | // Append |
| 6657 | snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n" |
| 6658 | "auth_server_addr=%s\\n" |
| 6659 | "auth_server_port=%s\\n" |
| 6660 | "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file); |
| 6661 | else { |
| 6662 | // Delete the three lines setting after the "# radius 1" comment |
| 6663 | snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file); |
| 6664 | _syscmd(cmd, buf, sizeof(buf)); |
| 6665 | memset(cmd, 0, sizeof(cmd)); |
| 6666 | // Use "# radius 1" comment to find the location to insert the radius setting |
| 6667 | snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/" |
| 6668 | "# radius 1\\n" |
| 6669 | "auth_server_addr=%s\\n" |
| 6670 | "auth_server_port=%s\\n" |
| 6671 | "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file); |
| 6672 | } |
| 6673 | if(_syscmd(cmd, buf, sizeof(buf))) { |
| 6674 | wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd); |
| 6675 | return RETURN_ERR; |
| 6676 | } |
| 6677 | |
| 6678 | wifi_reloadAp(apIndex); |
| 6679 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6680 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6681 | } |
| 6682 | |
| 6683 | INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output) |
| 6684 | { |
developer | 8f2ddd5 | 2022-09-13 15:39:24 +0800 | [diff] [blame] | 6685 | char config_file[64] = {0}; |
| 6686 | char buf[64] = {0}; |
| 6687 | char cmd[256] = {0}; |
| 6688 | |
| 6689 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6690 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6691 | if(!IP_output || !Port_output || !RadiusSecret_output) |
| 6692 | return RETURN_ERR; |
developer | 8f2ddd5 | 2022-09-13 15:39:24 +0800 | [diff] [blame] | 6693 | |
| 6694 | // Read the second matched config |
| 6695 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6696 | sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file); |
| 6697 | _syscmd(cmd, buf, sizeof(buf)); |
| 6698 | strncpy(IP_output, buf, 64); |
| 6699 | |
| 6700 | memset(buf, 0, sizeof(buf)); |
| 6701 | sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file); |
| 6702 | _syscmd(cmd, buf, sizeof(buf)); |
| 6703 | *Port_output = atoi(buf); |
| 6704 | |
| 6705 | memset(buf, 0, sizeof(buf)); |
| 6706 | sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file); |
| 6707 | _syscmd(cmd, buf, sizeof(buf)); |
| 6708 | strncpy(RadiusSecret_output, buf, 64); |
| 6709 | |
| 6710 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6711 | return RETURN_OK; |
| 6712 | } |
| 6713 | |
| 6714 | INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret) |
| 6715 | { |
developer | 8f2ddd5 | 2022-09-13 15:39:24 +0800 | [diff] [blame] | 6716 | char config_file[64] = {0}; |
| 6717 | char port_str[8] = {0}; |
| 6718 | char cmd[256] = {0}; |
| 6719 | char buf[128] = {0}; |
| 6720 | |
| 6721 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6722 | |
| 6723 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6724 | |
| 6725 | snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file); |
| 6726 | _syscmd(cmd, buf, sizeof(buf)); |
| 6727 | memset(cmd, 0, sizeof(cmd)); |
| 6728 | |
| 6729 | snprintf(port_str, sizeof(port_str), "%d", port); |
| 6730 | if (strlen(buf) == 0) |
| 6731 | // Append |
| 6732 | snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n" |
| 6733 | "auth_server_addr=%s\\n" |
| 6734 | "auth_server_port=%s\\n" |
| 6735 | "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file); |
| 6736 | else { |
| 6737 | // Delete the three lines setting after the "# radius 2" comment |
| 6738 | snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file); |
| 6739 | _syscmd(cmd, buf, sizeof(buf)); |
| 6740 | memset(cmd, 0, sizeof(cmd)); |
| 6741 | // Use "# radius 2" comment to find the location to insert the radius setting |
| 6742 | snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/" |
| 6743 | "# radius 2\\n" |
| 6744 | "auth_server_addr=%s\\n" |
| 6745 | "auth_server_port=%s\\n" |
| 6746 | "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file); |
| 6747 | } |
| 6748 | if(_syscmd(cmd, buf, sizeof(buf))) { |
| 6749 | wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd); |
| 6750 | return RETURN_ERR; |
| 6751 | } |
| 6752 | |
| 6753 | wifi_reloadAp(apIndex); |
| 6754 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6755 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6756 | } |
| 6757 | |
| 6758 | //RadiusSettings |
| 6759 | INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output) |
| 6760 | { |
| 6761 | if(!output) |
| 6762 | return RETURN_ERR; |
| 6763 | |
| 6764 | output->RadiusServerRetries = 3; //Number of retries for Radius requests. |
| 6765 | output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available. |
| 6766 | output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs). |
| 6767 | output->PMKCaching = FALSE; //Enable or disable caching of PMK. |
| 6768 | output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes). |
| 6769 | 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. |
| 6770 | output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so. |
| 6771 | output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it. |
| 6772 | output->QuietPeriodAfterFailedAuthentication = 5; //The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it. |
| 6773 | //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. |
| 6774 | |
| 6775 | return RETURN_OK; |
| 6776 | } |
| 6777 | |
| 6778 | INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input) |
| 6779 | { |
| 6780 | //store the paramters, and apply instantly |
| 6781 | return RETURN_ERR; |
| 6782 | } |
| 6783 | |
| 6784 | //Device.WiFi.AccessPoint.{i}.WPS.Enable |
| 6785 | //Enables or disables WPS functionality for this access point. |
| 6786 | // outputs the WPS enable state of this ap in output_bool |
| 6787 | INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool) |
| 6788 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6789 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6790 | char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value; |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 6791 | if(!output_bool) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6792 | return RETURN_ERR; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 6793 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6794 | return RETURN_ERR; |
| 6795 | sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6796 | _syscmd(cmd, buf, sizeof(buf)); |
| 6797 | if(strstr(buf, "configured")) |
| 6798 | *output_bool=TRUE; |
| 6799 | else |
| 6800 | *output_bool=FALSE; |
| 6801 | |
| 6802 | return RETURN_OK; |
| 6803 | } |
| 6804 | |
| 6805 | //Device.WiFi.AccessPoint.{i}.WPS.Enable |
| 6806 | // sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled |
| 6807 | INT wifi_setApWpsEnable(INT apIndex, BOOL enable) |
| 6808 | { |
| 6809 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6810 | struct params params; |
| 6811 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6812 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6813 | //store the paramters, and wait for wifi up to apply |
| 6814 | params.name = "wps_state"; |
| 6815 | params.value = enable ? "2":"0"; |
| 6816 | |
| 6817 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6818 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 6819 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 6820 | wifi_reloadAp(apIndex); |
| 6821 | |
| 6822 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6823 | return RETURN_OK; |
| 6824 | } |
| 6825 | |
| 6826 | //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 |
| 6827 | INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output) |
| 6828 | { |
| 6829 | if(!output) |
| 6830 | return RETURN_ERR; |
| 6831 | snprintf(output, 128, "PushButton,PIN"); |
| 6832 | return RETURN_OK; |
| 6833 | } |
| 6834 | |
| 6835 | //Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled |
| 6836 | //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. |
| 6837 | // Outputs a common separated list of the enabled WPS config methods, 64 bytes max |
| 6838 | INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output) |
| 6839 | { |
| 6840 | if(!output) |
| 6841 | return RETURN_ERR; |
| 6842 | snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods |
| 6843 | |
| 6844 | return RETURN_OK; |
| 6845 | } |
| 6846 | |
| 6847 | //Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled |
| 6848 | // 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 |
| 6849 | INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString) |
| 6850 | { |
| 6851 | //apply instantly. No setting need to be stored. |
| 6852 | char methods[MAX_BUF_SIZE], *token, *next_token; |
| 6853 | char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0}; |
| 6854 | struct params params; |
| 6855 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 6856 | if(!methodString) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6857 | return RETURN_ERR; |
| 6858 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6859 | //store the paramters, and wait for wifi up to apply |
| 6860 | |
| 6861 | snprintf(methods, sizeof(methods), "%s", methodString); |
| 6862 | for(token=methods; *token; token=next_token) |
| 6863 | { |
| 6864 | strtok_r(token, ",", &next_token); |
| 6865 | if(*token=='U' && !strcmp(methods, "USBFlashDrive")) |
| 6866 | snprintf(config_methods, sizeof(config_methods), "%s ", "usba"); |
| 6867 | else if(*token=='E') |
| 6868 | { |
| 6869 | if(!strcmp(methods, "Ethernet")) |
| 6870 | snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet"); |
| 6871 | else if(!strcmp(methods, "ExternalNFCToken")) |
| 6872 | snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token"); |
| 6873 | else |
| 6874 | printf("%s: Unknown WpsConfigMethod\n", __func__); |
| 6875 | } |
| 6876 | else if(*token=='I' && !strcmp(token, "IntegratedNFCToken")) |
| 6877 | snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token"); |
| 6878 | else if(*token=='N' && !strcmp(token, "NFCInterface")) |
| 6879 | snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface"); |
| 6880 | else if(*token=='P' ) |
| 6881 | { |
| 6882 | if(!strcmp(token, "PushButton")) |
| 6883 | snprintf(config_methods, sizeof(config_methods), "%s ", "virtual_push_button"); |
| 6884 | else if(!strcmp(token, "PIN")) |
| 6885 | snprintf(config_methods, sizeof(config_methods), "%s ", "keypad"); |
| 6886 | else |
| 6887 | printf("%s: Unknown WpsConfigMethod\n", __func__); |
| 6888 | } |
| 6889 | else |
| 6890 | printf("%s: Unknown WpsConfigMethod\n", __func__); |
| 6891 | } |
| 6892 | params.name = "config_methods"; |
| 6893 | params.value = config_methods; |
| 6894 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6895 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 6896 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 6897 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6898 | |
| 6899 | return RETURN_OK; |
| 6900 | } |
| 6901 | |
| 6902 | // outputs the pin value, ulong_pin must be allocated by the caller |
| 6903 | INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong) |
| 6904 | { |
| 6905 | char buf[MAX_BUF_SIZE] = {0}; |
| 6906 | char cmd[MAX_CMD_SIZE] = {0}; |
| 6907 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 6908 | if(!output_ulong) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6909 | return RETURN_ERR; |
| 6910 | snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex); |
| 6911 | _syscmd(cmd, buf, sizeof(buf)); |
| 6912 | if(strlen(buf) > 0) |
| 6913 | *output_ulong=strtoul(buf, NULL, 10); |
| 6914 | |
| 6915 | return RETURN_OK; |
| 6916 | } |
| 6917 | |
| 6918 | // set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed. |
| 6919 | INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin) |
| 6920 | { |
| 6921 | //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply |
| 6922 | char ap_pin[16] = {0}; |
| 6923 | char buf[MAX_BUF_SIZE] = {0}; |
| 6924 | char config_file[MAX_BUF_SIZE] = {0}; |
| 6925 | ULONG prev_pin = 0; |
| 6926 | struct params params; |
| 6927 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6928 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6929 | snprintf(ap_pin, sizeof(ap_pin), "%lu", pin); |
| 6930 | params.name = "ap_pin"; |
| 6931 | params.value = ap_pin; |
| 6932 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6933 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 6934 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 6935 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6936 | |
| 6937 | return RETURN_OK; |
| 6938 | } |
| 6939 | |
| 6940 | // Output string is either Not configured or Configured, max 32 characters |
| 6941 | INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string) |
| 6942 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6943 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6944 | char cmd[MAX_CMD_SIZE]; |
| 6945 | char buf[MAX_BUF_SIZE]={0}; |
| 6946 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 6947 | if(!output_string) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6948 | return RETURN_ERR; |
| 6949 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6950 | snprintf(output_string, 32, "Not configured"); |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 6951 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6952 | return RETURN_ERR; |
| 6953 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6954 | _syscmd(cmd, buf, sizeof(buf)); |
| 6955 | |
developer | 348e3d9 | 2022-09-13 14:48:41 +0800 | [diff] [blame] | 6956 | if(!strncmp(buf, "configured", 10)) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6957 | snprintf(output_string, 32, "Configured"); |
| 6958 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6959 | |
| 6960 | return RETURN_OK; |
| 6961 | } |
| 6962 | |
| 6963 | // sets the WPS pin for this AP |
| 6964 | INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin) |
| 6965 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6966 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6967 | char cmd[MAX_CMD_SIZE]; |
| 6968 | char buf[MAX_BUF_SIZE]={0}; |
| 6969 | BOOL enable; |
| 6970 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6971 | wifi_getApEnable(apIndex, &enable); |
| 6972 | if (!enable) |
| 6973 | return RETURN_ERR; |
| 6974 | wifi_getApWpsEnable(apIndex, &enable); |
| 6975 | if (!enable) |
| 6976 | return RETURN_ERR; |
| 6977 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 6978 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6979 | return RETURN_ERR; |
| 6980 | snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6981 | _syscmd(cmd, buf, sizeof(buf)); |
| 6982 | if((strstr(buf, "OK"))!=NULL) |
| 6983 | return RETURN_OK; |
| 6984 | |
| 6985 | return RETURN_ERR; |
| 6986 | } |
| 6987 | |
| 6988 | // This function is called when the WPS push button has been pressed for this AP |
| 6989 | INT wifi_setApWpsButtonPush(INT apIndex) |
| 6990 | { |
| 6991 | char cmd[MAX_CMD_SIZE]; |
| 6992 | char buf[MAX_BUF_SIZE]={0}; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 6993 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6994 | BOOL enable=FALSE; |
| 6995 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 6996 | wifi_getApEnable(apIndex, &enable); |
| 6997 | if (!enable) |
| 6998 | return RETURN_ERR; |
| 6999 | |
| 7000 | wifi_getApWpsEnable(apIndex, &enable); |
| 7001 | if (!enable) |
| 7002 | return RETURN_ERR; |
| 7003 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 7004 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7005 | return RETURN_ERR; |
| 7006 | |
| 7007 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7008 | _syscmd(cmd, buf, sizeof(buf)); |
| 7009 | |
| 7010 | if((strstr(buf, "OK"))!=NULL) |
| 7011 | return RETURN_OK; |
| 7012 | return RETURN_ERR; |
| 7013 | } |
| 7014 | |
| 7015 | // cancels WPS mode for this AP |
| 7016 | INT wifi_cancelApWPS(INT apIndex) |
| 7017 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7018 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7019 | char cmd[MAX_CMD_SIZE]; |
| 7020 | char buf[MAX_BUF_SIZE]={0}; |
| 7021 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 7022 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7023 | return RETURN_ERR; |
| 7024 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7025 | _syscmd(cmd,buf, sizeof(buf)); |
| 7026 | |
| 7027 | if((strstr(buf, "OK"))!=NULL) |
| 7028 | return RETURN_OK; |
| 7029 | return RETURN_ERR; |
| 7030 | } |
| 7031 | |
| 7032 | //Device.WiFi.AccessPoint.{i}.AssociatedDevice.* |
| 7033 | //HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array" |
| 7034 | INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size) |
| 7035 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7036 | char interface_name[16] = {0}; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7037 | FILE *f = NULL; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7038 | int read_flag=0, auth_temp=0, mac_temp=0,i=0; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7039 | char cmd[256] = {0}, buf[2048] = {0}; |
| 7040 | char *param = NULL, *value = NULL, *line=NULL; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7041 | size_t len = 0; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7042 | ssize_t nread = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7043 | wifi_associated_dev_t *dev=NULL; |
| 7044 | |
| 7045 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7046 | *associated_dev_array = NULL; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 7047 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7048 | return RETURN_ERR; |
| 7049 | sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7050 | _syscmd(cmd,buf,sizeof(buf)); |
| 7051 | *output_array_size = atoi(buf); |
| 7052 | |
| 7053 | if (*output_array_size <= 0) |
| 7054 | return RETURN_OK; |
| 7055 | |
| 7056 | dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t)); |
| 7057 | *associated_dev_array = dev; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7058 | sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7059 | _syscmd(cmd,buf,sizeof(buf)); |
| 7060 | f = fopen("/tmp/connected_devices.txt", "r"); |
| 7061 | if (f==NULL) |
| 7062 | { |
| 7063 | *output_array_size=0; |
| 7064 | return RETURN_ERR; |
| 7065 | } |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7066 | while ((getline(&line, &len, f)) != -1) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7067 | { |
| 7068 | param = strtok(line,"="); |
| 7069 | value = strtok(NULL,"="); |
| 7070 | |
| 7071 | if( strcmp("flags",param) == 0 ) |
| 7072 | { |
| 7073 | value[strlen(value)-1]='\0'; |
| 7074 | if(strstr (value,"AUTHORIZED") != NULL ) |
| 7075 | { |
| 7076 | dev[auth_temp].cli_AuthenticationState = 1; |
| 7077 | dev[auth_temp].cli_Active = 1; |
| 7078 | auth_temp++; |
| 7079 | read_flag=1; |
| 7080 | } |
| 7081 | } |
| 7082 | if(read_flag==1) |
| 7083 | { |
| 7084 | if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 ) |
| 7085 | { |
| 7086 | value[strlen(value)-1]='\0'; |
| 7087 | sscanf(value, "%x:%x:%x:%x:%x:%x", |
| 7088 | (unsigned int *)&dev[mac_temp].cli_MACAddress[0], |
| 7089 | (unsigned int *)&dev[mac_temp].cli_MACAddress[1], |
| 7090 | (unsigned int *)&dev[mac_temp].cli_MACAddress[2], |
| 7091 | (unsigned int *)&dev[mac_temp].cli_MACAddress[3], |
| 7092 | (unsigned int *)&dev[mac_temp].cli_MACAddress[4], |
| 7093 | (unsigned int *)&dev[mac_temp].cli_MACAddress[5] ); |
| 7094 | mac_temp++; |
| 7095 | read_flag=0; |
| 7096 | } |
| 7097 | } |
| 7098 | } |
| 7099 | *output_array_size = auth_temp; |
| 7100 | auth_temp=0; |
| 7101 | mac_temp=0; |
| 7102 | free(line); |
| 7103 | fclose(f); |
| 7104 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7105 | return RETURN_OK; |
| 7106 | } |
| 7107 | |
| 7108 | #define MACADDRESS_SIZE 6 |
| 7109 | |
| 7110 | INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 7111 | { |
| 7112 | FILE *fp = NULL; |
| 7113 | char str[MAX_BUF_SIZE] = {0}; |
| 7114 | int wificlientindex = 0 ; |
| 7115 | int count = 0; |
| 7116 | int signalstrength = 0; |
| 7117 | int arr[MACADDRESS_SIZE] = {0}; |
| 7118 | unsigned char mac[MACADDRESS_SIZE] = {0}; |
| 7119 | UINT wifi_count = 0; |
| 7120 | char virtual_interface_name[MAX_BUF_SIZE] = {0}; |
| 7121 | char pipeCmd[MAX_CMD_SIZE] = {0}; |
| 7122 | |
| 7123 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7124 | *output_array_size = 0; |
| 7125 | *associated_dev_array = NULL; |
| 7126 | |
| 7127 | sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name); |
| 7128 | fp = popen(pipeCmd, "r"); |
| 7129 | if (fp == NULL) |
| 7130 | { |
| 7131 | printf("Failed to run command inside function %s\n",__FUNCTION__ ); |
| 7132 | return RETURN_ERR; |
| 7133 | } |
| 7134 | |
| 7135 | /* Read the output a line at a time - output it. */ |
| 7136 | fgets(str, sizeof(str)-1, fp); |
| 7137 | wifi_count = (unsigned int) atoi ( str ); |
| 7138 | *output_array_size = wifi_count; |
| 7139 | printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex); |
| 7140 | pclose(fp); |
| 7141 | |
| 7142 | if(wifi_count == 0) |
| 7143 | { |
| 7144 | return RETURN_OK; |
| 7145 | } |
| 7146 | else |
| 7147 | { |
| 7148 | wifi_associated_dev3_t* temp = NULL; |
| 7149 | temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ; |
| 7150 | if(temp == NULL) |
| 7151 | { |
| 7152 | printf("Error Statement. Insufficient memory \n"); |
| 7153 | return RETURN_ERR; |
| 7154 | } |
| 7155 | |
| 7156 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name); |
| 7157 | system(pipeCmd); |
| 7158 | memset(pipeCmd,0,sizeof(pipeCmd)); |
| 7159 | if(apIndex == 0) |
| 7160 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name); |
| 7161 | else if(apIndex == 1) |
| 7162 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name); |
| 7163 | system(pipeCmd); |
| 7164 | |
| 7165 | fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r"); |
| 7166 | if(fp == NULL) |
| 7167 | { |
| 7168 | printf("/tmp/AssociatedDevice_Stats.txt not exists \n"); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7169 | free(temp); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7170 | return RETURN_ERR; |
| 7171 | } |
| 7172 | fclose(fp); |
| 7173 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7174 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7175 | fp = popen(pipeCmd, "r"); |
| 7176 | if(fp) |
| 7177 | { |
| 7178 | for(count =0 ; count < wifi_count; count++) |
| 7179 | { |
| 7180 | fgets(str, MAX_BUF_SIZE, fp); |
| 7181 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 7182 | { |
| 7183 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 7184 | { |
| 7185 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 7186 | |
| 7187 | } |
| 7188 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 7189 | 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]); |
| 7190 | } |
| 7191 | temp[count].cli_AuthenticationState = 1; //TODO |
| 7192 | temp[count].cli_Active = 1; //TODO |
| 7193 | } |
| 7194 | pclose(fp); |
| 7195 | } |
| 7196 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7197 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7198 | fp = popen(pipeCmd, "r"); |
| 7199 | if(fp) |
| 7200 | { |
| 7201 | pclose(fp); |
| 7202 | } |
| 7203 | fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r"); |
| 7204 | if(fp) |
| 7205 | { |
| 7206 | for(count =0 ; count < wifi_count ;count++) |
| 7207 | { |
| 7208 | fgets(str, MAX_BUF_SIZE, fp); |
| 7209 | signalstrength = atoi(str); |
| 7210 | temp[count].cli_SignalStrength = signalstrength; |
| 7211 | temp[count].cli_RSSI = signalstrength; |
| 7212 | temp[count].cli_SNR = signalstrength + 95; |
| 7213 | } |
| 7214 | pclose(fp); |
| 7215 | } |
| 7216 | |
| 7217 | |
| 7218 | if((apIndex == 0) || (apIndex == 4)) |
| 7219 | { |
| 7220 | for(count =0 ; count < wifi_count ;count++) |
| 7221 | { |
| 7222 | strcpy(temp[count].cli_OperatingStandard,"g"); |
| 7223 | strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz"); |
| 7224 | } |
| 7225 | |
| 7226 | //BytesSent |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7227 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7228 | fp = popen(pipeCmd, "r"); |
| 7229 | if(fp) |
| 7230 | { |
| 7231 | pclose(fp); |
| 7232 | } |
| 7233 | fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r"); |
| 7234 | if(fp) |
| 7235 | { |
| 7236 | for (count = 0; count < wifi_count; count++) |
| 7237 | { |
| 7238 | fgets(str, MAX_BUF_SIZE, fp); |
| 7239 | temp[count].cli_BytesSent = strtoul(str, NULL, 10); |
| 7240 | } |
| 7241 | pclose(fp); |
| 7242 | } |
| 7243 | |
| 7244 | //BytesReceived |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7245 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7246 | fp = popen(pipeCmd, "r"); |
| 7247 | if (fp) |
| 7248 | { |
| 7249 | pclose(fp); |
| 7250 | } |
| 7251 | fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 7252 | if (fp) |
| 7253 | { |
| 7254 | for (count = 0; count < wifi_count; count++) |
| 7255 | { |
| 7256 | fgets(str, MAX_BUF_SIZE, fp); |
| 7257 | temp[count].cli_BytesReceived = strtoul(str, NULL, 10); |
| 7258 | } |
| 7259 | pclose(fp); |
| 7260 | } |
| 7261 | |
| 7262 | //PacketsSent |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7263 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7264 | fp = popen(pipeCmd, "r"); |
| 7265 | if (fp) |
| 7266 | { |
| 7267 | pclose(fp); |
| 7268 | } |
| 7269 | |
| 7270 | fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r"); |
| 7271 | if (fp) |
| 7272 | { |
| 7273 | for (count = 0; count < wifi_count; count++) |
| 7274 | { |
| 7275 | fgets(str, MAX_BUF_SIZE, fp); |
| 7276 | temp[count].cli_PacketsSent = strtoul(str, NULL, 10); |
| 7277 | } |
| 7278 | pclose(fp); |
| 7279 | } |
| 7280 | |
| 7281 | //PacketsReceived |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7282 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7283 | fp = popen(pipeCmd, "r"); |
| 7284 | if (fp) |
| 7285 | { |
| 7286 | pclose(fp); |
| 7287 | } |
| 7288 | fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 7289 | if (fp) |
| 7290 | { |
| 7291 | for (count = 0; count < wifi_count; count++) |
| 7292 | { |
| 7293 | fgets(str, MAX_BUF_SIZE, fp); |
| 7294 | temp[count].cli_PacketsReceived = strtoul(str, NULL, 10); |
| 7295 | } |
| 7296 | pclose(fp); |
| 7297 | } |
| 7298 | |
| 7299 | //ErrorsSent |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7300 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7301 | fp = popen(pipeCmd, "r"); |
| 7302 | if (fp) |
| 7303 | { |
| 7304 | pclose(fp); |
| 7305 | } |
| 7306 | fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r"); |
| 7307 | if (fp) |
| 7308 | { |
| 7309 | for (count = 0; count < wifi_count; count++) |
| 7310 | { |
| 7311 | fgets(str, MAX_BUF_SIZE, fp); |
| 7312 | temp[count].cli_ErrorsSent = strtoul(str, NULL, 10); |
| 7313 | } |
| 7314 | pclose(fp); |
| 7315 | } |
| 7316 | |
| 7317 | //ErrorsSent |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7318 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7319 | fp = popen(pipeCmd, "r"); |
| 7320 | if (fp) |
| 7321 | { |
| 7322 | pclose(fp); |
| 7323 | } |
| 7324 | fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r"); |
| 7325 | if (fp) |
| 7326 | { |
| 7327 | for (count = 0; count < wifi_count; count++) |
| 7328 | { |
| 7329 | fgets(str, MAX_BUF_SIZE, fp); |
| 7330 | temp[count].cli_ErrorsSent = strtoul(str, NULL, 10); |
| 7331 | } |
| 7332 | pclose(fp); |
| 7333 | } |
| 7334 | |
| 7335 | //LastDataDownlinkRate |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7336 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7337 | fp = popen(pipeCmd, "r"); |
| 7338 | if (fp) |
| 7339 | { |
| 7340 | pclose(fp); |
| 7341 | } |
| 7342 | fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r"); |
| 7343 | if (fp) |
| 7344 | { |
| 7345 | for (count = 0; count < wifi_count; count++) |
| 7346 | { |
| 7347 | fgets(str, MAX_BUF_SIZE, fp); |
| 7348 | temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10); |
| 7349 | temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps |
| 7350 | } |
| 7351 | pclose(fp); |
| 7352 | } |
| 7353 | |
| 7354 | //LastDataUplinkRate |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7355 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7356 | fp = popen(pipeCmd, "r"); |
| 7357 | if (fp) |
| 7358 | { |
| 7359 | pclose(fp); |
| 7360 | } |
| 7361 | fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 7362 | if (fp) |
| 7363 | { |
| 7364 | for (count = 0; count < wifi_count; count++) |
| 7365 | { |
| 7366 | fgets(str, MAX_BUF_SIZE, fp); |
| 7367 | temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10); |
| 7368 | temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps |
| 7369 | } |
| 7370 | pclose(fp); |
| 7371 | } |
| 7372 | |
| 7373 | } |
| 7374 | else if ((apIndex == 1) || (apIndex == 5)) |
| 7375 | { |
| 7376 | for (count = 0; count < wifi_count; count++) |
| 7377 | { |
| 7378 | strcpy(temp[count].cli_OperatingStandard, "a"); |
| 7379 | strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz"); |
| 7380 | temp[count].cli_BytesSent = 0; |
| 7381 | temp[count].cli_BytesReceived = 0; |
| 7382 | temp[count].cli_LastDataUplinkRate = 0; |
| 7383 | temp[count].cli_LastDataDownlinkRate = 0; |
| 7384 | temp[count].cli_PacketsSent = 0; |
| 7385 | temp[count].cli_PacketsReceived = 0; |
| 7386 | temp[count].cli_ErrorsSent = 0; |
| 7387 | } |
| 7388 | } |
| 7389 | |
| 7390 | for (count = 0; count < wifi_count; count++) |
| 7391 | { |
| 7392 | temp[count].cli_Retransmissions = 0; |
| 7393 | temp[count].cli_DataFramesSentAck = 0; |
| 7394 | temp[count].cli_DataFramesSentNoAck = 0; |
| 7395 | temp[count].cli_MinRSSI = 0; |
| 7396 | temp[count].cli_MaxRSSI = 0; |
| 7397 | strncpy(temp[count].cli_InterferenceSources, "", 64); |
| 7398 | memset(temp[count].cli_IPAddress, 0, 64); |
| 7399 | temp[count].cli_RetransCount = 0; |
| 7400 | temp[count].cli_FailedRetransCount = 0; |
| 7401 | temp[count].cli_RetryCount = 0; |
| 7402 | temp[count].cli_MultipleRetryCount = 0; |
| 7403 | } |
| 7404 | *associated_dev_array = temp; |
| 7405 | } |
| 7406 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7407 | return RETURN_OK; |
| 7408 | } |
| 7409 | |
| 7410 | int wifihal_interfacestatus(CHAR *wifi_status,CHAR *interface_name) |
| 7411 | { |
| 7412 | FILE *fp = NULL; |
| 7413 | char path[512] = {0},status[MAX_BUF_SIZE] = {0}; |
| 7414 | char cmd[MAX_CMD_SIZE]; |
| 7415 | int count = 0; |
| 7416 | |
| 7417 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7418 | sprintf(cmd, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4", interface_name); |
| 7419 | fp = popen(cmd,"r"); |
| 7420 | if(fp == NULL) |
| 7421 | { |
| 7422 | printf("Failed to run command in Function %s\n",__FUNCTION__); |
| 7423 | return 0; |
| 7424 | } |
| 7425 | if(fgets(path, sizeof(path)-1, fp) != NULL) |
| 7426 | { |
| 7427 | for(count=0;path[count]!='\n';count++) |
| 7428 | status[count]=path[count]; |
| 7429 | status[count]='\0'; |
| 7430 | } |
| 7431 | strcpy(wifi_status,status); |
| 7432 | pclose(fp); |
| 7433 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7434 | return RETURN_OK; |
| 7435 | } |
| 7436 | |
| 7437 | /* #define HOSTAPD_STA_PARAM_ENTRIES 29 |
| 7438 | struct hostapd_sta_param { |
| 7439 | char key[50]; |
| 7440 | char value[100]; |
| 7441 | } |
| 7442 | |
| 7443 | static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){ |
| 7444 | int i = 0; |
| 7445 | |
| 7446 | while(i<HOSTAPD_STA_PARAM_ENTRIES) { |
| 7447 | if (strncmp(params[i].key,key,50) == 0){ |
| 7448 | return ¶ms[i].value; |
| 7449 | } |
| 7450 | i++; |
| 7451 | } |
| 7452 | return NULL; |
| 7453 | |
| 7454 | } */ |
| 7455 | |
| 7456 | static unsigned int count_occurences(const char *buf, const char *word) |
| 7457 | { |
| 7458 | unsigned int n = 0; |
| 7459 | char *ptr = strstr(buf, word); |
| 7460 | |
| 7461 | while (ptr++) { |
| 7462 | n++; |
| 7463 | ptr = strstr(ptr, word); |
| 7464 | } |
| 7465 | |
| 7466 | wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word); |
| 7467 | return n; |
| 7468 | } |
| 7469 | |
| 7470 | static const char *get_line_from_str_buf(const char *buf, char *line) |
| 7471 | { |
| 7472 | int i; |
| 7473 | int n = strlen(buf); |
| 7474 | |
| 7475 | for (i = 0; i < n; i++) { |
| 7476 | line[i] = buf[i]; |
| 7477 | if (buf[i] == '\n') { |
| 7478 | line[i] = '\0'; |
| 7479 | return &buf[i + 1]; |
| 7480 | } |
| 7481 | } |
| 7482 | |
| 7483 | return NULL; |
| 7484 | } |
| 7485 | |
| 7486 | INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 7487 | { |
| 7488 | unsigned int assoc_cnt = 0; |
| 7489 | char interface_name[50] = {0}; |
| 7490 | char buf[MAX_BUF_SIZE * 50]= {'\0'}; // Increase this buffer if more fields are added to 'iw dev' output filter |
| 7491 | char cmd[MAX_CMD_SIZE] = {'\0'}; |
| 7492 | char line[256] = {'\0'}; |
| 7493 | int i = 0; |
| 7494 | int ret = 0; |
| 7495 | const char *ptr = NULL; |
| 7496 | char *key = NULL; |
| 7497 | char *val = NULL; |
| 7498 | wifi_associated_dev3_t *temp = NULL; |
| 7499 | int rssi; |
| 7500 | |
| 7501 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7502 | |
| 7503 | if (wifi_getApName(apIndex, interface_name) != RETURN_OK) { |
| 7504 | wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__); |
| 7505 | return RETURN_ERR; |
| 7506 | } |
| 7507 | |
| 7508 | // Example filtered output of 'iw dev' command: |
| 7509 | // Station 0a:69:72:10:d2:fa (on wifi0) |
| 7510 | // signal avg:-67 [-71, -71] dBm |
| 7511 | // Station 28:c2:1f:25:5f:99 (on wifi0) |
| 7512 | // signal avg:-67 [-71, -70] dBm |
| 7513 | if (sprintf(cmd,"iw dev %s station dump | tr -d '\\t' | grep 'Station\\|signal avg'", interface_name) < 0) { |
| 7514 | wifi_dbg_printf("%s: failed to build iw dev command for %s\n", __FUNCTION__, interface_name); |
| 7515 | return RETURN_ERR; |
| 7516 | } |
| 7517 | |
| 7518 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 7519 | if (ret == RETURN_ERR) { |
| 7520 | wifi_dbg_printf("%s: failed to execute '%s' for %s\n", __FUNCTION__, cmd, interface_name); |
| 7521 | return RETURN_ERR; |
| 7522 | } |
| 7523 | |
| 7524 | *output_array_size = count_occurences(buf, "Station"); |
| 7525 | if (*output_array_size == 0) return RETURN_OK; |
| 7526 | |
| 7527 | temp = calloc(*output_array_size, sizeof(wifi_associated_dev3_t)); |
| 7528 | if (temp == NULL) { |
| 7529 | wifi_dbg_printf("%s: failed to allocate dev array for %s\n", __FUNCTION__, interface_name); |
| 7530 | return RETURN_ERR; |
| 7531 | } |
| 7532 | *associated_dev_array = temp; |
| 7533 | |
| 7534 | wifi_dbg_printf("%s: array_size = %u\n", __FUNCTION__, *output_array_size); |
| 7535 | ptr = get_line_from_str_buf(buf, line); |
| 7536 | i = -1; |
| 7537 | while (ptr) { |
| 7538 | if (strstr(line, "Station")) { |
| 7539 | i++; |
| 7540 | key = strtok(line, " "); |
| 7541 | val = strtok(NULL, " "); |
| 7542 | if (sscanf(val, "%02x:%02x:%02x:%02x:%02x:%02x", |
| 7543 | &temp[i].cli_MACAddress[0], |
| 7544 | &temp[i].cli_MACAddress[1], |
| 7545 | &temp[i].cli_MACAddress[2], |
| 7546 | &temp[i].cli_MACAddress[3], |
| 7547 | &temp[i].cli_MACAddress[4], |
| 7548 | &temp[i].cli_MACAddress[5]) != MACADDRESS_SIZE) { |
| 7549 | wifi_dbg_printf("%s: failed to parse MAC of client connected to %s\n", __FUNCTION__, interface_name); |
| 7550 | free(*associated_dev_array); |
| 7551 | return RETURN_ERR; |
| 7552 | } |
| 7553 | } |
| 7554 | else if (i < 0) { |
| 7555 | ptr = get_line_from_str_buf(ptr, line); |
| 7556 | continue; // We didn't detect 'station' entry yet |
| 7557 | } |
| 7558 | else if (strstr(line, "signal avg")) { |
| 7559 | key = strtok(line, ":"); |
| 7560 | val = strtok(NULL, " "); |
| 7561 | if (sscanf(val, "%d", &rssi) <= 0 ) { |
| 7562 | wifi_dbg_printf("%s: failed to parse RSSI of client connected to %s\n", __FUNCTION__, interface_name); |
| 7563 | free(*associated_dev_array); |
| 7564 | return RETURN_ERR; |
| 7565 | } |
| 7566 | temp[i].cli_RSSI = rssi; |
| 7567 | temp[i].cli_SNR = 95 + rssi; // We use constant -95 noise floor |
| 7568 | } |
| 7569 | // Here other fields can be parsed if added to filter of 'iw dev' command |
| 7570 | |
| 7571 | ptr = get_line_from_str_buf(ptr, line); |
| 7572 | }; |
| 7573 | |
| 7574 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7575 | |
| 7576 | return RETURN_OK; |
| 7577 | } |
| 7578 | |
| 7579 | #if 0 |
| 7580 | //To-do |
| 7581 | INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 7582 | { |
| 7583 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7584 | |
| 7585 | //Using different approach to get required WiFi Parameters from system available commands |
| 7586 | #if 0 |
| 7587 | FILE *f; |
| 7588 | int read_flag=0, auth_temp=0, mac_temp=0,i=0; |
| 7589 | char cmd[256], buf[2048]; |
| 7590 | char *param , *value, *line=NULL; |
| 7591 | size_t len = 0; |
| 7592 | ssize_t nread; |
| 7593 | wifi_associated_dev3_t *dev=NULL; |
| 7594 | *associated_dev_array = NULL; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7595 | sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7596 | _syscmd(cmd,buf,sizeof(buf)); |
| 7597 | *output_array_size = atoi(buf); |
| 7598 | |
| 7599 | if (*output_array_size <= 0) |
| 7600 | return RETURN_OK; |
| 7601 | |
| 7602 | dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t)); |
| 7603 | *associated_dev_array = dev; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7604 | sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7605 | _syscmd(cmd,buf,sizeof(buf)); |
| 7606 | f = fopen("/tmp/connected_devices.txt", "r"); |
| 7607 | if (f==NULL) |
| 7608 | { |
| 7609 | *output_array_size=0; |
| 7610 | return RETURN_ERR; |
| 7611 | } |
| 7612 | while ((nread = getline(&line, &len, f)) != -1) |
| 7613 | { |
| 7614 | param = strtok(line,"="); |
| 7615 | value = strtok(NULL,"="); |
| 7616 | |
| 7617 | if( strcmp("flags",param) == 0 ) |
| 7618 | { |
| 7619 | value[strlen(value)-1]='\0'; |
| 7620 | if(strstr (value,"AUTHORIZED") != NULL ) |
| 7621 | { |
| 7622 | dev[auth_temp].cli_AuthenticationState = 1; |
| 7623 | dev[auth_temp].cli_Active = 1; |
| 7624 | auth_temp++; |
| 7625 | read_flag=1; |
| 7626 | } |
| 7627 | } |
| 7628 | if(read_flag==1) |
| 7629 | { |
| 7630 | if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 ) |
| 7631 | { |
| 7632 | value[strlen(value)-1]='\0'; |
| 7633 | sscanf(value, "%x:%x:%x:%x:%x:%x", |
| 7634 | (unsigned int *)&dev[mac_temp].cli_MACAddress[0], |
| 7635 | (unsigned int *)&dev[mac_temp].cli_MACAddress[1], |
| 7636 | (unsigned int *)&dev[mac_temp].cli_MACAddress[2], |
| 7637 | (unsigned int *)&dev[mac_temp].cli_MACAddress[3], |
| 7638 | (unsigned int *)&dev[mac_temp].cli_MACAddress[4], |
| 7639 | (unsigned int *)&dev[mac_temp].cli_MACAddress[5] ); |
| 7640 | |
| 7641 | } |
| 7642 | else if( strcmp("rx_packets",param) == 0 ) |
| 7643 | { |
| 7644 | sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived)); |
| 7645 | } |
| 7646 | |
| 7647 | else if( strcmp("tx_packets",param) == 0 ) |
| 7648 | { |
| 7649 | sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent)); |
| 7650 | } |
| 7651 | |
| 7652 | else if( strcmp("rx_bytes",param) == 0 ) |
| 7653 | { |
| 7654 | sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived)); |
| 7655 | } |
| 7656 | |
| 7657 | else if( strcmp("tx_bytes",param) == 0 ) |
| 7658 | { |
| 7659 | sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent)); |
| 7660 | mac_temp++; |
| 7661 | read_flag=0; |
| 7662 | } |
| 7663 | } |
| 7664 | } |
| 7665 | |
| 7666 | *output_array_size = auth_temp; |
| 7667 | auth_temp=0; |
| 7668 | mac_temp=0; |
| 7669 | free(line); |
| 7670 | fclose(f); |
| 7671 | #endif |
| 7672 | char interface_name[MAX_BUF_SIZE] = {0}; |
| 7673 | char wifi_status[MAX_BUF_SIZE] = {0}; |
| 7674 | char hostapdconf[MAX_BUF_SIZE] = {0}; |
| 7675 | |
| 7676 | wifi_associated_dev3_t *dev_array = NULL; |
| 7677 | ULONG wifi_count = 0; |
| 7678 | |
| 7679 | *associated_dev_array = NULL; |
| 7680 | *output_array_size = 0; |
| 7681 | |
| 7682 | printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex); |
| 7683 | //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI. |
| 7684 | { |
| 7685 | sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex); |
| 7686 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 7687 | wifi_GetInterfaceName(interface_name, hostapdconf); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7688 | |
| 7689 | if(strlen(interface_name) > 1) |
| 7690 | { |
| 7691 | wifihal_interfacestatus(wifi_status,interface_name); |
| 7692 | if(strcmp(wifi_status,"RUNNING") == 0) |
| 7693 | { |
| 7694 | wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count); |
| 7695 | |
| 7696 | *associated_dev_array = dev_array; |
| 7697 | *output_array_size = wifi_count; |
| 7698 | } |
| 7699 | else |
| 7700 | { |
| 7701 | *associated_dev_array = NULL; |
| 7702 | } |
| 7703 | } |
| 7704 | } |
| 7705 | |
| 7706 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7707 | return RETURN_OK; |
| 7708 | } |
| 7709 | #endif |
| 7710 | |
| 7711 | /* getIPAddress function */ |
| 7712 | /** |
| 7713 | * @description Returning IpAddress of the Matched String |
| 7714 | * |
| 7715 | * @param |
| 7716 | * @str Having MacAddress |
| 7717 | * @ipaddr Having ipaddr |
| 7718 | * @return The status of the operation |
| 7719 | * @retval RETURN_OK if successful |
| 7720 | * @retval RETURN_ERR if any error is detected |
| 7721 | * |
| 7722 | */ |
| 7723 | |
| 7724 | INT getIPAddress(char *str,char *ipaddr) |
| 7725 | { |
| 7726 | FILE *fp = NULL; |
| 7727 | char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0}; |
| 7728 | int LeaseTime = 0,ret = 0; |
| 7729 | if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL ) |
| 7730 | { |
| 7731 | return RETURN_ERR; |
| 7732 | } |
| 7733 | |
| 7734 | while ( fgets(buf, sizeof(buf), fp)!= NULL ) |
| 7735 | { |
| 7736 | /* |
| 7737 | Sample:sss |
| 7738 | 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6 |
| 7739 | 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6 |
| 7740 | */ |
| 7741 | ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT, |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7742 | &(LeaseTime), |
| 7743 | phyAddr, |
| 7744 | ipAddr, |
| 7745 | hostName |
| 7746 | ); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7747 | if(ret != 4) |
| 7748 | continue; |
| 7749 | if(strcmp(str,phyAddr) == 0) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7750 | strcpy(ipaddr,ipAddr); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7751 | } |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7752 | fclose(fp); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7753 | return RETURN_OK; |
| 7754 | } |
| 7755 | |
| 7756 | /* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */ |
| 7757 | /** |
| 7758 | * @description Returning Inactive wireless connected clients informations |
| 7759 | * |
| 7760 | * @param |
| 7761 | * @filename Holding private_wifi 2g/5g content files |
| 7762 | * @associated_dev_array Having inactiv wireless clients informations |
| 7763 | * @output_array_size Returning Inactive wireless counts |
| 7764 | * @return The status of the operation |
| 7765 | * @retval RETURN_OK if successful |
| 7766 | * @retval RETURN_ERR if any error is detected |
| 7767 | * |
| 7768 | */ |
| 7769 | |
| 7770 | INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 7771 | { |
| 7772 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7773 | int count = 0,maccount = 0,i = 0,wificlientindex = 0; |
| 7774 | FILE *fp = NULL; |
| 7775 | int arr[MACADDRESS_SIZE] = {0}; |
| 7776 | unsigned char mac[MACADDRESS_SIZE] = {0}; |
| 7777 | char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0}; |
| 7778 | sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename); |
| 7779 | fp = popen(buf,"r"); |
| 7780 | if(fp == NULL) |
| 7781 | return RETURN_ERR; |
| 7782 | else |
| 7783 | { |
| 7784 | fgets(path,sizeof(path),fp); |
| 7785 | maccount = atoi(path); |
| 7786 | } |
| 7787 | pclose(fp); |
| 7788 | *output_array_size = maccount; |
| 7789 | wifi_associated_dev3_t* temp = NULL; |
| 7790 | temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t)); |
| 7791 | *associated_dev_array = temp; |
| 7792 | if(temp == NULL) |
| 7793 | { |
| 7794 | printf("Error Statement. Insufficient memory \n"); |
| 7795 | return RETURN_ERR; |
| 7796 | } |
| 7797 | memset(buf,0,sizeof(buf)); |
| 7798 | sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename); |
| 7799 | fp = popen(buf,"r"); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7800 | if (fp == NULL) { |
| 7801 | fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf); |
| 7802 | return RETURN_ERR; |
| 7803 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7804 | for(count = 0; count < maccount ; count++) |
| 7805 | { |
| 7806 | fgets(path,sizeof(path),fp); |
| 7807 | for(i = 0; path[i]!='\n';i++) |
| 7808 | str[i]=path[i]; |
| 7809 | str[i]='\0'; |
| 7810 | getIPAddress(str,ipaddr); |
| 7811 | memset(buf,0,sizeof(buf)); |
| 7812 | if(strlen(ipaddr) > 0) |
| 7813 | { |
| 7814 | sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr); |
| 7815 | if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info |
| 7816 | { |
| 7817 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 7818 | { |
| 7819 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 7820 | { |
| 7821 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 7822 | |
| 7823 | } |
| 7824 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 7825 | 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]); |
| 7826 | } |
| 7827 | temp[count].cli_AuthenticationState = 0; //TODO |
| 7828 | temp[count].cli_Active = 0; //TODO |
| 7829 | temp[count].cli_SignalStrength = 0; |
| 7830 | } |
| 7831 | else //Active wireless clients info |
| 7832 | { |
| 7833 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 7834 | { |
| 7835 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 7836 | { |
| 7837 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 7838 | |
| 7839 | } |
| 7840 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 7841 | 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]); |
| 7842 | } |
| 7843 | temp[count].cli_Active = 1; |
| 7844 | } |
| 7845 | } |
| 7846 | memset(ipaddr,0,sizeof(ipaddr)); |
| 7847 | } |
| 7848 | pclose(fp); |
| 7849 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7850 | return RETURN_OK; |
| 7851 | } |
| 7852 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering object |
| 7853 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o |
| 7854 | //To get Band Steering Capability |
| 7855 | INT wifi_getBandSteeringCapability(BOOL *support) |
| 7856 | { |
| 7857 | *support = FALSE; |
| 7858 | return RETURN_OK; |
| 7859 | } |
| 7860 | |
| 7861 | |
| 7862 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w |
| 7863 | //To get Band Steering enable status |
| 7864 | INT wifi_getBandSteeringEnable(BOOL *enable) |
| 7865 | { |
| 7866 | *enable = FALSE; |
| 7867 | return RETURN_OK; |
| 7868 | } |
| 7869 | |
| 7870 | //To turn on/off Band steering |
| 7871 | INT wifi_setBandSteeringEnable(BOOL enable) |
| 7872 | { |
| 7873 | return RETURN_OK; |
| 7874 | } |
| 7875 | |
| 7876 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w |
| 7877 | //To get Band Steering AP group |
| 7878 | INT wifi_getBandSteeringApGroup(char *output_ApGroup) |
| 7879 | { |
| 7880 | if (NULL == output_ApGroup) |
| 7881 | return RETURN_ERR; |
| 7882 | |
| 7883 | strcpy(output_ApGroup, "1,2"); |
| 7884 | return RETURN_OK; |
| 7885 | } |
| 7886 | |
| 7887 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w |
| 7888 | //to set and read the band steering BandUtilizationThreshold parameters |
| 7889 | INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold) |
| 7890 | { |
| 7891 | return RETURN_ERR; |
| 7892 | } |
| 7893 | |
| 7894 | INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold) |
| 7895 | { |
| 7896 | return RETURN_ERR; |
| 7897 | } |
| 7898 | |
| 7899 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w |
| 7900 | //to set and read the band steering RSSIThreshold parameters |
| 7901 | INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold) |
| 7902 | { |
| 7903 | return RETURN_ERR; |
| 7904 | } |
| 7905 | |
| 7906 | INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold) |
| 7907 | { |
| 7908 | return RETURN_ERR; |
| 7909 | } |
| 7910 | |
| 7911 | |
| 7912 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w |
| 7913 | //to set and read the band steering physical modulation rate threshold parameters |
| 7914 | INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold) |
| 7915 | { |
| 7916 | //If chip is not support, return -1 |
| 7917 | return RETURN_ERR; |
| 7918 | } |
| 7919 | |
| 7920 | INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold) |
| 7921 | { |
| 7922 | //If chip is not support, return -1 |
| 7923 | return RETURN_ERR; |
| 7924 | } |
| 7925 | |
| 7926 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w |
| 7927 | //to set and read the inactivity time (in seconds) for steering under overload condition |
| 7928 | INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold) |
| 7929 | { |
| 7930 | return RETURN_ERR; |
| 7931 | } |
| 7932 | |
| 7933 | INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold) |
| 7934 | { |
| 7935 | return RETURN_ERR; |
| 7936 | } |
| 7937 | |
| 7938 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w |
| 7939 | //to set and read the inactivity time (in seconds) for steering under Idle condition |
| 7940 | INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold) |
| 7941 | { |
| 7942 | return RETURN_ERR; |
| 7943 | } |
| 7944 | |
| 7945 | INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold) |
| 7946 | { |
| 7947 | return RETURN_ERR; |
| 7948 | } |
| 7949 | |
| 7950 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o |
| 7951 | //pClientMAC[64] |
| 7952 | //pSourceSSIDIndex[64] |
| 7953 | //pDestSSIDIndex[64] |
| 7954 | //pSteeringReason[256] |
| 7955 | INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason) |
| 7956 | { |
| 7957 | //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 |
| 7958 | *pSteeringTime=time(NULL); |
| 7959 | *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose) |
| 7960 | return RETURN_OK; |
| 7961 | } |
| 7962 | |
| 7963 | INT wifi_ifConfigDown(INT apIndex) |
| 7964 | { |
| 7965 | INT status = RETURN_OK; |
| 7966 | char cmd[64]; |
| 7967 | |
| 7968 | snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex); |
| 7969 | printf("%s: %s\n", __func__, cmd); |
| 7970 | system(cmd); |
| 7971 | |
| 7972 | return status; |
| 7973 | } |
| 7974 | |
| 7975 | INT wifi_ifConfigUp(INT apIndex) |
| 7976 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7977 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7978 | char cmd[128]; |
| 7979 | char buf[1024]; |
| 7980 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 7981 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7982 | return RETURN_ERR; |
| 7983 | snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7984 | _syscmd(cmd, buf, sizeof(buf)); |
| 7985 | return 0; |
| 7986 | } |
| 7987 | |
| 7988 | //>> Deprecated. Replace with wifi_applyRadioSettings |
| 7989 | INT wifi_pushBridgeInfo(INT apIndex) |
| 7990 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 7991 | char interface_name[16] = {0}; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 7992 | char ip[32] = {0}; |
| 7993 | char subnet[32] = {0}; |
| 7994 | char bridge[32] = {0}; |
| 7995 | int vlanId = 0; |
| 7996 | char cmd[128] = {0}; |
| 7997 | char buf[1024] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 7998 | |
| 7999 | wifi_getApBridgeInfo(apIndex,bridge,ip,subnet); |
| 8000 | wifi_getApVlanID(apIndex,&vlanId); |
| 8001 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 8002 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8003 | return RETURN_ERR; |
| 8004 | snprintf(cmd, sizeof(cmd), "cfgVlan %s %s %d %s ", interface_name, bridge, vlanId, ip); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8005 | _syscmd(cmd,buf, sizeof(buf)); |
| 8006 | |
| 8007 | return 0; |
| 8008 | } |
| 8009 | |
| 8010 | INT wifi_pushChannel(INT radioIndex, UINT channel) |
| 8011 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8012 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8013 | char cmd[128]; |
| 8014 | char buf[1024]; |
| 8015 | int apIndex; |
| 8016 | |
| 8017 | apIndex=(radioIndex==0)?0:1; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 8018 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8019 | return RETURN_ERR; |
| 8020 | snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8021 | _syscmd(cmd,buf, sizeof(buf)); |
| 8022 | |
| 8023 | return 0; |
| 8024 | } |
| 8025 | |
| 8026 | INT wifi_pushChannelMode(INT radioIndex) |
| 8027 | { |
| 8028 | //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly |
| 8029 | return RETURN_ERR; |
| 8030 | } |
| 8031 | |
| 8032 | INT wifi_pushDefaultValues(INT radioIndex) |
| 8033 | { |
| 8034 | //Apply Comcast specified default radio settings instantly |
| 8035 | //AMPDU=1 |
| 8036 | //AMPDUFrames=32 |
| 8037 | //AMPDULim=50000 |
| 8038 | //txqueuelen=1000 |
| 8039 | |
| 8040 | return RETURN_ERR; |
| 8041 | } |
| 8042 | |
| 8043 | INT wifi_pushTxChainMask(INT radioIndex) |
| 8044 | { |
| 8045 | //Apply default TxChainMask instantly |
| 8046 | return RETURN_ERR; |
| 8047 | } |
| 8048 | |
| 8049 | INT wifi_pushRxChainMask(INT radioIndex) |
| 8050 | { |
| 8051 | //Apply default RxChainMask instantly |
| 8052 | return RETURN_ERR; |
| 8053 | } |
| 8054 | |
| 8055 | INT wifi_pushSSID(INT apIndex, CHAR *ssid) |
| 8056 | { |
| 8057 | INT status; |
| 8058 | |
| 8059 | status = wifi_setSSIDName(apIndex,ssid); |
| 8060 | wifi_setApEnable(apIndex,FALSE); |
| 8061 | wifi_setApEnable(apIndex,TRUE); |
| 8062 | |
| 8063 | return status; |
| 8064 | } |
| 8065 | |
| 8066 | INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable) |
| 8067 | { |
| 8068 | //Apply default Ssid Advertisement instantly |
| 8069 | return RETURN_ERR; |
| 8070 | } |
| 8071 | |
| 8072 | INT wifi_getRadioUpTime(INT radioIndex, ULONG *output) |
| 8073 | { |
| 8074 | INT status = RETURN_ERR; |
| 8075 | *output = 0; |
| 8076 | return RETURN_ERR; |
| 8077 | } |
| 8078 | |
| 8079 | INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled) |
| 8080 | { |
| 8081 | return RETURN_OK; |
| 8082 | } |
| 8083 | |
| 8084 | INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int) |
| 8085 | { |
| 8086 | return RETURN_OK; |
| 8087 | } |
| 8088 | |
| 8089 | //To-do |
| 8090 | INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string) |
| 8091 | { |
developer | eb199ae | 2022-09-13 14:04:27 +0800 | [diff] [blame] | 8092 | char output[16]={'\0'}; |
| 8093 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8094 | |
| 8095 | if (!output_string) |
| 8096 | return RETURN_ERR; |
| 8097 | |
| 8098 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 8099 | wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output)); |
| 8100 | |
| 8101 | if (strlen(output) == 0) |
| 8102 | snprintf(output_string, 64, "Disabled"); |
| 8103 | else if (strncmp(output, "0", 1) == 0) |
| 8104 | snprintf(output_string, 64, "Disabled"); |
| 8105 | else if (strncmp(output, "1", 1) == 0) |
| 8106 | snprintf(output_string, 64, "Optional"); |
| 8107 | else if (strncmp(output, "2", 1) == 0) |
| 8108 | snprintf(output_string, 64, "Required"); |
| 8109 | else { |
| 8110 | wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output); |
| 8111 | return RETURN_ERR; |
| 8112 | } |
| 8113 | |
| 8114 | wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8115 | return RETURN_OK; |
| 8116 | } |
| 8117 | INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig) |
| 8118 | { |
developer | eb199ae | 2022-09-13 14:04:27 +0800 | [diff] [blame] | 8119 | char str[MAX_BUF_SIZE]={'\0'}; |
| 8120 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 8121 | struct params params; |
| 8122 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8123 | |
| 8124 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8125 | if(NULL == MfpConfig || strlen(MfpConfig) >= 32 ) |
| 8126 | return RETURN_ERR; |
| 8127 | |
| 8128 | params.name = "ieee80211w"; |
| 8129 | if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0) |
| 8130 | params.value = "0"; |
| 8131 | else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0) |
| 8132 | params.value = "1"; |
| 8133 | else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0) |
| 8134 | params.value = "2"; |
| 8135 | else{ |
| 8136 | wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__); |
| 8137 | return RETURN_ERR; |
| 8138 | } |
| 8139 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 8140 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 8141 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8142 | return RETURN_OK; |
| 8143 | } |
| 8144 | INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool) |
| 8145 | { |
| 8146 | char output[16]={'\0'}; |
| 8147 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8148 | |
| 8149 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8150 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
| 8151 | wifi_hostapdRead(config_file,"channel",output,sizeof(output)); |
| 8152 | |
| 8153 | *output_bool = (strncmp(output, "0", 1)==0) ? TRUE : FALSE; |
| 8154 | WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__); |
| 8155 | |
| 8156 | return RETURN_OK; |
| 8157 | } |
| 8158 | |
| 8159 | INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled) |
| 8160 | { |
| 8161 | return RETURN_OK; |
| 8162 | } |
| 8163 | |
| 8164 | INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval) |
| 8165 | { |
| 8166 | return RETURN_OK; |
| 8167 | } |
| 8168 | |
| 8169 | INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled) |
| 8170 | { |
| 8171 | return RETURN_OK; |
| 8172 | } |
| 8173 | |
| 8174 | INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output) |
| 8175 | { |
| 8176 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8177 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8178 | |
| 8179 | if (NULL == output) |
| 8180 | return RETURN_ERR; |
| 8181 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex); |
| 8182 | wifi_hostapdRead(config_file,"hw_mode",output,64); |
| 8183 | |
| 8184 | if(strcmp(output,"b")==0) |
| 8185 | sprintf(output, "%s", "1,2,5.5,11"); |
| 8186 | else if (strcmp(output,"a")==0) |
| 8187 | sprintf(output, "%s", "6,9,11,12,18,24,36,48,54"); |
| 8188 | else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) |
| 8189 | sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54"); |
| 8190 | |
| 8191 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8192 | return RETURN_OK; |
| 8193 | } |
| 8194 | |
| 8195 | INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output) |
| 8196 | { |
| 8197 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8198 | char *temp; |
| 8199 | char temp_output[128]; |
| 8200 | char temp_TransmitRates[128]; |
| 8201 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8202 | |
| 8203 | if (NULL == output) |
| 8204 | return RETURN_ERR; |
| 8205 | |
| 8206 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex); |
| 8207 | wifi_hostapdRead(config_file,"supported_rates",output,64); |
| 8208 | |
developer | 5b398df | 2022-11-17 20:39:48 +0800 | [diff] [blame] | 8209 | if (strlen(output) == 0) { |
| 8210 | wifi_getRadioSupportedDataTransmitRates(wlanIndex, output); |
| 8211 | return RETURN_OK; |
| 8212 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8213 | strcpy(temp_TransmitRates,output); |
| 8214 | strcpy(temp_output,""); |
| 8215 | temp = strtok(temp_TransmitRates," "); |
| 8216 | while(temp!=NULL) |
| 8217 | { |
| 8218 | temp[strlen(temp)-1]=0; |
| 8219 | if((temp[0]=='5') && (temp[1]=='\0')) |
| 8220 | { |
| 8221 | temp="5.5"; |
| 8222 | } |
| 8223 | strcat(temp_output,temp); |
| 8224 | temp = strtok(NULL," "); |
| 8225 | if(temp!=NULL) |
| 8226 | { |
| 8227 | strcat(temp_output,","); |
| 8228 | } |
| 8229 | } |
| 8230 | strcpy(output,temp_output); |
| 8231 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8232 | |
| 8233 | return RETURN_OK; |
| 8234 | } |
| 8235 | |
| 8236 | INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output) |
| 8237 | { |
| 8238 | return RETURN_OK; |
| 8239 | } |
| 8240 | |
| 8241 | |
| 8242 | INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output) |
| 8243 | { |
| 8244 | int i=0; |
| 8245 | char *temp; |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8246 | char temp1[128] = {0}; |
| 8247 | char temp_output[128] = {0}; |
| 8248 | char temp_TransmitRates[128] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8249 | struct params params={'\0'}; |
| 8250 | char config_file[MAX_BUF_SIZE] = {0}; |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8251 | wifi_band band = wifi_index_to_band(wlanIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8252 | |
| 8253 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8254 | if(NULL == output) |
| 8255 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8256 | strcpy(temp_TransmitRates,output); |
| 8257 | |
| 8258 | for(i=0;i<strlen(temp_TransmitRates);i++) |
| 8259 | { |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8260 | if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==',')) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8261 | { |
| 8262 | continue; |
| 8263 | } |
| 8264 | else |
| 8265 | { |
| 8266 | return RETURN_ERR; |
| 8267 | } |
| 8268 | } |
| 8269 | strcpy(temp_output,""); |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8270 | temp = strtok(temp_TransmitRates,","); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8271 | while(temp!=NULL) |
| 8272 | { |
| 8273 | strcpy(temp1,temp); |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8274 | if(band == band_5) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8275 | { |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8276 | if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0)) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8277 | { |
| 8278 | return RETURN_ERR; |
| 8279 | } |
| 8280 | } |
| 8281 | |
| 8282 | if(strcmp(temp,"5.5")==0) |
| 8283 | { |
| 8284 | strcpy(temp1,"55"); |
| 8285 | } |
| 8286 | else |
| 8287 | { |
| 8288 | strcat(temp1,"0"); |
| 8289 | } |
| 8290 | strcat(temp_output,temp1); |
developer | ef93876 | 2022-10-19 17:21:01 +0800 | [diff] [blame] | 8291 | temp = strtok(NULL,","); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8292 | if(temp!=NULL) |
| 8293 | { |
| 8294 | strcat(temp_output," "); |
| 8295 | } |
| 8296 | } |
| 8297 | strcpy(output,temp_output); |
| 8298 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8299 | params.name = "supported_rates"; |
| 8300 | params.value = output; |
| 8301 | |
| 8302 | wifi_dbg_printf("\n%s:",__func__); |
| 8303 | wifi_dbg_printf("params.value=%s\n",params.value); |
| 8304 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex); |
| 8305 | wifi_hostapdWrite(config_file,¶ms,1); |
| 8306 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8307 | |
| 8308 | return RETURN_OK; |
| 8309 | } |
| 8310 | |
| 8311 | |
| 8312 | static char *sncopy(char *dst, int dst_sz, const char *src) |
| 8313 | { |
| 8314 | if (src && dst && dst_sz > 0) { |
| 8315 | strncpy(dst, src, dst_sz); |
| 8316 | dst[dst_sz - 1] = '\0'; |
| 8317 | } |
| 8318 | return dst; |
| 8319 | } |
| 8320 | |
| 8321 | static int util_get_sec_chan_offset(int channel, const char* ht_mode) |
| 8322 | { |
| 8323 | if (0 == strcmp(ht_mode, "HT40") || |
| 8324 | 0 == strcmp(ht_mode, "HT80") || |
| 8325 | 0 == strcmp(ht_mode, "HT160")) { |
| 8326 | switch (channel) { |
| 8327 | case 1 ... 7: |
| 8328 | case 36: |
| 8329 | case 44: |
| 8330 | case 52: |
| 8331 | case 60: |
| 8332 | case 100: |
| 8333 | case 108: |
| 8334 | case 116: |
| 8335 | case 124: |
| 8336 | case 132: |
| 8337 | case 140: |
| 8338 | case 149: |
| 8339 | case 157: |
| 8340 | return 1; |
| 8341 | case 8 ... 13: |
| 8342 | case 40: |
| 8343 | case 48: |
| 8344 | case 56: |
| 8345 | case 64: |
| 8346 | case 104: |
| 8347 | case 112: |
| 8348 | case 120: |
| 8349 | case 128: |
| 8350 | case 136: |
| 8351 | case 144: |
| 8352 | case 153: |
| 8353 | case 161: |
| 8354 | return -1; |
| 8355 | default: |
| 8356 | return -EINVAL; |
| 8357 | } |
| 8358 | } |
| 8359 | |
| 8360 | return -EINVAL; |
| 8361 | } |
| 8362 | |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8363 | static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode) |
| 8364 | { |
| 8365 | int idx = channel%8; |
| 8366 | if (0 == strcmp(ht_mode, "HT40") || |
| 8367 | 0 == strcmp(ht_mode, "HT80") || |
| 8368 | 0 == strcmp(ht_mode, "HT160")) { |
| 8369 | switch (idx) { |
| 8370 | case 1: |
| 8371 | return 1; |
| 8372 | case 5: |
| 8373 | return -1; |
| 8374 | default: |
| 8375 | return -EINVAL; |
| 8376 | } |
| 8377 | } |
| 8378 | |
| 8379 | return -EINVAL; |
| 8380 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8381 | static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len) |
| 8382 | { |
| 8383 | if (NULL == hw_mode) return; |
| 8384 | |
| 8385 | if (0 == strcmp(hw_mode, "ac")) |
| 8386 | sncopy(bw_mode, bw_mode_len, "ht vht"); |
| 8387 | |
| 8388 | if (0 == strcmp(hw_mode, "n")) |
| 8389 | sncopy(bw_mode, bw_mode_len, "ht"); |
| 8390 | |
| 8391 | return; |
| 8392 | } |
| 8393 | |
| 8394 | static int util_chan_to_freq(int chan) |
| 8395 | { |
| 8396 | if (chan == 14) |
| 8397 | return 2484; |
| 8398 | else if (chan < 14) |
| 8399 | return 2407 + chan * 5; |
| 8400 | else if (chan >= 182 && chan <= 196) |
| 8401 | return 4000 + chan * 5; |
| 8402 | else |
| 8403 | return 5000 + chan * 5; |
| 8404 | return 0; |
| 8405 | } |
| 8406 | |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8407 | static int util_6G_chan_to_freq(int chan) |
| 8408 | { |
| 8409 | if (chan) |
| 8410 | return 5950 + chan * 5; |
| 8411 | else |
| 8412 | return 0; |
| 8413 | |
| 8414 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8415 | const int *util_unii_5g_chan2list(int chan, int width) |
| 8416 | { |
| 8417 | static const int lists[] = { |
| 8418 | // <width>, <chan1>, <chan2>..., 0, |
| 8419 | 20, 36, 0, |
| 8420 | 20, 40, 0, |
| 8421 | 20, 44, 0, |
| 8422 | 20, 48, 0, |
| 8423 | 20, 52, 0, |
| 8424 | 20, 56, 0, |
| 8425 | 20, 60, 0, |
| 8426 | 20, 64, 0, |
| 8427 | 20, 100, 0, |
| 8428 | 20, 104, 0, |
| 8429 | 20, 108, 0, |
| 8430 | 20, 112, 0, |
| 8431 | 20, 116, 0, |
| 8432 | 20, 120, 0, |
| 8433 | 20, 124, 0, |
| 8434 | 20, 128, 0, |
| 8435 | 20, 132, 0, |
| 8436 | 20, 136, 0, |
| 8437 | 20, 140, 0, |
| 8438 | 20, 144, 0, |
| 8439 | 20, 149, 0, |
| 8440 | 20, 153, 0, |
| 8441 | 20, 157, 0, |
| 8442 | 20, 161, 0, |
| 8443 | 20, 165, 0, |
| 8444 | 40, 36, 40, 0, |
| 8445 | 40, 44, 48, 0, |
| 8446 | 40, 52, 56, 0, |
| 8447 | 40, 60, 64, 0, |
| 8448 | 40, 100, 104, 0, |
| 8449 | 40, 108, 112, 0, |
| 8450 | 40, 116, 120, 0, |
| 8451 | 40, 124, 128, 0, |
| 8452 | 40, 132, 136, 0, |
| 8453 | 40, 140, 144, 0, |
| 8454 | 40, 149, 153, 0, |
| 8455 | 40, 157, 161, 0, |
| 8456 | 80, 36, 40, 44, 48, 0, |
| 8457 | 80, 52, 56, 60, 64, 0, |
| 8458 | 80, 100, 104, 108, 112, 0, |
| 8459 | 80, 116, 120, 124, 128, 0, |
| 8460 | 80, 132, 136, 140, 144, 0, |
| 8461 | 80, 149, 153, 157, 161, 0, |
| 8462 | 160, 36, 40, 44, 48, 52, 56, 60, 64, 0, |
| 8463 | 160, 100, 104, 108, 112, 116, 120, 124, 128, 0, |
| 8464 | -1 // final delimiter |
| 8465 | }; |
| 8466 | const int *start; |
| 8467 | const int *p; |
| 8468 | |
| 8469 | for (p = lists; *p != -1; p++) { |
| 8470 | if (*p == width) { |
| 8471 | for (start = ++p; *p != 0; p++) { |
| 8472 | if (*p == chan) |
| 8473 | return start; |
| 8474 | } |
| 8475 | } |
| 8476 | // move to the end of channel list of given width |
| 8477 | while (*p != 0) { |
| 8478 | p++; |
| 8479 | } |
| 8480 | } |
| 8481 | |
| 8482 | return NULL; |
| 8483 | } |
| 8484 | |
| 8485 | static int util_unii_5g_centerfreq(const char *ht_mode, int channel) |
| 8486 | { |
| 8487 | if (NULL == ht_mode) |
| 8488 | return 0; |
| 8489 | |
| 8490 | const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20"); |
| 8491 | const int *chans = util_unii_5g_chan2list(channel, width); |
| 8492 | int sum = 0; |
| 8493 | int cnt = 0; |
| 8494 | |
| 8495 | if (NULL == chans) |
| 8496 | return 0; |
| 8497 | |
| 8498 | while (*chans) { |
| 8499 | sum += *chans; |
| 8500 | cnt++; |
| 8501 | chans++; |
| 8502 | } |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 8503 | if (cnt == 0) |
| 8504 | return 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8505 | return sum / cnt; |
| 8506 | } |
| 8507 | |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8508 | static int util_unii_6g_centerfreq(const char *ht_mode, int channel) |
| 8509 | { |
| 8510 | if (NULL == ht_mode) |
| 8511 | return 0; |
| 8512 | |
| 8513 | int width = strtol((ht_mode + 2), NULL, 10); |
| 8514 | |
| 8515 | int idx = 0 ; |
| 8516 | int centerchan = 0; |
| 8517 | int chan_ofs = 1; |
| 8518 | |
| 8519 | if (width == 40){ |
| 8520 | idx = ((channel/4) + chan_ofs)%2; |
| 8521 | switch (idx) { |
| 8522 | case 0: |
| 8523 | centerchan = (channel - 2); |
| 8524 | break; |
| 8525 | case 1: |
| 8526 | centerchan = (channel + 2); |
| 8527 | break; |
| 8528 | default: |
| 8529 | return -EINVAL; |
| 8530 | } |
| 8531 | }else if (width == 80){ |
| 8532 | idx = ((channel/4) + chan_ofs)%4; |
| 8533 | switch (idx) { |
| 8534 | case 0: |
| 8535 | centerchan = (channel - 6); |
| 8536 | break; |
| 8537 | case 1: |
| 8538 | centerchan = (channel + 6); |
| 8539 | break; |
| 8540 | case 2: |
| 8541 | centerchan = (channel + 2); |
| 8542 | break; |
| 8543 | case 3: |
| 8544 | centerchan = (channel - 2); |
| 8545 | break; |
| 8546 | default: |
| 8547 | return -EINVAL; |
| 8548 | } |
| 8549 | }else if (width == 160){ |
| 8550 | switch (channel) { |
| 8551 | case 1 ... 29: |
| 8552 | centerchan = 15; |
| 8553 | break; |
| 8554 | case 33 ... 61: |
| 8555 | centerchan = 47; |
| 8556 | break; |
| 8557 | case 65 ... 93: |
| 8558 | centerchan = 79; |
| 8559 | break; |
| 8560 | case 97 ... 125: |
| 8561 | centerchan = 111; |
| 8562 | break; |
| 8563 | case 129 ... 157: |
| 8564 | centerchan = 143; |
| 8565 | break; |
| 8566 | case 161 ... 189: |
| 8567 | centerchan = 175; |
| 8568 | break; |
| 8569 | case 193 ... 221: |
| 8570 | centerchan = 207; |
| 8571 | break; |
| 8572 | default: |
| 8573 | return -EINVAL; |
| 8574 | } |
| 8575 | } |
| 8576 | return centerchan; |
| 8577 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8578 | static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size) |
| 8579 | { |
| 8580 | BOOL onlyG, onlyN, onlyA; |
| 8581 | CHAR tmp[64]; |
| 8582 | int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA); |
| 8583 | if (ret == RETURN_OK) { |
| 8584 | sncopy(hw_mode, hw_mode_size, tmp); |
| 8585 | } |
| 8586 | return ret; |
| 8587 | } |
| 8588 | |
| 8589 | INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count) |
| 8590 | { |
| 8591 | // Sample commands: |
| 8592 | // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht |
| 8593 | // hostapd_cli -i wifi0 chan_switch 30 2437 |
| 8594 | char cmd[MAX_CMD_SIZE] = {0}; |
| 8595 | char buf[MAX_BUF_SIZE] = {0}; |
| 8596 | int freq = 0, ret = 0; |
| 8597 | char center_freq1_str[32] = ""; // center_freq1=%d |
| 8598 | char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht |
| 8599 | char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d |
| 8600 | char hw_mode[16] = ""; // n|ac |
| 8601 | char bw_mode[16] = ""; // ht|ht vht |
| 8602 | char ht_mode[16] = ""; // HT20|HT40|HT80|HT160 |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8603 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8604 | int sec_chan_offset; |
| 8605 | int width; |
developer | 4fb0b92 | 2022-09-30 14:29:09 +0800 | [diff] [blame] | 8606 | char config_file[64] = {0}; |
| 8607 | BOOL stbcEnable = FALSE; |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8608 | char *ext_str = "None"; |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8609 | wifi_band band = band_invalid; |
| 8610 | int center_chan = 0; |
| 8611 | int center_freq1 = 0; |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8612 | |
developer | 4fb0b92 | 2022-09-30 14:29:09 +0800 | [diff] [blame] | 8613 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8614 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 8615 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8616 | return RETURN_ERR; |
| 8617 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8618 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8619 | |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8620 | band = wifi_index_to_band(radioIndex); |
| 8621 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8622 | width = channel_width_MHz > 20 ? channel_width_MHz : 20; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8623 | |
| 8624 | // Get radio mode HT20|HT40|HT80 etc. |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8625 | if (channel){ |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8626 | if (band == band_6){ |
| 8627 | freq = util_6G_chan_to_freq(channel); |
| 8628 | }else{ |
| 8629 | freq = util_chan_to_freq(channel); |
| 8630 | } |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8631 | snprintf(ht_mode, sizeof(ht_mode), "HT%d", width); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8632 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8633 | // Provide bandwith if specified |
| 8634 | if (channel_width_MHz > 20) { |
| 8635 | // Select bandwidth mode from hardware n --> ht | ac --> ht vht |
| 8636 | util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode)); |
| 8637 | util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8638 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8639 | snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode); |
| 8640 | }else if (channel_width_MHz == 20){ |
| 8641 | snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width); |
| 8642 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8643 | |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8644 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8645 | if (channel_width_MHz > 20) { |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8646 | if (band == band_6){ |
| 8647 | center_chan = util_unii_6g_centerfreq(ht_mode, channel); |
| 8648 | if(center_chan){ |
| 8649 | center_freq1 = util_6G_chan_to_freq(center_chan); |
| 8650 | } |
| 8651 | }else{ |
| 8652 | center_chan = util_unii_5g_centerfreq(ht_mode, channel); |
| 8653 | if(center_chan){ |
| 8654 | center_freq1 = util_chan_to_freq(center_chan); |
| 8655 | } |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8656 | } |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8657 | |
| 8658 | if (center_freq1) |
| 8659 | snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1); |
| 8660 | |
| 8661 | } |
| 8662 | |
| 8663 | // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160) |
| 8664 | if (band == band_6){ |
| 8665 | sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode); |
| 8666 | }else{ |
| 8667 | sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8668 | } |
developer | b7593de | 2022-10-18 09:51:57 +0800 | [diff] [blame] | 8669 | if (sec_chan_offset != -EINVAL) |
| 8670 | snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8671 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8672 | // Only the first AP, other are hanging on the same radio |
| 8673 | int apIndex = radioIndex; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8674 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s chan_switch %d %d %s %s %s", |
| 8675 | interface_name, csa_beacon_count, freq, |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8676 | sec_chan_offset_str, center_freq1_str, opt_chan_info_str); |
| 8677 | wifi_dbg_printf("execute: '%s'\n", cmd); |
| 8678 | ret = _syscmd(cmd, buf, sizeof(buf)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8679 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8680 | ret = wifi_setRadioChannel(radioIndex, channel); |
| 8681 | if (ret != RETURN_OK) { |
| 8682 | fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__); |
| 8683 | return RETURN_ERR; |
| 8684 | } |
| 8685 | |
| 8686 | if (sec_chan_offset == 1) ext_str = "Above"; |
| 8687 | else if (sec_chan_offset == -1) ext_str = "Below"; |
| 8688 | |
| 8689 | wifi_setRadioCenterChannel(radioIndex, center_chan); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8690 | |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 8691 | } else { |
| 8692 | if (channel_width_MHz > 20) |
| 8693 | ext_str = "Above"; |
| 8694 | } |
developer | 4fb0b92 | 2022-09-30 14:29:09 +0800 | [diff] [blame] | 8695 | snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file); |
| 8696 | _syscmd(cmd, buf, sizeof(buf)); |
| 8697 | if (strlen(buf) != 0) |
| 8698 | stbcEnable = TRUE; |
| 8699 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8700 | wifi_setRadioExtChannel(radioIndex, ext_str); |
| 8701 | |
developer | 4fb0b92 | 2022-09-30 14:29:09 +0800 | [diff] [blame] | 8702 | wifi_setRadioSTBCEnable(radioIndex, stbcEnable); |
| 8703 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8704 | char mhz_str[16]; |
| 8705 | snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width); |
| 8706 | wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str); |
| 8707 | |
| 8708 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8709 | |
| 8710 | return RETURN_OK; |
| 8711 | } |
| 8712 | |
| 8713 | INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) |
| 8714 | { |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8715 | int index = -1; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8716 | wifi_neighbor_ap2_t *scan_array = NULL; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8717 | char cmd[256]={0}; |
| 8718 | char buf[128]={0}; |
| 8719 | char file_name[32] = {0}; |
| 8720 | char filter_SSID[32] = {0}; |
| 8721 | char line[256] = {0}; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8722 | char interface_name[16] = {0}; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8723 | char *ret = NULL; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8724 | int freq=0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8725 | FILE *f = NULL; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8726 | size_t len=0; |
| 8727 | int channels_num = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8728 | int vht_channel_width = 0; |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 8729 | int get_noise_ret = RETURN_ERR; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8730 | bool filter_enable = false; |
| 8731 | bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd. |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 8732 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8733 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8734 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8735 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8736 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index); |
| 8737 | f = fopen(file_name, "r"); |
| 8738 | if (f != NULL) { |
| 8739 | fgets(filter_SSID, sizeof(file_name), f); |
| 8740 | if (strlen(filter_SSID) != 0) |
| 8741 | filter_enable = true; |
| 8742 | fclose(f); |
| 8743 | } |
| 8744 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 8745 | if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8746 | return RETURN_ERR; |
| 8747 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 8748 | phyId = radio_index_to_phy(radio_index); |
| 8749 | |
| 8750 | snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8751 | _syscmd(cmd, buf, sizeof(buf)); |
| 8752 | channels_num = strtol(buf, NULL, 10); |
| 8753 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8754 | sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \ |
| 8755 | // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8756 | fprintf(stderr, "cmd: %s\n", cmd); |
| 8757 | if ((f = popen(cmd, "r")) == NULL) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8758 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 8759 | return RETURN_ERR; |
| 8760 | } |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 8761 | |
| 8762 | struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise)); |
| 8763 | get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num); |
| 8764 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8765 | ret = fgets(line, sizeof(line), f); |
| 8766 | while (ret != NULL) { |
| 8767 | if(strstr(line, "BSS") != NULL) { // new neighbor info |
| 8768 | // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag. |
| 8769 | // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop. |
| 8770 | // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS. |
| 8771 | |
| 8772 | if (!filter_BSS) { |
| 8773 | index++; |
| 8774 | wifi_neighbor_ap2_t *tmp; |
| 8775 | tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1)); |
| 8776 | if (tmp == NULL) { // no more memory to use |
| 8777 | index--; |
| 8778 | wifi_dbg_printf("%s: realloc failed\n", __func__); |
| 8779 | break; |
| 8780 | } |
| 8781 | scan_array = tmp; |
| 8782 | } |
| 8783 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8784 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8785 | filter_BSS = false; |
| 8786 | sscanf(line, "BSS %17s", scan_array[index].ap_BSSID); |
| 8787 | strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure")); |
| 8788 | strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None")); |
| 8789 | strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None")); |
| 8790 | } else if (strstr(line, "freq") != NULL) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8791 | sscanf(line," freq: %d", &freq); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8792 | scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8793 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8794 | if (freq >= 2412 && freq <= 2484) { |
| 8795 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")); |
| 8796 | strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g")); |
| 8797 | strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g")); |
| 8798 | } |
| 8799 | else if (freq >= 5160 && freq <= 5805) { |
| 8800 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")); |
| 8801 | strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a")); |
| 8802 | strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a")); |
| 8803 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8804 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8805 | scan_array[index].ap_Noise = 0; |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 8806 | if (get_noise_ret == RETURN_OK) { |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8807 | for (int i = 0; i < channels_num; i++) { |
| 8808 | if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) { |
| 8809 | scan_array[index].ap_Noise = channels_noise_arr[i].noise; |
| 8810 | break; |
| 8811 | } |
| 8812 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8813 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8814 | } else if (strstr(line, "beacon interval") != NULL) { |
| 8815 | sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)); |
| 8816 | } else if (strstr(line, "signal") != NULL) { |
| 8817 | sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)); |
| 8818 | } else if (strstr(line,"SSID") != NULL) { |
| 8819 | sscanf(line," SSID: %s", scan_array[index].ap_SSID); |
| 8820 | if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) { |
| 8821 | filter_BSS = true; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8822 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8823 | } else if (strstr(line, "Supported rates") != NULL) { |
| 8824 | char SRate[80] = {0}, *tmp = NULL; |
| 8825 | memset(buf, 0, sizeof(buf)); |
| 8826 | strcpy(SRate, line); |
| 8827 | tmp = strtok(SRate, ":"); |
| 8828 | tmp = strtok(NULL, ":"); |
| 8829 | strcpy(buf, tmp); |
| 8830 | memset(SRate, 0, sizeof(SRate)); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8831 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8832 | tmp = strtok(buf, " \n"); |
| 8833 | while (tmp != NULL) { |
| 8834 | strcat(SRate, tmp); |
| 8835 | if (SRate[strlen(SRate) - 1] == '*') { |
| 8836 | SRate[strlen(SRate) - 1] = '\0'; |
| 8837 | } |
| 8838 | strcat(SRate, ","); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8839 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8840 | tmp = strtok(NULL, " \n"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8841 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8842 | SRate[strlen(SRate) - 1] = '\0'; |
| 8843 | strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate); |
| 8844 | } else if (strstr(line, "DTIM") != NULL) { |
| 8845 | sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf); |
| 8846 | } else if (strstr(line, "VHT capabilities") != NULL) { |
| 8847 | strcat(scan_array[index].ap_SupportedStandards, ",ac"); |
| 8848 | strcpy(scan_array[index].ap_OperatingStandards, "ac"); |
| 8849 | } else if (strstr(line, "HT capabilities") != NULL) { |
| 8850 | strcat(scan_array[index].ap_SupportedStandards, ",n"); |
| 8851 | strcpy(scan_array[index].ap_OperatingStandards, "n"); |
| 8852 | } else if (strstr(line, "VHT operation") != NULL) { |
| 8853 | ret = fgets(line, sizeof(line), f); |
| 8854 | sscanf(line," * channel width: %d", &vht_channel_width); |
| 8855 | if(vht_channel_width == 1) { |
| 8856 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80"); |
| 8857 | } else { |
| 8858 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40"); |
| 8859 | } |
| 8860 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 8861 | continue; |
| 8862 | } else if (strstr(line, "HT operation") != NULL) { |
| 8863 | ret = fgets(line, sizeof(line), f); |
| 8864 | sscanf(line," * secondary channel offset: %s", &buf); |
| 8865 | if (!strcmp(buf, "above")) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8866 | //40Mhz + |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8867 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8868 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8869 | else if (!strcmp(buf, "below")) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8870 | //40Mhz - |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8871 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G"); |
| 8872 | } else { |
| 8873 | //20Mhz |
| 8874 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8875 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8876 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8877 | continue; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8878 | } else if (strstr(line, "HE capabilities") != NULL) { |
| 8879 | strcat(scan_array[index].ap_SupportedStandards, ",ax"); |
| 8880 | strcpy(scan_array[index].ap_OperatingStandards, "ax"); |
| 8881 | ret = fgets(line, sizeof(line), f); |
| 8882 | if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) { |
| 8883 | if (strstr(line, "HE40/2.4GHz") != NULL) |
| 8884 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS"); |
| 8885 | else |
| 8886 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20"); |
| 8887 | } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) { |
| 8888 | if (strstr(line, "HE80/5GHz") != NULL) { |
| 8889 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80"); |
| 8890 | ret = fgets(line, sizeof(line), f); |
| 8891 | } else |
| 8892 | continue; |
| 8893 | if (strstr(line, "HE160/5GHz") != NULL) |
| 8894 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8895 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8896 | continue; |
| 8897 | } else if (strstr(line, "WPA") != NULL) { |
| 8898 | strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA"); |
| 8899 | } else if (strstr(line, "RSN") != NULL) { |
| 8900 | strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN"); |
| 8901 | } else if (strstr(line, "Group cipher") != NULL) { |
| 8902 | sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode); |
| 8903 | if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) { |
| 8904 | strcpy(scan_array[index].ap_EncryptionMode, "AES"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8905 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8906 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8907 | ret = fgets(line, sizeof(line), f); |
| 8908 | } |
| 8909 | |
| 8910 | if (!filter_BSS) { |
| 8911 | *output_array_size = index + 1; |
| 8912 | } else { |
| 8913 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 8914 | *output_array_size = index; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8915 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8916 | *neighbor_ap_array = scan_array; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8917 | pclose(f); |
developer | 5550e24 | 2022-09-30 09:59:32 +0800 | [diff] [blame] | 8918 | free(channels_noise_arr); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8919 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8920 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8921 | } |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 8922 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8923 | INT wifi_getApAssociatedDeviceStats( |
| 8924 | INT apIndex, |
| 8925 | mac_address_t *clientMacAddress, |
| 8926 | wifi_associated_dev_stats_t *associated_dev_stats, |
| 8927 | u64 *handle) |
| 8928 | { |
| 8929 | wifi_associated_dev_stats_t *dev_stats = associated_dev_stats; |
| 8930 | char interface_name[50] = {0}; |
| 8931 | char cmd[1024] = {0}; |
| 8932 | char mac_str[18] = {0}; |
| 8933 | char *key = NULL; |
| 8934 | char *val = NULL; |
| 8935 | FILE *f = NULL; |
| 8936 | char *line = NULL; |
| 8937 | size_t len = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8938 | |
| 8939 | if(wifi_getApName(apIndex, interface_name) != RETURN_OK) { |
| 8940 | wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__); |
| 8941 | return RETURN_ERR; |
| 8942 | } |
| 8943 | |
| 8944 | sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]); |
| 8945 | sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str); |
| 8946 | if((f = popen(cmd, "r")) == NULL) { |
| 8947 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 8948 | return RETURN_ERR; |
| 8949 | } |
| 8950 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 8951 | while ((getline(&line, &len, f)) != -1) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8952 | key = strtok(line,":"); |
| 8953 | val = strtok(NULL,":"); |
| 8954 | |
| 8955 | if(!strncmp(key,"rx bytes",8)) |
| 8956 | sscanf(val, "%llu", &dev_stats->cli_rx_bytes); |
| 8957 | if(!strncmp(key,"tx bytes",8)) |
| 8958 | sscanf(val, "%llu", &dev_stats->cli_tx_bytes); |
| 8959 | if(!strncmp(key,"rx packets",10)) |
| 8960 | sscanf(val, "%llu", &dev_stats->cli_tx_frames); |
| 8961 | if(!strncmp(key,"tx packets",10)) |
| 8962 | sscanf(val, "%llu", &dev_stats->cli_tx_frames); |
| 8963 | if(!strncmp(key,"tx retries",10)) |
| 8964 | sscanf(val, "%llu", &dev_stats->cli_tx_retries); |
| 8965 | if(!strncmp(key,"tx failed",9)) |
| 8966 | sscanf(val, "%llu", &dev_stats->cli_tx_errors); |
| 8967 | if(!strncmp(key,"rx drop misc",13)) |
| 8968 | sscanf(val, "%llu", &dev_stats->cli_rx_errors); |
| 8969 | if(!strncmp(key,"rx bitrate",10)) { |
| 8970 | val = strtok(val, " "); |
| 8971 | sscanf(val, "%lf", &dev_stats->cli_rx_rate); |
| 8972 | } |
| 8973 | if(!strncmp(key,"tx bitrate",10)) { |
| 8974 | val = strtok(val, " "); |
| 8975 | sscanf(val, "%lf", &dev_stats->cli_tx_rate); |
| 8976 | } |
| 8977 | } |
| 8978 | free(line); |
| 8979 | pclose(f); |
| 8980 | return RETURN_OK; |
| 8981 | } |
| 8982 | |
| 8983 | INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string) |
| 8984 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8985 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8986 | char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0}; |
| 8987 | |
| 8988 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8989 | if (NULL == output_string) |
| 8990 | return RETURN_ERR; |
| 8991 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 8992 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 8993 | return RETURN_ERR; |
| 8994 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\n'", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 8995 | _syscmd(cmd, buf, sizeof(buf)); |
| 8996 | |
| 8997 | //size of SSID name restricted to value less than 32 bytes |
| 8998 | snprintf(output_string, 32, "%s", buf); |
| 8999 | WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__); |
| 9000 | |
| 9001 | return RETURN_OK; |
| 9002 | } |
| 9003 | |
| 9004 | INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode) |
| 9005 | { |
| 9006 | //char cmd[MAX_CMD_SIZE] = {0}; |
| 9007 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9008 | char buf[32] = {0}; |
| 9009 | |
| 9010 | if (!output_filterMode) |
| 9011 | return RETURN_ERR; |
| 9012 | |
| 9013 | //snprintf(cmd, sizeof(cmd), "syscfg get %dblockall", apIndex); |
| 9014 | //_syscmd(cmd, buf, sizeof(buf)); |
| 9015 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9016 | wifi_hostapdRead(config_file, "macaddr_acl", buf, sizeof(buf)); |
developer | 10adcc1 | 2022-09-13 14:39:17 +0800 | [diff] [blame] | 9017 | if(strlen(buf) == 0) { |
| 9018 | *output_filterMode = 0; |
| 9019 | } |
| 9020 | else { |
| 9021 | int macaddr_acl_mode = strtol(buf, NULL, 10); |
| 9022 | if (macaddr_acl_mode == 1) { |
| 9023 | *output_filterMode = 1; |
| 9024 | } else if (macaddr_acl_mode == 0) { |
| 9025 | wifi_hostapdRead(config_file, "deny_mac_file", buf, sizeof(buf)); |
| 9026 | if (strlen(buf) == 0) { |
| 9027 | *output_filterMode = 0; |
| 9028 | } else { |
| 9029 | *output_filterMode = 2; |
| 9030 | } |
| 9031 | } else { |
| 9032 | return RETURN_ERR; |
| 9033 | } |
| 9034 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9035 | |
| 9036 | return RETURN_OK; |
| 9037 | } |
| 9038 | |
| 9039 | INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size) |
| 9040 | { |
| 9041 | FILE *fp = NULL; |
| 9042 | char str[MAX_BUF_SIZE] = {0}; |
| 9043 | int wificlientindex = 0 ; |
| 9044 | int count = 0; |
| 9045 | int signalstrength = 0; |
| 9046 | int arr[MACADDRESS_SIZE] = {0}; |
| 9047 | unsigned char mac[MACADDRESS_SIZE] = {0}; |
| 9048 | UINT wifi_count = 0; |
| 9049 | char virtual_interface_name[MAX_BUF_SIZE] = {0}; |
| 9050 | char pipeCmd[MAX_CMD_SIZE] = {0}; |
| 9051 | |
| 9052 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9053 | *output_array_size = 0; |
| 9054 | *associated_dev_array = NULL; |
| 9055 | char interface_name[50] = {0}; |
| 9056 | |
| 9057 | if(wifi_getApName(apIndex, interface_name) != RETURN_OK) { |
| 9058 | wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__); |
| 9059 | return RETURN_ERR; |
| 9060 | } |
| 9061 | |
| 9062 | sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name); |
| 9063 | fp = popen(pipeCmd, "r"); |
| 9064 | if (fp == NULL) |
| 9065 | { |
| 9066 | printf("Failed to run command inside function %s\n",__FUNCTION__ ); |
| 9067 | return RETURN_ERR; |
| 9068 | } |
| 9069 | |
| 9070 | /* Read the output a line at a time - output it. */ |
| 9071 | fgets(str, sizeof(str)-1, fp); |
| 9072 | wifi_count = (unsigned int) atoi ( str ); |
| 9073 | *output_array_size = wifi_count; |
| 9074 | wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex); |
| 9075 | pclose(fp); |
| 9076 | |
| 9077 | if(wifi_count == 0) |
| 9078 | { |
| 9079 | return RETURN_OK; |
| 9080 | } |
| 9081 | else |
| 9082 | { |
| 9083 | wifi_associated_dev2_t* temp = NULL; |
| 9084 | temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t)); |
| 9085 | *associated_dev_array = temp; |
| 9086 | if(temp == NULL) |
| 9087 | { |
| 9088 | printf("Error Statement. Insufficient memory \n"); |
| 9089 | return RETURN_ERR; |
| 9090 | } |
| 9091 | |
| 9092 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name); |
| 9093 | system(pipeCmd); |
| 9094 | |
| 9095 | fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r"); |
| 9096 | if(fp == NULL) |
| 9097 | { |
| 9098 | printf("/tmp/AssociatedDevice_Stats.txt not exists \n"); |
| 9099 | return RETURN_ERR; |
| 9100 | } |
| 9101 | fclose(fp); |
| 9102 | |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 9103 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9104 | fp = popen(pipeCmd, "r"); |
| 9105 | if(fp) |
| 9106 | { |
| 9107 | for(count =0 ; count < wifi_count; count++) |
| 9108 | { |
| 9109 | fgets(str, MAX_BUF_SIZE, fp); |
| 9110 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 9111 | { |
| 9112 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 9113 | { |
| 9114 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 9115 | |
| 9116 | } |
| 9117 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 9118 | 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]); |
| 9119 | } |
| 9120 | temp[count].cli_AuthenticationState = 1; //TODO |
| 9121 | temp[count].cli_Active = 1; //TODO |
| 9122 | } |
| 9123 | pclose(fp); |
| 9124 | } |
| 9125 | |
| 9126 | //Updating RSSI per client |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 9127 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9128 | fp = popen(pipeCmd, "r"); |
| 9129 | if(fp) |
| 9130 | { |
| 9131 | pclose(fp); |
| 9132 | } |
| 9133 | fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r"); |
| 9134 | if(fp) |
| 9135 | { |
| 9136 | for(count =0 ; count < wifi_count ;count++) |
| 9137 | { |
| 9138 | fgets(str, MAX_BUF_SIZE, fp); |
| 9139 | signalstrength = atoi(str); |
| 9140 | temp[count].cli_RSSI = signalstrength; |
| 9141 | } |
| 9142 | pclose(fp); |
| 9143 | } |
| 9144 | |
| 9145 | |
| 9146 | //LastDataDownlinkRate |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 9147 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9148 | fp = popen(pipeCmd, "r"); |
| 9149 | if (fp) |
| 9150 | { |
| 9151 | pclose(fp); |
| 9152 | } |
| 9153 | fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r"); |
| 9154 | if (fp) |
| 9155 | { |
| 9156 | for (count = 0; count < wifi_count; count++) |
| 9157 | { |
| 9158 | fgets(str, MAX_BUF_SIZE, fp); |
| 9159 | temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10); |
| 9160 | temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps |
| 9161 | } |
| 9162 | pclose(fp); |
| 9163 | } |
| 9164 | |
| 9165 | //LastDataUplinkRate |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 9166 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9167 | fp = popen(pipeCmd, "r"); |
| 9168 | if (fp) |
| 9169 | { |
| 9170 | pclose(fp); |
| 9171 | } |
| 9172 | fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 9173 | if (fp) |
| 9174 | { |
| 9175 | for (count = 0; count < wifi_count; count++) |
| 9176 | { |
| 9177 | fgets(str, MAX_BUF_SIZE, fp); |
| 9178 | temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10); |
| 9179 | temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps |
| 9180 | } |
| 9181 | pclose(fp); |
| 9182 | } |
| 9183 | } |
| 9184 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9185 | return RETURN_OK; |
| 9186 | |
| 9187 | } |
| 9188 | |
| 9189 | INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct) |
| 9190 | { |
| 9191 | #if 0 |
| 9192 | /*char buf[1024] = {0}; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9193 | sprintf(cmd, "ifconfig %s ", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9194 | _syscmd(cmd, buf, sizeof(buf));*/ |
| 9195 | |
| 9196 | output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters. |
| 9197 | output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters. |
| 9198 | output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface. |
| 9199 | output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface. |
| 9200 | |
| 9201 | 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. |
| 9202 | 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]. |
| 9203 | 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]. |
| 9204 | 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]. |
| 9205 | output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012]. |
| 9206 | output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac. |
| 9207 | |
| 9208 | output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors. |
| 9209 | output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol. |
| 9210 | output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol. |
| 9211 | 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. |
| 9212 | 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. |
| 9213 | 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. |
| 9214 | 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. |
| 9215 | 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. |
| 9216 | 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. |
| 9217 | 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. |
| 9218 | output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol. |
| 9219 | #endif |
| 9220 | |
| 9221 | FILE *fp = NULL; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9222 | char interface_name[50] = {0}; |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9223 | char pipeCmd[128] = {0}; |
| 9224 | char str[256] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9225 | wifi_ssidTrafficStats2_t *out = output_struct; |
| 9226 | |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9227 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9228 | if (!output_struct) |
| 9229 | return RETURN_ERR; |
| 9230 | |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9231 | memset(out, 0, sizeof(wifi_ssidTrafficStats2_t)); |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 9232 | if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK) |
developer | dbbd678 | 2022-12-16 14:26:20 +0800 | [diff] [blame] | 9233 | return RETURN_ERR; |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9234 | sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9235 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9236 | fp = popen(pipeCmd, "r"); |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9237 | if (fp == NULL) { |
| 9238 | fprintf(stderr, "%s: popen failed\n", __func__); |
| 9239 | return RETURN_ERR; |
| 9240 | } |
| 9241 | fgets(str, sizeof(str), fp); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9242 | pclose(fp); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9243 | |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9244 | if (strlen(str) == 0) // interface not exist |
| 9245 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9246 | |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9247 | sscanf(str, "%*[^:]: %lu %lu %lu %lu %* %* %* %* %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \ |
| 9248 | &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9249 | |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9250 | memset(str, 0, sizeof(str)); |
| 9251 | sprintf(pipeCmd, "tail -n1 /proc/net/netstat"); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9252 | fp = popen(pipeCmd, "r"); |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9253 | if (fp == NULL) { |
| 9254 | fprintf(stderr, "%s: popen failed\n", __func__); |
| 9255 | return RETURN_ERR; |
| 9256 | } |
| 9257 | fgets(str, sizeof(str), fp); |
| 9258 | |
| 9259 | sscanf(str, "%*[^:]: %* %* %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \ |
| 9260 | &out->ssid_BroadcastPacketsSent); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9261 | pclose(fp); |
developer | ce73639 | 2022-09-13 15:24:34 +0800 | [diff] [blame] | 9262 | |
| 9263 | out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent; |
| 9264 | out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived; |
| 9265 | |
| 9266 | // Not supported |
| 9267 | output_struct->ssid_RetransCount = 0; |
| 9268 | output_struct->ssid_FailedRetransCount = 0; |
| 9269 | output_struct->ssid_RetryCount = 0; |
| 9270 | output_struct->ssid_MultipleRetryCount = 0; |
| 9271 | output_struct->ssid_ACKFailureCount = 0; |
| 9272 | output_struct->ssid_AggregatedPacketCount = 0; |
| 9273 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9274 | return RETURN_OK; |
| 9275 | } |
| 9276 | |
| 9277 | //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). |
| 9278 | INT wifi_getApIsolationEnable(INT apIndex, BOOL *output) |
| 9279 | { |
| 9280 | char output_val[16]={'\0'}; |
| 9281 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9282 | |
| 9283 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9284 | if (!output) |
| 9285 | return RETURN_ERR; |
| 9286 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 9287 | wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val)); |
| 9288 | |
| 9289 | if( strcmp(output_val,"1") == 0 ) |
| 9290 | *output = TRUE; |
| 9291 | else |
| 9292 | *output = FALSE; |
| 9293 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9294 | |
| 9295 | return RETURN_OK; |
| 9296 | } |
| 9297 | |
| 9298 | INT wifi_setApIsolationEnable(INT apIndex, BOOL enable) |
| 9299 | { |
| 9300 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9301 | char str[MAX_BUF_SIZE]={'\0'}; |
| 9302 | char string[MAX_BUF_SIZE]={'\0'}; |
| 9303 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 9304 | char *ch; |
| 9305 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9306 | struct params params; |
| 9307 | |
| 9308 | if(enable == TRUE) |
| 9309 | strcpy(string,"1"); |
| 9310 | else |
| 9311 | strcpy(string,"0"); |
| 9312 | |
| 9313 | params.name = "ap_isolate"; |
| 9314 | params.value = string; |
| 9315 | |
| 9316 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 9317 | wifi_hostapdWrite(config_file,¶ms,1); |
| 9318 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9319 | |
| 9320 | return RETURN_OK; |
| 9321 | } |
| 9322 | |
| 9323 | INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm) |
| 9324 | { |
| 9325 | if (NULL == output_dBm) |
| 9326 | return RETURN_ERR; |
| 9327 | |
| 9328 | *output_dBm = 0; |
| 9329 | return RETURN_OK; |
| 9330 | } |
| 9331 | |
| 9332 | INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm) |
| 9333 | { |
| 9334 | return RETURN_OK; |
| 9335 | } |
| 9336 | INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size) |
| 9337 | { |
| 9338 | return RETURN_OK; |
| 9339 | } |
| 9340 | INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms) |
| 9341 | { |
| 9342 | return RETURN_OK; |
| 9343 | } |
| 9344 | INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms) |
| 9345 | { |
| 9346 | return RETURN_OK; |
| 9347 | } |
| 9348 | INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable) |
| 9349 | { |
| 9350 | return RETURN_OK; |
| 9351 | } |
| 9352 | INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate) |
| 9353 | { |
| 9354 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9355 | struct params list; |
| 9356 | |
| 9357 | list.name = "bss_transition"; |
| 9358 | list.value = activate?"1":"0"; |
| 9359 | snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex); |
| 9360 | wifi_hostapdWrite(config_file, &list, 1); |
| 9361 | |
| 9362 | return RETURN_OK; |
| 9363 | } |
| 9364 | wifi_apAuthEvent_callback apAuthEvent_cb = NULL; |
| 9365 | |
| 9366 | void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc) |
| 9367 | { |
| 9368 | return; |
| 9369 | } |
| 9370 | |
| 9371 | INT wifi_setApCsaDeauth(INT apIndex, INT mode) |
| 9372 | { |
| 9373 | // TODO Implement me! |
| 9374 | return RETURN_OK; |
| 9375 | } |
| 9376 | |
| 9377 | INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid) |
| 9378 | { |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 9379 | char file_name[128] = {0}; |
| 9380 | char buf[128] = {0}; |
| 9381 | FILE *f = NULL; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 9382 | int max_num_radios = 0; |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 9383 | |
| 9384 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9385 | |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 9386 | wifi_getMaxRadioNumber(&max_num_radios); |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 9387 | if (essid == NULL || strlen(essid) == 0 || apIndex == -1) { |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 9388 | for (int index = 0; index < max_num_radios; index++) { |
developer | a3c68b9 | 2022-09-13 15:27:29 +0800 | [diff] [blame] | 9389 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index); |
| 9390 | f = fopen(file_name, "w"); |
| 9391 | if (f == NULL) |
| 9392 | return RETURN_ERR; |
| 9393 | // For mode == 0 is to disable filter, just don't write to the file. |
| 9394 | if (mode) |
| 9395 | fprintf(f, "%s", essid); |
| 9396 | |
| 9397 | fclose(f); |
| 9398 | } |
| 9399 | } else { // special case, need to set AP's SSID as filter for each radio. |
| 9400 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex); |
| 9401 | f = fopen(file_name, "w"); |
| 9402 | if (f == NULL) |
| 9403 | return RETURN_ERR; |
| 9404 | |
| 9405 | // For mode == 0 is to disable filter, just don't write to the file. |
| 9406 | if (mode) |
| 9407 | fprintf(f, "%s", essid); |
| 9408 | |
| 9409 | fclose(f); |
| 9410 | } |
| 9411 | |
| 9412 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9413 | return RETURN_OK; |
| 9414 | } |
| 9415 | |
| 9416 | INT wifi_pushRadioChannel(INT radioIndex, UINT channel) |
| 9417 | { |
| 9418 | // TODO Implement me! |
| 9419 | //Apply wifi_pushRadioChannel() instantly |
| 9420 | return RETURN_ERR; |
| 9421 | } |
| 9422 | |
| 9423 | INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable) |
| 9424 | { |
| 9425 | // TODO Implement me! |
| 9426 | return RETURN_OK; |
| 9427 | } |
| 9428 | |
| 9429 | #ifdef HAL_NETLINK_IMPL |
| 9430 | static int tidStats_callback(struct nl_msg *msg, void *arg) { |
| 9431 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 9432 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 9433 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 9434 | struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr; |
| 9435 | int rem , tid_index = 0; |
| 9436 | |
| 9437 | wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg; |
| 9438 | wifi_associated_dev_tid_entry_t *stats_entry; |
| 9439 | |
| 9440 | static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { |
| 9441 | [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }, |
| 9442 | }; |
| 9443 | static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = { |
| 9444 | [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 }, |
| 9445 | }; |
| 9446 | |
| 9447 | nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 9448 | genlmsg_attrlen(gnlh, 0), NULL); |
| 9449 | |
| 9450 | |
| 9451 | if (!tb[NL80211_ATTR_STA_INFO]) { |
| 9452 | fprintf(stderr, "station stats missing!\n"); |
| 9453 | return NL_SKIP; |
| 9454 | } |
| 9455 | |
| 9456 | if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, |
| 9457 | tb[NL80211_ATTR_STA_INFO], |
| 9458 | stats_policy)) { |
| 9459 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 9460 | return NL_SKIP; |
| 9461 | } |
| 9462 | |
| 9463 | nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem) |
| 9464 | { |
| 9465 | stats_entry = &out->tid_array[tid_index]; |
| 9466 | |
| 9467 | stats_entry->tid = tid_index; |
| 9468 | stats_entry->ac = _tid_ac_index_get[tid_index]; |
| 9469 | |
| 9470 | if(sinfo[NL80211_STA_INFO_TID_STATS]) |
| 9471 | { |
| 9472 | if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) { |
| 9473 | printf("failed to parse nested stats attributes!"); |
| 9474 | return NL_SKIP; |
| 9475 | } |
| 9476 | } |
| 9477 | if(stats_info[NL80211_TID_STATS_TX_MSDU]) |
| 9478 | stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]); |
| 9479 | |
| 9480 | if(tid_index < (PS_MAX_TID - 1)) |
| 9481 | tid_index++; |
| 9482 | } |
| 9483 | //ToDo: sum_time_ms, ewma_time_ms |
| 9484 | return NL_SKIP; |
| 9485 | } |
| 9486 | #endif |
| 9487 | |
| 9488 | INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle) |
| 9489 | { |
| 9490 | #ifdef HAL_NETLINK_IMPL |
| 9491 | Netlink nl; |
| 9492 | char if_name[10]; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9493 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9494 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 9495 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9496 | return RETURN_ERR; |
| 9497 | |
| 9498 | snprintf(if_name, sizeof(if_name), "%s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9499 | |
| 9500 | nl.id = initSock80211(&nl); |
| 9501 | |
| 9502 | if (nl.id < 0) { |
| 9503 | fprintf(stderr, "Error initializing netlink \n"); |
| 9504 | return -1; |
| 9505 | } |
| 9506 | |
| 9507 | struct nl_msg* msg = nlmsg_alloc(); |
| 9508 | |
| 9509 | if (!msg) { |
| 9510 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 9511 | nlfree(&nl); |
| 9512 | return -2; |
| 9513 | } |
| 9514 | |
| 9515 | genlmsg_put(msg, |
| 9516 | NL_AUTO_PORT, |
| 9517 | NL_AUTO_SEQ, |
| 9518 | nl.id, |
| 9519 | 0, |
| 9520 | 0, |
| 9521 | NL80211_CMD_GET_STATION, |
| 9522 | 0); |
| 9523 | |
| 9524 | nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress); |
| 9525 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 9526 | nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats); |
| 9527 | nl_send_auto(nl.socket, msg); |
| 9528 | nl_recvmsgs(nl.socket, nl.cb); |
| 9529 | nlmsg_free(msg); |
| 9530 | nlfree(&nl); |
| 9531 | return RETURN_OK; |
| 9532 | #else |
| 9533 | //iw implementation |
| 9534 | #define TID_STATS_FILE "/tmp/tid_stats_file.txt" |
| 9535 | #define TOTAL_MAX_LINES 50 |
| 9536 | |
| 9537 | char buf[256] = {'\0'}; /* or other suitable maximum line size */ |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9538 | char if_name[32] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9539 | FILE *fp=NULL; |
| 9540 | char pipeCmd[1024]= {'\0'}; |
| 9541 | int lines,tid_index=0; |
| 9542 | char mac_addr[20] = {'\0'}; |
| 9543 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 9544 | if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9545 | return RETURN_ERR; |
| 9546 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9547 | wifi_associated_dev_tid_entry_t *stats_entry; |
| 9548 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9549 | strcpy(mac_addr,clientMacAddress); |
| 9550 | |
| 9551 | snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name); |
| 9552 | fp= popen(pipeCmd,"r"); |
| 9553 | if(fp == NULL) |
| 9554 | { |
| 9555 | perror("popen for station dump failed\n"); |
| 9556 | return RETURN_ERR; |
| 9557 | } |
| 9558 | pclose(fp); |
| 9559 | |
| 9560 | snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1"); |
| 9561 | fp=popen(pipeCmd,"r"); |
| 9562 | if(fp == NULL) |
| 9563 | { |
| 9564 | perror("popen for grep station failed\n"); |
| 9565 | return RETURN_ERR; |
| 9566 | } |
| 9567 | else if(fgets(buf,sizeof(buf),fp) != NULL) |
| 9568 | lines=atoi(buf); |
| 9569 | else |
| 9570 | { |
| 9571 | pclose(fp); |
| 9572 | fprintf(stderr,"No devices are connected \n"); |
| 9573 | return RETURN_ERR; |
| 9574 | } |
| 9575 | pclose(fp); |
| 9576 | |
| 9577 | if(lines == 1) |
| 9578 | lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output |
| 9579 | |
| 9580 | for(tid_index=0; tid_index<PS_MAX_TID; tid_index++) |
| 9581 | { |
| 9582 | stats_entry = &tid_stats->tid_array[tid_index]; |
| 9583 | stats_entry->tid = tid_index; |
| 9584 | |
| 9585 | 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); |
| 9586 | |
| 9587 | fp=popen(pipeCmd,"r"); |
| 9588 | if(fp ==NULL) |
| 9589 | { |
| 9590 | perror("Failed to read from tid file \n"); |
| 9591 | return RETURN_ERR; |
| 9592 | } |
| 9593 | else if(fgets(buf,sizeof(buf),fp) != NULL) |
| 9594 | stats_entry->num_msdus = atol(buf); |
| 9595 | |
| 9596 | pclose(fp); |
| 9597 | stats_entry->ac = _tid_ac_index_get[tid_index]; |
| 9598 | // TODO: |
| 9599 | // ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus |
| 9600 | // ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval |
| 9601 | } |
| 9602 | return RETURN_OK; |
| 9603 | #endif |
| 9604 | } |
| 9605 | |
| 9606 | |
| 9607 | INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list) |
| 9608 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9609 | char interface_name[16] = {0}; |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 9610 | char cmd[128]={0}; |
| 9611 | char buf[128]={0}; |
| 9612 | int freq = 0; |
| 9613 | |
| 9614 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9615 | |
| 9616 | // full mode is used to scan all channels. |
| 9617 | // multiple channels is ambiguous, iw can not set multiple frequencies in one time. |
| 9618 | if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL) |
| 9619 | ieee80211_channel_to_frequency(chan_list[0], &freq); |
| 9620 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 9621 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9622 | return RETURN_ERR; |
| 9623 | |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 9624 | if (freq) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9625 | snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 9626 | else |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9627 | snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time); |
developer | 615510b | 2022-09-27 10:14:35 +0800 | [diff] [blame] | 9628 | |
| 9629 | _syscmd(cmd, buf, sizeof(buf)); |
| 9630 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9631 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9632 | return RETURN_OK; |
| 9633 | } |
| 9634 | |
| 9635 | |
| 9636 | INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5) |
| 9637 | { |
| 9638 | // TODO Implement me! |
| 9639 | return RETURN_ERR; |
| 9640 | } |
| 9641 | |
| 9642 | INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config) |
| 9643 | { |
| 9644 | // TODO Implement me! |
| 9645 | return RETURN_ERR; |
| 9646 | } |
| 9647 | |
| 9648 | INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac) |
| 9649 | { |
| 9650 | // TODO Implement me! |
| 9651 | return RETURN_ERR; |
| 9652 | } |
| 9653 | |
| 9654 | INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac) |
| 9655 | { |
| 9656 | // TODO Implement me! |
| 9657 | return RETURN_ERR; |
| 9658 | } |
| 9659 | |
| 9660 | INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason) |
| 9661 | { |
| 9662 | // TODO Implement me! |
| 9663 | return RETURN_ERR; |
| 9664 | } |
| 9665 | |
| 9666 | INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb) |
| 9667 | { |
| 9668 | // TODO Implement me! |
| 9669 | return RETURN_ERR; |
| 9670 | } |
| 9671 | |
| 9672 | INT wifi_steering_eventUnregister(void) |
| 9673 | { |
| 9674 | // TODO Implement me! |
| 9675 | return RETURN_ERR; |
| 9676 | } |
| 9677 | |
| 9678 | INT wifi_delApAclDevices(INT apIndex) |
| 9679 | { |
| 9680 | #if 0 |
| 9681 | char cmd[MAX_BUF_SIZE] = {0}; |
| 9682 | char buf[MAX_BUF_SIZE] = {0}; |
| 9683 | |
| 9684 | /* Not reset proof solution */ |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9685 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s accept_acl CLEAR", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9686 | if(_syscmd(cmd,buf,sizeof(buf))) |
| 9687 | return RETURN_ERR; |
| 9688 | #endif |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 9689 | char cmd[MAX_CMD_SIZE]={0}; |
| 9690 | char buf[MAX_BUF_SIZE]={0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9691 | |
developer | e6aafda | 2022-09-13 14:59:28 +0800 | [diff] [blame] | 9692 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9693 | sprintf(cmd, "rm %s%d 2>&1 && touch %s%d", ACL_PREFIX, apIndex, ACL_PREFIX, apIndex); |
| 9694 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 9695 | return RETURN_ERR; |
| 9696 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9697 | |
| 9698 | return RETURN_OK; |
| 9699 | } |
| 9700 | |
| 9701 | #ifdef HAL_NETLINK_IMPL |
| 9702 | static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) { |
| 9703 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 9704 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 9705 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 9706 | struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 9707 | struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1]; |
| 9708 | char mac_addr[20],dev[20]; |
| 9709 | |
| 9710 | nla_parse(tb, |
| 9711 | NL80211_ATTR_MAX, |
| 9712 | genlmsg_attrdata(gnlh, 0), |
| 9713 | genlmsg_attrlen(gnlh, 0), |
| 9714 | NULL); |
| 9715 | |
| 9716 | if(!tb[NL80211_ATTR_STA_INFO]) { |
| 9717 | fprintf(stderr, "sta stats missing!\n"); |
| 9718 | return NL_SKIP; |
| 9719 | } |
| 9720 | |
| 9721 | if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) { |
| 9722 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 9723 | return NL_SKIP; |
| 9724 | } |
| 9725 | mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); |
| 9726 | |
| 9727 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); |
| 9728 | |
| 9729 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) { |
| 9730 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 9731 | return NL_SKIP; |
| 9732 | } |
| 9733 | |
| 9734 | if(sinfo[NL80211_STA_INFO_TID_STATS]) |
| 9735 | { |
| 9736 | if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) { |
| 9737 | printf("failed to parse nested stats attributes!"); |
| 9738 | return NL_SKIP; |
| 9739 | } |
| 9740 | } |
| 9741 | |
| 9742 | if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) ) |
| 9743 | { |
| 9744 | printf("Type is VHT\n"); |
| 9745 | if(rinfo[NL80211_RATE_INFO_VHT_NSS]) |
| 9746 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]); |
| 9747 | |
| 9748 | if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) |
| 9749 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1; |
| 9750 | if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH]) |
| 9751 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2; |
| 9752 | if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) |
| 9753 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2; |
| 9754 | if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH]) |
| 9755 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2; |
| 9756 | if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) ) |
| 9757 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0; |
| 9758 | } |
| 9759 | else |
| 9760 | { |
| 9761 | printf(" OFDM or CCK \n"); |
| 9762 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0; |
| 9763 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0; |
| 9764 | } |
| 9765 | |
| 9766 | if(sinfo[NL80211_STA_INFO_RX_BITRATE]) { |
| 9767 | if(rinfo[NL80211_RATE_INFO_MCS]) |
| 9768 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]); |
| 9769 | } |
| 9770 | if(sinfo[NL80211_STA_INFO_RX_BYTES64]) |
| 9771 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]); |
| 9772 | else if (sinfo[NL80211_STA_INFO_RX_BYTES]) |
| 9773 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]); |
| 9774 | |
| 9775 | if(stats_info[NL80211_TID_STATS_RX_MSDU]) |
| 9776 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]); |
| 9777 | |
| 9778 | if (sinfo[NL80211_STA_INFO_SIGNAL]) |
| 9779 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]); |
| 9780 | //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0 |
| 9781 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0; |
| 9782 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0; |
| 9783 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0; |
| 9784 | //rssi_array need to be filled |
| 9785 | return NL_SKIP; |
| 9786 | } |
| 9787 | #endif |
| 9788 | |
| 9789 | INT wifi_getApAssociatedDeviceRxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_rx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle) |
| 9790 | { |
| 9791 | #ifdef HAL_NETLINK_IMPL |
| 9792 | Netlink nl; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9793 | char if_name[32]; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 9794 | if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9795 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9796 | |
| 9797 | *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t); |
| 9798 | |
| 9799 | if (*output_array_size <= 0) |
| 9800 | return RETURN_OK; |
| 9801 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9802 | nl.id = initSock80211(&nl); |
| 9803 | |
| 9804 | if (nl.id < 0) { |
| 9805 | fprintf(stderr, "Error initializing netlink \n"); |
| 9806 | return 0; |
| 9807 | } |
| 9808 | |
| 9809 | struct nl_msg* msg = nlmsg_alloc(); |
| 9810 | |
| 9811 | if (!msg) { |
| 9812 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 9813 | nlfree(&nl); |
| 9814 | return 0; |
| 9815 | } |
| 9816 | |
| 9817 | genlmsg_put(msg, |
| 9818 | NL_AUTO_PORT, |
| 9819 | NL_AUTO_SEQ, |
| 9820 | nl.id, |
| 9821 | 0, |
| 9822 | 0, |
| 9823 | NL80211_CMD_GET_STATION, |
| 9824 | 0); |
| 9825 | |
| 9826 | nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress); |
| 9827 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 9828 | nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array); |
| 9829 | nl_send_auto(nl.socket, msg); |
| 9830 | nl_recvmsgs(nl.socket, nl.cb); |
| 9831 | nlmsg_free(msg); |
| 9832 | nlfree(&nl); |
| 9833 | return RETURN_OK; |
| 9834 | #else |
| 9835 | //TODO Implement me |
| 9836 | return RETURN_OK; |
| 9837 | #endif |
| 9838 | } |
| 9839 | |
| 9840 | #ifdef HAL_NETLINK_IMPL |
| 9841 | static int txStatsInfo_callback(struct nl_msg *msg, void *arg) { |
| 9842 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 9843 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 9844 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 9845 | struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 9846 | struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1]; |
| 9847 | char mac_addr[20],dev[20]; |
| 9848 | |
| 9849 | nla_parse(tb, |
| 9850 | NL80211_ATTR_MAX, |
| 9851 | genlmsg_attrdata(gnlh, 0), |
| 9852 | genlmsg_attrlen(gnlh, 0), |
| 9853 | NULL); |
| 9854 | |
| 9855 | if(!tb[NL80211_ATTR_STA_INFO]) { |
| 9856 | fprintf(stderr, "sta stats missing!\n"); |
| 9857 | return NL_SKIP; |
| 9858 | } |
| 9859 | |
| 9860 | if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) { |
| 9861 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 9862 | return NL_SKIP; |
| 9863 | } |
| 9864 | |
| 9865 | mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); |
| 9866 | |
| 9867 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); |
| 9868 | |
| 9869 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { |
| 9870 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 9871 | return NL_SKIP; |
| 9872 | } |
| 9873 | |
| 9874 | if(sinfo[NL80211_STA_INFO_TID_STATS]) |
| 9875 | { |
| 9876 | if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) { |
| 9877 | printf("failed to parse nested stats attributes!"); |
| 9878 | return NL_SKIP; |
| 9879 | } |
| 9880 | } |
| 9881 | if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY])) |
| 9882 | { |
| 9883 | printf("Type is VHT\n"); |
| 9884 | if(rinfo[NL80211_RATE_INFO_VHT_NSS]) |
| 9885 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]); |
| 9886 | |
| 9887 | if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) |
| 9888 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1; |
| 9889 | if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH]) |
| 9890 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2; |
| 9891 | if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) |
| 9892 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2; |
| 9893 | if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH]) |
| 9894 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2; |
| 9895 | if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH])) |
| 9896 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0; |
| 9897 | } |
| 9898 | else |
| 9899 | { |
| 9900 | printf(" OFDM or CCK \n"); |
| 9901 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0; |
| 9902 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0; |
| 9903 | } |
| 9904 | |
| 9905 | if(sinfo[NL80211_STA_INFO_TX_BITRATE]) { |
| 9906 | if(rinfo[NL80211_RATE_INFO_MCS]) |
| 9907 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]); |
| 9908 | } |
| 9909 | |
| 9910 | if(sinfo[NL80211_STA_INFO_TX_BYTES64]) |
| 9911 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]); |
| 9912 | else if (sinfo[NL80211_STA_INFO_TX_BYTES]) |
| 9913 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]); |
| 9914 | |
| 9915 | //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink |
| 9916 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0; |
| 9917 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0; |
| 9918 | |
| 9919 | if(stats_info[NL80211_TID_STATS_TX_MSDU]) |
| 9920 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]); |
| 9921 | |
| 9922 | if(sinfo[NL80211_STA_INFO_TX_RETRIES]) |
| 9923 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]); |
| 9924 | |
| 9925 | if(sinfo[NL80211_STA_INFO_TX_FAILED]) |
| 9926 | ((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]); |
| 9927 | |
| 9928 | return NL_SKIP; |
| 9929 | } |
| 9930 | #endif |
| 9931 | |
| 9932 | INT wifi_getApAssociatedDeviceTxStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_rate_info_tx_stats_t **stats_array, UINT *output_array_size, ULLONG *handle) |
| 9933 | { |
| 9934 | #ifdef HAL_NETLINK_IMPL |
| 9935 | Netlink nl; |
| 9936 | char if_name[10]; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9937 | char interface_name[16] = {0}; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 9938 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9939 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9940 | |
| 9941 | *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t); |
| 9942 | |
| 9943 | if (*output_array_size <= 0) |
| 9944 | return RETURN_OK; |
| 9945 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 9946 | snprintf(if_name, sizeof(if_name), "%s", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 9947 | |
| 9948 | nl.id = initSock80211(&nl); |
| 9949 | |
| 9950 | if(nl.id < 0) { |
| 9951 | fprintf(stderr, "Error initializing netlink \n"); |
| 9952 | return 0; |
| 9953 | } |
| 9954 | |
| 9955 | struct nl_msg* msg = nlmsg_alloc(); |
| 9956 | |
| 9957 | if(!msg) { |
| 9958 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 9959 | nlfree(&nl); |
| 9960 | return 0; |
| 9961 | } |
| 9962 | |
| 9963 | genlmsg_put(msg, |
| 9964 | NL_AUTO_PORT, |
| 9965 | NL_AUTO_SEQ, |
| 9966 | nl.id, |
| 9967 | 0, |
| 9968 | 0, |
| 9969 | NL80211_CMD_GET_STATION, |
| 9970 | 0); |
| 9971 | |
| 9972 | nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress); |
| 9973 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 9974 | nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array); |
| 9975 | nl_send_auto(nl.socket, msg); |
| 9976 | nl_recvmsgs(nl.socket, nl.cb); |
| 9977 | nlmsg_free(msg); |
| 9978 | nlfree(&nl); |
| 9979 | return RETURN_OK; |
| 9980 | #else |
| 9981 | //TODO Implement me |
| 9982 | return RETURN_OK; |
| 9983 | #endif |
| 9984 | } |
| 9985 | |
| 9986 | INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate) |
| 9987 | { |
| 9988 | // TODO Implement me! |
| 9989 | char buf[MAX_BUF_SIZE] = {0}; |
| 9990 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9991 | |
| 9992 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9993 | wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf)); |
| 9994 | *activate = (strncmp("1",buf,1) == 0); |
| 9995 | |
| 9996 | return RETURN_OK; |
| 9997 | } |
| 9998 | |
| 9999 | INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate) |
| 10000 | { |
| 10001 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10002 | struct params list; |
| 10003 | |
| 10004 | list.name = "rrm_neighbor_report"; |
| 10005 | list.value = activate?"1":"0"; |
| 10006 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 10007 | wifi_hostapdWrite(config_file, &list, 1); |
| 10008 | |
| 10009 | return RETURN_OK; |
| 10010 | } |
| 10011 | |
| 10012 | INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate) |
| 10013 | { |
| 10014 | char buf[32] = {0}; |
| 10015 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10016 | |
| 10017 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 10018 | wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf)); |
| 10019 | *activate = (strncmp("1",buf,1) == 0); |
| 10020 | |
| 10021 | return RETURN_OK; |
| 10022 | } |
| 10023 | #undef HAL_NETLINK_IMPL |
| 10024 | #ifdef HAL_NETLINK_IMPL |
| 10025 | static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) { |
| 10026 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 10027 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 10028 | struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; |
| 10029 | char dev[20]; |
| 10030 | int freq =0 ; |
| 10031 | static int i=0; |
| 10032 | |
| 10033 | wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg; |
| 10034 | |
| 10035 | static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = { |
| 10036 | }; |
| 10037 | |
| 10038 | nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL); |
| 10039 | |
| 10040 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); |
| 10041 | |
| 10042 | if (!tb[NL80211_ATTR_SURVEY_INFO]) { |
| 10043 | fprintf(stderr, "survey data missing!\n"); |
| 10044 | return NL_SKIP; |
| 10045 | } |
| 10046 | |
| 10047 | if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy)) |
| 10048 | { |
| 10049 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 10050 | return NL_SKIP; |
| 10051 | } |
| 10052 | |
| 10053 | |
| 10054 | if(out[0].array_size == 1 ) |
| 10055 | { |
| 10056 | if(sinfo[NL80211_SURVEY_INFO_IN_USE]) |
| 10057 | { |
| 10058 | if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) |
| 10059 | freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]); |
| 10060 | out[0].ch_number = ieee80211_frequency_to_channel(freq); |
| 10061 | |
| 10062 | if (sinfo[NL80211_SURVEY_INFO_NOISE]) |
| 10063 | out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]); |
| 10064 | if (sinfo[NL80211_SURVEY_INFO_TIME_RX]) |
| 10065 | out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]); |
| 10066 | if (sinfo[NL80211_SURVEY_INFO_TIME_TX]) |
| 10067 | out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]); |
| 10068 | if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY]) |
| 10069 | out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]); |
| 10070 | if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]) |
| 10071 | out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]); |
| 10072 | if (sinfo[NL80211_SURVEY_INFO_TIME]) |
| 10073 | out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]); |
| 10074 | return NL_STOP; |
| 10075 | } |
| 10076 | } |
| 10077 | else |
| 10078 | { |
| 10079 | if ( i <= out[0].array_size ) |
| 10080 | { |
| 10081 | if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) |
| 10082 | freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]); |
| 10083 | out[i].ch_number = ieee80211_frequency_to_channel(freq); |
| 10084 | |
| 10085 | if (sinfo[NL80211_SURVEY_INFO_NOISE]) |
| 10086 | out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]); |
| 10087 | if (sinfo[NL80211_SURVEY_INFO_TIME_RX]) |
| 10088 | out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]); |
| 10089 | if (sinfo[NL80211_SURVEY_INFO_TIME_TX]) |
| 10090 | out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]); |
| 10091 | if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY]) |
| 10092 | out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]); |
| 10093 | if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]) |
| 10094 | out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]); |
| 10095 | if (sinfo[NL80211_SURVEY_INFO_TIME]) |
| 10096 | out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]); |
| 10097 | } |
| 10098 | } |
| 10099 | |
| 10100 | i++; |
| 10101 | return NL_SKIP; |
| 10102 | } |
| 10103 | #endif |
| 10104 | |
| 10105 | static int ieee80211_channel_to_frequency(int channel, int *freqMHz) |
| 10106 | { |
| 10107 | char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE]; |
| 10108 | FILE *fp; |
| 10109 | |
| 10110 | if(access("/tmp/freq-channel-map.txt", F_OK)==-1) |
| 10111 | { |
| 10112 | printf("Creating Frequency-Channel Map\n"); |
| 10113 | system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt"); |
| 10114 | } |
| 10115 | snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel); |
| 10116 | if((fp = popen(command, "r"))) |
| 10117 | { |
| 10118 | fgets(output, sizeof(output), fp); |
| 10119 | *freqMHz = atoi(output); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 10120 | pclose(fp); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10121 | } |
| 10122 | |
| 10123 | return 0; |
| 10124 | } |
| 10125 | |
| 10126 | static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz) |
| 10127 | { |
| 10128 | int freqMHz = -1; |
| 10129 | char cmd[MAX_CMD_SIZE] = {'\0'}; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 10130 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10131 | |
| 10132 | ieee80211_channel_to_frequency(channel, &freqMHz); |
| 10133 | if (freqMHz == -1) { |
| 10134 | wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel); |
| 10135 | return -1; |
| 10136 | } |
| 10137 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 10138 | phyId = radio_index_to_phy(radioIndex); |
| 10139 | if (sprintf(cmd,"iw dev %s%d survey dump | grep -A5 %d | tr -d '\\t'", RADIO_PREFIX, phyId, freqMHz) < 0) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10140 | wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__, |
| 10141 | radioIndex, freqMHz); |
| 10142 | return -1; |
| 10143 | } |
| 10144 | |
| 10145 | if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) { |
| 10146 | wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex); |
| 10147 | return -1; |
| 10148 | } |
| 10149 | |
| 10150 | return 0; |
| 10151 | } |
| 10152 | |
| 10153 | static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats) |
| 10154 | { |
| 10155 | const char *ptr = buf; |
| 10156 | char *key = NULL; |
| 10157 | char *val = NULL; |
| 10158 | char line[256] = { '\0' }; |
| 10159 | |
| 10160 | while (ptr = get_line_from_str_buf(ptr, line)) { |
| 10161 | if (strstr(line, "Frequency")) continue; |
| 10162 | |
| 10163 | key = strtok(line, ":"); |
| 10164 | val = strtok(NULL, " "); |
| 10165 | wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val); |
| 10166 | |
| 10167 | if (!strcmp(key, "noise")) { |
| 10168 | sscanf(val, "%d", &stats->ch_noise); |
| 10169 | if (stats->ch_noise == 0) { |
| 10170 | // Workaround for missing noise information. |
| 10171 | // Assume -95 for 2.4G and -103 for 5G |
| 10172 | if (radioIndex == 0) stats->ch_noise = -95; |
| 10173 | if (radioIndex == 1) stats->ch_noise = -103; |
| 10174 | } |
| 10175 | } |
| 10176 | else if (!strcmp(key, "channel active time")) { |
| 10177 | sscanf(val, "%llu", &stats->ch_utilization_total); |
| 10178 | } |
| 10179 | else if (!strcmp(key, "channel busy time")) { |
| 10180 | sscanf(val, "%llu", &stats->ch_utilization_busy); |
| 10181 | } |
| 10182 | else if (!strcmp(key, "channel receive time")) { |
| 10183 | sscanf(val, "%llu", &stats->ch_utilization_busy_rx); |
| 10184 | } |
| 10185 | else if (!strcmp(key, "channel transmit time")) { |
| 10186 | sscanf(val, "%llu", &stats->ch_utilization_busy_tx); |
| 10187 | } |
| 10188 | }; |
| 10189 | |
| 10190 | return 0; |
| 10191 | } |
| 10192 | |
| 10193 | INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size) |
| 10194 | { |
| 10195 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10196 | #ifdef HAL_NETLINK_IMPL |
| 10197 | Netlink nl; |
| 10198 | wifi_channelStats_t_loc local[array_size]; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 10199 | char if_name[32]; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10200 | |
| 10201 | local[0].array_size = array_size; |
| 10202 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 10203 | if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 10204 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10205 | |
| 10206 | nl.id = initSock80211(&nl); |
| 10207 | |
| 10208 | if (nl.id < 0) { |
| 10209 | fprintf(stderr, "Error initializing netlink \n"); |
| 10210 | return -1; |
| 10211 | } |
| 10212 | |
| 10213 | struct nl_msg* msg = nlmsg_alloc(); |
| 10214 | |
| 10215 | if (!msg) { |
| 10216 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 10217 | nlfree(&nl); |
| 10218 | return -2; |
| 10219 | } |
| 10220 | |
| 10221 | genlmsg_put(msg, |
| 10222 | NL_AUTO_PORT, |
| 10223 | NL_AUTO_SEQ, |
| 10224 | nl.id, |
| 10225 | 0, |
| 10226 | NLM_F_DUMP, |
| 10227 | NL80211_CMD_GET_SURVEY, |
| 10228 | 0); |
| 10229 | |
| 10230 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 10231 | nl_send_auto(nl.socket, msg); |
| 10232 | nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local); |
| 10233 | nl_recvmsgs(nl.socket, nl.cb); |
| 10234 | nlmsg_free(msg); |
| 10235 | nlfree(&nl); |
| 10236 | //Copying the Values |
| 10237 | for(int i=0;i<array_size;i++) |
| 10238 | { |
| 10239 | input_output_channelStats_array[i].ch_number = local[i].ch_number; |
| 10240 | input_output_channelStats_array[i].ch_noise = local[i].ch_noise; |
| 10241 | input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx; |
| 10242 | input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx; |
| 10243 | input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy; |
| 10244 | input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext; |
| 10245 | input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total; |
| 10246 | //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self |
| 10247 | } |
| 10248 | #else |
| 10249 | ULONG channel = 0; |
| 10250 | int i; |
| 10251 | int number_of_channels = array_size; |
| 10252 | char buf[512]; |
| 10253 | INT ret; |
| 10254 | wifi_channelStats_t tmp_stats; |
| 10255 | |
| 10256 | if (number_of_channels == 0) { |
| 10257 | if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) { |
| 10258 | wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex); |
| 10259 | return RETURN_ERR; |
| 10260 | } |
| 10261 | number_of_channels = 1; |
| 10262 | input_output_channelStats_array[0].ch_number = channel; |
| 10263 | } |
| 10264 | |
| 10265 | for (i = 0; i < number_of_channels; i++) { |
| 10266 | |
| 10267 | input_output_channelStats_array[i].ch_noise = 0; |
| 10268 | input_output_channelStats_array[i].ch_utilization_busy_rx = 0; |
| 10269 | input_output_channelStats_array[i].ch_utilization_busy_tx = 0; |
| 10270 | input_output_channelStats_array[i].ch_utilization_busy = 0; |
| 10271 | input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable |
| 10272 | input_output_channelStats_array[i].ch_utilization_total = 0; |
| 10273 | |
| 10274 | memset(buf, 0, sizeof(buf)); |
| 10275 | if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) { |
| 10276 | return RETURN_ERR; |
| 10277 | } |
| 10278 | if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) { |
| 10279 | wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex); |
| 10280 | return RETURN_ERR; |
| 10281 | } |
| 10282 | |
| 10283 | // XXX: fake missing 'self' counter which is not available in iw survey output |
| 10284 | // the 'self' counter (a.k.a 'bss') requires Linux Kernel update |
| 10285 | input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8; |
| 10286 | |
| 10287 | input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000; |
| 10288 | input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000; |
| 10289 | input_output_channelStats_array[i].ch_utilization_busy_self *= 1000; |
| 10290 | input_output_channelStats_array[i].ch_utilization_busy *= 1000; |
| 10291 | input_output_channelStats_array[i].ch_utilization_total *= 1000; |
| 10292 | |
| 10293 | 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", |
| 10294 | __func__, |
| 10295 | input_output_channelStats_array[i].ch_number, |
| 10296 | input_output_channelStats_array[i].ch_noise, |
| 10297 | input_output_channelStats_array[i].ch_utilization_total, |
| 10298 | input_output_channelStats_array[i].ch_utilization_busy, |
| 10299 | input_output_channelStats_array[i].ch_utilization_busy_rx, |
| 10300 | input_output_channelStats_array[i].ch_utilization_busy_tx, |
| 10301 | input_output_channelStats_array[i].ch_utilization_busy_self, |
| 10302 | input_output_channelStats_array[i].ch_utilization_busy_ext); |
| 10303 | } |
| 10304 | #endif |
| 10305 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10306 | return RETURN_OK; |
| 10307 | } |
| 10308 | #define HAL_NETLINK_IMPL |
| 10309 | |
| 10310 | /* Hostapd events */ |
| 10311 | |
| 10312 | #ifndef container_of |
| 10313 | #define offset_of(st, m) ((size_t)&(((st *)0)->m)) |
| 10314 | #define container_of(ptr, type, member) \ |
| 10315 | ((type *)((char *)ptr - offset_of(type, member))) |
| 10316 | #endif /* container_of */ |
| 10317 | |
| 10318 | struct ctrl { |
| 10319 | char sockpath[128]; |
| 10320 | char sockdir[128]; |
| 10321 | char bss[IFNAMSIZ]; |
| 10322 | char reply[4096]; |
| 10323 | int ssid_index; |
| 10324 | void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len); |
| 10325 | void (*overrun)(struct ctrl *ctrl); |
| 10326 | struct wpa_ctrl *wpa; |
| 10327 | unsigned int ovfl; |
| 10328 | size_t reply_len; |
| 10329 | int initialized; |
| 10330 | ev_timer retry; |
| 10331 | ev_timer watchdog; |
| 10332 | ev_stat stat; |
| 10333 | ev_io io; |
| 10334 | }; |
| 10335 | static wifi_newApAssociatedDevice_callback clients_connect_cb; |
| 10336 | static wifi_apDisassociatedDevice_callback clients_disconnect_cb; |
| 10337 | static struct ctrl wpa_ctrl[MAX_APS]; |
| 10338 | static int initialized; |
| 10339 | |
| 10340 | static unsigned int ctrl_get_drops(struct ctrl *ctrl) |
| 10341 | { |
| 10342 | char cbuf[256] = {}; |
| 10343 | struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) }; |
| 10344 | struct cmsghdr *cmsg; |
| 10345 | unsigned int ovfl = ctrl->ovfl; |
| 10346 | unsigned int drop; |
| 10347 | |
| 10348 | recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT); |
| 10349 | for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) |
| 10350 | if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) |
| 10351 | ovfl = *(unsigned int *)CMSG_DATA(cmsg); |
| 10352 | |
| 10353 | drop = ovfl - ctrl->ovfl; |
| 10354 | ctrl->ovfl = ovfl; |
| 10355 | |
| 10356 | return drop; |
| 10357 | } |
| 10358 | |
| 10359 | static void ctrl_close(struct ctrl *ctrl) |
| 10360 | { |
| 10361 | if (ctrl->io.cb) |
| 10362 | ev_io_stop(EV_DEFAULT_ &ctrl->io); |
| 10363 | if (ctrl->retry.cb) |
| 10364 | ev_timer_stop(EV_DEFAULT_ &ctrl->retry); |
| 10365 | if (!ctrl->wpa) |
| 10366 | return; |
| 10367 | |
| 10368 | wpa_ctrl_detach(ctrl->wpa); |
| 10369 | wpa_ctrl_close(ctrl->wpa); |
| 10370 | ctrl->wpa = NULL; |
| 10371 | printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index); |
| 10372 | } |
| 10373 | |
| 10374 | static void ctrl_process(struct ctrl *ctrl) |
| 10375 | { |
| 10376 | const char *str; |
| 10377 | int drops; |
| 10378 | int level; |
| 10379 | int err; |
| 10380 | |
| 10381 | /* Example events: |
| 10382 | * |
| 10383 | * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 |
| 10384 | * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid |
| 10385 | * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19 |
| 10386 | * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=] |
| 10387 | * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1 |
| 10388 | */ |
| 10389 | if (!(str = index(ctrl->reply, '>'))) |
| 10390 | return; |
| 10391 | if (sscanf(ctrl->reply, "<%d>", &level) != 1) |
| 10392 | return; |
| 10393 | |
| 10394 | str++; |
| 10395 | |
| 10396 | if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) { |
| 10397 | if (!(str = index(ctrl->reply, ' '))) |
| 10398 | return; |
| 10399 | wifi_associated_dev_t sta; |
| 10400 | memset(&sta, 0, sizeof(sta)); |
| 10401 | |
| 10402 | sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", |
| 10403 | &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2], |
| 10404 | &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]); |
| 10405 | |
| 10406 | sta.cli_Active=true; |
| 10407 | |
| 10408 | (clients_connect_cb)(ctrl->ssid_index, &sta); |
| 10409 | goto handled; |
| 10410 | } |
| 10411 | |
| 10412 | if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) { |
| 10413 | if (!(str = index(ctrl->reply, ' '))) |
| 10414 | return; |
| 10415 | |
| 10416 | (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0); |
| 10417 | goto handled; |
| 10418 | } |
| 10419 | |
| 10420 | if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) { |
| 10421 | printf("CTRL_WPA: handle TERMINATING event\n"); |
| 10422 | goto retry; |
| 10423 | } |
| 10424 | |
| 10425 | if (strncmp("AP-DISABLED", str, 11) == 0) { |
| 10426 | printf("CTRL_WPA: handle AP-DISABLED\n"); |
| 10427 | goto retry; |
| 10428 | } |
| 10429 | |
| 10430 | printf("Event not supported!!\n"); |
| 10431 | |
| 10432 | handled: |
| 10433 | |
| 10434 | if ((drops = ctrl_get_drops(ctrl))) { |
| 10435 | printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index); |
| 10436 | if (ctrl->overrun) |
| 10437 | ctrl->overrun(ctrl); |
| 10438 | } |
| 10439 | |
| 10440 | return; |
| 10441 | |
| 10442 | retry: |
| 10443 | printf("WPA_CTRL: closing\n"); |
| 10444 | ctrl_close(ctrl); |
| 10445 | printf("WPA_CTRL: retrying from ctrl prcoess\n"); |
| 10446 | ev_timer_again(EV_DEFAULT_ &ctrl->retry); |
| 10447 | } |
| 10448 | |
| 10449 | static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events) |
| 10450 | { |
| 10451 | struct ctrl *ctrl = container_of(io, struct ctrl, io); |
| 10452 | int err; |
| 10453 | |
| 10454 | memset(ctrl->reply, 0, sizeof(ctrl->reply)); |
| 10455 | ctrl->reply_len = sizeof(ctrl->reply) - 1; |
| 10456 | err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len); |
| 10457 | ctrl->reply[ctrl->reply_len] = 0; |
| 10458 | if (err < 0) { |
| 10459 | if (errno == EAGAIN || errno == EWOULDBLOCK) |
| 10460 | return; |
| 10461 | ctrl_close(ctrl); |
| 10462 | ev_timer_again(EV_A_ &ctrl->retry); |
| 10463 | return; |
| 10464 | } |
| 10465 | |
| 10466 | ctrl_process(ctrl); |
| 10467 | } |
| 10468 | |
| 10469 | static int ctrl_open(struct ctrl *ctrl) |
| 10470 | { |
| 10471 | int fd; |
| 10472 | |
| 10473 | if (ctrl->wpa) |
| 10474 | return 0; |
| 10475 | |
| 10476 | ctrl->wpa = wpa_ctrl_open(ctrl->sockpath); |
| 10477 | if (!ctrl->wpa) |
| 10478 | goto err; |
| 10479 | |
| 10480 | if (wpa_ctrl_attach(ctrl->wpa) < 0) |
| 10481 | goto err_close; |
| 10482 | |
| 10483 | fd = wpa_ctrl_get_fd(ctrl->wpa); |
| 10484 | if (fd < 0) |
| 10485 | goto err_detach; |
| 10486 | |
| 10487 | if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0) |
| 10488 | goto err_detach; |
| 10489 | |
| 10490 | ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ); |
| 10491 | ev_io_start(EV_DEFAULT_ &ctrl->io); |
| 10492 | |
| 10493 | return 0; |
| 10494 | |
| 10495 | err_detach: |
| 10496 | wpa_ctrl_detach(ctrl->wpa); |
| 10497 | err_close: |
| 10498 | wpa_ctrl_close(ctrl->wpa); |
| 10499 | err: |
| 10500 | ctrl->wpa = NULL; |
| 10501 | return -1; |
| 10502 | } |
| 10503 | |
| 10504 | static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events) |
| 10505 | { |
| 10506 | struct ctrl *ctrl = container_of(stat, struct ctrl, stat); |
| 10507 | |
| 10508 | printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index); |
| 10509 | ctrl_open(ctrl); |
| 10510 | } |
| 10511 | |
| 10512 | static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events) |
| 10513 | { |
| 10514 | struct ctrl *ctrl = container_of(timer, struct ctrl, retry); |
| 10515 | |
| 10516 | printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index); |
| 10517 | if (ctrl_open(ctrl) == 0) { |
| 10518 | printf("WPA_CTRL: retry successful\n"); |
| 10519 | ev_timer_stop(EV_DEFAULT_ &ctrl->retry); |
| 10520 | } |
| 10521 | } |
| 10522 | |
| 10523 | int ctrl_enable(struct ctrl *ctrl) |
| 10524 | { |
| 10525 | if (ctrl->wpa) |
| 10526 | return 0; |
| 10527 | |
| 10528 | if (!ctrl->stat.cb) { |
| 10529 | ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.); |
| 10530 | ev_stat_start(EV_DEFAULT_ &ctrl->stat); |
| 10531 | } |
| 10532 | |
| 10533 | if (!ctrl->retry.cb) { |
| 10534 | ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.); |
| 10535 | } |
| 10536 | |
| 10537 | return ctrl_open(ctrl); |
| 10538 | } |
| 10539 | |
| 10540 | static void |
| 10541 | ctrl_msg_cb(char *buf, size_t len) |
| 10542 | { |
| 10543 | struct ctrl *ctrl = container_of(buf, struct ctrl, reply); |
| 10544 | |
| 10545 | printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf); |
| 10546 | ctrl_process(ctrl); |
| 10547 | } |
| 10548 | |
| 10549 | static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len) |
| 10550 | { |
| 10551 | int err; |
| 10552 | |
| 10553 | if (!ctrl->wpa) |
| 10554 | return -1; |
| 10555 | if (*reply_len < 2) |
| 10556 | return -1; |
| 10557 | |
| 10558 | (*reply_len)--; |
| 10559 | ctrl->reply_len = sizeof(ctrl->reply); |
| 10560 | err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb); |
| 10561 | printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err); |
| 10562 | if (err < 0) |
| 10563 | return err; |
| 10564 | |
| 10565 | if (ctrl->reply_len > *reply_len) |
| 10566 | ctrl->reply_len = *reply_len; |
| 10567 | |
| 10568 | *reply_len = ctrl->reply_len; |
| 10569 | memcpy(reply, ctrl->reply, *reply_len); |
| 10570 | reply[*reply_len - 1] = 0; |
| 10571 | printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply); |
| 10572 | return 0; |
| 10573 | } |
| 10574 | |
| 10575 | static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events) |
| 10576 | { |
| 10577 | const char *pong = "PONG"; |
| 10578 | const char *ping = "PING"; |
| 10579 | char reply[1024]; |
| 10580 | size_t len = sizeof(reply); |
| 10581 | int err; |
| 10582 | ULONG s, snum; |
| 10583 | INT ret; |
| 10584 | BOOL status; |
| 10585 | |
| 10586 | printf("WPA_CTRL: watchdog cb\n"); |
| 10587 | |
| 10588 | ret = wifi_getSSIDNumberOfEntries(&snum); |
| 10589 | if (ret != RETURN_OK) { |
| 10590 | printf("%s: failed to get SSID count", __func__); |
| 10591 | return; |
| 10592 | } |
| 10593 | |
| 10594 | if (snum > MAX_APS) { |
| 10595 | printf("more ssid than supported! %lu\n", snum); |
| 10596 | return; |
| 10597 | } |
| 10598 | |
| 10599 | for (s = 0; s < snum; s++) { |
| 10600 | if (wifi_getApEnable(s, &status) != RETURN_OK) { |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 10601 | printf("%s: failed to get AP Enable for index: %lu\n", __func__, s); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10602 | continue; |
| 10603 | } |
| 10604 | if (status == false) continue; |
| 10605 | |
| 10606 | memset(reply, 0, sizeof(reply)); |
| 10607 | len = sizeof(reply); |
| 10608 | printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index); |
| 10609 | err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len); |
| 10610 | if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong))) |
| 10611 | continue; |
| 10612 | |
| 10613 | printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index); |
| 10614 | ctrl_close(&wpa_ctrl[s]); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 10615 | printf("WPA_CTRL: ev_timer_again %lu\n", s); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10616 | ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry); |
| 10617 | } |
| 10618 | } |
| 10619 | |
| 10620 | static int init_wpa() |
| 10621 | { |
| 10622 | int ret = 0, i = 0; |
| 10623 | ULONG s, snum; |
| 10624 | |
| 10625 | ret = wifi_getSSIDNumberOfEntries(&snum); |
| 10626 | if (ret != RETURN_OK) { |
| 10627 | printf("%s: failed to get SSID count", __func__); |
| 10628 | return RETURN_ERR; |
| 10629 | } |
| 10630 | |
| 10631 | if (snum > MAX_APS) { |
| 10632 | printf("more ssid than supported! %lu\n", snum); |
| 10633 | return RETURN_ERR; |
| 10634 | } |
| 10635 | |
| 10636 | for (s = 0; s < snum; s++) { |
| 10637 | memset(&wpa_ctrl[s], 0, sizeof(struct ctrl)); |
| 10638 | sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s); |
| 10639 | wpa_ctrl[s].ssid_index = s; |
| 10640 | ctrl_enable(&wpa_ctrl[s]); |
| 10641 | } |
| 10642 | |
| 10643 | ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.); |
| 10644 | ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog); |
| 10645 | |
| 10646 | initialized = 1; |
| 10647 | printf("WPA_CTRL: initialized\n"); |
| 10648 | |
| 10649 | return RETURN_OK; |
| 10650 | } |
| 10651 | |
| 10652 | void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc) |
| 10653 | { |
| 10654 | clients_connect_cb = callback_proc; |
| 10655 | if (!initialized) |
| 10656 | init_wpa(); |
| 10657 | } |
| 10658 | |
| 10659 | void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc) |
| 10660 | { |
| 10661 | clients_disconnect_cb = callback_proc; |
| 10662 | if (!initialized) |
| 10663 | init_wpa(); |
| 10664 | } |
| 10665 | |
| 10666 | INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request) |
| 10667 | { |
| 10668 | // TODO Implement me! |
| 10669 | return RETURN_ERR; |
| 10670 | } |
| 10671 | |
| 10672 | INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken) |
| 10673 | { |
| 10674 | // TODO Implement me! |
| 10675 | return RETURN_ERR; |
| 10676 | } |
| 10677 | |
| 10678 | INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize) |
| 10679 | { |
| 10680 | int i; |
| 10681 | char cmd[256]; |
| 10682 | char channel_numbers_buf[256]; |
| 10683 | char dfs_state_buf[256]; |
| 10684 | char line[256]; |
| 10685 | const char *ptr; |
| 10686 | |
| 10687 | memset(cmd, 0, sizeof(cmd)); |
| 10688 | memset(channel_numbers_buf, 0, sizeof(channel_numbers_buf)); |
| 10689 | memset(line, 0, sizeof(line)); |
| 10690 | memset(dfs_state_buf, 0, sizeof(dfs_state_buf)); |
| 10691 | memset(outputMap, 0, outputMapSize); // all unused entries should be zero |
| 10692 | |
| 10693 | if (radioIndex == 0) { // 2.4G - all allowed |
| 10694 | if (outputMapSize < 11) { |
| 10695 | wifi_dbg_printf("%s: outputMapSize too small (%d)\n", __FUNCTION__, outputMapSize); |
| 10696 | return RETURN_ERR; |
| 10697 | } |
| 10698 | |
| 10699 | for (i = 0; i < 11; i++) { |
| 10700 | outputMap[i].ch_number = i + 1; |
| 10701 | outputMap[i].ch_state = CHAN_STATE_AVAILABLE; |
| 10702 | } |
| 10703 | |
| 10704 | return RETURN_OK; |
| 10705 | } |
| 10706 | |
| 10707 | if (radioIndex == 1) { // 5G |
| 10708 | // Example output of iw list: |
| 10709 | // |
| 10710 | // Frequencies: |
| 10711 | // * 5180 MHz [36] (17.0 dBm) |
| 10712 | // * 5200 MHz [40] (17.0 dBm) |
| 10713 | // * 5220 MHz [44] (17.0 dBm) |
| 10714 | // * 5240 MHz [48] (17.0 dBm) |
| 10715 | // * 5260 MHz [52] (23.0 dBm) (radar detection) |
| 10716 | // DFS state: usable (for 78930 sec) |
| 10717 | // DFS CAC time: 60000 ms |
| 10718 | // * 5280 MHz [56] (23.0 dBm) (radar detection) |
| 10719 | // DFS state: usable (for 78930 sec) |
| 10720 | // DFS CAC time: 60000 ms |
| 10721 | // * 5300 MHz [60] (23.0 dBm) (radar detection) |
| 10722 | // DFS state: usable (for 78930 sec) |
| 10723 | // DFS CAC time: 60000 ms |
| 10724 | // * 5320 MHz [64] (23.0 dBm) (radar detection) |
| 10725 | // DFS state: usable (for 78930 sec) |
| 10726 | // DFS CAC time: 60000 ms |
| 10727 | // * 5500 MHz [100] (disabled) |
| 10728 | // * 5520 MHz [104] (disabled) |
| 10729 | // * 5540 MHz [108] (disabled) |
| 10730 | // * 5560 MHz [112] (disabled) |
| 10731 | // |
| 10732 | // Below command should fetch channel numbers of each enabled channel in 5GHz band: |
| 10733 | if (sprintf(cmd,"iw list | grep MHz | tr -d '\\t' | grep -v disabled | tr -d '*' | grep '^ 5' | awk '{print $3}' | tr -d '[]'") < 0) { |
| 10734 | wifi_dbg_printf("%s: failed to build iw list command\n", __FUNCTION__); |
| 10735 | return RETURN_ERR; |
| 10736 | } |
| 10737 | |
| 10738 | if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) { |
| 10739 | wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd); |
| 10740 | return RETURN_ERR; |
| 10741 | } |
| 10742 | |
| 10743 | ptr = channel_numbers_buf; |
| 10744 | i = 0; |
| 10745 | while (ptr = get_line_from_str_buf(ptr, line)) { |
| 10746 | if (i >= outputMapSize) { |
| 10747 | wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__); |
| 10748 | return RETURN_ERR; |
| 10749 | } |
| 10750 | sscanf(line, "%d", &outputMap[i].ch_number); |
| 10751 | |
| 10752 | memset(cmd, 0, sizeof(cmd)); |
| 10753 | // Below command should fetch string for DFS state (usable, available or unavailable) |
| 10754 | // Example line: "DFS state: usable (for 78930 sec)" |
| 10755 | 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) { |
| 10756 | wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__); |
| 10757 | return RETURN_ERR; |
| 10758 | } |
| 10759 | |
| 10760 | memset(dfs_state_buf, 0, sizeof(dfs_state_buf)); |
| 10761 | if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) { |
| 10762 | wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd); |
| 10763 | return RETURN_ERR; |
| 10764 | } |
| 10765 | |
| 10766 | wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf); |
| 10767 | |
| 10768 | if (!strcmp(dfs_state_buf, "usable")) { |
| 10769 | outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED; |
| 10770 | } else if (!strcmp(dfs_state_buf, "available")) { |
| 10771 | outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED; |
| 10772 | } else if (!strcmp(dfs_state_buf, "unavailable")) { |
| 10773 | outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START; |
| 10774 | } else { |
| 10775 | outputMap[i].ch_state = CHAN_STATE_AVAILABLE; |
| 10776 | } |
| 10777 | i++; |
| 10778 | } |
| 10779 | |
| 10780 | return RETURN_OK; |
| 10781 | } |
| 10782 | |
| 10783 | wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex); |
| 10784 | return RETURN_ERR; |
| 10785 | } |
| 10786 | |
| 10787 | INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb) |
| 10788 | { |
| 10789 | // TODO Implement me! |
| 10790 | return RETURN_ERR; |
| 10791 | } |
| 10792 | |
| 10793 | INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage) |
| 10794 | { |
| 10795 | return RETURN_OK; |
| 10796 | } |
| 10797 | |
| 10798 | INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn) |
| 10799 | { |
| 10800 | // TODO Implement me! |
| 10801 | return RETURN_ERR; |
| 10802 | } |
| 10803 | |
| 10804 | INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand) |
| 10805 | { |
| 10806 | // TODO API refrence Implementaion is present on RPI hal |
| 10807 | return RETURN_ERR; |
| 10808 | } |
| 10809 | |
| 10810 | INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg) |
| 10811 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 10812 | char interface_name[16] = {0}; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 10813 | char cmd[128]={'\0'}; |
| 10814 | char buf[128]={'\0'}; |
| 10815 | char *support; |
| 10816 | int maximum_tx = 0, current_tx = 0; |
| 10817 | |
| 10818 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10819 | if(txpwr_pcntg == NULL) |
| 10820 | return RETURN_ERR; |
| 10821 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 10822 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 10823 | return RETURN_ERR; |
| 10824 | |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 10825 | // Get the maximum tx power of the device |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 10826 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name); |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 10827 | _syscmd(cmd, buf, sizeof(buf)); |
| 10828 | maximum_tx = strtol(buf, NULL, 10); |
| 10829 | |
| 10830 | // Get the current tx power |
| 10831 | memset(cmd, 0, sizeof(cmd)); |
| 10832 | memset(buf, 0, sizeof(buf)); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 10833 | snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name); |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 10834 | _syscmd(cmd, buf, sizeof(buf)); |
| 10835 | current_tx = strtol(buf, NULL, 10); |
| 10836 | |
| 10837 | // Get the power supported list and find the current power percentage in supported list |
| 10838 | memset(buf, 0, sizeof(buf)); |
| 10839 | wifi_getRadioTransmitPowerSupported(apIndex, buf); |
| 10840 | support = strtok(buf, ","); |
| 10841 | while(true) |
| 10842 | { |
| 10843 | if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal. |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 10844 | *txpwr_pcntg = 100; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 10845 | wifi_dbg_printf("current power is not in supported list\n"); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 10846 | return RETURN_OK; |
developer | a5005b6 | 2022-09-13 15:43:35 +0800 | [diff] [blame] | 10847 | } |
| 10848 | int tmp = maximum_tx*strtol(support, NULL, 10)/100; |
| 10849 | if (tmp == current_tx) { |
| 10850 | *txpwr_pcntg = strtol(support, NULL, 10); |
| 10851 | break; |
| 10852 | } |
| 10853 | support = strtok(NULL, ","); |
| 10854 | } |
| 10855 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10856 | return RETURN_OK; |
| 10857 | } |
| 10858 | |
| 10859 | INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac) |
| 10860 | { |
developer | 58599c2 | 2022-09-13 16:40:34 +0800 | [diff] [blame] | 10861 | // TODO precac feature. |
| 10862 | struct params params = {0}; |
| 10863 | char config_file[128] = {0}; |
| 10864 | |
| 10865 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10866 | |
| 10867 | params.name = "enable_background_radar"; |
| 10868 | params.value = enable?"1":"0"; |
| 10869 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 10870 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 10871 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 10872 | |
| 10873 | /* TODO precac feature */ |
| 10874 | |
| 10875 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10876 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10877 | } |
| 10878 | |
| 10879 | INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac) |
| 10880 | { |
developer | 58599c2 | 2022-09-13 16:40:34 +0800 | [diff] [blame] | 10881 | char config_file[128] = {0}; |
| 10882 | char buf[64] = {0}; |
| 10883 | |
| 10884 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10885 | if (NULL == enable || NULL == precac) |
| 10886 | return RETURN_ERR; |
| 10887 | |
| 10888 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 10889 | wifi_hostapdRead(config_file, "enable_background_radar", buf, sizeof(buf)); |
| 10890 | if (strncmp(enable, "1", 1) == 0) |
| 10891 | *enable = true; |
| 10892 | else |
| 10893 | *enable = false; |
| 10894 | |
| 10895 | /* TODO precac feature */ |
| 10896 | |
| 10897 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10898 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10899 | } |
| 10900 | |
| 10901 | INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported) |
| 10902 | { |
developer | 58599c2 | 2022-09-13 16:40:34 +0800 | [diff] [blame] | 10903 | *supported = TRUE; |
| 10904 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 10905 | } |
| 10906 | |
developer | 3e6b169 | 2022-09-30 18:04:05 +0800 | [diff] [blame] | 10907 | INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type) |
| 10908 | { |
| 10909 | // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)) |
| 10910 | struct params params = {0}; |
| 10911 | char config_file[64] = {0}; |
| 10912 | char buf[64] = {0}; |
| 10913 | unsigned int set_mu_type = 0; |
| 10914 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10915 | |
| 10916 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 10917 | wifi_hostapdRead(config_file, "hemu_onoff", buf, sizeof(buf)); |
| 10918 | |
| 10919 | if (strlen(buf) > 0) |
| 10920 | set_mu_type = strtol(buf, NULL, 10); |
| 10921 | |
| 10922 | if (mu_type == WIFI_DL_MU_TYPE_NONE) { |
| 10923 | set_mu_type &= ~0x05; // unset bit 0, 2 |
| 10924 | } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) { |
| 10925 | set_mu_type |= 0x01; |
| 10926 | set_mu_type &= ~0x04; |
| 10927 | } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) { |
| 10928 | set_mu_type &= ~0x01; |
| 10929 | set_mu_type |= 0x04; |
| 10930 | } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO){ |
| 10931 | set_mu_type |= 0x05; // set bit 0, 2 |
| 10932 | } |
| 10933 | |
| 10934 | params.name = "hemu_onoff"; |
| 10935 | sprintf(buf, "%u", set_mu_type); |
| 10936 | params.value = buf; |
| 10937 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 10938 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 10939 | wifi_hostapdProcessUpdate(radio_index, ¶ms, 1); |
| 10940 | |
| 10941 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10942 | return RETURN_OK; |
| 10943 | } |
| 10944 | |
| 10945 | INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type) |
| 10946 | { |
| 10947 | struct params params={0}; |
| 10948 | char config_file[64] = {0}; |
| 10949 | char buf[64] = {0}; |
| 10950 | unsigned int get_mu_type = 0; |
| 10951 | |
| 10952 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10953 | |
| 10954 | if (mu_type == NULL) |
| 10955 | return RETURN_ERR; |
| 10956 | |
| 10957 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 10958 | wifi_hostapdRead(config_file, "hemu_onoff", buf, sizeof(buf)); |
| 10959 | get_mu_type = strtol(buf, NULL, 10); |
| 10960 | |
| 10961 | if (get_mu_type & 0x04 && get_mu_type & 0x01) |
| 10962 | *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO; |
| 10963 | else if (get_mu_type & 0x04) |
| 10964 | *mu_type = WIFI_DL_MU_TYPE_MIMO; |
| 10965 | else if (get_mu_type & 0x01) |
| 10966 | *mu_type = WIFI_DL_MU_TYPE_OFDMA; |
| 10967 | else |
| 10968 | *mu_type = WIFI_DL_MU_TYPE_NONE; |
| 10969 | |
| 10970 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10971 | return RETURN_OK; |
| 10972 | } |
| 10973 | |
| 10974 | INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type) |
| 10975 | { |
| 10976 | // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)) |
| 10977 | struct params params={0}; |
| 10978 | char config_file[64] = {0}; |
| 10979 | char buf[64] = {0}; |
| 10980 | unsigned int set_mu_type = 0; |
| 10981 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10982 | |
| 10983 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 10984 | wifi_hostapdRead(config_file, "hemu_onoff", buf, sizeof(buf)); |
| 10985 | |
| 10986 | if (strlen(buf) > 0) |
| 10987 | set_mu_type = strtol(buf, NULL, 10); |
| 10988 | |
| 10989 | // wifi hal only define up link type none and OFDMA, there is NO MU-MIMO. |
| 10990 | if (mu_type == WIFI_UL_MU_TYPE_NONE) { |
| 10991 | set_mu_type &= ~0x0a; |
| 10992 | } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) { |
| 10993 | set_mu_type |= 0x02; |
| 10994 | set_mu_type &= ~0x08; |
| 10995 | } |
| 10996 | |
| 10997 | params.name = "hemu_onoff"; |
| 10998 | sprintf(buf, "%u", set_mu_type); |
| 10999 | params.value = buf; |
| 11000 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 11001 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 11002 | wifi_hostapdProcessUpdate(radio_index, ¶ms, 1); |
| 11003 | |
| 11004 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11005 | return RETURN_OK; |
| 11006 | } |
| 11007 | |
| 11008 | INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type) |
| 11009 | { |
| 11010 | struct params params={0}; |
| 11011 | char config_file[64] = {0}; |
| 11012 | char buf[64] = {0}; |
| 11013 | unsigned int get_mu_type = 0; |
| 11014 | |
| 11015 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11016 | |
| 11017 | if (mu_type == NULL) |
| 11018 | return RETURN_ERR; |
| 11019 | |
| 11020 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 11021 | wifi_hostapdRead(config_file, "hemu_onoff", buf, sizeof(buf)); |
| 11022 | |
| 11023 | get_mu_type = strtol(buf, NULL, 10); |
| 11024 | if (get_mu_type & 0x02) |
| 11025 | *mu_type = WIFI_DL_MU_TYPE_OFDMA; |
| 11026 | else |
| 11027 | *mu_type = WIFI_DL_MU_TYPE_NONE; |
| 11028 | |
| 11029 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11030 | return RETURN_OK; |
| 11031 | } |
| 11032 | |
| 11033 | |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11034 | INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval) |
| 11035 | { |
| 11036 | char cmd[128] = {0}; |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11037 | char buf[256] = {0}; |
| 11038 | char config_file[64] = {0}; |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11039 | char GI[8] = {0}; |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11040 | int mode_map = 0; |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11041 | FILE *f = NULL; |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11042 | wifi_band band = band_invalid; |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11043 | |
| 11044 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11045 | |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11046 | if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) { |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11047 | wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__); |
| 11048 | return RETURN_ERR; |
| 11049 | } |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11050 | |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11051 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index); |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11052 | band = wifi_index_to_band(radio_index); |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11053 | |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11054 | // Hostapd are not supported HE mode GI 1600, 3200 ns. |
| 11055 | if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 11056 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file); |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11057 | _syscmd(cmd, buf, sizeof(buf)); |
| 11058 | } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){ |
| 11059 | wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf)); |
| 11060 | if (strstr(buf, "[SHORT-GI-") == NULL) { |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 11061 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file); |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11062 | _syscmd(cmd, buf, sizeof(buf)); |
| 11063 | } |
| 11064 | if (band == band_5) { |
| 11065 | wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf)); |
| 11066 | if (strstr(buf, "[SHORT-GI-") == NULL) { |
developer | 6372c2b | 2022-10-27 17:39:51 +0800 | [diff] [blame] | 11067 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file); |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11068 | _syscmd(cmd, buf, sizeof(buf)); |
| 11069 | } |
| 11070 | } |
| 11071 | } |
| 11072 | wifi_reloadAp(radio_index); |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11073 | |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11074 | if (guard_interval == wifi_guard_interval_400) |
| 11075 | strcpy(GI, "0.4"); |
| 11076 | else if (guard_interval == wifi_guard_interval_800) |
| 11077 | strcpy(GI, "0.8"); |
| 11078 | else if (guard_interval == wifi_guard_interval_1600) |
| 11079 | strcpy(GI, "1.6"); |
| 11080 | else if (guard_interval == wifi_guard_interval_3200) |
| 11081 | strcpy(GI, "3.2"); |
| 11082 | else if (guard_interval == wifi_guard_interval_auto) |
| 11083 | strcpy(GI, "auto"); |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11084 | // Record GI for get GI function |
| 11085 | snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index); |
| 11086 | f = fopen(buf, "w"); |
developer | 254882b | 2022-09-30 17:12:31 +0800 | [diff] [blame] | 11087 | if (f == NULL) |
| 11088 | return RETURN_ERR; |
| 11089 | fprintf(f, "%s", GI); |
developer | 454b946 | 2022-09-13 15:29:16 +0800 | [diff] [blame] | 11090 | fclose(f); |
| 11091 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11092 | return RETURN_OK; |
| 11093 | } |
| 11094 | |
| 11095 | INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval) |
| 11096 | { |
| 11097 | char buf[32] = {0}; |
| 11098 | char cmd[64] = {0}; |
| 11099 | |
| 11100 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11101 | |
| 11102 | if (guard_interval == NULL) |
| 11103 | return RETURN_ERR; |
| 11104 | |
| 11105 | snprintf(cmd, sizeof(cmd), "cat %s%d.txt", GUARD_INTERVAL_FILE, radio_index); |
| 11106 | _syscmd(cmd, buf, sizeof(buf)); |
| 11107 | |
| 11108 | if (strncmp(buf, "0.4", 3) == 0) |
| 11109 | *guard_interval = wifi_guard_interval_400; |
| 11110 | else if (strncmp(buf, "0.8", 3) == 0) |
| 11111 | *guard_interval = wifi_guard_interval_800; |
| 11112 | else if (strncmp(buf, "1.6", 3) == 0) |
| 11113 | *guard_interval = wifi_guard_interval_1600; |
| 11114 | else if (strncmp(buf, "3.2", 3) == 0) |
| 11115 | *guard_interval = wifi_guard_interval_3200; |
| 11116 | else |
| 11117 | *guard_interval = wifi_guard_interval_auto; |
| 11118 | |
| 11119 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11120 | return RETURN_OK; |
| 11121 | } |
| 11122 | |
developer | 3cc61d1 | 2022-09-13 16:36:05 +0800 | [diff] [blame] | 11123 | INT wifi_setBSSColor(INT radio_index, UCHAR color) |
| 11124 | { |
| 11125 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11126 | struct params params = {0}; |
| 11127 | char config_file[128] = {0}; |
| 11128 | char bss_color[4] ={0}; |
| 11129 | |
| 11130 | params.name = "he_bss_color"; |
| 11131 | snprintf(bss_color, sizeof(bss_color), "%hhu", color); |
| 11132 | params.value = bss_color; |
| 11133 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 11134 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 11135 | wifi_hostapdProcessUpdate(radio_index, ¶ms, 1); |
| 11136 | |
| 11137 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11138 | return RETURN_OK; |
| 11139 | } |
| 11140 | |
| 11141 | INT wifi_getBSSColor(INT radio_index, UCHAR *color) |
| 11142 | { |
| 11143 | char config_file[128] = {0}; |
| 11144 | char buf[64] = {0}; |
| 11145 | char temp_output[128] = {'\0'}; |
| 11146 | |
| 11147 | wifi_dbg_printf("\nFunc=%s\n", __func__); |
| 11148 | if (NULL == color) |
| 11149 | return RETURN_ERR; |
| 11150 | |
| 11151 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 11152 | wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf)); |
| 11153 | |
| 11154 | if(strlen(buf) > 0) { |
| 11155 | snprintf(temp_output, sizeof(temp_output), "%s", buf); |
| 11156 | } else { |
| 11157 | snprintf(temp_output, sizeof(temp_output), "1"); // default value |
| 11158 | } |
| 11159 | |
| 11160 | *color = (UCHAR)strtoul(temp_output, NULL, 10); |
| 11161 | wifi_dbg_printf("\noutput_string=%s\n", color); |
| 11162 | |
| 11163 | return RETURN_OK; |
| 11164 | } |
| 11165 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11166 | /* multi-psk support */ |
| 11167 | INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key) |
| 11168 | { |
| 11169 | char cmd[256]; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11170 | char interface_name[16] = {0}; |
| 11171 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 11172 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11173 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11174 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11175 | sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'", |
| 11176 | interface_name, |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11177 | mac[0], |
| 11178 | mac[1], |
| 11179 | mac[2], |
| 11180 | mac[3], |
| 11181 | mac[4], |
| 11182 | mac[5] |
| 11183 | ); |
| 11184 | printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd); |
| 11185 | _syscmd(cmd, key->wifi_keyId, 64); |
| 11186 | |
| 11187 | |
| 11188 | return RETURN_OK; |
| 11189 | } |
| 11190 | |
| 11191 | INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber) |
| 11192 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11193 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11194 | FILE *fd = NULL; |
| 11195 | char fname[100]; |
| 11196 | char cmd[128] = {0}; |
| 11197 | char out[64] = {0}; |
| 11198 | wifi_key_multi_psk_t * key = NULL; |
| 11199 | if(keysNumber < 0) |
| 11200 | return RETURN_ERR; |
| 11201 | |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 11202 | snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11203 | fd = fopen(fname, "w"); |
| 11204 | if (!fd) { |
| 11205 | return RETURN_ERR; |
| 11206 | } |
| 11207 | key= (wifi_key_multi_psk_t *) keys; |
| 11208 | for(int i=0; i<keysNumber; ++i, key++) { |
| 11209 | fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk); |
| 11210 | } |
| 11211 | fclose(fd); |
| 11212 | |
| 11213 | //reload file |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 11214 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11215 | return RETURN_ERR; |
| 11216 | sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11217 | _syscmd(cmd, out, 64); |
| 11218 | return RETURN_OK; |
| 11219 | } |
| 11220 | |
| 11221 | INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber) |
| 11222 | { |
| 11223 | FILE *fd = NULL; |
| 11224 | char fname[100]; |
| 11225 | char * line = NULL; |
| 11226 | char * pos = NULL; |
| 11227 | size_t len = 0; |
| 11228 | ssize_t read = 0; |
| 11229 | INT ret = RETURN_OK; |
| 11230 | wifi_key_multi_psk_t *keys_it = NULL; |
| 11231 | |
| 11232 | if (keysNumber < 1) { |
| 11233 | return RETURN_ERR; |
| 11234 | } |
| 11235 | |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 11236 | snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11237 | fd = fopen(fname, "r"); |
| 11238 | if (!fd) { |
| 11239 | return RETURN_ERR; |
| 11240 | } |
| 11241 | |
| 11242 | if (keys == NULL) { |
| 11243 | ret = RETURN_ERR; |
| 11244 | goto close; |
| 11245 | } |
| 11246 | |
| 11247 | keys_it = keys; |
| 11248 | while ((read = getline(&line, &len, fd)) != -1) { |
| 11249 | //Strip trailing new line if present |
| 11250 | if (read > 0 && line[read-1] == '\n') { |
| 11251 | line[read-1] = '\0'; |
| 11252 | } |
| 11253 | |
| 11254 | if(strcmp(line,"keyid=")) { |
| 11255 | sscanf(line, "keyid=%s", &(keys_it->wifi_keyId)); |
| 11256 | if (!(pos = index(line, ' '))) { |
| 11257 | ret = RETURN_ERR; |
| 11258 | goto close; |
| 11259 | } |
| 11260 | pos++; |
| 11261 | //Here should be 00:00:00:00:00:00 |
| 11262 | if (!(strcmp(pos,"00:00:00:00:00:00"))) { |
| 11263 | printf("Not supported MAC: %s\n", pos); |
| 11264 | } |
| 11265 | if (!(pos = index(pos, ' '))) { |
| 11266 | ret = RETURN_ERR; |
| 11267 | goto close; |
| 11268 | } |
| 11269 | pos++; |
| 11270 | |
| 11271 | //The rest is PSK |
| 11272 | snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos); |
| 11273 | keys_it++; |
| 11274 | |
| 11275 | if(--keysNumber <= 0) |
| 11276 | break; |
| 11277 | } |
| 11278 | } |
| 11279 | |
| 11280 | close: |
| 11281 | free(line); |
| 11282 | fclose(fd); |
| 11283 | return ret; |
| 11284 | } |
| 11285 | /* end of multi-psk support */ |
| 11286 | |
| 11287 | INT wifi_setNeighborReports(UINT apIndex, |
| 11288 | UINT numNeighborReports, |
| 11289 | wifi_NeighborReport_t *neighborReports) |
| 11290 | { |
| 11291 | char cmd[256] = { 0 }; |
| 11292 | char hex_bssid[13] = { 0 }; |
| 11293 | char bssid[18] = { 0 }; |
| 11294 | char nr[256] = { 0 }; |
| 11295 | char ssid[256]; |
| 11296 | char hex_ssid[256]; |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11297 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11298 | INT ret; |
| 11299 | |
| 11300 | /*rmeove all neighbors*/ |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11301 | wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name); |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 11302 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11303 | return RETURN_ERR; |
| 11304 | sprintf(cmd, "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",interface_name,interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11305 | system(cmd); |
| 11306 | |
| 11307 | for(unsigned int i = 0; i < numNeighborReports; i++) |
| 11308 | { |
| 11309 | memset(ssid, 0, sizeof(ssid)); |
| 11310 | ret = wifi_getSSIDName(apIndex, ssid); |
| 11311 | if (ret != RETURN_OK) |
| 11312 | return RETURN_ERR; |
| 11313 | |
| 11314 | memset(hex_ssid, 0, sizeof(hex_ssid)); |
| 11315 | for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 ) |
| 11316 | sprintf(hex_ssid + k,"%02x", ssid[j]); |
| 11317 | |
| 11318 | snprintf(hex_bssid, sizeof(hex_bssid), |
| 11319 | "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", |
| 11320 | neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]); |
| 11321 | snprintf(bssid, sizeof(bssid), |
| 11322 | "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", |
| 11323 | neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]); |
| 11324 | |
| 11325 | snprintf(nr, sizeof(nr), |
| 11326 | "%s" // bssid |
| 11327 | "%02hhx%02hhx%02hhx%02hhx" // bssid_info |
| 11328 | "%02hhx" // operclass |
| 11329 | "%02hhx" // channel |
| 11330 | "%02hhx", // phy_mode |
| 11331 | hex_bssid, |
| 11332 | neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff, |
| 11333 | (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff, |
| 11334 | neighborReports[i].opClass, |
| 11335 | neighborReports[i].channel, |
| 11336 | neighborReports[i].phyTable); |
| 11337 | |
| 11338 | snprintf(cmd, sizeof(cmd), |
| 11339 | "hostapd_cli set_neighbor " |
| 11340 | "%s " // bssid |
| 11341 | "ssid=%s " // ssid |
| 11342 | "nr=%s " // nr |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 11343 | "-i %s", |
| 11344 | bssid,hex_ssid,nr, interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11345 | |
| 11346 | if (WEXITSTATUS(system(cmd)) != 0) |
| 11347 | { |
| 11348 | wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd); |
| 11349 | } |
| 11350 | } |
| 11351 | |
| 11352 | return RETURN_OK; |
| 11353 | } |
| 11354 | |
| 11355 | INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct) |
| 11356 | { |
| 11357 | return RETURN_OK; |
| 11358 | } |
| 11359 | |
| 11360 | #ifdef _WIFI_HAL_TEST_ |
| 11361 | int main(int argc,char **argv) |
| 11362 | { |
| 11363 | int index; |
| 11364 | INT ret=0; |
| 11365 | char buf[1024]=""; |
| 11366 | |
| 11367 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11368 | if(argc<3) |
| 11369 | { |
| 11370 | if(argc==2) |
| 11371 | { |
| 11372 | if(!strcmp(argv[1], "init")) |
| 11373 | return wifi_init(); |
| 11374 | if(!strcmp(argv[1], "reset")) |
| 11375 | return wifi_reset(); |
| 11376 | if(!strcmp(argv[1], "wifi_getHalVersion")) |
| 11377 | { |
| 11378 | char buffer[64]; |
| 11379 | if(wifi_getHalVersion(buffer)==RETURN_OK) |
| 11380 | printf("Version: %s\n", buffer); |
| 11381 | else |
| 11382 | printf("Error in wifi_getHalVersion\n"); |
| 11383 | return RETURN_OK; |
| 11384 | } |
| 11385 | } |
| 11386 | printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n"); |
| 11387 | exit(-1); |
| 11388 | } |
| 11389 | |
| 11390 | index = atoi(argv[2]); |
| 11391 | if(strstr(argv[1], "wifi_getApName")!=NULL) |
| 11392 | { |
| 11393 | wifi_getApName(index,buf); |
| 11394 | printf("Ap name is %s \n",buf); |
| 11395 | return 0; |
| 11396 | } |
| 11397 | if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL) |
| 11398 | { |
| 11399 | BOOL b = FALSE; |
| 11400 | BOOL *output_bool = &b; |
| 11401 | wifi_getRadioAutoChannelEnable(index,output_bool); |
| 11402 | printf("Channel enabled = %d \n",b); |
| 11403 | return 0; |
| 11404 | } |
| 11405 | if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL) |
| 11406 | { |
| 11407 | wifi_getApWpaEncryptionMode(index,buf); |
| 11408 | printf("encryption enabled = %s\n",buf); |
| 11409 | return 0; |
| 11410 | } |
| 11411 | if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL) |
| 11412 | { |
| 11413 | BOOL b = FALSE; |
| 11414 | BOOL *output_bool = &b; |
| 11415 | wifi_getApSsidAdvertisementEnable(index,output_bool); |
| 11416 | printf("advertisment enabled = %d\n",b); |
| 11417 | return 0; |
| 11418 | } |
| 11419 | if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL) |
| 11420 | { |
| 11421 | if(argc <= 3 ) |
| 11422 | { |
| 11423 | printf("Insufficient arguments \n"); |
| 11424 | exit(-1); |
| 11425 | } |
| 11426 | |
| 11427 | char sta[20] = {'\0'}; |
| 11428 | ULLONG handle= 0; |
| 11429 | strcpy(sta,argv[3]); |
| 11430 | mac_address_t st; |
| 11431 | mac_addr_aton(st,sta); |
| 11432 | |
| 11433 | wifi_associated_dev_tid_stats_t tid_stats; |
| 11434 | wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle); |
| 11435 | for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats |
| 11436 | 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); |
| 11437 | } |
| 11438 | |
| 11439 | if(strstr(argv[1], "getApEnable")!=NULL) { |
| 11440 | BOOL enable; |
| 11441 | ret=wifi_getApEnable(index, &enable); |
| 11442 | printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret); |
| 11443 | } |
| 11444 | else if(strstr(argv[1], "setApEnable")!=NULL) { |
| 11445 | BOOL enable = atoi(argv[3]); |
| 11446 | ret=wifi_setApEnable(index, enable); |
| 11447 | printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret); |
| 11448 | } |
| 11449 | else if(strstr(argv[1], "getApStatus")!=NULL) { |
| 11450 | char status[64]; |
| 11451 | ret=wifi_getApStatus(index, status); |
| 11452 | printf("%s %d: %s, returns %d\n", argv[1], index, status, ret); |
| 11453 | } |
| 11454 | else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL) |
| 11455 | { |
| 11456 | wifi_getSSIDNameStatus(index,buf); |
| 11457 | printf("%s %d: active ssid : %s\n",argv[1], index,buf); |
| 11458 | return 0; |
| 11459 | } |
| 11460 | else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) { |
| 11461 | wifi_ssidTrafficStats2_t stats={0}; |
| 11462 | ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181 |
| 11463 | printf("%s %d: returns %d\n", argv[1], index, ret); |
| 11464 | printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent); |
| 11465 | printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived); |
| 11466 | printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent); |
| 11467 | printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived); |
| 11468 | printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount); |
| 11469 | printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount); |
| 11470 | printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount); |
| 11471 | printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount); |
| 11472 | printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount); |
| 11473 | printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount); |
| 11474 | printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent); |
| 11475 | printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived); |
| 11476 | printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent); |
| 11477 | printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived); |
| 11478 | printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent); |
| 11479 | printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived); |
| 11480 | printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent); |
| 11481 | printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived); |
| 11482 | printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent); |
| 11483 | printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied); |
| 11484 | printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived); |
| 11485 | } |
| 11486 | else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) { |
| 11487 | wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL; |
| 11488 | UINT array_size=0; |
| 11489 | UINT i=0; |
| 11490 | ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size); |
| 11491 | printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret); |
| 11492 | for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) { |
| 11493 | printf(" neighbor %d:\n", i); |
| 11494 | printf(" ap_SSID =%s\n", pt->ap_SSID); |
| 11495 | printf(" ap_BSSID =%s\n", pt->ap_BSSID); |
| 11496 | printf(" ap_Mode =%s\n", pt->ap_Mode); |
| 11497 | printf(" ap_Channel =%d\n", pt->ap_Channel); |
| 11498 | printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength); |
| 11499 | printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled); |
| 11500 | printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode); |
| 11501 | printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards); |
| 11502 | printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards); |
| 11503 | printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth); |
| 11504 | printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled); |
| 11505 | printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod); |
| 11506 | printf(" ap_Noise =%d\n", pt->ap_Noise); |
| 11507 | printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates); |
| 11508 | printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates); |
| 11509 | printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod); |
| 11510 | printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization); |
| 11511 | } |
| 11512 | if(neighbor_ap_array) |
| 11513 | free(neighbor_ap_array); //make sure to free the list |
| 11514 | } |
| 11515 | else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) { |
| 11516 | wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL; |
| 11517 | UINT array_size=0; |
| 11518 | UINT i=0; |
| 11519 | ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size); |
| 11520 | printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret); |
| 11521 | for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) { |
| 11522 | printf(" associated_dev %d:\n", i); |
| 11523 | printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard); |
| 11524 | printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth); |
| 11525 | printf(" cli_SNR =%d\n", pt->cli_SNR); |
| 11526 | printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources); |
| 11527 | printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck); |
| 11528 | printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck); |
| 11529 | printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent); |
| 11530 | printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived); |
| 11531 | printf(" cli_RSSI =%d\n", pt->cli_RSSI); |
| 11532 | printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI); |
| 11533 | printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI); |
| 11534 | printf(" cli_Disassociations =%d\n", pt->cli_Disassociations); |
| 11535 | printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures); |
| 11536 | } |
| 11537 | if(associated_dev_array) |
| 11538 | free(associated_dev_array); //make sure to free the list |
| 11539 | } |
| 11540 | |
| 11541 | if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL) |
| 11542 | { |
| 11543 | #define MAX_ARRAY_SIZE 64 |
| 11544 | int i, array_size; |
| 11545 | char *p, *ch_str; |
| 11546 | wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE]; |
| 11547 | |
| 11548 | if(argc != 5) |
| 11549 | { |
| 11550 | printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n"); |
| 11551 | exit(-1); |
| 11552 | } |
| 11553 | memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array)); |
| 11554 | |
| 11555 | for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p) |
| 11556 | { |
| 11557 | strtok_r(ch_str, ",", &p); |
| 11558 | input_output_channelStats_array[i].ch_number = atoi(ch_str); |
| 11559 | } |
| 11560 | wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size); |
| 11561 | if(!array_size) |
| 11562 | array_size=1;//Need to print current channel statistics |
| 11563 | for(i=0; i<array_size; i++) |
| 11564 | printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\ |
| 11565 | ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\ |
| 11566 | ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\ |
| 11567 | input_output_channelStats_array[i].ch_number,\ |
| 11568 | input_output_channelStats_array[i].ch_noise,\ |
| 11569 | input_output_channelStats_array[i].ch_utilization_busy_rx,\ |
| 11570 | input_output_channelStats_array[i].ch_utilization_busy_tx,\ |
| 11571 | input_output_channelStats_array[i].ch_utilization_busy,\ |
| 11572 | input_output_channelStats_array[i].ch_utilization_busy_ext,\ |
| 11573 | input_output_channelStats_array[i].ch_utilization_total); |
| 11574 | } |
| 11575 | |
| 11576 | if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL) |
| 11577 | { |
| 11578 | if(argc <= 3 ) |
| 11579 | { |
| 11580 | printf("Insufficient arguments \n"); |
| 11581 | exit(-1); |
| 11582 | } |
| 11583 | char mac_addr[20] = {'\0'}; |
| 11584 | wifi_device_t output_struct; |
| 11585 | int dev_index = atoi(argv[3]); |
| 11586 | |
| 11587 | wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct); |
| 11588 | mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress); |
| 11589 | 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); |
| 11590 | } |
| 11591 | |
| 11592 | if(strstr(argv[1],"wifi_setNeighborReports")!=NULL) |
| 11593 | { |
| 11594 | if (argc <= 3) |
| 11595 | { |
| 11596 | printf("Insufficient arguments\n"); |
| 11597 | exit(-1); |
| 11598 | } |
| 11599 | char args[256]; |
| 11600 | wifi_NeighborReport_t *neighborReports; |
| 11601 | |
| 11602 | neighborReports = calloc(argc - 2, sizeof(neighborReports)); |
| 11603 | if (!neighborReports) |
| 11604 | { |
| 11605 | printf("Failed to allocate memory"); |
| 11606 | exit(-1); |
| 11607 | } |
| 11608 | |
| 11609 | for (int i = 3; i < argc; ++i) |
| 11610 | { |
| 11611 | char *val; |
| 11612 | int j = 0; |
| 11613 | memset(args, 0, sizeof(args)); |
| 11614 | strncpy(args, argv[i], sizeof(args)); |
| 11615 | val = strtok(args, ";"); |
| 11616 | while (val != NULL) |
| 11617 | { |
| 11618 | if (j == 0) |
| 11619 | { |
| 11620 | mac_addr_aton(neighborReports[i - 3].bssid, val); |
| 11621 | } else if (j == 1) |
| 11622 | { |
| 11623 | neighborReports[i - 3].info = strtol(val, NULL, 16); |
| 11624 | } else if (j == 2) |
| 11625 | { |
| 11626 | neighborReports[i - 3].opClass = strtol(val, NULL, 16); |
| 11627 | } else if (j == 3) |
| 11628 | { |
| 11629 | neighborReports[i - 3].channel = strtol(val, NULL, 16); |
| 11630 | } else if (j == 4) |
| 11631 | { |
| 11632 | neighborReports[i - 3].phyTable = strtol(val, NULL, 16); |
| 11633 | } else { |
| 11634 | printf("Insufficient arguments]n\n"); |
| 11635 | exit(-1); |
| 11636 | } |
| 11637 | val = strtok(NULL, ";"); |
| 11638 | j++; |
| 11639 | } |
| 11640 | } |
| 11641 | |
| 11642 | INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports); |
| 11643 | if (ret != RETURN_OK) |
| 11644 | { |
| 11645 | printf("wifi_setNeighborReports ret = %d", ret); |
| 11646 | exit(-1); |
| 11647 | } |
| 11648 | } |
| 11649 | if(strstr(argv[1],"wifi_getRadioIfName")!=NULL) |
| 11650 | { |
| 11651 | if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK) |
| 11652 | printf("%s.\n", buf); |
| 11653 | else |
| 11654 | printf("Error returned\n"); |
| 11655 | } |
| 11656 | if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL) |
| 11657 | { |
| 11658 | if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK) |
| 11659 | printf("%s.\n", buf); |
| 11660 | else |
| 11661 | printf("Error returned\n"); |
| 11662 | } |
| 11663 | if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL) |
| 11664 | { |
| 11665 | if (argc <= 2) |
| 11666 | { |
| 11667 | printf("Insufficient arguments\n"); |
| 11668 | exit(-1); |
| 11669 | } |
| 11670 | char buf[64]= {'\0'}; |
| 11671 | wifi_getRadioOperatingChannelBandwidth(index,buf); |
| 11672 | printf("Current bandwidth is %s \n",buf); |
| 11673 | return 0; |
| 11674 | } |
| 11675 | if(strstr(argv[1],"pushRadioChannel2")!=NULL) |
| 11676 | { |
| 11677 | if (argc <= 5) |
| 11678 | { |
| 11679 | printf("Insufficient arguments\n"); |
| 11680 | exit(-1); |
| 11681 | } |
| 11682 | UINT channel = atoi(argv[3]); |
| 11683 | UINT width = atoi(argv[4]); |
| 11684 | UINT beacon = atoi(argv[5]); |
| 11685 | INT ret = wifi_pushRadioChannel2(index,channel,width,beacon); |
| 11686 | printf("Result = %d", ret); |
| 11687 | } |
| 11688 | |
| 11689 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11690 | return 0; |
| 11691 | } |
| 11692 | |
| 11693 | #endif |
| 11694 | |
| 11695 | #ifdef WIFI_HAL_VERSION_3 |
| 11696 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11697 | INT BitMapToTransmitRates(UINT bitMap, char *BasicRate) |
| 11698 | { |
| 11699 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11700 | if (bitMap & WIFI_BITRATE_1MBPS) |
| 11701 | strcat(BasicRate, "1,"); |
| 11702 | if (bitMap & WIFI_BITRATE_2MBPS) |
| 11703 | strcat(BasicRate, "2,"); |
| 11704 | if (bitMap & WIFI_BITRATE_5_5MBPS) |
| 11705 | strcat(BasicRate, "5.5,"); |
| 11706 | if (bitMap & WIFI_BITRATE_6MBPS) |
| 11707 | strcat(BasicRate, "6,"); |
| 11708 | if (bitMap & WIFI_BITRATE_9MBPS) |
| 11709 | strcat(BasicRate, "9,"); |
| 11710 | if (bitMap & WIFI_BITRATE_11MBPS) |
| 11711 | strcat(BasicRate, "11,"); |
| 11712 | if (bitMap & WIFI_BITRATE_12MBPS) |
| 11713 | strcat(BasicRate, "12,"); |
| 11714 | if (bitMap & WIFI_BITRATE_18MBPS) |
| 11715 | strcat(BasicRate, "18,"); |
| 11716 | if (bitMap & WIFI_BITRATE_24MBPS) |
| 11717 | strcat(BasicRate, "24,"); |
| 11718 | if (bitMap & WIFI_BITRATE_36MBPS) |
| 11719 | strcat(BasicRate, "36,"); |
| 11720 | if (bitMap & WIFI_BITRATE_48MBPS) |
| 11721 | strcat(BasicRate, "48,"); |
| 11722 | if (bitMap & WIFI_BITRATE_54MBPS) |
| 11723 | strcat(BasicRate, "54,"); |
| 11724 | if (strlen(BasicRate) != 0) // remove last comma |
| 11725 | BasicRate[strlen(BasicRate) - 1] = '\0'; |
| 11726 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11727 | return RETURN_OK; |
| 11728 | } |
| 11729 | |
| 11730 | INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap) |
| 11731 | { |
| 11732 | UINT BitMap = 0; |
| 11733 | char *rate; |
| 11734 | |
| 11735 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11736 | rate = strtok(BasicRatesList, ","); |
| 11737 | while(rate != NULL) |
| 11738 | { |
| 11739 | if (strcmp(rate, "1") == 0) |
| 11740 | BitMap |= WIFI_BITRATE_1MBPS; |
| 11741 | else if (strcmp(rate, "2") == 0) |
| 11742 | BitMap |= WIFI_BITRATE_2MBPS; |
| 11743 | else if (strcmp(rate, "5.5") == 0) |
| 11744 | BitMap |= WIFI_BITRATE_5_5MBPS; |
| 11745 | else if (strcmp(rate, "6") == 0) |
| 11746 | BitMap |= WIFI_BITRATE_6MBPS; |
| 11747 | else if (strcmp(rate, "9") == 0) |
| 11748 | BitMap |= WIFI_BITRATE_9MBPS; |
| 11749 | else if (strcmp(rate, "11") == 0) |
| 11750 | BitMap |= WIFI_BITRATE_11MBPS; |
| 11751 | else if (strcmp(rate, "12") == 0) |
| 11752 | BitMap |= WIFI_BITRATE_12MBPS; |
| 11753 | else if (strcmp(rate, "18") == 0) |
| 11754 | BitMap |= WIFI_BITRATE_18MBPS; |
| 11755 | else if (strcmp(rate, "24") == 0) |
| 11756 | BitMap |= WIFI_BITRATE_24MBPS; |
| 11757 | else if (strcmp(rate, "36") == 0) |
| 11758 | BitMap |= WIFI_BITRATE_36MBPS; |
| 11759 | else if (strcmp(rate, "48") == 0) |
| 11760 | BitMap |= WIFI_BITRATE_48MBPS; |
| 11761 | else if (strcmp(rate, "54") == 0) |
| 11762 | BitMap |= WIFI_BITRATE_54MBPS; |
| 11763 | rate = strtok(NULL, ","); |
| 11764 | } |
| 11765 | *basicRateBitMap = BitMap; |
| 11766 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11767 | return RETURN_OK; |
| 11768 | } |
| 11769 | |
| 11770 | // This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration. |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11771 | INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam) |
| 11772 | { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11773 | char buf[128] = {0}; |
| 11774 | char cmd[128] = {0}; |
| 11775 | char config_file[64] = {0}; |
| 11776 | int bandwidth; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 11777 | int set_mode = 0; |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11778 | wifi_radio_operationParam_t current_param; |
| 11779 | |
| 11780 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11781 | |
| 11782 | multiple_set = TRUE; |
| 11783 | if (wifi_getRadioOperatingParameters(index, ¤t_param) != RETURN_OK) { |
| 11784 | fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__); |
| 11785 | return RETURN_ERR; |
| 11786 | } |
| 11787 | if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) { |
| 11788 | if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) { |
| 11789 | fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__); |
| 11790 | return RETURN_ERR; |
| 11791 | } |
| 11792 | } |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 11793 | |
| 11794 | if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ) |
| 11795 | bandwidth = 20; |
| 11796 | else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ) |
| 11797 | bandwidth = 40; |
| 11798 | else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ) |
| 11799 | bandwidth = 80; |
| 11800 | else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ) |
| 11801 | bandwidth = 160; |
| 11802 | if (operationParam->autoChannelEnabled){ |
| 11803 | if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) { |
| 11804 | fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__); |
| 11805 | return RETURN_ERR; |
| 11806 | } |
| 11807 | }else{ |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11808 | if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) { |
| 11809 | fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__); |
| 11810 | return RETURN_ERR; |
| 11811 | } |
| 11812 | } |
developer | 5884e98 | 2022-10-06 10:52:50 +0800 | [diff] [blame] | 11813 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11814 | if (current_param.variant != operationParam->variant) { |
| 11815 | // Two different definition bit map, so need to check every bit. |
| 11816 | if (operationParam->variant & WIFI_80211_VARIANT_A) |
| 11817 | set_mode |= WIFI_MODE_A; |
| 11818 | if (operationParam->variant & WIFI_80211_VARIANT_B) |
| 11819 | set_mode |= WIFI_MODE_B; |
| 11820 | if (operationParam->variant & WIFI_80211_VARIANT_G) |
| 11821 | set_mode |= WIFI_MODE_G; |
| 11822 | if (operationParam->variant & WIFI_80211_VARIANT_N) |
| 11823 | set_mode |= WIFI_MODE_N; |
| 11824 | if (operationParam->variant & WIFI_80211_VARIANT_AC) |
| 11825 | set_mode |= WIFI_MODE_AC; |
| 11826 | if (operationParam->variant & WIFI_80211_VARIANT_AX) |
| 11827 | set_mode |= WIFI_MODE_AX; |
| 11828 | // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed. |
| 11829 | memset(buf, 0, sizeof(buf)); |
| 11830 | if (wifi_setRadioMode(index, buf, set_mode) != RETURN_OK) { |
| 11831 | fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__); |
| 11832 | return RETURN_ERR; |
| 11833 | } |
| 11834 | } |
| 11835 | if (current_param.dtimPeriod != operationParam->dtimPeriod) { |
| 11836 | if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) { |
| 11837 | fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__); |
| 11838 | return RETURN_ERR; |
| 11839 | } |
| 11840 | } |
| 11841 | if (current_param.beaconInterval != operationParam->beaconInterval) { |
| 11842 | if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) { |
| 11843 | fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__); |
| 11844 | return RETURN_ERR; |
| 11845 | } |
| 11846 | } |
| 11847 | if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) { |
| 11848 | BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf); |
| 11849 | if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) { |
| 11850 | fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__); |
| 11851 | return RETURN_ERR; |
| 11852 | } |
| 11853 | } |
| 11854 | if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) { |
| 11855 | if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) { |
| 11856 | fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__); |
| 11857 | return RETURN_ERR; |
| 11858 | } |
| 11859 | } |
| 11860 | if (current_param.guardInterval != operationParam->guardInterval) { |
| 11861 | if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) { |
| 11862 | fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__); |
| 11863 | return RETURN_ERR; |
| 11864 | } |
| 11865 | } |
| 11866 | if (current_param.transmitPower != operationParam->transmitPower) { |
| 11867 | if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) { |
| 11868 | fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__); |
| 11869 | return RETURN_ERR; |
| 11870 | } |
| 11871 | } |
| 11872 | if (current_param.rtsThreshold != operationParam->rtsThreshold) { |
| 11873 | if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) { |
| 11874 | fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__); |
| 11875 | return RETURN_ERR; |
| 11876 | } |
| 11877 | } |
| 11878 | if (current_param.obssCoex != operationParam->obssCoex) { |
| 11879 | if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) { |
| 11880 | fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__); |
| 11881 | return RETURN_ERR; |
| 11882 | } |
| 11883 | } |
| 11884 | if (current_param.stbcEnable != operationParam->stbcEnable) { |
| 11885 | if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) { |
| 11886 | fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__); |
| 11887 | return RETURN_ERR; |
| 11888 | } |
| 11889 | } |
| 11890 | if (current_param.greenFieldEnable != operationParam->greenFieldEnable) { |
| 11891 | if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) { |
| 11892 | fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__); |
| 11893 | return RETURN_ERR; |
| 11894 | } |
| 11895 | } |
| 11896 | |
| 11897 | // if enable is true, then restart the radio |
| 11898 | wifi_setRadioEnable(index, FALSE); |
| 11899 | if (operationParam->enable == TRUE) |
| 11900 | wifi_setRadioEnable(index, TRUE); |
| 11901 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11902 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11903 | return RETURN_OK; |
| 11904 | } |
| 11905 | |
| 11906 | INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam) |
| 11907 | { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11908 | char band[64] = {0}; |
| 11909 | char buf[256] = {0}; |
| 11910 | char config_file[64] = {0}; |
| 11911 | char cmd[128] = {0}; |
| 11912 | int ret = RETURN_ERR; |
| 11913 | int mode = 0; |
| 11914 | ULONG channel = 0; |
| 11915 | BOOL enabled = FALSE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11916 | |
| 11917 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11918 | printf("Entering %s index = %d\n", __func__, (int)index); |
| 11919 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11920 | memset(operationParam, 0, sizeof(wifi_radio_operationParam_t)); |
| 11921 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index); |
| 11922 | if (wifi_getRadioEnable(index, &enabled) != RETURN_OK) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11923 | { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11924 | fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11925 | return RETURN_ERR; |
| 11926 | } |
| 11927 | operationParam->enable = enabled; |
| 11928 | |
| 11929 | memset(band, 0, sizeof(band)); |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11930 | if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11931 | { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11932 | fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11933 | return RETURN_ERR; |
| 11934 | } |
| 11935 | |
| 11936 | if (!strcmp(band, "2.4GHz")) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11937 | operationParam->band = WIFI_FREQUENCY_2_4_BAND; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11938 | else if (!strcmp(band, "5GHz")) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11939 | operationParam->band = WIFI_FREQUENCY_5_BAND; |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11940 | else if (!strcmp(band, "6GHz")) |
| 11941 | operationParam->band = WIFI_FREQUENCY_6_BAND; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11942 | else |
| 11943 | { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11944 | fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index, |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11945 | band); |
| 11946 | } |
| 11947 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11948 | wifi_hostapdRead(config_file, "channel", buf, sizeof(buf)); |
| 11949 | if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) { |
| 11950 | operationParam->channel = 0; |
| 11951 | operationParam->autoChannelEnabled = TRUE; |
| 11952 | } else { |
| 11953 | operationParam->channel = strtol(buf, NULL, 10); |
| 11954 | operationParam->autoChannelEnabled = FALSE; |
| 11955 | } |
| 11956 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11957 | memset(buf, 0, sizeof(buf)); |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11958 | if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) { |
| 11959 | fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__); |
| 11960 | return RETURN_ERR; |
| 11961 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11962 | if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ; |
| 11963 | else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ; |
| 11964 | else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ; |
developer | 87d5a78 | 2022-10-07 13:23:27 +0800 | [diff] [blame] | 11965 | else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ; |
| 11966 | else if (!strcmp(buf, "80+80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80_80MHZ; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11967 | else |
| 11968 | { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11969 | fprintf(stderr, "Unknown channel bandwidth: %s\n", buf); |
| 11970 | return false; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11971 | } |
| 11972 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11973 | if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) { |
| 11974 | fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__); |
| 11975 | return RETURN_ERR; |
| 11976 | } |
| 11977 | // Two different definition bit map, so need to check every bit. |
| 11978 | if (mode & WIFI_MODE_A) |
| 11979 | operationParam->variant |= WIFI_80211_VARIANT_A; |
| 11980 | if (mode & WIFI_MODE_B) |
| 11981 | operationParam->variant |= WIFI_80211_VARIANT_B; |
| 11982 | if (mode & WIFI_MODE_G) |
| 11983 | operationParam->variant |= WIFI_80211_VARIANT_G; |
| 11984 | if (mode & WIFI_MODE_N) |
| 11985 | operationParam->variant |= WIFI_80211_VARIANT_N; |
| 11986 | if (mode & WIFI_MODE_AC) |
| 11987 | operationParam->variant |= WIFI_80211_VARIANT_AC; |
| 11988 | if (mode & WIFI_MODE_AX) |
| 11989 | operationParam->variant |= WIFI_80211_VARIANT_AX; |
| 11990 | if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) { |
| 11991 | fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__); |
| 11992 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 11993 | } |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 11994 | if (wifi_getApDTIMInterval(index, &operationParam->dtimPeriod) != RETURN_OK) { |
| 11995 | fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__); |
| 11996 | return RETURN_ERR; |
| 11997 | } |
| 11998 | if (wifi_getRadioBeaconPeriod(index, &operationParam->dtimPeriod) != RETURN_OK) { |
| 11999 | fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__); |
| 12000 | return RETURN_ERR; |
| 12001 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12002 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12003 | memset(buf, 0, sizeof(buf)); |
| 12004 | if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) { |
| 12005 | fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__); |
| 12006 | return RETURN_ERR; |
| 12007 | } |
| 12008 | TransmitRatesToBitMap(buf, &operationParam->basicDataTransmitRates); |
| 12009 | |
| 12010 | memset(buf, 0, sizeof(buf)); |
| 12011 | if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) { |
| 12012 | fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__); |
| 12013 | return RETURN_ERR; |
| 12014 | } |
| 12015 | TransmitRatesToBitMap(buf, &operationParam->operationalDataTransmitRates); |
| 12016 | |
| 12017 | memset(buf, 0, sizeof(buf)); |
| 12018 | wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf)); |
| 12019 | operationParam->fragmentationThreshold = strtoul(buf, NULL, 10); |
| 12020 | |
| 12021 | if (wifi_getGuardInterval(index, &operationParam->guardInterval) != RETURN_OK) { |
| 12022 | fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__); |
| 12023 | return RETURN_ERR; |
| 12024 | } |
| 12025 | if (wifi_getRadioPercentageTransmitPower(index, &operationParam->transmitPower) != RETURN_OK) { |
| 12026 | fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__); |
| 12027 | return RETURN_ERR; |
| 12028 | } |
| 12029 | |
| 12030 | memset(buf, 0, sizeof(buf)); |
| 12031 | wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf)); |
| 12032 | if (strcmp(buf, "-1") == 0) { |
| 12033 | operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value |
| 12034 | operationParam->ctsProtection = FALSE; |
| 12035 | } else { |
| 12036 | operationParam->rtsThreshold = strtoul(buf, NULL, 10); |
| 12037 | operationParam->ctsProtection = TRUE; |
| 12038 | } |
| 12039 | |
| 12040 | memset(buf, 0, sizeof(buf)); |
| 12041 | wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf)); |
| 12042 | if (strcmp(buf, "0") == 0) |
| 12043 | operationParam->obssCoex = FALSE; |
| 12044 | else |
| 12045 | operationParam->obssCoex = TRUE; |
| 12046 | |
| 12047 | snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file); |
| 12048 | _syscmd(cmd, buf, sizeof(buf)); |
| 12049 | if (strlen(buf) != 0) |
| 12050 | operationParam->stbcEnable = TRUE; |
| 12051 | else |
| 12052 | operationParam->stbcEnable = FALSE; |
| 12053 | |
| 12054 | if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) { |
| 12055 | fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__); |
| 12056 | return RETURN_ERR; |
| 12057 | } |
| 12058 | |
| 12059 | // Below value is hardcoded |
| 12060 | |
| 12061 | operationParam->numSecondaryChannels = 0; |
| 12062 | for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) { |
| 12063 | operationParam->channelSecondary[i] = 0; |
| 12064 | } |
| 12065 | operationParam->csa_beacon_count = 15; |
| 12066 | operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12067 | |
| 12068 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12069 | return RETURN_OK; |
| 12070 | } |
| 12071 | |
| 12072 | static int array_index_to_vap_index(UINT radioIndex, int arrayIndex) |
| 12073 | { |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12074 | int max_radio_num = 0; |
| 12075 | |
| 12076 | wifi_getMaxRadioNumber(&max_radio_num); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 12077 | if (radioIndex >= max_radio_num) { |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12078 | fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex); |
| 12079 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12080 | } |
| 12081 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12082 | return (arrayIndex * max_radio_num) + radioIndex; |
| 12083 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12084 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12085 | wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) { |
| 12086 | if (strncmp(beaconRate, "1Mbps", 5) == 0) |
| 12087 | return WIFI_BITRATE_1MBPS; |
| 12088 | else if (strncmp(beaconRate, "2Mbps", 5) == 0) |
| 12089 | return WIFI_BITRATE_2MBPS; |
| 12090 | else if (strncmp(beaconRate, "5.5Mbps", 7) == 0) |
| 12091 | return WIFI_BITRATE_5_5MBPS; |
| 12092 | else if (strncmp(beaconRate, "6Mbps", 5) == 0) |
| 12093 | return WIFI_BITRATE_6MBPS; |
| 12094 | else if (strncmp(beaconRate, "9Mbps", 5) == 0) |
| 12095 | return WIFI_BITRATE_9MBPS; |
| 12096 | else if (strncmp(beaconRate, "11Mbps", 6) == 0) |
| 12097 | return WIFI_BITRATE_11MBPS; |
| 12098 | else if (strncmp(beaconRate, "12Mbps", 6) == 0) |
| 12099 | return WIFI_BITRATE_12MBPS; |
| 12100 | else if (strncmp(beaconRate, "18Mbps", 6) == 0) |
| 12101 | return WIFI_BITRATE_18MBPS; |
| 12102 | else if (strncmp(beaconRate, "24Mbps", 6) == 0) |
| 12103 | return WIFI_BITRATE_24MBPS; |
| 12104 | else if (strncmp(beaconRate, "36Mbps", 6) == 0) |
| 12105 | return WIFI_BITRATE_36MBPS; |
| 12106 | else if (strncmp(beaconRate, "48Mbps", 6) == 0) |
| 12107 | return WIFI_BITRATE_48MBPS; |
| 12108 | else if (strncmp(beaconRate, "54Mbps", 6) == 0) |
| 12109 | return WIFI_BITRATE_54MBPS; |
| 12110 | return WIFI_BITRATE_DEFAULT; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12111 | } |
| 12112 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12113 | INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str) |
| 12114 | { |
| 12115 | if (beacon == WIFI_BITRATE_1MBPS) |
| 12116 | strcpy(beacon_str, "1Mbps"); |
| 12117 | else if (beacon == WIFI_BITRATE_2MBPS) |
| 12118 | strcpy(beacon_str, "2Mbps"); |
| 12119 | else if (beacon == WIFI_BITRATE_5_5MBPS) |
| 12120 | strcpy(beacon_str, "5.5Mbps"); |
| 12121 | else if (beacon == WIFI_BITRATE_6MBPS) |
| 12122 | strcpy(beacon_str, "6Mbps"); |
| 12123 | else if (beacon == WIFI_BITRATE_9MBPS) |
| 12124 | strcpy(beacon_str, "9Mbps"); |
| 12125 | else if (beacon == WIFI_BITRATE_11MBPS) |
| 12126 | strcpy(beacon_str, "11Mbps"); |
| 12127 | else if (beacon == WIFI_BITRATE_12MBPS) |
| 12128 | strcpy(beacon_str, "12Mbps"); |
| 12129 | else if (beacon == WIFI_BITRATE_18MBPS) |
| 12130 | strcpy(beacon_str, "18Mbps"); |
| 12131 | else if (beacon == WIFI_BITRATE_24MBPS) |
| 12132 | strcpy(beacon_str, "24Mbps"); |
| 12133 | else if (beacon == WIFI_BITRATE_36MBPS) |
| 12134 | strcpy(beacon_str, "36Mbps"); |
| 12135 | else if (beacon == WIFI_BITRATE_48MBPS) |
| 12136 | strcpy(beacon_str, "48Mbps"); |
| 12137 | else if (beacon == WIFI_BITRATE_54MBPS) |
| 12138 | strcpy(beacon_str, "54Mbps"); |
| 12139 | return RETURN_OK; |
| 12140 | } |
| 12141 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12142 | INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map) |
| 12143 | { |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12144 | INT mode = 0; |
| 12145 | INT ret = -1; |
| 12146 | INT output = 0; |
| 12147 | int i = 0; |
| 12148 | int vap_index = 0; |
| 12149 | BOOL enabled = FALSE; |
| 12150 | char buf[256] = {0}; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 12151 | wifi_vap_security_t security = {0}; |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12152 | map->num_vaps = 5; // Hardcoded |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12153 | |
| 12154 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12155 | printf("Entering %s index = %d\n", __func__, (int)index); |
| 12156 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12157 | for (i = 0; i < 5; i++) |
| 12158 | { |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12159 | map->vap_array[i].radio_index = index; |
| 12160 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12161 | vap_index = array_index_to_vap_index(index, i); |
| 12162 | if (vap_index < 0) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12163 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12164 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12165 | strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12166 | |
| 12167 | map->vap_array[i].vap_index = vap_index; |
| 12168 | |
| 12169 | memset(buf, 0, sizeof(buf)); |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12170 | ret = wifi_getApName(vap_index, buf); |
| 12171 | if (ret != RETURN_OK) { |
| 12172 | printf("%s: wifi_getApName return error\n", __func__); |
| 12173 | return RETURN_ERR; |
| 12174 | } |
| 12175 | snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf); |
| 12176 | |
| 12177 | memset(buf, 0, sizeof(buf)); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12178 | ret = wifi_getSSIDName(vap_index, buf); |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12179 | if (ret != RETURN_OK) { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12180 | printf("%s: wifi_getSSIDName return error\n", __func__); |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12181 | return RETURN_ERR; |
| 12182 | } |
| 12183 | snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12184 | |
| 12185 | ret = wifi_getSSIDEnable(vap_index, &enabled); |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12186 | if (ret != RETURN_OK) { |
| 12187 | printf("%s: wifi_getSSIDEnable return error\n", __func__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12188 | return RETURN_ERR; |
| 12189 | } |
| 12190 | map->vap_array[i].u.bss_info.enabled = enabled; |
| 12191 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12192 | ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled); |
| 12193 | if (ret != RETURN_OK) { |
| 12194 | printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__); |
| 12195 | return RETURN_ERR; |
| 12196 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12197 | map->vap_array[i].u.bss_info.showSsid = enabled; |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12198 | |
| 12199 | ret = wifi_getApIsolationEnable(vap_index, &enabled); |
| 12200 | if (ret != RETURN_OK) { |
| 12201 | printf("%s: wifi_getApIsolationEnable return error\n", __func__); |
| 12202 | return RETURN_ERR; |
| 12203 | } |
| 12204 | map->vap_array[i].u.bss_info.isolation = enabled; |
| 12205 | |
| 12206 | ret = wifi_getApMaxAssociatedDevices(vap_index, &output); |
| 12207 | if (ret != RETURN_OK) { |
| 12208 | printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__); |
| 12209 | return RETURN_ERR; |
| 12210 | } |
| 12211 | map->vap_array[i].u.bss_info.bssMaxSta = output; |
| 12212 | |
| 12213 | ret = wifi_getBSSTransitionActivation(vap_index, &enabled); |
| 12214 | if (ret != RETURN_OK) { |
| 12215 | printf("%s: wifi_getBSSTransitionActivation return error\n", __func__); |
| 12216 | return RETURN_ERR; |
| 12217 | } |
| 12218 | map->vap_array[i].u.bss_info.bssTransitionActivated = enabled; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12219 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12220 | ret = wifi_getNeighborReportActivation(vap_index, &enabled); |
| 12221 | if (ret != RETURN_OK) { |
| 12222 | printf("%s: wifi_getNeighborReportActivation return error\n", __func__); |
| 12223 | return RETURN_ERR; |
| 12224 | } |
| 12225 | map->vap_array[i].u.bss_info.nbrReportActivated = enabled; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12226 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12227 | ret = wifi_getApSecurity(vap_index, &security); |
| 12228 | if (ret != RETURN_OK) { |
| 12229 | printf("%s: wifi_getApSecurity return error\n", __func__); |
| 12230 | return RETURN_ERR; |
| 12231 | } |
| 12232 | map->vap_array[i].u.bss_info.security = security; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12233 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12234 | ret = wifi_getApMacAddressControlMode(vap_index, &mode); |
| 12235 | if (ret != RETURN_OK) { |
| 12236 | printf("%s: wifi_getApMacAddressControlMode return error\n", __func__); |
| 12237 | return RETURN_ERR; |
| 12238 | } |
| 12239 | if (mode == 0) |
| 12240 | map->vap_array[i].u.bss_info.mac_filter_enable = FALSE; |
| 12241 | else |
| 12242 | map->vap_array[i].u.bss_info.mac_filter_enable = TRUE; |
| 12243 | if (mode == 1) |
| 12244 | map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list; |
| 12245 | else if (mode == 2) |
| 12246 | map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12247 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12248 | ret = wifi_getApWmmEnable(vap_index, &enabled); |
| 12249 | if (ret != RETURN_OK) { |
| 12250 | printf("%s: wifi_getApWmmEnable return error\n", __func__); |
| 12251 | return RETURN_ERR; |
| 12252 | } |
| 12253 | map->vap_array[i].u.bss_info.wmm_enabled = enabled; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12254 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12255 | ret = wifi_getApUAPSDCapability(vap_index, &enabled); |
| 12256 | if (ret != RETURN_OK) { |
| 12257 | printf("%s: wifi_getApUAPSDCapability return error\n", __func__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12258 | return RETURN_ERR; |
| 12259 | } |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12260 | map->vap_array[i].u.bss_info.UAPSDEnabled = enabled; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12261 | |
| 12262 | memset(buf, 0, sizeof(buf)); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12263 | ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf); |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12264 | if (ret != RETURN_OK) { |
| 12265 | printf("%s: wifi_getApBeaconRate return error\n", __func__); |
| 12266 | return RETURN_ERR; |
| 12267 | } |
| 12268 | map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12269 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12270 | memset(buf, 0, sizeof(buf)); |
| 12271 | ret = wifi_getBaseBSSID(vap_index, buf); |
| 12272 | if (ret != RETURN_OK) { |
| 12273 | printf("%s: wifi_getBaseBSSID return error\n", __func__); |
| 12274 | return RETURN_ERR; |
| 12275 | } |
| 12276 | sscanf(buf, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", |
| 12277 | &map->vap_array[i].u.bss_info.bssid[0], |
| 12278 | &map->vap_array[i].u.bss_info.bssid[1], |
| 12279 | &map->vap_array[i].u.bss_info.bssid[2], |
| 12280 | &map->vap_array[i].u.bss_info.bssid[3], |
| 12281 | &map->vap_array[i].u.bss_info.bssid[4], |
| 12282 | &map->vap_array[i].u.bss_info.bssid[5]); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12283 | // fprintf(stderr, "%s index %d: mac: %02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx\n", __func__, vap_index, map->vap_array[i].u.bss_info.bssid[0], map->vap_array[i].u.bss_info.bssid[1], map->vap_array[i].u.bss_info.bssid[2], map->vap_array[i].u.bss_info.bssid[3], map->vap_array[i].u.bss_info.bssid[4], map->vap_array[i].u.bss_info.bssid[5]); |
| 12284 | |
| 12285 | ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled); |
| 12286 | if (ret != RETURN_OK) { |
| 12287 | fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__); |
| 12288 | return RETURN_ERR; |
| 12289 | } |
| 12290 | map->vap_array[i].u.bss_info.mcast2ucast = enabled; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12291 | |
developer | c086fb7 | 2022-10-04 10:18:22 +0800 | [diff] [blame] | 12292 | // TODO: wps, noack |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12293 | } |
| 12294 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12295 | return RETURN_OK; |
| 12296 | } |
| 12297 | |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12298 | void checkVapStatus(int apIndex, bool *enable) |
| 12299 | { |
| 12300 | char if_name[16] = {0}; |
| 12301 | char cmd[128] = {0}; |
| 12302 | char buf[128] = {0}; |
| 12303 | |
| 12304 | *enable = FALSE; |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 12305 | if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK) |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12306 | return; |
| 12307 | |
| 12308 | snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name); |
| 12309 | _syscmd(cmd, buf, sizeof(buf)); |
| 12310 | if (strlen(buf) > 0) |
| 12311 | *enable = TRUE; |
| 12312 | return; |
| 12313 | } |
| 12314 | |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 12315 | static int prepareInterface(UINT apIndex, char *new_interface) |
| 12316 | { |
| 12317 | char cur_interface[16] = {0}; |
| 12318 | char config_file[128] = {0}; |
| 12319 | char cmd[128] = {0}; |
| 12320 | char buf[16] = {0}; |
| 12321 | int max_radio_num = 0; |
| 12322 | int radioIndex = -1; |
| 12323 | int phyIndex = -1; |
| 12324 | |
| 12325 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 12326 | wifi_hostapdRead(config_file, "interface", cur_interface, sizeof(cur_interface)); |
| 12327 | |
| 12328 | if (strncmp(cur_interface, new_interface, sizeof(cur_interface)) != 0) { |
| 12329 | wifi_getMaxRadioNumber(&max_radio_num); |
| 12330 | radioIndex = apIndex % max_radio_num; |
| 12331 | phyIndex = radio_index_to_phy(radioIndex); |
| 12332 | // disable and del old interface, then add new interface |
| 12333 | wifi_setApEnable(apIndex, FALSE); |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12334 | snprintf(cmd, sizeof(cmd), "iw %s del && iw phy%d interface add %s type __ap", cur_interface, phyIndex, new_interface); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 12335 | _syscmd(cmd, buf, sizeof(buf)); |
| 12336 | } |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12337 | // update the vap status file |
| 12338 | snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=1' %s", cur_interface, new_interface, VAP_STATUS_FILE); |
| 12339 | _syscmd(cmd, buf, sizeof(buf)); |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 12340 | return RETURN_OK; |
| 12341 | } |
| 12342 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12343 | INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map) |
| 12344 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 12345 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12346 | unsigned int i; |
| 12347 | wifi_vap_info_t *vap_info = NULL; |
| 12348 | int acl_mode; |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12349 | int ret = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12350 | char *sec_str = NULL; |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12351 | char buf[256] = {0}; |
| 12352 | char cmd[128] = {0}; |
| 12353 | char config_file[64] = {0}; |
| 12354 | char bssid[32] = {0}; |
| 12355 | char psk_file[64] = {0}; |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12356 | bool enable = FALSE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12357 | |
| 12358 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12359 | printf("Entering %s index = %d\n", __func__, (int)index); |
| 12360 | for (i = 0; i < map->num_vaps; i++) |
| 12361 | { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12362 | multiple_set = TRUE; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12363 | vap_info = &map->vap_array[i]; |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12364 | |
| 12365 | // Check vap status file to enable multiple ap if the system boot. |
| 12366 | checkVapStatus(vap_info->vap_index, &enable); |
| 12367 | if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE) |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12368 | continue; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12369 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12370 | fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i); |
| 12371 | |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12372 | if (wifi_getApEnable(vap_info->vap_index, &enable) != RETURN_OK) |
| 12373 | enable = FALSE; |
| 12374 | |
| 12375 | // multi-ap first up need to copy current radio config |
| 12376 | if (vap_info->radio_index != vap_info->vap_index && enable == FALSE) { |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12377 | snprintf(cmd, sizeof(cmd), "cp %s%d.conf %s%d.conf", CONFIG_PREFIX, vap_info->radio_index, CONFIG_PREFIX, vap_info->vap_index); |
| 12378 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12379 | if (strlen(vap_info->vap_name) == 0) // default name of the interface is wifiX |
| 12380 | snprintf(vap_info->vap_name, 16, "wifi%d", vap_info->vap_index); |
| 12381 | } else { |
| 12382 | // Check whether the interface name is valid or this ap change it. |
| 12383 | int apIndex = -1; |
| 12384 | wifi_getApIndexFromName(vap_info->vap_name, &apIndex); |
| 12385 | if (apIndex != -1 && apIndex != vap_info->vap_index) |
| 12386 | continue; |
| 12387 | prepareInterface(vap_info->vap_index, vap_info->vap_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12388 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12389 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12390 | struct params params[3]; |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12391 | params[0].name = "interface"; |
| 12392 | params[0].value = vap_info->vap_name; |
| 12393 | mac_addr_ntoa(bssid, vap_info->u.bss_info.bssid); |
| 12394 | params[1].name = "bssid"; |
| 12395 | params[1].value = bssid; |
developer | 431128d | 2022-12-16 15:30:41 +0800 | [diff] [blame] | 12396 | snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index); |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12397 | params[2].name = "wpa_psk_file"; |
| 12398 | params[2].value = psk_file; |
| 12399 | |
| 12400 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index); |
| 12401 | wifi_hostapdWrite(config_file, params, 3); |
| 12402 | |
| 12403 | snprintf(cmd, sizeof(cmd), "touch %s", psk_file); |
| 12404 | _syscmd(cmd, buf, sizeof(buf)); |
| 12405 | |
| 12406 | ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid); |
| 12407 | if (ret != RETURN_OK) { |
| 12408 | fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__); |
| 12409 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12410 | } |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12411 | |
| 12412 | ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid); |
| 12413 | if (ret != RETURN_OK) { |
| 12414 | fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__); |
| 12415 | return RETURN_ERR; |
| 12416 | } |
| 12417 | |
| 12418 | ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation); |
| 12419 | if (ret != RETURN_OK) { |
| 12420 | fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__); |
| 12421 | return RETURN_ERR; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12422 | } |
| 12423 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12424 | ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta); |
| 12425 | if (ret != RETURN_OK) { |
| 12426 | fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__); |
| 12427 | return RETURN_ERR; |
| 12428 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12429 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12430 | ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated); |
| 12431 | if (ret != RETURN_OK) { |
| 12432 | fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__); |
| 12433 | return RETURN_ERR; |
| 12434 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12435 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12436 | ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated); |
| 12437 | if (ret != RETURN_OK) { |
| 12438 | fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__); |
| 12439 | return RETURN_ERR; |
| 12440 | } |
| 12441 | |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 12442 | if (vap_info->u.bss_info.mac_filter_enable == false){ |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12443 | acl_mode = 0; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 12444 | }else { |
| 12445 | if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){ |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12446 | acl_mode = 2; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 12447 | snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index); |
| 12448 | _syscmd(cmd, buf, sizeof(buf)); |
| 12449 | }else{ |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12450 | acl_mode = 1; |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 12451 | } |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12452 | } |
| 12453 | |
| 12454 | ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled); |
| 12455 | if (ret != RETURN_OK) { |
| 12456 | fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__); |
| 12457 | return RETURN_ERR; |
| 12458 | } |
| 12459 | |
| 12460 | ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled); |
| 12461 | if (ret != RETURN_OK) { |
| 12462 | fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__); |
| 12463 | return RETURN_ERR; |
| 12464 | } |
| 12465 | |
| 12466 | memset(buf, 0, sizeof(buf)); |
| 12467 | beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf); |
| 12468 | // fprintf(stderr, "%s: beaconrate: %d, buf: %s\n", __func__, vap_info->u.bss_info.beaconRate, buf); |
| 12469 | ret = wifi_setApBeaconRate(vap_info->radio_index, buf); |
| 12470 | if (ret != RETURN_OK) { |
| 12471 | fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__); |
| 12472 | return RETURN_ERR; |
| 12473 | } |
| 12474 | |
| 12475 | ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast); |
| 12476 | if (ret != RETURN_OK) { |
| 12477 | fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__); |
| 12478 | return RETURN_ERR; |
| 12479 | } |
| 12480 | |
| 12481 | wifi_setApEnable(vap_info->vap_index, TRUE); |
| 12482 | multiple_set = FALSE; |
| 12483 | |
| 12484 | // If config use hostapd_cli to set, we calling these type of functions after enable the ap. |
| 12485 | ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security); |
| 12486 | if (ret != RETURN_OK) { |
| 12487 | fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__); |
| 12488 | return RETURN_ERR; |
| 12489 | } |
| 12490 | |
| 12491 | ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode); |
| 12492 | if (ret != RETURN_OK) { |
| 12493 | fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__); |
| 12494 | return RETURN_ERR; |
| 12495 | } |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12496 | |
developer | 1d57d00 | 2022-10-12 18:03:15 +0800 | [diff] [blame] | 12497 | // TODO mgmtPowerControl, interworking, wps |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12498 | } |
| 12499 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12500 | return RETURN_OK; |
| 12501 | } |
| 12502 | |
| 12503 | int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr) |
| 12504 | { |
| 12505 | char *token, *next; |
| 12506 | const char s[2] = ","; |
| 12507 | int count =0; |
| 12508 | |
| 12509 | /* get the first token */ |
| 12510 | token = strtok_r(pchannels, s, &next); |
| 12511 | |
| 12512 | /* walk through other tokens */ |
| 12513 | while( token != NULL && count < MAX_CHANNELS) { |
| 12514 | chlistptr->channels_list[count++] = atoi(token); |
| 12515 | token = strtok_r(NULL, s, &next); |
| 12516 | } |
| 12517 | |
| 12518 | return count; |
| 12519 | } |
| 12520 | |
| 12521 | static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap) |
| 12522 | { |
| 12523 | INT status; |
| 12524 | wifi_channels_list_t *chlistp; |
| 12525 | CHAR output_string[64]; |
| 12526 | CHAR pchannels[128]; |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12527 | wifi_band band; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 12528 | int phyId = 0; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12529 | |
| 12530 | if(rcap == NULL) |
| 12531 | { |
| 12532 | return RETURN_ERR; |
| 12533 | } |
| 12534 | |
| 12535 | rcap->numSupportedFreqBand = 1; |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12536 | band = wifi_index_to_band(radioIndex); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12537 | |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12538 | if (band == band_2_4) |
| 12539 | rcap->band[0] = WIFI_FREQUENCY_2_4_BAND; |
| 12540 | else if (band == band_5) |
| 12541 | rcap->band[0] = WIFI_FREQUENCY_5_BAND; |
| 12542 | else if (band == band_6) |
| 12543 | rcap->band[0] = WIFI_FREQUENCY_6_BAND; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12544 | |
| 12545 | chlistp = &(rcap->channel_list[0]); |
| 12546 | memset(pchannels, 0, sizeof(pchannels)); |
| 12547 | |
| 12548 | /* possible number of radio channels */ |
| 12549 | status = wifi_getRadioPossibleChannels(radioIndex, pchannels); |
| 12550 | { |
| 12551 | printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels); |
| 12552 | } |
| 12553 | /* Number of channels and list*/ |
| 12554 | chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp); |
| 12555 | |
| 12556 | /* autoChannelSupported */ |
| 12557 | /* always ON with wifi_getRadioAutoChannelSupported */ |
| 12558 | rcap->autoChannelSupported = TRUE; |
| 12559 | |
| 12560 | /* DCSSupported */ |
| 12561 | /* always ON with wifi_getRadioDCSSupported */ |
| 12562 | rcap->DCSSupported = TRUE; |
| 12563 | |
| 12564 | /* zeroDFSSupported - TBD */ |
| 12565 | rcap->zeroDFSSupported = FALSE; |
| 12566 | |
| 12567 | /* Supported Country List*/ |
| 12568 | memset(output_string, 0, sizeof(output_string)); |
| 12569 | status = wifi_getRadioCountryCode(radioIndex, output_string); |
| 12570 | if( status != 0 ) { |
| 12571 | printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string); |
| 12572 | return RETURN_ERR; |
| 12573 | } else { |
| 12574 | printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string); |
| 12575 | } |
| 12576 | if(!strcmp(output_string,"US")){ |
| 12577 | rcap->countrySupported[0] = wifi_countrycode_US; |
| 12578 | rcap->countrySupported[1] = wifi_countrycode_CA; |
| 12579 | } else if (!strcmp(output_string,"CA")) { |
| 12580 | rcap->countrySupported[0] = wifi_countrycode_CA; |
| 12581 | rcap->countrySupported[1] = wifi_countrycode_US; |
| 12582 | } else { |
| 12583 | printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string); |
| 12584 | } |
| 12585 | |
| 12586 | rcap->numcountrySupported = 2; |
| 12587 | |
| 12588 | /* csi */ |
| 12589 | rcap->csi.maxDevices = 8; |
| 12590 | rcap->csi.soudingFrameSupported = TRUE; |
| 12591 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 12592 | phyId = radio_index_to_phy(radioIndex); |
| 12593 | snprintf(rcap->ifaceName, 64, "%s%d", RADIO_PREFIX, phyId); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12594 | |
| 12595 | /* channelWidth - all supported bandwidths */ |
| 12596 | int i=0; |
| 12597 | rcap->channelWidth[i] = 0; |
| 12598 | if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) { |
| 12599 | rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ | |
| 12600 | WIFI_CHANNELBANDWIDTH_40MHZ); |
| 12601 | |
| 12602 | } |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12603 | else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12604 | rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ | |
| 12605 | WIFI_CHANNELBANDWIDTH_40MHZ | |
| 12606 | WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ); |
| 12607 | } |
| 12608 | |
| 12609 | |
| 12610 | /* mode - all supported variants */ |
| 12611 | // rcap->mode[i] = WIFI_80211_VARIANT_H; |
| 12612 | if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12613 | rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX ); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12614 | } |
| 12615 | else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) { |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12616 | rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX ); |
| 12617 | } |
| 12618 | else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) { |
| 12619 | rcap->mode[i] = ( WIFI_80211_VARIANT_AX ); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12620 | } |
| 12621 | rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 : |
| 12622 | ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0); |
| 12623 | |
| 12624 | /* supportedBitRate - all supported bitrates */ |
| 12625 | rcap->supportedBitRate[i] = 0; |
| 12626 | if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) { |
| 12627 | rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS | |
| 12628 | WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS); |
| 12629 | } |
developer | 1e5aa16 | 2022-09-13 16:06:24 +0800 | [diff] [blame] | 12630 | else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) | rcap->band[i] & (WIFI_FREQUENCY_6_BAND )) { |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12631 | rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS | |
| 12632 | WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS | |
| 12633 | WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS); |
| 12634 | } |
| 12635 | |
| 12636 | |
| 12637 | rcap->transmitPowerSupported_list[i].numberOfElements = 5; |
| 12638 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12; |
| 12639 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25; |
| 12640 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50; |
| 12641 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75; |
| 12642 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100; |
| 12643 | rcap->cipherSupported = 0; |
| 12644 | rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP; |
| 12645 | rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO; |
| 12646 | |
| 12647 | return RETURN_OK; |
| 12648 | } |
| 12649 | |
| 12650 | INT wifi_getHalCapability(wifi_hal_capability_t *cap) |
| 12651 | { |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 12652 | INT status = 0, radioIndex = 0; |
| 12653 | char cmd[MAX_BUF_SIZE] = {0}, output[MAX_BUF_SIZE] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12654 | int iter = 0; |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 12655 | unsigned int j = 0; |
| 12656 | wifi_interface_name_idex_map_t *iface_info = NULL; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12657 | |
| 12658 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12659 | |
| 12660 | memset(cap, 0, sizeof(wifi_hal_capability_t)); |
| 12661 | |
| 12662 | /* version */ |
| 12663 | cap->version.major = WIFI_HAL_MAJOR_VERSION; |
| 12664 | cap->version.minor = WIFI_HAL_MINOR_VERSION; |
| 12665 | |
| 12666 | /* number of radios platform property */ |
| 12667 | snprintf(cmd, sizeof(cmd), "ls -d /sys/class/net/wlan* | wc -l"); |
| 12668 | _syscmd(cmd, output, sizeof(output)); |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 12669 | cap->wifi_prop.numRadios = atoi(output) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS: atoi(output) ; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12670 | |
| 12671 | for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++) |
| 12672 | { |
| 12673 | status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex])); |
| 12674 | if (status != 0) { |
| 12675 | printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex); |
| 12676 | return RETURN_ERR; |
| 12677 | } |
| 12678 | |
| 12679 | for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++) |
| 12680 | { |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 12681 | if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12682 | { |
| 12683 | printf("%s: to many vaps for index map (%d)\n", __func__, iter); |
| 12684 | return RETURN_ERR; |
| 12685 | } |
| 12686 | iface_info = &cap->wifi_prop.interface_map[iter]; |
| 12687 | iface_info->phy_index = radioIndex; // XXX: parse phyX index instead |
| 12688 | iface_info->rdk_radio_index = radioIndex; |
| 12689 | memset(output, 0, sizeof(output)); |
| 12690 | if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK) |
| 12691 | { |
| 12692 | strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1); |
| 12693 | } |
| 12694 | // TODO: bridge name |
| 12695 | // TODO: vlan id |
| 12696 | // TODO: primary |
| 12697 | iface_info->index = array_index_to_vap_index(radioIndex, j); |
| 12698 | memset(output, 0, sizeof(output)); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 12699 | if (iface_info->index >= 0 && wifi_getApName(iface_info->index, output) == RETURN_OK) |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12700 | { |
| 12701 | strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1); |
| 12702 | } |
| 12703 | iter++; |
| 12704 | } |
| 12705 | } |
| 12706 | |
| 12707 | cap->BandSteeringSupported = FALSE; |
| 12708 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12709 | return RETURN_OK; |
| 12710 | } |
| 12711 | |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12712 | INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable) |
| 12713 | { |
| 12714 | struct params h_config={0}; |
| 12715 | char config_file[64] = {0}; |
| 12716 | |
| 12717 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 12718 | |
| 12719 | h_config.name = "okc"; |
| 12720 | h_config.value = okc_enable?"1":"0"; |
| 12721 | |
| 12722 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 12723 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 12724 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 12725 | |
| 12726 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 12727 | return RETURN_OK; |
| 12728 | } |
| 12729 | |
| 12730 | INT wifi_setSAEMFP(int ap_index, BOOL enable) |
| 12731 | { |
| 12732 | struct params h_config={0}; |
| 12733 | char config_file[64] = {0}; |
| 12734 | char buf[128] = {0}; |
| 12735 | |
| 12736 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 12737 | |
| 12738 | h_config.name = "sae_require_mfp"; |
| 12739 | h_config.value = enable?"1":"0"; |
| 12740 | |
| 12741 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 12742 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 12743 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 12744 | |
| 12745 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 12746 | return RETURN_OK; |
| 12747 | } |
| 12748 | |
| 12749 | INT wifi_setSAEpwe(int ap_index, int sae_pwe) |
| 12750 | { |
| 12751 | struct params h_config={0}; |
| 12752 | char config_file[64] = {0}; |
| 12753 | char buf[128] = {0}; |
| 12754 | |
| 12755 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 12756 | |
| 12757 | h_config.name = "sae_pwe"; |
| 12758 | snprintf(buf, sizeof(buf), "%d", sae_pwe); |
| 12759 | h_config.value = buf; |
| 12760 | |
| 12761 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 12762 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 12763 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 12764 | |
| 12765 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 12766 | return RETURN_OK; |
| 12767 | } |
| 12768 | |
| 12769 | INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries) |
| 12770 | { |
| 12771 | // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3. |
| 12772 | struct params h_config={0}; |
| 12773 | char config_file[64] = {0}; |
| 12774 | |
| 12775 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 12776 | |
| 12777 | h_config.name = "wpa_disable_eapol_key_retries"; |
| 12778 | h_config.value = disable_EAPOL_retries?"1":"0"; |
| 12779 | |
| 12780 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 12781 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 12782 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 12783 | |
| 12784 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 12785 | return RETURN_OK; |
| 12786 | } |
| 12787 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12788 | INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security) |
| 12789 | { |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12790 | char buf[128] = {0}; |
| 12791 | char config_file[128] = {0}; |
| 12792 | char password[64] = {0}; |
| 12793 | char mfp[32] = {0}; |
| 12794 | char wpa_mode[32] = {0}; |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12795 | BOOL okc_enable = FALSE; |
| 12796 | BOOL sae_MFP = FALSE; |
| 12797 | BOOL disable_EAPOL_retries = TRUE; |
| 12798 | int sae_pwe = 0; |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12799 | struct params params = {0}; |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12800 | wifi_band band = band_invalid; |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12801 | |
| 12802 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12803 | |
| 12804 | multiple_set = TRUE; |
| 12805 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 12806 | if (security->mode == wifi_security_mode_none) { |
| 12807 | strcpy(wpa_mode, "None"); |
| 12808 | } else if (security->mode == wifi_security_mode_wpa_personal) |
| 12809 | strcpy(wpa_mode, "WPA-Personal"); |
| 12810 | else if (security->mode == wifi_security_mode_wpa2_personal) |
| 12811 | strcpy(wpa_mode, "WPA2-Personal"); |
| 12812 | else if (security->mode == wifi_security_mode_wpa_wpa2_personal) |
| 12813 | strcpy(wpa_mode, "WPA-WPA2-Personal"); |
| 12814 | else if (security->mode == wifi_security_mode_wpa_enterprise) |
| 12815 | strcpy(wpa_mode, "WPA-Enterprise"); |
| 12816 | else if (security->mode == wifi_security_mode_wpa2_enterprise) |
| 12817 | strcpy(wpa_mode, "WPA2-Enterprise"); |
| 12818 | else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise) |
| 12819 | strcpy(wpa_mode, "WPA-WPA2-Enterprise"); |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12820 | else if (security->mode == wifi_security_mode_wpa3_personal) { |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12821 | strcpy(wpa_mode, "WPA3-Personal"); |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12822 | okc_enable = TRUE; |
| 12823 | sae_MFP = TRUE; |
| 12824 | sae_pwe = 2; |
| 12825 | disable_EAPOL_retries = FALSE; |
| 12826 | } else if (security->mode == wifi_security_mode_wpa3_transition) { |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 12827 | strcpy(wpa_mode, "WPA3-Personal-Transition"); |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12828 | okc_enable = TRUE; |
| 12829 | sae_MFP = TRUE; |
| 12830 | sae_pwe = 2; |
| 12831 | disable_EAPOL_retries = FALSE; |
| 12832 | } else if (security->mode == wifi_security_mode_wpa3_enterprise) { |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12833 | strcpy(wpa_mode, "WPA3-Enterprise"); |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12834 | sae_MFP = TRUE; |
| 12835 | sae_pwe = 2; |
| 12836 | disable_EAPOL_retries = FALSE; |
| 12837 | } |
| 12838 | |
| 12839 | band = wifi_index_to_band(ap_index); |
| 12840 | if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) { |
| 12841 | fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__); |
| 12842 | return RETURN_ERR; |
| 12843 | } |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12844 | |
| 12845 | wifi_setApSecurityModeEnabled(ap_index, wpa_mode); |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12846 | wifi_setOpportunisticKeyCaching(ap_index, okc_enable); |
developer | c083031 | 2022-10-13 13:22:36 +0800 | [diff] [blame] | 12847 | wifi_setSAEMFP(ap_index, sae_MFP); |
| 12848 | wifi_setSAEpwe(ap_index, sae_pwe); |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12849 | wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries); |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12850 | |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12851 | if (security->mode != wifi_security_mode_none) { |
| 12852 | if (security->u.key.type == wifi_security_key_type_psk || security->u.key.type == wifi_security_key_type_psk_sae) { |
| 12853 | strncpy(password, security->u.key.key, 63); // 8 to 63 characters |
| 12854 | password[63] = '\0'; |
| 12855 | wifi_setApSecurityKeyPassphrase(ap_index, password); |
| 12856 | } |
| 12857 | if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) { |
| 12858 | params.name = "sae_password"; |
| 12859 | params.value = security->u.key.key; |
| 12860 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12861 | } |
| 12862 | } |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12863 | |
| 12864 | if (security->mode != wifi_security_mode_none) { |
| 12865 | memset(¶ms, 0, sizeof(params)); |
| 12866 | params.name = "wpa_pairwise"; |
| 12867 | if (security->encr == wifi_encryption_tkip) |
| 12868 | params.value = "TKIP"; |
| 12869 | else if (security->encr == wifi_encryption_aes) |
| 12870 | params.value = "CCMP"; |
| 12871 | else if (security->encr == wifi_encryption_aes_tkip) |
| 12872 | params.value = "TKIP CCMP"; |
| 12873 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12874 | } |
| 12875 | |
| 12876 | if (security->mfp == wifi_mfp_cfg_disabled) |
developer | c083031 | 2022-10-13 13:22:36 +0800 | [diff] [blame] | 12877 | strcpy(mfp, "Disabled"); |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12878 | else if (security->mfp == wifi_mfp_cfg_optional) |
| 12879 | strcpy(mfp, "Optional"); |
| 12880 | else if (security->mfp == wifi_mfp_cfg_required) |
| 12881 | strcpy(mfp, "Required"); |
| 12882 | wifi_setApSecurityMFPConfig(ap_index, mfp); |
| 12883 | |
| 12884 | memset(¶ms, 0, sizeof(params)); |
| 12885 | params.name = "transition_disable"; |
| 12886 | if (security->wpa3_transition_disable == TRUE) |
| 12887 | params.value = "0x01"; |
| 12888 | else |
| 12889 | params.value = "0x00"; |
| 12890 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12891 | |
| 12892 | memset(¶ms, 0, sizeof(params)); |
| 12893 | params.name = "wpa_group_rekey"; |
| 12894 | snprintf(buf, sizeof(buf), "%d", security->rekey_interval); |
| 12895 | params.value = buf; |
| 12896 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12897 | |
| 12898 | memset(¶ms, 0, sizeof(params)); |
| 12899 | params.name = "wpa_strict_rekey"; |
| 12900 | params.value = security->strict_rekey?"1":"0"; |
| 12901 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12902 | |
| 12903 | memset(¶ms, 0, sizeof(params)); |
| 12904 | params.name = "wpa_pairwise_update_count"; |
| 12905 | snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries); |
| 12906 | params.value = buf; |
| 12907 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12908 | |
| 12909 | memset(¶ms, 0, sizeof(params)); |
| 12910 | params.name = "disable_pmksa_caching"; |
| 12911 | params.value = security->disable_pmksa_caching?"1":"0"; |
| 12912 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 12913 | |
| 12914 | wifi_setApEnable(ap_index, FALSE); |
| 12915 | wifi_setApEnable(ap_index, TRUE); |
| 12916 | |
| 12917 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12918 | |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 12919 | return RETURN_OK; |
| 12920 | } |
| 12921 | |
| 12922 | INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security) |
| 12923 | { |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12924 | char buf[256] = {0}; |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12925 | char config_file[128] = {0}; |
| 12926 | int disable = 0; |
| 12927 | // struct params params = {0}; |
| 12928 | |
| 12929 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12930 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 12931 | wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config |
| 12932 | security->mode = wifi_security_mode_none; |
| 12933 | if (strlen(buf) != 0) { |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12934 | if (!strcmp(buf, "WPA-Personal")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12935 | security->mode = wifi_security_mode_wpa_personal; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12936 | else if (!strcmp(buf, "WPA2-Personal")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12937 | security->mode = wifi_security_mode_wpa2_personal; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12938 | else if (!strcmp(buf, "WPA-WPA2-Personal")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12939 | security->mode = wifi_security_mode_wpa_wpa2_personal; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12940 | else if (!strcmp(buf, "WPA-Enterprise")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12941 | security->mode = wifi_security_mode_wpa_enterprise; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12942 | else if (!strcmp(buf, "WPA2-Enterprise")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12943 | security->mode = wifi_security_mode_wpa2_enterprise; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12944 | else if (!strcmp(buf, "WPA-WPA2-Enterprise")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12945 | security->mode = wifi_security_mode_wpa_wpa2_enterprise; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12946 | else if (!strcmp(buf, "WPA3-Personal")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12947 | security->mode = wifi_security_mode_wpa3_personal; |
developer | 4a35967 | 2022-10-13 15:30:46 +0800 | [diff] [blame] | 12948 | else if (!strcmp(buf, "WPA3-Personal-Transition")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12949 | security->mode = wifi_security_mode_wpa3_transition; |
developer | 517a979 | 2022-10-05 19:37:42 +0800 | [diff] [blame] | 12950 | else if (!strcmp(buf, "WPA3-Enterprise")) |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12951 | security->mode = wifi_security_mode_wpa3_enterprise; |
| 12952 | } |
| 12953 | |
| 12954 | wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf)); |
| 12955 | if (security->mode == wifi_security_mode_none) |
| 12956 | security->encr = wifi_encryption_none; |
| 12957 | else { |
| 12958 | if (strcmp(buf, "TKIP") == 0) |
| 12959 | security->encr = wifi_encryption_tkip; |
| 12960 | else if (strcmp(buf, "CCMP") == 0) |
| 12961 | security->encr = wifi_encryption_aes; |
| 12962 | else |
| 12963 | security->encr = wifi_encryption_aes_tkip; |
| 12964 | } |
| 12965 | |
developer | 9df4e65 | 2022-10-11 11:27:38 +0800 | [diff] [blame] | 12966 | if (security->mode != wifi_encryption_none) { |
| 12967 | memset(buf, 0, sizeof(buf)); |
| 12968 | // wpa3 can use one or both configs as password, so we check sae_password first. |
| 12969 | wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf)); |
| 12970 | if (security->mode == wifi_security_mode_wpa3_personal && strlen(buf) != 0) { |
| 12971 | security->u.key.type = wifi_security_key_type_sae; |
| 12972 | } else { |
| 12973 | security->u.key.type = wifi_security_key_type_psk; |
| 12974 | wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf)); |
| 12975 | } |
| 12976 | strncpy(security->u.key.key, buf, sizeof(buf)); |
| 12977 | security->u.key.key[255] = '\0'; |
| 12978 | } |
| 12979 | |
developer | 587c1b6 | 2022-09-27 15:58:59 +0800 | [diff] [blame] | 12980 | memset(buf, 0, sizeof(buf)); |
| 12981 | wifi_getApSecurityMFPConfig(ap_index, buf); |
| 12982 | if (strcmp(buf, "Disabled") == 0) |
| 12983 | security->mfp = wifi_mfp_cfg_disabled; |
| 12984 | else if (strcmp(buf, "Optional") == 0) |
| 12985 | security->mfp = wifi_mfp_cfg_optional; |
| 12986 | else if (strcmp(buf, "Required") == 0) |
| 12987 | security->mfp = wifi_mfp_cfg_required; |
| 12988 | |
| 12989 | memset(buf, 0, sizeof(buf)); |
| 12990 | security->wpa3_transition_disable = FALSE; |
| 12991 | wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf)); |
| 12992 | disable = strtol(buf, NULL, 16); |
| 12993 | if (disable != 0) |
| 12994 | security->wpa3_transition_disable = TRUE; |
| 12995 | |
| 12996 | memset(buf, 0, sizeof(buf)); |
| 12997 | wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf)); |
| 12998 | if (strlen(buf) == 0) |
| 12999 | security->rekey_interval = 86400; |
| 13000 | else |
| 13001 | security->rekey_interval = strtol(buf, NULL, 10); |
| 13002 | |
| 13003 | memset(buf, 0, sizeof(buf)); |
| 13004 | wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf)); |
| 13005 | if (strlen(buf) == 0) |
| 13006 | security->strict_rekey = 1; |
| 13007 | else |
| 13008 | security->strict_rekey = strtol(buf, NULL, 10); |
| 13009 | |
| 13010 | memset(buf, 0, sizeof(buf)); |
| 13011 | wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf)); |
| 13012 | if (strlen(buf) == 0) |
| 13013 | security->eapol_key_retries = 4; |
| 13014 | else |
| 13015 | security->eapol_key_retries = strtol(buf, NULL, 10); |
| 13016 | |
| 13017 | memset(buf, 0, sizeof(buf)); |
| 13018 | wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf)); |
| 13019 | if (strlen(buf) == 0) |
| 13020 | security->disable_pmksa_caching = FALSE; |
| 13021 | else |
| 13022 | security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE; |
| 13023 | |
| 13024 | /* TODO |
| 13025 | eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries |
| 13026 | */ |
| 13027 | security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol. |
| 13028 | security->eap_identity_req_timeout = 0; |
| 13029 | security->eap_identity_req_retries = 0; |
| 13030 | security->eap_req_timeout = 0; |
| 13031 | security->eap_req_retries = 0; |
| 13032 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 13033 | return RETURN_OK; |
| 13034 | } |
| 13035 | |
| 13036 | #endif /* WIFI_HAL_VERSION_3 */ |
| 13037 | |
| 13038 | #ifdef WIFI_HAL_VERSION_3_PHASE2 |
| 13039 | INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices) |
| 13040 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 13041 | char interface_name[16] = {0}; |
developer | 13df933 | 2022-09-27 16:53:22 +0800 | [diff] [blame] | 13042 | char cmd[128] = {0}; |
| 13043 | char buf[128] = {0}; |
| 13044 | char *mac_addr = NULL; |
| 13045 | BOOL status = FALSE; |
| 13046 | size_t len = 0; |
| 13047 | |
| 13048 | if(ap_index > MAX_APS) |
| 13049 | return RETURN_ERR; |
| 13050 | |
| 13051 | *output_numDevices = 0; |
| 13052 | wifi_getApEnable(ap_index, &status); |
| 13053 | if (status == FALSE) |
| 13054 | return RETURN_OK; |
| 13055 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 13056 | if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 13057 | return RETURN_ERR; |
| 13058 | sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name); |
developer | 13df933 | 2022-09-27 16:53:22 +0800 | [diff] [blame] | 13059 | _syscmd(cmd, buf, sizeof(buf)); |
| 13060 | |
| 13061 | mac_addr = strtok(buf, "\n"); |
| 13062 | for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) { |
| 13063 | *output_numDevices = i + 1; |
| 13064 | fprintf(stderr, "mac_addr: %s\n", mac_addr); |
| 13065 | addr_ptr = output_deviceMacAddressArray[i]; |
| 13066 | mac_addr_aton(addr_ptr, mac_addr); |
| 13067 | mac_addr = strtok(NULL, "\n"); |
| 13068 | } |
| 13069 | |
| 13070 | return RETURN_OK; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 13071 | } |
| 13072 | #else |
| 13073 | INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size) |
| 13074 | { |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 13075 | char interface_name[16] = {0}; |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 13076 | char cmd[128]; |
| 13077 | BOOL status = false; |
| 13078 | |
| 13079 | if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0) |
| 13080 | return RETURN_ERR; |
| 13081 | |
| 13082 | output_buf[0] = '\0'; |
| 13083 | |
| 13084 | wifi_getApEnable(ap_index,&status); |
| 13085 | if (!status) |
| 13086 | return RETURN_OK; |
| 13087 | |
developer | ac6f114 | 2022-12-20 19:26:35 +0800 | [diff] [blame] | 13088 | if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) |
developer | d946fd6 | 2022-12-08 18:03:28 +0800 | [diff] [blame] | 13089 | return RETURN_ERR; |
| 13090 | sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name); |
developer | 06a01d9 | 2022-09-07 16:32:39 +0800 | [diff] [blame] | 13091 | _syscmd(cmd, output_buf, output_buf_size); |
| 13092 | |
| 13093 | return RETURN_OK; |
| 13094 | } |
| 13095 | #endif |
developer | 2f513ab | 2022-09-13 14:26:06 +0800 | [diff] [blame] | 13096 | |
| 13097 | INT wifi_getProxyArp(INT apIndex, BOOL *enable) |
| 13098 | { |
| 13099 | char output[16]={'\0'}; |
| 13100 | char config_file[MAX_BUF_SIZE] = {0}; |
| 13101 | |
| 13102 | if (!enable) |
| 13103 | return RETURN_ERR; |
| 13104 | |
| 13105 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 13106 | wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output)); |
| 13107 | |
| 13108 | if (strlen(output) == 0) |
| 13109 | *enable = FALSE; |
| 13110 | else if (strncmp(output, "1", 1) == 0) |
| 13111 | *enable = TRUE; |
| 13112 | else |
| 13113 | *enable = FALSE; |
| 13114 | |
| 13115 | wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output); |
| 13116 | return RETURN_OK; |
| 13117 | } |
developer | 2d9c30f | 2022-09-13 15:06:14 +0800 | [diff] [blame] | 13118 | |
| 13119 | INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable) |
| 13120 | { |
developer | 804c64f | 2022-10-19 13:54:40 +0800 | [diff] [blame] | 13121 | if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS) |
developer | 2d9c30f | 2022-09-13 15:06:14 +0800 | [diff] [blame] | 13122 | return RETURN_ERR; |
| 13123 | *output_enable=TRUE; |
| 13124 | return RETURN_OK; |
| 13125 | } |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13126 | |
| 13127 | INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned) |
| 13128 | { |
| 13129 | char cmd[128] = {0}; |
| 13130 | char buf[128] = {0}; |
| 13131 | char line[128] = {0}; |
| 13132 | size_t len = 0; |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13133 | FILE *f = NULL; |
| 13134 | int index = 0; |
| 13135 | int exp = 0; |
| 13136 | int mantissa = 0; |
| 13137 | int duration = 0; |
| 13138 | int radio_index = 0; |
| 13139 | int max_radio_num = 0; |
| 13140 | uint twt_wake_interval = 0; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 13141 | int phyId = 0; |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13142 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13143 | |
| 13144 | wifi_getMaxRadioNumber(&max_radio_num); |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 13145 | |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13146 | radio_index = ap_index % max_radio_num; |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 13147 | |
| 13148 | phyId = radio_index_to_phy(radio_index); |
| 13149 | sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId); |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13150 | _syscmd(cmd, buf, sizeof(buf)); |
| 13151 | *numSessionReturned = strtol(buf, NULL, 10) - 1; |
| 13152 | if (*numSessionReturned > maxNumberSessions) |
| 13153 | *numSessionReturned = maxNumberSessions; |
| 13154 | else if (*numSessionReturned < 1) { |
| 13155 | *numSessionReturned = 0; |
| 13156 | return RETURN_OK; |
| 13157 | } |
| 13158 | |
developer | 033b37b | 2022-10-18 11:27:46 +0800 | [diff] [blame] | 13159 | sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned); |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13160 | if ((f = popen(cmd, "r")) == NULL) { |
| 13161 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 13162 | return RETURN_ERR; |
| 13163 | } |
| 13164 | |
| 13165 | // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]" |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 13166 | while((fgets(line, sizeof(line), f)) != NULL) { |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13167 | char *tmp = NULL; |
| 13168 | strcpy(buf, line); |
| 13169 | tmp = strtok(buf, " "); |
| 13170 | twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10); |
| 13171 | tmp = strtok(NULL, " "); |
| 13172 | twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10); |
| 13173 | tmp = strtok(NULL, " "); |
| 13174 | if (strstr(tmp, "t")) { |
| 13175 | twtSessions[index].twtParameters.operation.trigger_enabled = TRUE; |
| 13176 | } |
| 13177 | if (strstr(tmp, "a")) { |
| 13178 | twtSessions[index].twtParameters.operation.announced = TRUE; |
| 13179 | } |
| 13180 | tmp = strtok(NULL, " "); |
| 13181 | exp = strtol(tmp, NULL, 10); |
| 13182 | tmp = strtok(NULL, " "); |
| 13183 | mantissa = strtol(tmp, NULL, 10); |
| 13184 | tmp = strtok(NULL, " "); |
| 13185 | duration = strtol(tmp, NULL, 10); |
| 13186 | |
| 13187 | // only implicit supported |
| 13188 | twtSessions[index].twtParameters.operation.implicit = TRUE; |
| 13189 | // only individual agreement supported |
| 13190 | twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual; |
| 13191 | |
| 13192 | // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47. |
| 13193 | twt_wake_interval = mantissa * (1 << exp); |
developer | 3042373 | 2022-12-01 16:17:49 +0800 | [diff] [blame] | 13194 | if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) { |
developer | fd7d289 | 2022-09-13 16:44:53 +0800 | [diff] [blame] | 13195 | // Overflow handling |
| 13196 | twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int |
| 13197 | } else { |
| 13198 | twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval; |
| 13199 | } |
| 13200 | twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256; |
| 13201 | index++; |
| 13202 | } |
| 13203 | |
| 13204 | pclose(f); |
| 13205 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13206 | return RETURN_OK; |
| 13207 | } |