developer | 72fb0bb | 2023-01-11 09:46:29 +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 | */ |
| 37 | #define MTK_IMPL |
| 38 | #define HAL_NETLINK_IMPL |
| 39 | #define _GNU_SOURCE /* needed for strcasestr */ |
| 40 | |
| 41 | #include <stdio.h> |
| 42 | #include <stdlib.h> |
| 43 | #include <unistd.h> |
| 44 | #include <string.h> |
| 45 | #include <fcntl.h> |
| 46 | #include <stdbool.h> |
| 47 | #include "wifi_hal.h" |
| 48 | |
| 49 | #ifdef HAL_NETLINK_IMPL |
| 50 | #include <errno.h> |
| 51 | #include <netlink/attr.h> |
| 52 | #include <netlink/netlink.h> |
| 53 | #include <netlink/genl/genl.h> |
| 54 | #include <netlink/genl/family.h> |
| 55 | #include <netlink/genl/ctrl.h> |
| 56 | #include <linux/nl80211.h> |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 57 | #include <net/if.h> |
| 58 | #include <unl.h> |
| 59 | #include "mtk_vendor_nl80211.h" |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 60 | #endif |
| 61 | |
| 62 | #include <ev.h> |
| 63 | #include <wpa_ctrl.h> |
| 64 | #include <errno.h> |
| 65 | #include <time.h> |
| 66 | #define MAC_ALEN 6 |
| 67 | |
| 68 | #define MAX_BUF_SIZE 256 |
| 69 | #define MAX_CMD_SIZE 256 |
| 70 | #define IF_NAME_SIZE 16 |
| 71 | #define CONFIG_PREFIX "/nvram/hostapd" |
| 72 | #define ACL_PREFIX "/nvram/hostapd-acl" |
| 73 | #define DENY_PREFIX "/nvram/hostapd-deny" |
| 74 | //#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention |
| 75 | #define SOCK_PREFIX "/var/run/hostapd/wifi" |
| 76 | #define VAP_STATUS_FILE "/nvram/vap-status" |
| 77 | #define ESSID_FILE "/tmp/essid" |
| 78 | #define GUARD_INTERVAL_FILE "/nvram/guard-interval" |
| 79 | #define CHANNEL_STATS_FILE "/tmp/channel_stats" |
| 80 | #define DFS_ENABLE_FILE "/nvram/dfs_enable.txt" |
| 81 | #define VLAN_FILE "/nvram/hostapd.vlan" |
| 82 | #define PSK_FILE "/nvram/hostapd" |
| 83 | #define MCS_FILE "/tmp/MCS" |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 84 | #define POWER_PERCENTAGE "/tmp/POWER" |
| 85 | #define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl" |
| 86 | /*LOGAN_DAT_FILE: may be different on customer's platform.*/ |
| 87 | #define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b" |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 88 | #define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b" |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 89 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 90 | #define NOACK_MAP_FILE "/tmp/NoAckMap" |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 91 | #define RADIO_RESET_FILE "/nvram/radio_reset" |
developer | f6a8754 | 2023-05-16 15:47:28 +0800 | [diff] [blame] | 92 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 93 | #define BRIDGE_NAME "brlan0" |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 94 | #define BASE_PHY_INDEX 1 |
| 95 | #define BASE_RADIO_INDEX 0 |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 96 | |
| 97 | /* |
| 98 | MAX_APS - Number of all AP available in system |
| 99 | 2x Home AP |
| 100 | 2x Backhaul AP |
| 101 | 2x Guest AP |
| 102 | 2x Secure Onboard AP |
| 103 | 2x Service AP |
| 104 | |
| 105 | */ |
| 106 | |
| 107 | |
| 108 | #define MAX_APS MAX_NUM_RADIOS*5 |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 109 | |
| 110 | #define PREFIX_WIFI2G "ra" |
| 111 | #define PREFIX_WIFI5G "rai" |
| 112 | #define PREFIX_WIFI6G "rax" |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 113 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 114 | #define PREFIX_SSID_2G "RDKB_2G" |
| 115 | #define PREFIX_SSID_5G "RDKB_5G" |
| 116 | #define PREFIX_SSID_6G "RDKB_6G" |
| 117 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 118 | #ifndef RADIO_PREFIX |
| 119 | #define RADIO_PREFIX "wlan" |
| 120 | #endif |
| 121 | |
| 122 | #define MAX_ASSOCIATED_STA_NUM 2007 |
| 123 | |
| 124 | //Uncomment to enable debug logs |
| 125 | //#define WIFI_DEBUG |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 126 | enum { |
| 127 | DEBUG_OFF = 0, |
| 128 | DEBUG_ERROR = 1, |
| 129 | DEBUG_WARN = 2, |
| 130 | DEBUG_NOTICE = 3, |
| 131 | DEBUG_INFO = 4 |
| 132 | }; |
| 133 | int wifi_debug_level = DEBUG_NOTICE; |
| 134 | #define wifi_debug(level, fmt, args...) \ |
| 135 | { \ |
| 136 | if (level <= wifi_debug_level) \ |
| 137 | { \ |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 138 | printf("[%s][%d]"fmt"", __func__, __LINE__, ##args); \ |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 139 | } \ |
| 140 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 141 | |
| 142 | #ifdef WIFI_DEBUG |
| 143 | #define wifi_dbg_printf printf |
| 144 | #define WIFI_ENTRY_EXIT_DEBUG printf |
| 145 | #else |
| 146 | #define wifi_dbg_printf(format, args...) printf("") |
| 147 | #define WIFI_ENTRY_EXIT_DEBUG(format, args...) printf("") |
| 148 | #endif |
| 149 | |
| 150 | #define HOSTAPD_CONF_0 "/nvram/hostapd0.conf" //private-wifi-2g |
| 151 | #define HOSTAPD_CONF_1 "/nvram/hostapd1.conf" //private-wifi-5g |
| 152 | #define HOSTAPD_CONF_4 "/nvram/hostapd4.conf" //public-wifi-2g |
| 153 | #define HOSTAPD_CONF_5 "/nvram/hostapd5.conf" //public-wifi-5g |
| 154 | #define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf" |
| 155 | #define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf" |
| 156 | #define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf" |
| 157 | #define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf" |
| 158 | #define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg" |
| 159 | #define LM_DHCP_CLIENT_FORMAT "%63d %17s %63s %63s" |
| 160 | |
| 161 | #define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]" |
| 162 | |
| 163 | #define BW_FNAME "/nvram/bw_file.txt" |
| 164 | |
| 165 | #define PS_MAX_TID 16 |
| 166 | |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 167 | #define MAX_CARD_INDEX 3 |
| 168 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 169 | static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = { |
| 170 | WIFI_RADIO_QUEUE_TYPE_BE, /* 0 */ |
| 171 | WIFI_RADIO_QUEUE_TYPE_BK, /* 1 */ |
| 172 | WIFI_RADIO_QUEUE_TYPE_BK, /* 2 */ |
| 173 | WIFI_RADIO_QUEUE_TYPE_BE, /* 3 */ |
| 174 | WIFI_RADIO_QUEUE_TYPE_VI, /* 4 */ |
| 175 | WIFI_RADIO_QUEUE_TYPE_VI, /* 5 */ |
| 176 | WIFI_RADIO_QUEUE_TYPE_VO, /* 6 */ |
| 177 | WIFI_RADIO_QUEUE_TYPE_VO, /* 7 */ |
| 178 | WIFI_RADIO_QUEUE_TYPE_BE, /* 8 */ |
| 179 | WIFI_RADIO_QUEUE_TYPE_BK, /* 9 */ |
| 180 | WIFI_RADIO_QUEUE_TYPE_BK, /* 10 */ |
| 181 | WIFI_RADIO_QUEUE_TYPE_BE, /* 11 */ |
| 182 | WIFI_RADIO_QUEUE_TYPE_VI, /* 12 */ |
| 183 | WIFI_RADIO_QUEUE_TYPE_VI, /* 13 */ |
| 184 | WIFI_RADIO_QUEUE_TYPE_VO, /* 14 */ |
| 185 | WIFI_RADIO_QUEUE_TYPE_VO, /* 15 */ |
| 186 | }; |
| 187 | |
| 188 | typedef unsigned long long u64; |
| 189 | |
| 190 | /* Enum to define WiFi Bands */ |
| 191 | typedef enum |
| 192 | { |
| 193 | band_invalid = -1, |
| 194 | band_2_4 = 0, |
| 195 | band_5 = 1, |
| 196 | band_6 = 2, |
| 197 | } wifi_band; |
| 198 | |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 199 | char* wifi_band_str[] = { |
| 200 | "2G", |
| 201 | "5G", |
| 202 | "6G", |
| 203 | }; |
| 204 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 205 | typedef enum { |
| 206 | WIFI_MODE_A = 0x01, |
| 207 | WIFI_MODE_B = 0x02, |
| 208 | WIFI_MODE_G = 0x04, |
| 209 | WIFI_MODE_N = 0x08, |
| 210 | WIFI_MODE_AC = 0x10, |
| 211 | WIFI_MODE_AX = 0x20, |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 212 | WIFI_MODE_BE = 0x40, |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 213 | } wifi_ieee80211_Mode; |
| 214 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 215 | typedef enum ht_config_bw{ |
| 216 | HT_BW_20, |
| 217 | HT_BW_40, |
| 218 | }; |
| 219 | |
| 220 | typedef enum vht_config_bw{ |
| 221 | VHT_BW_2040, |
| 222 | VHT_BW_80, |
| 223 | VHT_BW_160, |
| 224 | VHT_BW_8080, |
| 225 | }; |
| 226 | |
| 227 | typedef enum eht_config_bw{ |
| 228 | EHT_BW_20, |
| 229 | EHT_BW_40, |
| 230 | EHT_BW_80, |
| 231 | EHT_BW_160, |
| 232 | EHT_BW_320, |
| 233 | }; |
| 234 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 235 | #ifdef WIFI_HAL_VERSION_3 |
| 236 | |
| 237 | // Return number of elements in array |
| 238 | #ifndef ARRAY_SIZE |
| 239 | #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0])) |
| 240 | #endif /* ARRAY_SIZE */ |
| 241 | |
| 242 | #ifndef ARRAY_AND_SIZE |
| 243 | #define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x) |
| 244 | #endif /* ARRAY_AND_SIZE */ |
| 245 | |
| 246 | #define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str} |
| 247 | |
| 248 | typedef struct { |
| 249 | int32_t value; |
| 250 | int32_t param; |
| 251 | intptr_t key; |
| 252 | intptr_t data; |
| 253 | } wifi_secur_list; |
| 254 | |
| 255 | static int util_unii_5g_centerfreq(const char *ht_mode, int channel); |
| 256 | static int util_unii_6g_centerfreq(const char *ht_mode, int channel); |
| 257 | wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key); |
| 258 | wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str); |
| 259 | char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key); |
| 260 | static int ieee80211_channel_to_frequency(int channel, int *freqMHz); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 261 | static void wifi_PrepareDefaultHostapdConfigs(void); |
| 262 | static void wifi_psk_file_reset(); |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 263 | static void wifi_psk_file_reset_by_radio(char radio_idx); |
| 264 | static void wifi_dat_file_reset(); |
| 265 | static void wifi_dat_file_reset_by_radio(char radio_idx); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 266 | static int util_get_sec_chan_offset(int channel, const char* ht_mode); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 267 | |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 268 | /*type define the nl80211 call back func*/ |
| 269 | typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *); |
| 270 | |
| 271 | /** |
| 272 | *struct mtk_nl80211_param |
| 273 | * init mtk nl80211 using parameters |
| 274 | * @sub_cmd: the cmd define in the mtk_vendor_nl80211.h. |
| 275 | * @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY. |
| 276 | * @if_idx: the index should match the interface or wiphy. |
| 277 | * Note: NA |
| 278 | **/ |
| 279 | struct mtk_nl80211_param { |
| 280 | unsigned int sub_cmd; |
| 281 | int if_type; |
| 282 | int if_idx; |
| 283 | }; |
| 284 | |
| 285 | /** |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 286 | *struct mtk_nl80211_cb_data |
| 287 | * init mtk nl80211 call back parameters |
| 288 | * @out_buf: store the mtk vendor output msg for wifi hal buffer. |
| 289 | * @out_len: the output buffer length. |
| 290 | * Note: NA |
| 291 | **/ |
| 292 | struct mtk_nl80211_cb_data { |
| 293 | char * out_buf; |
| 294 | unsigned int out_len; |
| 295 | }; |
| 296 | |
| 297 | /** |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 298 | *mtk_nl80211_init |
| 299 | * init mtk nl80211 netlink and init the vendor msg common part. |
| 300 | * @nl: netlink, just init it. |
| 301 | * @msg: netlink message will alloc it. |
| 302 | * the msg send success/fails is not free by app |
| 303 | * only the nla_put etc api fails should use nlmsg_free. |
| 304 | * @msg_data: vendor data msg attr pointer. |
| 305 | * @param: init using interface and sub_cmd parameter. |
| 306 | * |
| 307 | *init the netlink context and mtk netlink vendor msg. |
| 308 | * |
| 309 | *return: |
| 310 | * 0: success |
| 311 | * other: fail |
| 312 | **/ |
| 313 | |
| 314 | int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg, |
| 315 | struct nlattr **msg_data, struct mtk_nl80211_param *param) { |
| 316 | /*sanity check here*/ |
| 317 | if (!nl || !param) { |
| 318 | (void)fprintf(stderr, |
| 319 | "[%s][%d]:nl(0x%lx) or param(0x%lx) is null, error!\n", |
| 320 | __func__, __LINE__, nl, param); |
| 321 | return -1; |
| 322 | } |
| 323 | /*if_type check*/ |
| 324 | if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) { |
| 325 | (void)fprintf(stderr, |
| 326 | "[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n", |
| 327 | __func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY); |
| 328 | return -1; |
| 329 | } |
| 330 | /*init the nl*/ |
| 331 | if (unl_genl_init(nl, "nl80211") < 0) { |
| 332 | (void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211\n", |
| 333 | __func__, __LINE__); |
| 334 | return -1; |
| 335 | } |
| 336 | /*init the msg*/ |
| 337 | *msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false); |
| 338 | |
| 339 | if (nla_put_u32(*msg, param->if_type, param->if_idx) || |
| 340 | nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) || |
| 341 | nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) { |
| 342 | (void)fprintf(stderr, |
| 343 | "[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n", |
| 344 | __func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd); |
| 345 | goto err; |
| 346 | } |
| 347 | |
| 348 | *msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA); |
| 349 | if (!*msg_data) { |
| 350 | (void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n", |
| 351 | __func__, __LINE__); |
| 352 | goto err; |
| 353 | } |
| 354 | |
| 355 | return 0; |
| 356 | err: |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 357 | nlmsg_free(*msg); |
| 358 | unl_free(nl); |
| 359 | return -1; |
| 360 | } |
| 361 | |
| 362 | /** |
| 363 | *mtk_nl80211_send |
| 364 | * set the vendor cmd call back and sent the vendor msg. |
| 365 | * @nl: netlink. |
| 366 | * @msg: netlink message. |
| 367 | * @msg_data: vendor data msg attr pointer. |
| 368 | * @handler: if the msg have call back shoud add the call back func |
| 369 | * the event msg will handle by the call back func(exp:get cmd) |
| 370 | * other set it as NULL(exp:set cmd). |
| 371 | * @arg:call back func arg parameter. |
| 372 | *add end of the netlink msg, set the call back and send msg |
| 373 | * |
| 374 | *return: |
| 375 | * 0: success |
| 376 | * other: fail |
| 377 | **/ |
| 378 | int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg, |
| 379 | struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) { |
| 380 | int ret = 0; |
| 381 | /*sanity check*/ |
| 382 | if (!nl || !msg || !msg_data) { |
| 383 | (void)fprintf(stderr, |
| 384 | "[%s][%d]:nl(0x%lx),msg(0x%lx) or msg_data(0x%lx) is null, error!\n", |
| 385 | __func__, __LINE__, nl, msg, msg_data); |
| 386 | return -1; |
| 387 | } |
| 388 | /*end the msg attr of vendor data*/ |
| 389 | nla_nest_end(msg, msg_data); |
| 390 | /*send the msg and set call back */ |
| 391 | ret = unl_genl_request(nl, msg, handler, arg); |
| 392 | if (ret) |
| 393 | (void)fprintf(stderr, "send nl80211 cmd fails\n"); |
| 394 | return ret; |
| 395 | } |
| 396 | |
| 397 | /** |
| 398 | *mtk_nl80211_deint |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 399 | * deinit the netlink. |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 400 | * @nl: netlink. |
| 401 | * |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 402 | *free deinit the netlink. |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 403 | * |
| 404 | *return: |
| 405 | * 0: success |
| 406 | **/ |
| 407 | |
| 408 | int mtk_nl80211_deint(struct unl *nl) { |
| 409 | unl_free(nl); |
| 410 | return 0; |
| 411 | } |
| 412 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 413 | |
| 414 | static wifi_secur_list map_security[] = |
| 415 | { |
| 416 | WIFI_ITEM_STR(wifi_security_mode_none, "None"), |
| 417 | WIFI_ITEM_STR(wifi_security_mode_wep_64, "WEP-64"), |
| 418 | WIFI_ITEM_STR(wifi_security_mode_wep_128, "WEP-128"), |
| 419 | WIFI_ITEM_STR(wifi_security_mode_wpa_personal, "WPA-Personal"), |
| 420 | WIFI_ITEM_STR(wifi_security_mode_wpa_enterprise, "WPA-Enterprise"), |
| 421 | WIFI_ITEM_STR(wifi_security_mode_wpa2_personal, "WPA2-Personal"), |
| 422 | WIFI_ITEM_STR(wifi_security_mode_wpa2_enterprise, "WPA2-Enterprise"), |
| 423 | WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_personal, "WPA-WPA2-Personal"), |
| 424 | WIFI_ITEM_STR(wifi_security_mode_wpa_wpa2_enterprise, "WPA-WPA2-Enterprise"), |
| 425 | WIFI_ITEM_STR(wifi_security_mode_wpa3_personal, "WPA3-Personal"), |
| 426 | WIFI_ITEM_STR(wifi_security_mode_wpa3_transition, "WPA3-Personal-Transition"), |
| 427 | WIFI_ITEM_STR(wifi_security_mode_wpa3_enterprise, "WPA3-Enterprise") |
| 428 | }; |
| 429 | |
| 430 | wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key) |
| 431 | { |
| 432 | wifi_secur_list *item; |
| 433 | int i; |
| 434 | |
| 435 | for (item = list,i = 0;i < list_sz; item++, i++) { |
| 436 | if ((int)(item->key) == key) { |
| 437 | return item; |
| 438 | } |
| 439 | } |
| 440 | |
| 441 | return NULL; |
| 442 | } |
| 443 | |
| 444 | char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key) |
| 445 | { |
| 446 | wifi_secur_list *item = wifi_get_item_by_key(list, list_sz, key); |
| 447 | |
| 448 | if (!item) { |
| 449 | return ""; |
| 450 | } |
| 451 | |
| 452 | return (char *)(item->data); |
| 453 | } |
| 454 | |
| 455 | wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str) |
| 456 | { |
| 457 | wifi_secur_list *item; |
| 458 | int i; |
| 459 | |
| 460 | for (item = list,i = 0;i < list_sz; item++, i++) { |
| 461 | if (strcmp((char *)(item->data), str) == 0) { |
| 462 | return item; |
| 463 | } |
| 464 | } |
| 465 | |
| 466 | return NULL; |
| 467 | } |
| 468 | #endif /* WIFI_HAL_VERSION_3 */ |
| 469 | |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 470 | |
| 471 | static char l1profile[32] = "/etc/wireless/l1profile.dat"; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 472 | char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ]; |
| 473 | char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ]; |
| 474 | #define MAX_SSID_LEN 64 |
| 475 | char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];; |
developer | 745f0bd | 2023-03-06 14:32:53 +0800 | [diff] [blame] | 476 | int radio_band[MAX_NUM_RADIOS]; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 477 | |
| 478 | static int array_index_to_vap_index(UINT radioIndex, int arrayIndex); |
| 479 | static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex); |
| 480 | |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 481 | |
| 482 | static int |
| 483 | get_value(const char *conf_file, const char *param, char *value, int len) |
| 484 | { |
| 485 | FILE *fp; |
| 486 | int ret = -1; |
| 487 | int param_len = strlen(param); |
| 488 | int buf_len; |
| 489 | char buf[256]; |
| 490 | |
| 491 | fp = fopen(conf_file, "r"); |
| 492 | if (!fp) { |
| 493 | return -1; |
| 494 | } |
| 495 | |
| 496 | while (fgets(buf, sizeof(buf), fp)) { |
| 497 | buf_len = strlen(buf); |
| 498 | if (buf[buf_len - 1] == '\n') { |
| 499 | buf_len--; |
| 500 | buf[buf_len] = '\0'; |
| 501 | } |
| 502 | if ((buf_len > param_len) && |
| 503 | (strncmp(buf, param, param_len) == 0) && |
| 504 | (buf[param_len] == '=')) { |
| 505 | |
| 506 | if (buf_len == (param_len + 1)) { |
| 507 | value[0] = '\0'; |
| 508 | ret = 0; |
| 509 | } else { |
| 510 | ret = snprintf(value, len, "%s", buf + (param_len + 1)); |
| 511 | } |
| 512 | fclose(fp); |
| 513 | return ret; |
| 514 | } |
| 515 | } |
| 516 | fclose(fp); |
| 517 | return -1; |
| 518 | } |
| 519 | |
| 520 | static int |
| 521 | get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len) |
| 522 | { |
| 523 | char buf[256]; |
| 524 | int ret; |
| 525 | char *save_ptr = NULL; |
| 526 | char *tok = NULL; |
| 527 | |
| 528 | ret = get_value(conf_file, param, buf, sizeof(buf)); |
| 529 | if (ret < 0) |
| 530 | return ret; |
| 531 | |
| 532 | tok = strtok_r(buf, ";", &save_ptr); |
| 533 | do { |
| 534 | if (idx == 0 || tok == NULL) |
| 535 | break; |
| 536 | else |
| 537 | idx--; |
| 538 | |
| 539 | tok = strtok_r(NULL, ";", &save_ptr); |
| 540 | } while (tok != NULL); |
| 541 | |
| 542 | if (tok) { |
| 543 | ret = snprintf(value, len, "%s", tok); |
| 544 | } else { |
| 545 | ret = 0; |
| 546 | value[0] = '\0'; |
| 547 | } |
| 548 | |
| 549 | return ret; |
| 550 | } |
| 551 | |
| 552 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 553 | #ifdef HAL_NETLINK_IMPL |
| 554 | typedef struct { |
| 555 | int id; |
| 556 | struct nl_sock* socket; |
| 557 | struct nl_cb* cb; |
| 558 | } Netlink; |
| 559 | |
| 560 | static int mac_addr_aton(unsigned char *mac_addr, char *arg) |
| 561 | { |
| 562 | unsigned int mac_addr_int[6]={}; |
| 563 | sscanf(arg, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int+0, mac_addr_int+1, mac_addr_int+2, mac_addr_int+3, mac_addr_int+4, mac_addr_int+5); |
| 564 | mac_addr[0] = mac_addr_int[0]; |
| 565 | mac_addr[1] = mac_addr_int[1]; |
| 566 | mac_addr[2] = mac_addr_int[2]; |
| 567 | mac_addr[3] = mac_addr_int[3]; |
| 568 | mac_addr[4] = mac_addr_int[4]; |
| 569 | mac_addr[5] = mac_addr_int[5]; |
| 570 | return 0; |
| 571 | } |
| 572 | |
| 573 | static void mac_addr_ntoa(char *mac_addr, unsigned char *arg) |
| 574 | { |
| 575 | unsigned int mac_addr_int[6]={}; |
| 576 | mac_addr_int[0] = arg[0]; |
| 577 | mac_addr_int[1] = arg[1]; |
| 578 | mac_addr_int[2] = arg[2]; |
| 579 | mac_addr_int[3] = arg[3]; |
| 580 | mac_addr_int[4] = arg[4]; |
| 581 | mac_addr_int[5] = arg[5]; |
| 582 | snprintf(mac_addr, 20, "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", mac_addr_int[0], mac_addr_int[1],mac_addr_int[2],mac_addr_int[3],mac_addr_int[4],mac_addr_int[5]); |
| 583 | return; |
| 584 | } |
| 585 | |
| 586 | static int ieee80211_frequency_to_channel(int freq) |
| 587 | { |
| 588 | /* see 802.11-2007 17.3.8.3.2 and Annex J */ |
| 589 | if (freq == 2484) |
| 590 | return 14; |
| 591 | /* see 802.11ax D6.1 27.3.23.2 and Annex E */ |
| 592 | else if (freq == 5935) |
| 593 | return 2; |
| 594 | else if (freq < 2484) |
| 595 | return (freq - 2407) / 5; |
| 596 | else if (freq >= 4910 && freq <= 4980) |
| 597 | return (freq - 4000) / 5; |
| 598 | else if (freq < 5950) |
| 599 | return (freq - 5000) / 5; |
| 600 | else if (freq <= 45000) /* DMG band lower limit */ |
| 601 | /* see 802.11ax D6.1 27.3.23.2 */ |
| 602 | return (freq - 5950) / 5; |
| 603 | else if (freq >= 58320 && freq <= 70200) |
| 604 | return (freq - 56160) / 2160; |
| 605 | else |
| 606 | return 0; |
| 607 | } |
| 608 | |
| 609 | static int initSock80211(Netlink* nl) { |
| 610 | nl->socket = nl_socket_alloc(); |
| 611 | if (!nl->socket) { |
| 612 | fprintf(stderr, "Failing to allocate the sock\n"); |
| 613 | return -ENOMEM; |
| 614 | } |
| 615 | |
| 616 | nl_socket_set_buffer_size(nl->socket, 8192, 8192); |
| 617 | |
| 618 | if (genl_connect(nl->socket)) { |
| 619 | fprintf(stderr, "Failed to connect\n"); |
| 620 | nl_close(nl->socket); |
| 621 | nl_socket_free(nl->socket); |
| 622 | return -ENOLINK; |
| 623 | } |
| 624 | |
| 625 | nl->id = genl_ctrl_resolve(nl->socket, "nl80211"); |
| 626 | if (nl->id< 0) { |
| 627 | fprintf(stderr, "interface not found.\n"); |
| 628 | nl_close(nl->socket); |
| 629 | nl_socket_free(nl->socket); |
| 630 | return -ENOENT; |
| 631 | } |
| 632 | |
| 633 | nl->cb = nl_cb_alloc(NL_CB_DEFAULT); |
| 634 | if ((!nl->cb)) { |
| 635 | fprintf(stderr, "Failed to allocate netlink callback.\n"); |
| 636 | nl_close(nl->socket); |
| 637 | nl_socket_free(nl->socket); |
| 638 | return ENOMEM; |
| 639 | } |
| 640 | |
| 641 | return nl->id; |
| 642 | } |
| 643 | |
| 644 | static int nlfree(Netlink *nl) |
| 645 | { |
| 646 | nl_cb_put(nl->cb); |
| 647 | nl_close(nl->socket); |
| 648 | nl_socket_free(nl->socket); |
| 649 | return 0; |
| 650 | } |
| 651 | |
| 652 | static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { |
| 653 | [NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED }, |
| 654 | [NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED }, |
| 655 | [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED } |
| 656 | }; |
| 657 | |
| 658 | static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = { |
| 659 | }; |
| 660 | |
| 661 | static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = { |
| 662 | }; |
| 663 | |
| 664 | typedef struct _wifi_channelStats_loc { |
| 665 | INT array_size; |
| 666 | INT ch_number; |
| 667 | BOOL ch_in_pool; |
| 668 | INT ch_noise; |
| 669 | BOOL ch_radar_noise; |
| 670 | INT ch_max_80211_rssi; |
| 671 | INT ch_non_80211_noise; |
| 672 | INT ch_utilization; |
| 673 | ULLONG ch_utilization_total; |
| 674 | ULLONG ch_utilization_busy; |
| 675 | ULLONG ch_utilization_busy_tx; |
| 676 | ULLONG ch_utilization_busy_rx; |
| 677 | ULLONG ch_utilization_busy_self; |
| 678 | ULLONG ch_utilization_busy_ext; |
| 679 | } wifi_channelStats_t_loc; |
| 680 | |
| 681 | typedef struct wifi_device_info { |
| 682 | INT wifi_devIndex; |
| 683 | UCHAR wifi_devMacAddress[6]; |
| 684 | CHAR wifi_devIPAddress[64]; |
| 685 | BOOL wifi_devAssociatedDeviceAuthentiationState; |
| 686 | INT wifi_devSignalStrength; |
| 687 | INT wifi_devTxRate; |
| 688 | INT wifi_devRxRate; |
| 689 | } wifi_device_info_t; |
| 690 | |
| 691 | #endif |
| 692 | |
| 693 | //For 5g Alias Interfaces |
| 694 | static BOOL priv_flag = TRUE; |
| 695 | static BOOL pub_flag = TRUE; |
| 696 | static BOOL Radio_flag = TRUE; |
| 697 | //wifi_setApBeaconRate(1, beaconRate); |
| 698 | |
| 699 | BOOL multiple_set = FALSE; |
| 700 | |
| 701 | struct params |
| 702 | { |
| 703 | char * name; |
| 704 | char * value; |
| 705 | }; |
| 706 | |
| 707 | static int _syscmd(char *cmd, char *retBuf, int retBufSize) |
| 708 | { |
| 709 | FILE *f; |
| 710 | char *ptr = retBuf; |
| 711 | int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0; |
| 712 | |
| 713 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 714 | if((f = popen(cmd, "r")) == NULL) { |
| 715 | fprintf(stderr,"\npopen %s error\n", cmd); |
| 716 | return RETURN_ERR; |
| 717 | } |
| 718 | |
| 719 | while(!feof(f)) |
| 720 | { |
| 721 | *ptr = 0; |
| 722 | if(bufSize>=128) { |
| 723 | bufbytes=128; |
| 724 | } else { |
| 725 | bufbytes=bufSize-1; |
| 726 | } |
| 727 | |
| 728 | fgets(ptr,bufbytes,f); |
| 729 | readbytes=strlen(ptr); |
| 730 | |
| 731 | if(!readbytes) |
| 732 | break; |
| 733 | |
| 734 | bufSize-=readbytes; |
| 735 | ptr += readbytes; |
| 736 | } |
| 737 | cmd_ret = pclose(f); |
| 738 | retBuf[retBufSize-1]=0; |
| 739 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 740 | |
| 741 | return cmd_ret >> 8; |
| 742 | } |
| 743 | |
| 744 | INT radio_index_to_phy(int radioIndex) |
| 745 | { |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 746 | /* TODO */ |
| 747 | return radioIndex; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 748 | } |
| 749 | |
| 750 | INT wifi_getMaxRadioNumber(INT *max_radio_num) |
| 751 | { |
| 752 | char cmd[64] = {0}; |
| 753 | char buf[4] = {0}; |
| 754 | |
| 755 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 756 | |
| 757 | snprintf(cmd, sizeof(cmd), "iw list | grep Wiphy | wc -l"); |
| 758 | _syscmd(cmd, buf, sizeof(buf)); |
| 759 | *max_radio_num = strtoul(buf, NULL, 10) > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:strtoul(buf, NULL, 10); |
| 760 | |
| 761 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 762 | |
| 763 | return RETURN_OK; |
| 764 | } |
| 765 | |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 766 | wifi_band radio_index_to_band(int radioIndex) |
| 767 | { |
developer | 745f0bd | 2023-03-06 14:32:53 +0800 | [diff] [blame] | 768 | return radio_band[radioIndex]; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 769 | } |
| 770 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 771 | wifi_band wifi_index_to_band(int apIndex) |
| 772 | { |
| 773 | char cmd[128] = {0}; |
| 774 | char buf[64] = {0}; |
| 775 | int nl80211_band = 0; |
| 776 | int i = 0; |
| 777 | int phyIndex = 0; |
| 778 | int radioIndex = 0; |
| 779 | int max_radio_num = 0; |
| 780 | wifi_band band = band_invalid; |
| 781 | |
| 782 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 783 | |
| 784 | wifi_getMaxRadioNumber(&max_radio_num); |
| 785 | radioIndex = apIndex % max_radio_num; |
| 786 | phyIndex = radio_index_to_phy(radioIndex); |
| 787 | while(i < 10){ |
| 788 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex); |
| 789 | _syscmd(cmd, buf, sizeof(buf)); |
| 790 | nl80211_band = strtol(buf, NULL, 10); |
| 791 | if (nl80211_band == 1) |
| 792 | band = band_2_4; |
| 793 | else if (nl80211_band == 2) |
| 794 | band = band_5; |
| 795 | else if (nl80211_band == 4) // band == 3 is 60GHz |
| 796 | band = band_6; |
| 797 | |
| 798 | if(band != band_invalid) |
| 799 | break; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 800 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 801 | i++; |
| 802 | sleep(1); |
| 803 | } |
| 804 | |
| 805 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 806 | return band; |
| 807 | } |
| 808 | |
| 809 | static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size) |
| 810 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 811 | char cmd[MAX_CMD_SIZE] = {0}; |
| 812 | char buf[MAX_BUF_SIZE] = {0}; |
| 813 | int ret = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 814 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 815 | ret = snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", |
| 816 | conf_file, param); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 817 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 818 | if (ret < 0) { |
| 819 | printf("%s: snprintf error!", __func__); |
| 820 | return -1; |
| 821 | } |
| 822 | |
| 823 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 824 | if ((ret != 0) && (strlen(buf) == 0)) { |
| 825 | printf("%s: _syscmd error!", __func__); |
| 826 | return -1; |
| 827 | } |
| 828 | |
| 829 | snprintf(output, output_size, "%s", buf); |
| 830 | |
| 831 | return 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 832 | } |
| 833 | |
| 834 | static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count) |
| 835 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 836 | char cmd[MAX_CMD_SIZE] = {0}; |
| 837 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 838 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 839 | for (int i = 0; i < item_count; i++) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 840 | wifi_hostapdRead(conf_file, list[i].name, buf, sizeof(buf)); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 841 | if (strlen(buf) == 0) /*no such item, insert it*/ |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 842 | snprintf(cmd, sizeof(cmd), "sed -i -e '$a %s=%s' %s", list[i].name, list[i].value, conf_file); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 843 | else /*find the item, update it*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 844 | snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=%s/\" %s", list[i].name, list[i].name, list[i].value, conf_file); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 845 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 846 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 847 | return -1; |
| 848 | } |
| 849 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 850 | return 0; |
| 851 | } |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 852 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 853 | static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size) |
| 854 | { |
| 855 | char cmd[MAX_CMD_SIZE] = {0}; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 856 | int ret = 0; |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 857 | int len; |
| 858 | |
| 859 | ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s", conf_file, param); |
| 860 | if (ret < 0) { |
| 861 | printf("%s: snprintf error!", __func__); |
| 862 | return -1; |
| 863 | } |
| 864 | |
| 865 | ret = _syscmd(cmd, output, output_size); |
| 866 | if ((ret != 0) && (strlen(output) == 0)) { |
| 867 | printf("%s: _syscmd error!", __func__); |
| 868 | return -1; |
| 869 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 870 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 871 | len = strlen(output); |
| 872 | if ((len > 0) && (output[len - 1] == '\n')) { |
| 873 | output[len - 1] = '\0'; |
| 874 | } |
| 875 | |
| 876 | return 0; |
| 877 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 878 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 879 | static int wifi_datfileRead2(char *conf_file, int idx, char *param, char *output, int output_size) |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 880 | { |
| 881 | char cmd[MAX_CMD_SIZE] = {0}; |
| 882 | int ret = 0; |
| 883 | int len; |
| 884 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 885 | ret = snprintf(cmd, sizeof(cmd), "datconf -f %s get %s %d", conf_file, param, idx); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 886 | if (ret < 0) { |
| 887 | printf("%s: snprintf error!", __func__); |
| 888 | return -1; |
| 889 | } |
| 890 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 891 | ret = _syscmd(cmd, output, output_size); |
| 892 | if ((ret != 0) && (strlen(output) == 0)) { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 893 | printf("%s: _syscmd error!", __func__); |
| 894 | return -1; |
| 895 | } |
| 896 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 897 | len = strlen(output); |
| 898 | if ((len > 0) && (output[len - 1] == '\n')) { |
| 899 | output[len - 1] = '\0'; |
| 900 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 901 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 902 | return 0; |
| 903 | } |
| 904 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 905 | static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count) |
| 906 | { |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 907 | int ret; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 908 | char cmd[MAX_CMD_SIZE] = {0}; |
| 909 | char buf[MAX_BUF_SIZE] = {0}; |
| 910 | |
| 911 | for (int i = 0; i < item_count; i++) { |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 912 | ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value); |
| 913 | if (ret < 0) { |
| 914 | printf("%s: snprintf error!", __func__); |
| 915 | return -1; |
| 916 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 917 | |
| 918 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 919 | return -1; |
| 920 | } |
| 921 | |
| 922 | return 0; |
| 923 | } |
| 924 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 925 | static int wifi_datfileWrite2(char *conf_file, int idx, struct params *list, int item_count) |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 926 | { |
| 927 | int ret; |
| 928 | char cmd[MAX_CMD_SIZE] = {0}; |
| 929 | char buf[MAX_BUF_SIZE] = {0}; |
| 930 | |
| 931 | for (int i = 0; i < item_count; i++) { |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 932 | ret = snprintf(cmd, sizeof(cmd), "datconf -f %s set %s %d \"%s\"", conf_file, list[i].name, idx, list[i].value); |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 933 | if (ret < 0) { |
| 934 | printf("%s: snprintf error!", __func__); |
| 935 | return -1; |
| 936 | } |
| 937 | |
| 938 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 939 | return -1; |
| 940 | } |
| 941 | |
| 942 | return 0; |
| 943 | } |
| 944 | |
| 945 | static int wifi_l1ProfileRead(char *param, char *output, int output_size) |
| 946 | { |
| 947 | char buf[MAX_BUF_SIZE] = {0}; |
| 948 | int ret; |
| 949 | |
| 950 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 951 | if (!param || !output || (output_size <= 0)) { |
| 952 | fprintf(stderr, "%s: invalid parameters", __func__); |
| 953 | return RETURN_ERR; |
| 954 | } |
| 955 | |
| 956 | ret = wifi_datfileRead(l1profile, param, output, output_size); |
| 957 | if (ret != 0) { |
| 958 | fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, l1profile, ret); |
| 959 | return RETURN_ERR; |
| 960 | } |
| 961 | |
| 962 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 963 | return RETURN_OK; |
| 964 | } |
| 965 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 966 | static int wifi_l1ProfileRead2(char *param, int idx, char *output, int output_size) |
| 967 | { |
| 968 | char buf[MAX_BUF_SIZE] = {0}; |
| 969 | int ret; |
| 970 | |
| 971 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 972 | if (!param || !output || (output_size <= 0)) { |
| 973 | fprintf(stderr, "%s: invalid parameters", __func__); |
| 974 | return RETURN_ERR; |
| 975 | } |
| 976 | |
| 977 | ret = wifi_datfileRead2(l1profile, idx, param, output, output_size); |
| 978 | if (ret != 0) { |
| 979 | fprintf(stderr, "%s: wifi_datfileRead2 %s from %s failed, ret:%d", __func__, param, l1profile, ret); |
| 980 | return RETURN_ERR; |
| 981 | } |
| 982 | |
| 983 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 984 | return RETURN_OK; |
| 985 | } |
| 986 | |
| 987 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 988 | static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size) |
| 989 | { |
| 990 | char option[64]; |
| 991 | char card_profile_path[64]; |
| 992 | int ret; |
| 993 | |
| 994 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 995 | |
| 996 | if (!param || !output || (output_size <= 0)) { |
| 997 | fprintf(stderr, "%s: invalid parameters", __func__); |
| 998 | return RETURN_ERR; |
| 999 | } |
| 1000 | |
| 1001 | snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx); |
| 1002 | ret = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path)); |
| 1003 | if (ret != 0) { |
| 1004 | fprintf(stderr, "%s: wifi_l1ProfileRead %s failed, ret:%d", __func__, option, ret); |
| 1005 | return RETURN_ERR; |
| 1006 | } |
| 1007 | |
| 1008 | ret = wifi_datfileRead(card_profile_path, param, output, output_size); |
| 1009 | if (ret != 0) { |
| 1010 | fprintf(stderr, "%s: wifi_datfileRead %s from %s failed, ret:%d", __func__, param, card_profile_path, ret); |
| 1011 | return RETURN_ERR; |
| 1012 | } |
| 1013 | |
| 1014 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1015 | return RETURN_OK; |
| 1016 | } |
| 1017 | |
| 1018 | static int wifi_BandProfileRead(int card_idx, |
| 1019 | int radio_idx, |
| 1020 | char *param, |
| 1021 | char *output, |
| 1022 | int output_size, |
| 1023 | char *default_value) |
| 1024 | { |
| 1025 | char option[64]; |
| 1026 | char band_profile_path[64]; |
| 1027 | int ret; |
| 1028 | |
| 1029 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1030 | if (!param || !output || (output_size <= 0)) { |
| 1031 | fprintf(stderr, "%s: invalid parameters", __func__); |
| 1032 | return RETURN_ERR; |
| 1033 | } |
| 1034 | |
| 1035 | snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx); |
| 1036 | ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path)); |
| 1037 | if (ret != 0) { |
| 1038 | fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option); |
| 1039 | return RETURN_ERR; |
| 1040 | } |
| 1041 | |
| 1042 | ret = wifi_datfileRead(band_profile_path, param, output, output_size); |
| 1043 | if (ret != 0) { |
| 1044 | if (default_value) { |
| 1045 | snprintf(output, output_size, "%s", default_value); |
| 1046 | } else { |
| 1047 | output[0] = '\0'; |
| 1048 | } |
| 1049 | } |
| 1050 | |
| 1051 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1052 | return RETURN_OK; |
| 1053 | } |
| 1054 | |
| 1055 | static int wifi_BandProfileRead2(int card_idx, |
| 1056 | int radio_idx, |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 1057 | int idx, |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 1058 | char *param, |
| 1059 | char *output, |
| 1060 | int output_size, |
| 1061 | char* default_value) |
| 1062 | { |
| 1063 | char option[64]; |
| 1064 | char band_profile_path[64]; |
| 1065 | int ret; |
| 1066 | |
| 1067 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1068 | if (!param || !output || (output_size <= 0)) { |
| 1069 | fprintf(stderr, "%s: invalid parameters", __func__); |
| 1070 | return RETURN_ERR; |
| 1071 | } |
| 1072 | |
| 1073 | snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx); |
| 1074 | ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path)); |
| 1075 | if (ret != 0) { |
| 1076 | fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option); |
| 1077 | return RETURN_ERR; |
| 1078 | } |
| 1079 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 1080 | ret = wifi_datfileRead2(band_profile_path, idx, param, output, output_size); |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 1081 | if (ret != 0) { |
| 1082 | if (default_value) { |
| 1083 | snprintf(output, output_size, "%s", default_value); |
| 1084 | } else { |
| 1085 | output[0] = '\0'; |
| 1086 | } |
| 1087 | } |
| 1088 | |
| 1089 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1090 | return RETURN_OK; |
| 1091 | |
| 1092 | } |
| 1093 | |
| 1094 | static int wifi_BandProfileWrite(int card_idx, int radio_idx, struct params *list, int item_count) |
| 1095 | { |
| 1096 | char option[64]; |
| 1097 | char band_profile_path[64]; |
| 1098 | int ret; |
| 1099 | |
| 1100 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1101 | |
| 1102 | snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx); |
| 1103 | ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path)); |
| 1104 | if (ret != 0) { |
| 1105 | fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option); |
| 1106 | return RETURN_ERR; |
| 1107 | } |
| 1108 | |
| 1109 | for (int i = 0; i < item_count; i++) { |
| 1110 | } |
| 1111 | ret = wifi_datfileWrite(band_profile_path, list, item_count); |
| 1112 | if (ret != 0) { |
| 1113 | fprintf(stderr, "%s: wifi_datfileWrite failed, ret:%d", __func__); |
| 1114 | return RETURN_ERR; |
| 1115 | } |
| 1116 | |
| 1117 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1118 | return RETURN_OK; |
| 1119 | |
| 1120 | } |
| 1121 | |
| 1122 | static int wifi_BandProfileWrite2(int card_idx, |
| 1123 | int radio_idx, |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 1124 | int idx, |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 1125 | struct params *list, |
| 1126 | int item_count) |
| 1127 | { |
| 1128 | char option[64]; |
| 1129 | char band_profile_path[64]; |
| 1130 | char buf[64]; |
| 1131 | char buf2[MAX_BUF_SIZE]; |
| 1132 | int ret; |
| 1133 | |
| 1134 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1135 | |
| 1136 | snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx); |
| 1137 | ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path)); |
| 1138 | if (ret != 0) { |
| 1139 | fprintf(stderr, "%s: wifi_CardProfileRead %s failed, ret:%d", __func__, option); |
| 1140 | return RETURN_ERR; |
| 1141 | } |
| 1142 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 1143 | ret = wifi_datfileWrite2(band_profile_path, idx, list, item_count); |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 1144 | if (ret != 0) { |
| 1145 | fprintf(stderr, "%s: wifi_datfileWrite failed, ret:%d", __func__); |
| 1146 | return RETURN_ERR; |
| 1147 | } |
| 1148 | |
| 1149 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1150 | return RETURN_OK; |
| 1151 | |
| 1152 | } |
| 1153 | |
| 1154 | |
| 1155 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1156 | //For Getting Current Interface Name from corresponding hostapd configuration |
| 1157 | static int wifi_GetInterfaceName(int apIndex, char *interface_name) |
| 1158 | { |
| 1159 | char config_file[128] = {0}; |
| 1160 | |
| 1161 | if (interface_name == NULL) |
| 1162 | return RETURN_ERR; |
| 1163 | |
| 1164 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1165 | |
| 1166 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 1167 | wifi_hostapdRead(config_file, "interface", interface_name, 16); |
| 1168 | if (strlen(interface_name) == 0) |
| 1169 | return RETURN_ERR; |
| 1170 | |
| 1171 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1172 | return RETURN_OK; |
| 1173 | } |
| 1174 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 1175 | static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt) |
| 1176 | { |
| 1177 | char interface_name[IF_NAME_SIZE] = {0}; |
| 1178 | char cmd[MAX_BUF_SIZE]={'\0'}; |
| 1179 | char buf[MAX_CMD_SIZE]={'\0'}; |
| 1180 | UCHAR channel = 0; |
| 1181 | |
| 1182 | if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK) |
| 1183 | return RETURN_ERR; |
| 1184 | /*interface name to channel number*/ |
| 1185 | snprintf(cmd, sizeof(cmd), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name); |
| 1186 | _syscmd(cmd, buf, sizeof(buf)); |
| 1187 | channel = atoi(buf); |
| 1188 | WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel); |
| 1189 | /*count dev number with the same channel*/ |
| 1190 | snprintf(cmd, sizeof(cmd), "iw dev | grep -i 'channel %d' | wc -l", channel); |
| 1191 | _syscmd(cmd, buf, sizeof(buf)); |
| 1192 | *bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/ |
| 1193 | WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt); |
| 1194 | return RETURN_OK; |
| 1195 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1196 | |
| 1197 | static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count) |
| 1198 | { |
| 1199 | char interface_name[16] = {0}; |
| 1200 | if (multiple_set == TRUE) |
| 1201 | return RETURN_OK; |
| 1202 | char cmd[MAX_CMD_SIZE]="", output[32]=""; |
| 1203 | FILE *fp; |
| 1204 | int i; |
| 1205 | //NOTE RELOAD should be done in ApplySSIDSettings |
| 1206 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 1207 | return RETURN_ERR; |
| 1208 | for(i=0; i<item_count; i++, list++) |
| 1209 | { |
developer | f6a8754 | 2023-05-16 15:47:28 +0800 | [diff] [blame] | 1210 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1211 | if((fp = popen(cmd, "r"))==NULL) |
| 1212 | { |
| 1213 | perror("popen failed"); |
| 1214 | return -1; |
| 1215 | } |
| 1216 | if(!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) |
| 1217 | { |
| 1218 | pclose(fp); |
| 1219 | perror("fgets failed"); |
| 1220 | return -1; |
| 1221 | } |
| 1222 | pclose(fp); |
| 1223 | } |
| 1224 | return 0; |
| 1225 | } |
| 1226 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 1227 | static int wifi_quick_reload_ap(int apIndex) |
| 1228 | { |
| 1229 | char interface_name[IF_NAME_SIZE] = {0}; |
| 1230 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1231 | char buf[MAX_BUF_SIZE] = {0}; |
| 1232 | |
| 1233 | if (multiple_set == TRUE) |
| 1234 | return RETURN_OK; |
| 1235 | |
| 1236 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 1237 | return RETURN_ERR; |
| 1238 | |
| 1239 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name); |
| 1240 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 1241 | return RETURN_ERR; |
| 1242 | |
| 1243 | return RETURN_OK; |
| 1244 | } |
| 1245 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1246 | static int wifi_reloadAp(int apIndex) |
| 1247 | { |
| 1248 | char interface_name[16] = {0}; |
| 1249 | if (multiple_set == TRUE) |
| 1250 | return RETURN_OK; |
| 1251 | char cmd[MAX_CMD_SIZE]=""; |
| 1252 | char buf[MAX_BUF_SIZE]=""; |
| 1253 | |
| 1254 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 1255 | return RETURN_ERR; |
| 1256 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s reload", interface_name); |
| 1257 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 1258 | return RETURN_ERR; |
| 1259 | |
| 1260 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s disable", interface_name); |
| 1261 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 1262 | return RETURN_ERR; |
| 1263 | |
| 1264 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s enable", interface_name); |
| 1265 | if (_syscmd(cmd, buf, sizeof(buf)) == RETURN_ERR) |
| 1266 | return RETURN_ERR; |
| 1267 | |
| 1268 | return RETURN_OK; |
| 1269 | } |
| 1270 | |
| 1271 | INT File_Reading(CHAR *file, char *Value) |
| 1272 | { |
| 1273 | FILE *fp = NULL; |
| 1274 | char buf[MAX_CMD_SIZE] = {0}, copy_buf[MAX_CMD_SIZE] ={0}; |
| 1275 | int count = 0; |
| 1276 | |
| 1277 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1278 | fp = popen(file,"r"); |
| 1279 | if(fp == NULL) |
| 1280 | return RETURN_ERR; |
| 1281 | |
| 1282 | if(fgets(buf,sizeof(buf) -1,fp) != NULL) |
| 1283 | { |
| 1284 | for(count=0;buf[count]!='\n';count++) |
| 1285 | copy_buf[count]=buf[count]; |
| 1286 | copy_buf[count]='\0'; |
| 1287 | } |
| 1288 | strcpy(Value,copy_buf); |
| 1289 | pclose(fp); |
| 1290 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1291 | |
| 1292 | return RETURN_OK; |
| 1293 | } |
| 1294 | |
| 1295 | void wifi_RestartHostapd_2G() |
| 1296 | { |
| 1297 | int Public2GApIndex = 4; |
| 1298 | |
| 1299 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1300 | wifi_setApEnable(Public2GApIndex, FALSE); |
| 1301 | wifi_setApEnable(Public2GApIndex, TRUE); |
| 1302 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1303 | } |
| 1304 | |
| 1305 | void wifi_RestartHostapd_5G() |
| 1306 | { |
| 1307 | int Public5GApIndex = 5; |
| 1308 | |
| 1309 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1310 | wifi_setApEnable(Public5GApIndex, FALSE); |
| 1311 | wifi_setApEnable(Public5GApIndex, TRUE); |
| 1312 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1313 | } |
| 1314 | |
| 1315 | void wifi_RestartPrivateWifi_2G() |
| 1316 | { |
| 1317 | int PrivateApIndex = 0; |
| 1318 | |
| 1319 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1320 | wifi_setApEnable(PrivateApIndex, FALSE); |
| 1321 | wifi_setApEnable(PrivateApIndex, TRUE); |
| 1322 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1323 | } |
| 1324 | |
| 1325 | void wifi_RestartPrivateWifi_5G() |
| 1326 | { |
| 1327 | int Private5GApIndex = 1; |
| 1328 | |
| 1329 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1330 | wifi_setApEnable(Private5GApIndex, FALSE); |
| 1331 | wifi_setApEnable(Private5GApIndex, TRUE); |
| 1332 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1333 | } |
| 1334 | |
| 1335 | static int writeBandWidth(int radioIndex,char *bw_value) |
| 1336 | { |
| 1337 | char buf[MAX_BUF_SIZE]; |
| 1338 | char cmd[MAX_CMD_SIZE]; |
| 1339 | |
| 1340 | snprintf(cmd, sizeof(cmd), "grep SET_BW%d %s", radioIndex, BW_FNAME); |
| 1341 | if(_syscmd(cmd, buf, sizeof(buf))) |
| 1342 | { |
| 1343 | snprintf(cmd, sizeof(cmd), "echo SET_BW%d=%s >> %s", radioIndex, bw_value, BW_FNAME); |
| 1344 | _syscmd(cmd, buf, sizeof(buf)); |
| 1345 | return RETURN_OK; |
| 1346 | } |
| 1347 | |
| 1348 | sprintf(cmd,"sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME); |
| 1349 | _syscmd(cmd,buf,sizeof(buf)); |
| 1350 | return RETURN_OK; |
| 1351 | } |
| 1352 | |
| 1353 | static int readBandWidth(int radioIndex,char *bw_value) |
| 1354 | { |
| 1355 | char buf[MAX_BUF_SIZE] = {0}; |
| 1356 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1357 | sprintf(cmd,"grep 'SET_BW%d=' %s | sed 's/^.*=//'",radioIndex,BW_FNAME); |
| 1358 | _syscmd(cmd,buf,sizeof(buf)); |
| 1359 | if(NULL!=strstr(buf,"20MHz")) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1360 | strcpy(bw_value,"20MHz"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1361 | else if(NULL!=strstr(buf,"40MHz")) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1362 | strcpy(bw_value,"40MHz"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1363 | else if(NULL!=strstr(buf,"80MHz")) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1364 | strcpy(bw_value,"80MHz"); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 1365 | else if(NULL!=strstr(buf,"160MHz")) |
| 1366 | strcpy(bw_value,"160MHz"); |
| 1367 | else if(NULL!=strstr(buf,"320MHz")) |
| 1368 | strcpy(bw_value,"320MHz"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1369 | else |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1370 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1371 | return RETURN_OK; |
| 1372 | } |
| 1373 | |
| 1374 | // Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps" |
| 1375 | INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate) |
| 1376 | { |
| 1377 | struct params params={'\0'}; |
| 1378 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1379 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 1380 | |
| 1381 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1382 | // Copy the numeric value |
| 1383 | if (strlen (beaconRate) >= 5) { |
| 1384 | strncpy(buf, beaconRate, strlen(beaconRate) - 4); |
| 1385 | buf[strlen(beaconRate) - 4] = '\0'; |
| 1386 | } else if (strlen(beaconRate) > 0) |
| 1387 | strcpy(buf, beaconRate); |
| 1388 | else |
| 1389 | return RETURN_ERR; |
| 1390 | |
| 1391 | params.name = "beacon_rate"; |
| 1392 | // hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10. |
| 1393 | if (strncmp(buf, "5.5", 3) == 0) { |
| 1394 | snprintf(buf, sizeof(buf), "55"); |
| 1395 | params.value = buf; |
| 1396 | } else { |
| 1397 | strcat(buf, "0"); |
| 1398 | params.value = buf; |
| 1399 | } |
| 1400 | |
| 1401 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 1402 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 1403 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 1404 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1405 | |
| 1406 | return RETURN_OK; |
| 1407 | } |
| 1408 | |
| 1409 | INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate) |
| 1410 | { |
| 1411 | char config_file[128] = {'\0'}; |
| 1412 | char temp_output[128] = {'\0'}; |
| 1413 | char buf[128] = {'\0'}; |
| 1414 | char cmd[128] = {'\0'}; |
| 1415 | int rate = 0; |
| 1416 | int phyId = 0; |
| 1417 | |
| 1418 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1419 | if (NULL == beaconRate) |
| 1420 | return RETURN_ERR; |
| 1421 | |
| 1422 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 1423 | wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf)); |
| 1424 | phyId = radio_index_to_phy(radioIndex); |
| 1425 | // Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10. |
| 1426 | if(strlen(buf) > 0) { |
| 1427 | if (strncmp(buf, "55", 2) == 0) |
| 1428 | snprintf(temp_output, sizeof(temp_output), "5.5Mbps"); |
| 1429 | else { |
| 1430 | rate = strtol(buf, NULL, 10)/10; |
| 1431 | snprintf(temp_output, sizeof(temp_output), "%dMbps", rate); |
| 1432 | } |
| 1433 | } else { |
| 1434 | // config not set, so we would use lowest rate as default |
| 1435 | sprintf(cmd, "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId); |
| 1436 | _syscmd(cmd, buf, sizeof(buf)); |
| 1437 | snprintf(temp_output, sizeof(temp_output), "%sMbps", buf); |
| 1438 | } |
| 1439 | strncpy(beaconRate, temp_output, sizeof(temp_output)); |
| 1440 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1441 | |
| 1442 | return RETURN_OK; |
| 1443 | } |
| 1444 | |
| 1445 | INT wifi_setLED(INT radioIndex, BOOL enable) |
| 1446 | { |
| 1447 | return 0; |
| 1448 | } |
| 1449 | INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds) |
| 1450 | { |
| 1451 | return RETURN_OK; |
| 1452 | } |
| 1453 | /********************************************************************************** |
| 1454 | * |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 1455 | * Wifi Subsystem level function prototypes |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1456 | * |
| 1457 | **********************************************************************************/ |
| 1458 | //--------------------------------------------------------------------------------------------------- |
| 1459 | //Wifi system api |
| 1460 | //Get the wifi hal version in string, eg "2.0.0". WIFI_HAL_MAJOR_VERSION.WIFI_HAL_MINOR_VERSION.WIFI_HAL_MAINTENANCE_VERSION |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 1461 | INT wifi_getHalVersion(CHAR *output_string) //RDKB |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1462 | { |
| 1463 | if(!output_string) |
| 1464 | return RETURN_ERR; |
| 1465 | snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION); |
| 1466 | |
| 1467 | return RETURN_OK; |
| 1468 | } |
| 1469 | |
| 1470 | |
| 1471 | /* wifi_factoryReset() function */ |
| 1472 | /** |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 1473 | * @description Clears internal variables to implement a factory reset of the Wi-Fi |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1474 | * subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements. |
| 1475 | * |
| 1476 | * @param None |
| 1477 | * |
| 1478 | * @return The status of the operation. |
| 1479 | * @retval RETURN_OK if successful. |
| 1480 | * @retval RETURN_ERR if any error is detected |
| 1481 | * |
| 1482 | * @execution Synchronous |
| 1483 | * @sideeffect None |
| 1484 | * |
| 1485 | * @note This function must not suspend and must not invoke any blocking system |
| 1486 | * calls. It should probably just send a message to a driver event handler task. |
| 1487 | * |
| 1488 | */ |
| 1489 | INT wifi_factoryReset() |
| 1490 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1491 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1492 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1493 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1494 | /*delete running hostapd conf files*/ |
| 1495 | wifi_dbg_printf("\n[%s]: deleting hostapd conf file.", __func__); |
| 1496 | snprintf(cmd, MAX_CMD_SIZE, "rm -rf /nvram/*.conf"); |
| 1497 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1498 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1499 | wifi_PrepareDefaultHostapdConfigs(); |
| 1500 | wifi_psk_file_reset(); |
| 1501 | |
| 1502 | memset(cmd, 0, MAX_CMD_SIZE); |
| 1503 | memset(buf, 0, MAX_BUF_SIZE); |
| 1504 | |
| 1505 | snprintf(cmd, MAX_CMD_SIZE, "systemctl restart hostapd.service"); |
| 1506 | _syscmd(cmd, buf, sizeof(buf)); |
| 1507 | |
| 1508 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1509 | } |
| 1510 | |
| 1511 | /* wifi_factoryResetRadios() function */ |
| 1512 | /** |
| 1513 | * @description Restore all radio parameters without touching access point parameters. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements. |
| 1514 | * |
| 1515 | * @param None |
| 1516 | * @return The status of the operation |
| 1517 | * @retval RETURN_OK if successful |
| 1518 | * @retval RETURN_ERR if any error is detected |
| 1519 | * |
| 1520 | * @execution Synchronous |
| 1521 | * |
| 1522 | * @sideeffect None |
| 1523 | * |
| 1524 | * @note This function must not suspend and must not invoke any blocking system |
| 1525 | * calls. It should probably just send a message to a driver event handler task. |
| 1526 | * |
| 1527 | */ |
| 1528 | INT wifi_factoryResetRadios() |
| 1529 | { |
| 1530 | if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1))) |
| 1531 | return RETURN_OK; |
| 1532 | |
| 1533 | return RETURN_ERR; |
| 1534 | } |
| 1535 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 1536 | ULONG get_radio_reset_cnt(int radioIndex) |
| 1537 | { |
| 1538 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1539 | char buf[MAX_BUF_SIZE] = {0}; |
| 1540 | ULONG reset_count = 0; |
| 1541 | |
| 1542 | snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", |
| 1543 | RADIO_RESET_FILE, radioIndex); |
| 1544 | _syscmd(cmd, buf, sizeof(buf)); |
| 1545 | |
| 1546 | if (strlen(buf) == 0) |
| 1547 | return 0; |
| 1548 | else { |
| 1549 | reset_count = atol(buf); |
| 1550 | return reset_count; |
| 1551 | } |
| 1552 | } |
| 1553 | void update_radio_reset_cnt(int radioIndex) |
| 1554 | { |
| 1555 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1556 | char buf[MAX_BUF_SIZE] = {0}; |
| 1557 | ULONG reset_count = 0; |
| 1558 | |
| 1559 | snprintf(cmd, MAX_CMD_SIZE, "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", |
| 1560 | RADIO_RESET_FILE, radioIndex); |
| 1561 | _syscmd(cmd, buf, sizeof(buf)); |
| 1562 | |
| 1563 | if (strlen(buf) == 0) |
| 1564 | snprintf(cmd, sizeof(cmd), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE); |
| 1565 | else { |
| 1566 | reset_count = atol(buf); |
| 1567 | reset_count++; |
| 1568 | snprintf(cmd, sizeof(cmd), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE); |
| 1569 | } |
| 1570 | _syscmd(cmd, buf, sizeof(buf)); |
| 1571 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1572 | |
| 1573 | /* wifi_factoryResetRadio() function */ |
| 1574 | /** |
| 1575 | * @description Restore selected radio parameters without touching access point parameters |
| 1576 | * |
| 1577 | * @param radioIndex - Index of Wi-Fi Radio channel |
| 1578 | * |
| 1579 | * @return The status of the operation. |
| 1580 | * @retval RETURN_OK if successful. |
| 1581 | * @retval RETURN_ERR if any error is detected |
| 1582 | * |
| 1583 | * @execution Synchronous. |
| 1584 | * @sideeffect None. |
| 1585 | * |
| 1586 | * @note This function must not suspend and must not invoke any blocking system |
| 1587 | * calls. It should probably just send a message to a driver event handler task. |
| 1588 | * |
| 1589 | */ |
| 1590 | INT wifi_factoryResetRadio(int radioIndex) //RDKB |
| 1591 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1592 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1593 | char buf[MAX_BUF_SIZE] = {0}; |
| 1594 | char vap_idx = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1595 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1596 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1597 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 1598 | wifi_dat_file_reset_by_radio(radioIndex); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1599 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 1600 | /*reset gi setting*/ |
| 1601 | snprintf(cmd, sizeof(cmd), "echo 'Auto' > %s%d.txt", GUARD_INTERVAL_FILE, radioIndex); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1602 | _syscmd(cmd, buf, sizeof(buf)); |
| 1603 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 1604 | /*TBD: check mbss issue*/ |
| 1605 | wifi_factoryResetAP(radioIndex); |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 1606 | update_radio_reset_cnt(radioIndex); |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 1607 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1608 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 1609 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1610 | } |
| 1611 | |
| 1612 | /* wifi_initRadio() function */ |
| 1613 | /** |
| 1614 | * Description: This function call initializes the specified radio. |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 1615 | * Implementation specifics may dictate the functionality since |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1616 | * different hardware implementations may have different initilization requirements. |
| 1617 | * Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1 - type INT |
| 1618 | * |
| 1619 | * @return The status of the operation. |
| 1620 | * @retval RETURN_OK if successful. |
| 1621 | * @retval RETURN_ERR if any error is detected |
| 1622 | * |
| 1623 | * @execution Synchronous. |
| 1624 | * @sideeffect None. |
| 1625 | * |
| 1626 | * @note This function must not suspend and must not invoke any blocking system |
| 1627 | * calls. It should probably just send a message to a driver event handler task. |
| 1628 | * |
| 1629 | */ |
| 1630 | INT wifi_initRadio(INT radioIndex) |
| 1631 | { |
| 1632 | //TODO: Initializes the wifi subsystem (for specified radio) |
| 1633 | return RETURN_OK; |
| 1634 | } |
| 1635 | void macfilter_init() |
| 1636 | { |
| 1637 | char count[4]={'\0'}; |
| 1638 | char buf[253]={'\0'}; |
| 1639 | char tmp[19]={'\0'}; |
| 1640 | int dev_count,block,mac_entry=0; |
| 1641 | char res[4]={'\0'}; |
| 1642 | char acl_file_path[64] = {'\0'}; |
| 1643 | FILE *fp = NULL; |
| 1644 | int index=0; |
| 1645 | char iface[10]={'\0'}; |
| 1646 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1647 | |
| 1648 | |
| 1649 | sprintf(acl_file_path,"/tmp/mac_filter.sh"); |
| 1650 | |
| 1651 | fp=fopen(acl_file_path,"w+"); |
| 1652 | if (fp == NULL) { |
| 1653 | fprintf(stderr, "%s: failed to open file %s.\n", __func__, acl_file_path); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1654 | return; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 1655 | } |
| 1656 | sprintf(buf,"#!/bin/sh \n"); |
| 1657 | fprintf(fp,"%s\n",buf); |
| 1658 | |
| 1659 | system("chmod 0777 /tmp/mac_filter.sh"); |
| 1660 | |
| 1661 | for(index=0;index<=1;index++) |
| 1662 | { |
| 1663 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,index); |
| 1664 | wifi_hostapdRead(config_file, "interface", iface, sizeof(iface)); |
| 1665 | sprintf(buf,"syscfg get %dcountfilter",index); |
| 1666 | _syscmd(buf,count,sizeof(count)); |
| 1667 | mac_entry=atoi(count); |
| 1668 | |
| 1669 | sprintf(buf,"syscfg get %dblockall",index); |
| 1670 | _syscmd(buf,res,sizeof(res)); |
| 1671 | block = atoi(res); |
| 1672 | |
| 1673 | //Allow only those macs mentioned in ACL |
| 1674 | if(block==1) |
| 1675 | { |
| 1676 | sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index); |
| 1677 | fprintf(fp,"%s\n",buf); |
| 1678 | for(dev_count=1;dev_count<=mac_entry;dev_count++) |
| 1679 | { |
| 1680 | sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count); |
| 1681 | _syscmd(buf,tmp,sizeof(tmp)); |
| 1682 | fprintf(stderr,"MAcs to be Allowed *%s* ###########\n",tmp); |
| 1683 | sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",index,iface,tmp); |
| 1684 | fprintf(fp,"%s\n",buf); |
| 1685 | } |
| 1686 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac ! --mac-source %s -j DROP",index,iface,tmp); |
| 1687 | fprintf(fp,"%s\n",buf); |
| 1688 | } |
| 1689 | |
| 1690 | //Block all the macs mentioned in ACL |
| 1691 | else if(block==2) |
| 1692 | { |
| 1693 | sprintf(buf,"iptables -N WifiServices%d\n iptables -I INPUT 21 -j WifiServices%d\n",index,index); |
| 1694 | fprintf(fp,"%s\n",buf); |
| 1695 | |
| 1696 | for(dev_count=1;dev_count<=mac_entry;dev_count++) |
| 1697 | { |
| 1698 | sprintf(buf,"syscfg get %dmacfilter%d",index,dev_count); |
| 1699 | _syscmd(buf,tmp,sizeof(tmp)); |
| 1700 | fprintf(stderr,"MAcs to be blocked *%s* ###########\n",tmp); |
| 1701 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",index,iface,tmp); |
| 1702 | fprintf(fp,"%s\n",buf); |
| 1703 | } |
| 1704 | } |
| 1705 | } |
| 1706 | fclose(fp); |
| 1707 | } |
| 1708 | |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1709 | |
| 1710 | static void |
| 1711 | wifi_ParseProfile(void) |
| 1712 | { |
| 1713 | int i; |
| 1714 | int max_radio_num = 0; |
| 1715 | int card_idx; |
| 1716 | int band_idx; |
| 1717 | int phy_idx = 0; |
developer | 745f0bd | 2023-03-06 14:32:53 +0800 | [diff] [blame] | 1718 | int wireless_mode = 0; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1719 | char buf[MAX_BUF_SIZE] = {0}; |
| 1720 | char chip_name[12]; |
| 1721 | char card_profile[MAX_BUF_SIZE] = {0}; |
| 1722 | char band_profile[MAX_BUF_SIZE] = {0}; |
| 1723 | FILE* fp; |
| 1724 | |
| 1725 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1726 | |
| 1727 | memset(main_prefix, 0, sizeof(main_prefix)); |
| 1728 | memset(ext_prefix, 0, sizeof(ext_prefix)); |
| 1729 | memset(default_ssid, 0, sizeof(default_ssid)); |
developer | 745f0bd | 2023-03-06 14:32:53 +0800 | [diff] [blame] | 1730 | for (i = 0; i < MAX_NUM_RADIOS; i++) |
| 1731 | radio_band[i] = band_invalid; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1732 | |
| 1733 | if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) { |
| 1734 | /* LOG */ |
| 1735 | return; |
| 1736 | } |
| 1737 | |
| 1738 | for (card_idx = 0; card_idx < 3; card_idx++) { |
| 1739 | snprintf(buf, sizeof(buf), "INDEX%d", card_idx); |
| 1740 | if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) { |
| 1741 | break; |
| 1742 | } |
| 1743 | snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx); |
| 1744 | if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) { |
| 1745 | break; |
| 1746 | } |
| 1747 | for (band_idx = 0; band_idx < 3; band_idx++) { |
| 1748 | snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx); |
| 1749 | if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) { |
| 1750 | /* LOG */ |
| 1751 | break; |
| 1752 | } |
| 1753 | |
| 1754 | snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx); |
| 1755 | if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) { |
| 1756 | /* LOG */ |
| 1757 | } |
| 1758 | |
| 1759 | snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx); |
| 1760 | if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) { |
| 1761 | /* LOG */ |
| 1762 | } |
| 1763 | |
| 1764 | if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) { |
| 1765 | /* LOG */ |
| 1766 | } |
developer | 745f0bd | 2023-03-06 14:32:53 +0800 | [diff] [blame] | 1767 | if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) { |
| 1768 | /* LOG */ |
| 1769 | } |
| 1770 | |
| 1771 | wireless_mode = atoi(buf); |
| 1772 | switch (wireless_mode) { |
| 1773 | case 22: |
| 1774 | case 16: |
| 1775 | case 6: |
| 1776 | case 4: |
| 1777 | case 1: |
| 1778 | radio_band[phy_idx] = band_2_4; |
| 1779 | break; |
| 1780 | case 23: |
| 1781 | case 17: |
| 1782 | case 14: |
| 1783 | case 11: |
| 1784 | case 2: |
| 1785 | radio_band[phy_idx] = band_5; |
| 1786 | break; |
| 1787 | case 24: |
| 1788 | case 18: |
| 1789 | radio_band[phy_idx] = band_6; |
| 1790 | break; |
| 1791 | } |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1792 | phy_idx++; |
| 1793 | } |
| 1794 | } |
| 1795 | |
| 1796 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1797 | } |
| 1798 | |
| 1799 | static void |
| 1800 | wifi_PrepareDefaultHostapdConfigs(void) |
| 1801 | { |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1802 | int radio_idx; |
| 1803 | int bss_idx; |
| 1804 | int ap_idx; |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1805 | char buf[MAX_BUF_SIZE] = {0}; |
| 1806 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1807 | char ssid[MAX_BUF_SIZE] = {0}; |
| 1808 | char interface[32] = {0}; |
| 1809 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 1810 | char psk_file[64] = {0}; |
| 1811 | struct params params[3]; |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1812 | char *band_str[3] = {"2G", "5G", "6G"}; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1813 | |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1814 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1815 | for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1816 | |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1817 | for (bss_idx = 0; bss_idx < 5; bss_idx++) { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1818 | ap_idx = array_index_to_vap_index(radio_idx, bss_idx); |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1819 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1820 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx); |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 1821 | snprintf(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1822 | _syscmd(buf, ret_buf, sizeof(ret_buf)); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1823 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1824 | if (radio_idx == band_2_4) { |
| 1825 | snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx); |
| 1826 | snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx); |
| 1827 | } else if (radio_idx == band_5) { |
| 1828 | snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx); |
| 1829 | snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx); |
| 1830 | } else if (radio_idx == band_6) { |
| 1831 | snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx); |
| 1832 | snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx); |
| 1833 | } |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1834 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1835 | /* fix wpa_psk_file path */ |
| 1836 | snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", ap_idx); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1837 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1838 | params[0].name = "ssid"; |
| 1839 | params[0].value = ssid; |
| 1840 | params[1].name = "interface"; |
| 1841 | params[1].value = interface; |
| 1842 | params[2].name = "wpa_psk_file"; |
| 1843 | params[2].value = psk_file; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1844 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1845 | wifi_hostapdWrite(config_file, params, 3); |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1846 | } |
| 1847 | } |
| 1848 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1849 | } |
| 1850 | |
| 1851 | static void |
| 1852 | wifiBringUpInterfacesForRadio(int radio_idx) |
| 1853 | { |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1854 | int bss_idx; |
| 1855 | int ap_idx; |
| 1856 | int band_idx; |
| 1857 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1858 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1859 | char ret_buf[MAX_BUF_SIZE] = {0}; |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 1860 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1861 | |
| 1862 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 1863 | |
developer | ed997d3 | 2023-04-18 22:45:39 +0800 | [diff] [blame] | 1864 | bss_idx = 0; |
| 1865 | /*TBD: we need refine setup flow and mbss flow*/ |
| 1866 | // for (bss_idx = 0; bss_idx < 5; bss_idx++) { |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1867 | ap_idx = array_index_to_vap_index(radio_idx, bss_idx); |
| 1868 | |
| 1869 | snprintf(cmd, sizeof(cmd), "touch %s%d.psk", PSK_FILE, ap_idx); |
| 1870 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 1871 | |
| 1872 | memset(cmd, 0, MAX_CMD_SIZE); |
| 1873 | memset(ret_buf, 0, MAX_BUF_SIZE); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1874 | |
developer | 0132ed9 | 2023-03-21 13:48:53 +0800 | [diff] [blame] | 1875 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx); |
| 1876 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radio_idx, config_file); |
| 1877 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 1878 | |
| 1879 | wifi_GetInterfaceName(ap_idx, inf_name); |
| 1880 | |
| 1881 | memset(cmd, 0, MAX_CMD_SIZE); |
| 1882 | memset(ret_buf, 0, MAX_BUF_SIZE); |
| 1883 | |
| 1884 | /* fix vap-status file */ |
| 1885 | snprintf(cmd, sizeof(cmd), "sed -i \"s/^%s=.*/%s=1/\" %s", inf_name, inf_name, VAP_STATUS_FILE); |
| 1886 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
developer | ed997d3 | 2023-04-18 22:45:39 +0800 | [diff] [blame] | 1887 | // } |
| 1888 | |
| 1889 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1890 | } |
| 1891 | |
| 1892 | static void |
| 1893 | wifi_BringUpInterfaces(void) |
| 1894 | { |
| 1895 | int radio_idx; |
| 1896 | int bss_idx; |
| 1897 | int ap_idx; |
| 1898 | int band_idx; |
| 1899 | char cmd[MAX_BUF_SIZE] = {0}; |
| 1900 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1901 | char ret_buf[MAX_BUF_SIZE]={'\0'}; |
| 1902 | |
| 1903 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1904 | for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) { |
| 1905 | band_idx = radio_index_to_band(radio_idx); |
| 1906 | if (band_idx < 0) { |
| 1907 | break; |
| 1908 | } |
| 1909 | wifiBringUpInterfacesForRadio(radio_idx); |
| 1910 | } |
| 1911 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1912 | } |
| 1913 | |
| 1914 | static void |
| 1915 | wifi_BringDownInterfacesForRadio(int radio_idx) |
| 1916 | { |
| 1917 | int bss_idx; |
| 1918 | int ap_idx; |
| 1919 | int band_idx; |
| 1920 | char cmd[MAX_BUF_SIZE] = {0}; |
| 1921 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1922 | char ret_buf[MAX_BUF_SIZE]={'\0'}; |
| 1923 | |
| 1924 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1925 | |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 1926 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]); |
| 1927 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 1928 | |
| 1929 | |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 1930 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1931 | } |
| 1932 | |
| 1933 | |
| 1934 | static void |
| 1935 | wifi_BringDownInterfaces(void) |
| 1936 | { |
| 1937 | int radio_idx; |
| 1938 | int bss_idx; |
| 1939 | int ap_idx; |
| 1940 | int band_idx; |
| 1941 | char cmd[MAX_BUF_SIZE] = {0}; |
| 1942 | char config_file[MAX_BUF_SIZE] = {0}; |
| 1943 | char ret_buf[MAX_BUF_SIZE]={'\0'}; |
| 1944 | |
| 1945 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 1946 | for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) { |
| 1947 | band_idx = radio_index_to_band(radio_idx); |
| 1948 | if (band_idx < 0) { |
| 1949 | break; |
| 1950 | } |
| 1951 | wifi_BringDownInterfacesForRadio(radio_idx); |
| 1952 | } |
| 1953 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 1954 | } |
| 1955 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 1956 | static void wifi_dat_file_reset() |
| 1957 | { |
| 1958 | char radio_idx = 0; |
| 1959 | |
| 1960 | for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) |
| 1961 | wifi_dat_file_reset_by_radio(radio_idx); |
| 1962 | } |
| 1963 | |
| 1964 | static void wifi_dat_file_reset_by_radio(char radio_idx) |
| 1965 | { |
| 1966 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1967 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 1968 | char rom_dat_file[MAX_CMD_SIZE]= {0}; |
| 1969 | char dat_file[MAX_CMD_SIZE]= {0}; |
| 1970 | |
| 1971 | snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx); |
| 1972 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx); |
| 1973 | snprintf(cmd, MAX_CMD_SIZE, "cp -rf %s %s", rom_dat_file, dat_file); |
| 1974 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 1975 | |
| 1976 | } |
| 1977 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 1978 | static void wifi_psk_file_reset() |
| 1979 | { |
| 1980 | char cmd[MAX_CMD_SIZE] = {0}; |
| 1981 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 1982 | char psk_file[MAX_CMD_SIZE]= {0}; |
| 1983 | char vap_idx = 0; |
| 1984 | |
| 1985 | for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) { |
| 1986 | snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx); |
| 1987 | |
| 1988 | if (access(psk_file, F_OK) != 0) { |
| 1989 | snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file); |
| 1990 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 1991 | } else { |
| 1992 | snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file); |
| 1993 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 1994 | } |
| 1995 | } |
| 1996 | } |
| 1997 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 1998 | static void wifi_psk_file_reset_by_radio(char radio_idx) |
| 1999 | { |
| 2000 | char cmd[MAX_CMD_SIZE] = {0}; |
| 2001 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 2002 | char psk_file[MAX_CMD_SIZE]= {0}; |
| 2003 | char vap_idx = 0; |
| 2004 | |
| 2005 | for (vap_idx = radio_idx; vap_idx < MAX_APS; vap_idx += MAX_NUM_RADIOS) { |
| 2006 | snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx); |
| 2007 | |
| 2008 | if (access(psk_file, F_OK) != 0) { |
| 2009 | snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file); |
| 2010 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2011 | } else { |
| 2012 | snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file); |
| 2013 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2014 | } |
| 2015 | } |
| 2016 | |
| 2017 | } |
| 2018 | |
| 2019 | |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2020 | static void wifi_vap_status_reset() |
| 2021 | { |
| 2022 | char cmd[MAX_CMD_SIZE] = {0}; |
| 2023 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 2024 | char radio_idx = 0; |
| 2025 | char bss_idx = 0; |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 2026 | |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2027 | if (access(VAP_STATUS_FILE, F_OK) != 0) { |
| 2028 | snprintf(cmd, MAX_CMD_SIZE, "touch %s", VAP_STATUS_FILE); |
| 2029 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2030 | } else { |
| 2031 | snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", VAP_STATUS_FILE); |
| 2032 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2033 | } |
| 2034 | |
| 2035 | memset(cmd, 0, MAX_CMD_SIZE); |
| 2036 | memset(ret_buf, 0, MAX_BUF_SIZE); |
| 2037 | |
| 2038 | for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) |
| 2039 | for (bss_idx = 0; bss_idx < 5; bss_idx++) { |
| 2040 | snprintf(cmd, MAX_CMD_SIZE, "echo %s%d=0 >> %s", ext_prefix[radio_idx], bss_idx, VAP_STATUS_FILE); |
| 2041 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2042 | } |
| 2043 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2044 | } |
| 2045 | |
| 2046 | static void wifi_radio_reset_count_reset() |
| 2047 | { |
| 2048 | char cmd[MAX_CMD_SIZE] = {0}; |
| 2049 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 2050 | |
| 2051 | if (access(VAP_STATUS_FILE, F_OK) != 0) { |
| 2052 | snprintf(cmd, MAX_CMD_SIZE, "touch %s", RADIO_RESET_FILE); |
| 2053 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2054 | } else { |
| 2055 | snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", RADIO_RESET_FILE); |
| 2056 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 2057 | } |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2058 | } |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2059 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2060 | // Initializes the wifi subsystem (all radios) |
| 2061 | INT wifi_init() //RDKB |
| 2062 | { |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 2063 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2064 | //Not intitializing macfilter for Turris-Omnia Platform for now |
| 2065 | //macfilter_init(); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2066 | wifi_ParseProfile(); |
| 2067 | wifi_PrepareDefaultHostapdConfigs(); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 2068 | wifi_psk_file_reset(); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2069 | //system("/usr/sbin/iw reg set US"); |
| 2070 | system("systemctl start hostapd.service"); |
| 2071 | sleep(2); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2072 | |
| 2073 | wifi_vap_status_reset(); |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2074 | wifi_radio_reset_count_reset(); |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 2075 | |
| 2076 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2077 | |
| 2078 | return RETURN_OK; |
| 2079 | } |
| 2080 | |
| 2081 | /* wifi_reset() function */ |
| 2082 | /** |
| 2083 | * Description: Resets the Wifi subsystem. This includes reset of all AP varibles. |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2084 | * Implementation specifics may dictate what is actualy reset since |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2085 | * different hardware implementations may have different requirements. |
| 2086 | * Parameters : None |
| 2087 | * |
| 2088 | * @return The status of the operation. |
| 2089 | * @retval RETURN_OK if successful. |
| 2090 | * @retval RETURN_ERR if any error is detected |
| 2091 | * |
| 2092 | * @execution Synchronous. |
| 2093 | * @sideeffect None. |
| 2094 | * |
| 2095 | * @note This function must not suspend and must not invoke any blocking system |
| 2096 | * calls. It should probably just send a message to a driver event handler task. |
| 2097 | * |
| 2098 | */ |
| 2099 | INT wifi_reset() |
| 2100 | { |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2101 | |
| 2102 | wifi_BringDownInterfaces(); |
| 2103 | sleep(2); |
| 2104 | |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 2105 | //TODO: resets the wifi subsystem, deletes all APs |
| 2106 | system("systemctl stop hostapd.service"); |
| 2107 | sleep(2); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2108 | |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 2109 | system("systemctl start hostapd.service"); |
| 2110 | sleep(5); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2111 | |
| 2112 | wifi_PrepareDefaultHostapdConfigs(); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 2113 | wifi_psk_file_reset(); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2114 | sleep(2); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2115 | |
| 2116 | wifi_vap_status_reset(); |
| 2117 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2118 | return RETURN_OK; |
| 2119 | } |
| 2120 | |
| 2121 | /* wifi_down() function */ |
| 2122 | /** |
| 2123 | * @description Turns off transmit power for the entire Wifi subsystem, for all radios. |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2124 | * Implementation specifics may dictate some functionality since |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2125 | * different hardware implementations may have different requirements. |
| 2126 | * |
| 2127 | * @param None |
| 2128 | * |
| 2129 | * @return The status of the operation |
| 2130 | * @retval RETURN_OK if successful |
| 2131 | * @retval RETURN_ERR if any error is detected |
| 2132 | * |
| 2133 | * @execution Synchronous |
| 2134 | * @sideeffect None |
| 2135 | * |
| 2136 | * @note This function must not suspend and must not invoke any blocking system |
| 2137 | * calls. It should probably just send a message to a driver event handler task. |
| 2138 | * |
| 2139 | */ |
| 2140 | INT wifi_down() |
| 2141 | { |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 2142 | //TODO: turns off transmit power for the entire Wifi subsystem, for all radios |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 2143 | int max_num_radios = 0; |
| 2144 | wifi_getMaxRadioNumber(&max_num_radios); |
developer | 17038e6 | 2023-03-02 14:43:43 +0800 | [diff] [blame] | 2145 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 2146 | for (int radioIndex = 0; radioIndex < max_num_radios; radioIndex++) |
| 2147 | wifi_setRadioEnable(radioIndex, FALSE); |
| 2148 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2149 | return RETURN_OK; |
| 2150 | } |
| 2151 | |
| 2152 | |
| 2153 | /* wifi_createInitialConfigFiles() function */ |
| 2154 | /** |
| 2155 | * @description This function creates wifi configuration files. The format |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2156 | * and content of these files are implementation dependent. This function call is |
| 2157 | * used to trigger this task if necessary. Some implementations may not need this |
| 2158 | * function. If an implementation does not need to create config files the function call can |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2159 | * do nothing and return RETURN_OK. |
| 2160 | * |
| 2161 | * @param None |
| 2162 | * |
| 2163 | * @return The status of the operation |
| 2164 | * @retval RETURN_OK if successful |
| 2165 | * @retval RETURN_ERR if any error is detected |
| 2166 | * |
| 2167 | * @execution Synchronous |
| 2168 | * @sideeffect None |
| 2169 | * |
| 2170 | * @note This function must not suspend and must not invoke any blocking system |
| 2171 | * calls. It should probably just send a message to a driver event handler task. |
| 2172 | * |
| 2173 | */ |
| 2174 | INT wifi_createInitialConfigFiles() |
| 2175 | { |
| 2176 | //TODO: creates initial implementation dependent configuration files that are later used for variable storage. Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0) |
| 2177 | return RETURN_OK; |
| 2178 | } |
| 2179 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2180 | /* outputs the country code to a max 64 character string */ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2181 | INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string) |
| 2182 | { |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 2183 | int ret; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2184 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 2185 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2186 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 2187 | ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL); |
| 2188 | if (ret != 0) { |
| 2189 | fprintf(stderr, "%s: wifi_BandProfileRead CountryCode failed\n", __func__); |
| 2190 | return RETURN_ERR; |
| 2191 | } |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2192 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 2193 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2194 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 2195 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2196 | } |
| 2197 | |
| 2198 | INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode) |
| 2199 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2200 | /*Set wifi config. Wait for wifi reset to apply*/ |
| 2201 | char str[MAX_BUF_SIZE] = {0}; |
| 2202 | char cmd[MAX_CMD_SIZE] = {0}; |
| 2203 | struct params params; |
| 2204 | char config_file[MAX_BUF_SIZE] = {0}; |
| 2205 | int ret = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2206 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2207 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2208 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2209 | if(NULL == CountryCode || strlen(CountryCode) >= 32 ) { |
| 2210 | printf("%s: input para error!!!\n", __func__); |
| 2211 | return RETURN_ERR; |
| 2212 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2213 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2214 | if (!strlen(CountryCode)) |
| 2215 | strncpy(CountryCode, "US", sizeof("US")); /*default set the code to US*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2216 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2217 | params.name = "country_code"; |
| 2218 | params.value = CountryCode; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2219 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 2220 | snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2221 | ret = wifi_hostapdWrite(config_file, ¶ms, 1); |
| 2222 | |
| 2223 | if (ret) { |
| 2224 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n", |
| 2225 | __func__, ret); |
| 2226 | } |
| 2227 | |
| 2228 | ret = wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 2229 | |
| 2230 | if (ret) { |
| 2231 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n", |
| 2232 | __func__, ret); |
| 2233 | } |
| 2234 | |
| 2235 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 2236 | |
| 2237 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2238 | } |
| 2239 | |
| 2240 | INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2) |
| 2241 | { |
| 2242 | char interface_name[16] = {0}; |
| 2243 | char channel_util_file[64] = {0}; |
| 2244 | char cmd[128] = {0}; |
| 2245 | char buf[128] = {0}; |
| 2246 | char line[128] = {0}; |
| 2247 | char *param = NULL, *value = NULL; |
| 2248 | int read = 0; |
| 2249 | unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0; |
| 2250 | unsigned int preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0; |
| 2251 | size_t len = 0; |
| 2252 | FILE *f = NULL; |
| 2253 | |
| 2254 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2255 | |
| 2256 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 2257 | return RETURN_ERR; |
| 2258 | snprintf(cmd, sizeof(cmd), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name); |
| 2259 | _syscmd(cmd, buf, sizeof(buf)); |
| 2260 | outputChannelStats2->ch_Max80211Rssi = strtol(buf, NULL, 10); |
| 2261 | |
| 2262 | memset(cmd, 0, sizeof(cmd)); |
| 2263 | memset(buf, 0, sizeof(buf)); |
| 2264 | snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name); |
| 2265 | if ((f = popen(cmd, "r")) == NULL) { |
| 2266 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 2267 | return RETURN_ERR; |
| 2268 | } |
| 2269 | |
| 2270 | read = getline(&line, &len, f); |
| 2271 | while (read != -1) { |
| 2272 | param = strtok(line, ":\t"); |
| 2273 | value = strtok(NULL, " "); |
| 2274 | if(strstr(param, "frequency") != NULL) { |
| 2275 | outputChannelStats2->ch_Frequency = strtol(value, NULL, 10); |
| 2276 | } |
| 2277 | if(strstr(param, "noise") != NULL) { |
| 2278 | outputChannelStats2->ch_NoiseFloor = strtol(value, NULL, 10); |
| 2279 | outputChannelStats2->ch_Non80211Noise = strtol(value, NULL, 10); |
| 2280 | } |
| 2281 | if(strstr(param, "channel active time") != NULL) { |
| 2282 | ActiveTime = strtol(value, NULL, 10); |
| 2283 | } |
| 2284 | if(strstr(param, "channel busy time") != NULL) { |
| 2285 | BusyTime = strtol(value, NULL, 10); |
| 2286 | } |
| 2287 | if(strstr(param, "channel transmit time") != NULL) { |
| 2288 | TransmitTime = strtol(value, NULL, 10); |
| 2289 | } |
| 2290 | read = getline(&line, &len, f); |
| 2291 | } |
| 2292 | pclose(f); |
| 2293 | |
| 2294 | // The file should store the last active, busy and transmit time |
| 2295 | snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex); |
| 2296 | f = fopen(channel_util_file, "r"); |
| 2297 | if (f != NULL) { |
| 2298 | read = getline(&line, &len, f); |
| 2299 | preActiveTime = strtol(line, NULL, 10); |
| 2300 | read = getline(&line, &len, f); |
| 2301 | preBusyTime = strtol(line, NULL, 10); |
| 2302 | read = getline(&line, &len, f); |
| 2303 | preTransmitTime = strtol(line, NULL, 10); |
| 2304 | fclose(f); |
| 2305 | } |
| 2306 | |
| 2307 | outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime); |
| 2308 | outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime); |
| 2309 | |
| 2310 | f = fopen(channel_util_file, "w"); |
| 2311 | if (f != NULL) { |
| 2312 | fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime); |
| 2313 | fclose(f); |
| 2314 | } |
| 2315 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2316 | return RETURN_OK; |
| 2317 | } |
| 2318 | |
| 2319 | /********************************************************************************** |
| 2320 | * |
| 2321 | * Wifi radio level function prototypes |
| 2322 | * |
| 2323 | **********************************************************************************/ |
| 2324 | |
| 2325 | //Get the total number of radios in this wifi subsystem |
| 2326 | INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181 |
| 2327 | { |
| 2328 | if (NULL == output) |
| 2329 | return RETURN_ERR; |
| 2330 | *output = MAX_NUM_RADIOS; |
| 2331 | |
| 2332 | return RETURN_OK; |
| 2333 | } |
| 2334 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2335 | //Get the total number of SSID entries in this wifi subsystem |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2336 | INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181 |
| 2337 | { |
| 2338 | if (NULL == output) |
| 2339 | return RETURN_ERR; |
| 2340 | *output = MAX_APS; |
| 2341 | |
| 2342 | return RETURN_OK; |
| 2343 | } |
| 2344 | |
| 2345 | //Get the Radio enable config parameter |
| 2346 | INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB |
| 2347 | { |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 2348 | char option[64] = {}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2349 | char buf[128] = {0}, cmd[128] = {0}; |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 2350 | int ret; |
| 2351 | |
| 2352 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2353 | |
| 2354 | if (NULL == output_bool) |
| 2355 | return RETURN_ERR; |
| 2356 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 2357 | snprintf(option, sizeof(option), "INDEX%d_main_ifname", 0); |
| 2358 | ret = wifi_l1ProfileRead2(option, radioIndex, buf, sizeof(buf)); |
| 2359 | if ((ret != 0) || (strlen(buf) <= 0)) { |
| 2360 | *output_bool = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2361 | return RETURN_ERR; |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 2362 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2363 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 2364 | snprintf(cmd, sizeof(cmd), "iw %s info | grep channel", buf); |
| 2365 | _syscmd(cmd, buf, sizeof(buf)); |
| 2366 | if (strlen(buf) == 0) { |
| 2367 | *output_bool = 0; |
| 2368 | } else { |
| 2369 | *output_bool = 1; |
| 2370 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2371 | |
developer | 3a85ab8 | 2023-05-25 11:59:38 +0800 | [diff] [blame] | 2372 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2373 | return RETURN_OK; |
| 2374 | } |
| 2375 | |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 2376 | typedef long time_t; |
| 2377 | static time_t radio_up_time[MAX_NUM_RADIOS]; |
| 2378 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2379 | INT wifi_setRadioEnable(INT radioIndex, BOOL enable) |
| 2380 | { |
| 2381 | char interface_name[16] = {0}; |
| 2382 | char cmd[MAX_CMD_SIZE] = {0}; |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2383 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2384 | int apIndex, ret; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2385 | int max_radio_num = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2386 | int phyId = 0; |
| 2387 | |
| 2388 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2389 | |
| 2390 | phyId = radio_index_to_phy(radioIndex); |
| 2391 | |
| 2392 | wifi_getMaxRadioNumber(&max_radio_num); |
| 2393 | |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2394 | if(enable == FALSE) { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 2395 | |
| 2396 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 2397 | return RETURN_ERR; |
| 2398 | |
| 2399 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw REMOVE %s", interface_name); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2400 | _syscmd(cmd, buf, sizeof(buf)); |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 2401 | if(strncmp(buf, "OK", 2)) |
| 2402 | fprintf(stderr, "Could not detach %s from hostapd daemon", interface_name); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2403 | } else { |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 2404 | for (apIndex = radioIndex; apIndex < MAX_APS; apIndex += max_radio_num) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2405 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 2406 | return RETURN_ERR; |
| 2407 | |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2408 | memset(cmd, 0, MAX_CMD_SIZE); |
| 2409 | memset(buf, 0, MAX_BUF_SIZE); |
| 2410 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2411 | snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name); |
| 2412 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2413 | |
| 2414 | if(*buf == '1') { |
| 2415 | |
| 2416 | memset(cmd, 0, MAX_CMD_SIZE); |
| 2417 | memset(buf, 0, MAX_BUF_SIZE); |
| 2418 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2419 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf", |
| 2420 | phyId, apIndex); |
| 2421 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 2422 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2423 | } |
| 2424 | } |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 2425 | time(&radio_up_time[radioIndex]); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2426 | } |
| 2427 | |
| 2428 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2429 | return RETURN_OK; |
| 2430 | } |
| 2431 | |
| 2432 | //Get the Radio enable status |
| 2433 | INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool) //RDKB |
| 2434 | { |
| 2435 | if (NULL == output_bool) |
| 2436 | return RETURN_ERR; |
| 2437 | |
| 2438 | return wifi_getRadioEnable(radioIndex, output_bool); |
| 2439 | } |
| 2440 | |
| 2441 | //Get the Radio Interface name from platform, eg "wlan0" |
| 2442 | INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181 |
| 2443 | { |
| 2444 | if (NULL == output_string || radioIndex>=MAX_NUM_RADIOS || radioIndex<0) |
| 2445 | return RETURN_ERR; |
| 2446 | return wifi_GetInterfaceName(radioIndex, output_string); |
| 2447 | } |
| 2448 | |
| 2449 | //Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s" |
| 2450 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 2451 | INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB |
| 2452 | { |
| 2453 | // The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)" |
| 2454 | // For max bit rate, we should always choose the best MCS |
| 2455 | char mode[64] = {0}; |
| 2456 | char channel_bandwidth_str[64] = {0}; |
| 2457 | char *tmp = NULL; |
| 2458 | UINT mode_map = 0; |
| 2459 | UINT num_subcarrier = 0; |
| 2460 | UINT code_bits = 0; |
| 2461 | float code_rate = 0; // use max code rate |
| 2462 | int NSS = 0; |
| 2463 | UINT Symbol_duration = 0; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2464 | UINT GI_duration = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2465 | wifi_band band = band_invalid; |
| 2466 | wifi_guard_interval_t gi = wifi_guard_interval_auto; |
| 2467 | BOOL enable = FALSE; |
| 2468 | float bit_rate = 0; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 2469 | int ant_bitmap = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2470 | |
| 2471 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2472 | if (NULL == output_string) |
| 2473 | return RETURN_ERR; |
| 2474 | |
| 2475 | wifi_getRadioEnable(radioIndex, &enable); |
| 2476 | if (enable == FALSE) { |
| 2477 | snprintf(output_string, 64, "0 Mb/s"); |
| 2478 | return RETURN_OK; |
| 2479 | } |
| 2480 | |
| 2481 | if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) { |
| 2482 | fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__); |
| 2483 | return RETURN_ERR; |
| 2484 | } |
| 2485 | |
| 2486 | if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) { |
| 2487 | fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__); |
| 2488 | return RETURN_ERR; |
| 2489 | } |
| 2490 | |
| 2491 | if (gi == wifi_guard_interval_3200) |
| 2492 | GI_duration = 32; |
| 2493 | else if (gi == wifi_guard_interval_1600) |
| 2494 | GI_duration = 16; |
| 2495 | else if (gi == wifi_guard_interval_800) |
| 2496 | GI_duration = 8; |
| 2497 | else // auto, 400 |
| 2498 | GI_duration = 4; |
| 2499 | |
| 2500 | if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) { |
| 2501 | fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error\n", __func__); |
| 2502 | return RETURN_ERR; |
| 2503 | } |
| 2504 | |
| 2505 | if (strstr(channel_bandwidth_str, "80+80") != NULL) |
| 2506 | strcpy(channel_bandwidth_str, "160"); |
| 2507 | |
| 2508 | if (mode_map & WIFI_MODE_AX) { |
| 2509 | if (strstr(channel_bandwidth_str, "160") != NULL) |
| 2510 | num_subcarrier = 1960; |
| 2511 | else if (strstr(channel_bandwidth_str, "80") != NULL) |
| 2512 | num_subcarrier = 980; |
| 2513 | else if (strstr(channel_bandwidth_str, "40") != NULL) |
| 2514 | num_subcarrier = 468; |
| 2515 | else if (strstr(channel_bandwidth_str, "20") != NULL) |
| 2516 | num_subcarrier = 234; |
| 2517 | code_bits = 10; |
| 2518 | code_rate = (float)5/6; |
| 2519 | Symbol_duration = 128; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 2520 | GI_duration = 8;/*HE no GI 400ns*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2521 | } else if (mode_map & WIFI_MODE_AC) { |
| 2522 | if (strstr(channel_bandwidth_str, "160") != NULL) |
| 2523 | num_subcarrier = 468; |
| 2524 | else if (strstr(channel_bandwidth_str, "80") != NULL) |
| 2525 | num_subcarrier = 234; |
| 2526 | else if (strstr(channel_bandwidth_str, "40") != NULL) |
| 2527 | num_subcarrier = 108; |
| 2528 | else if (strstr(channel_bandwidth_str, "20") != NULL) |
| 2529 | num_subcarrier = 52; |
| 2530 | code_bits = 8; |
| 2531 | code_rate = (float)5/6; |
| 2532 | Symbol_duration = 32; |
| 2533 | } else if (mode_map & WIFI_MODE_N) { |
| 2534 | if (strstr(channel_bandwidth_str, "160") != NULL) |
| 2535 | num_subcarrier = 468; |
| 2536 | else if (strstr(channel_bandwidth_str, "80") != NULL) |
| 2537 | num_subcarrier = 234; |
| 2538 | else if (strstr(channel_bandwidth_str, "40") != NULL) |
| 2539 | num_subcarrier = 108; |
| 2540 | else if (strstr(channel_bandwidth_str, "20") != NULL) |
| 2541 | num_subcarrier = 52; |
| 2542 | code_bits = 6; |
| 2543 | code_rate = (float)3/4; |
| 2544 | Symbol_duration = 32; |
| 2545 | } else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) { |
| 2546 | // mode b must run with mode g, so we output mode g bitrate in 2.4 G. |
| 2547 | snprintf(output_string, 64, "65 Mb/s"); |
| 2548 | return RETURN_OK; |
| 2549 | } else { |
| 2550 | snprintf(output_string, 64, "0 Mb/s"); |
| 2551 | return RETURN_OK; |
| 2552 | } |
| 2553 | |
| 2554 | // Spatial streams |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 2555 | if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2556 | fprintf(stderr, "%s: wifi_getRadioTxChainMask return error\n", __func__); |
| 2557 | return RETURN_ERR; |
| 2558 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 2559 | for (; ant_bitmap > 0; ant_bitmap >>= 1) |
| 2560 | NSS += ant_bitmap & 1; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2561 | |
| 2562 | // multiple 10 is to align duration unit (0.1 us) |
| 2563 | bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10; |
| 2564 | snprintf(output_string, 64, "%.1f Mb/s", bit_rate); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 2565 | WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n", |
| 2566 | __func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2567 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2568 | |
| 2569 | return RETURN_OK; |
| 2570 | } |
| 2571 | #if 0 |
| 2572 | INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB |
| 2573 | { |
| 2574 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2575 | char cmd[64]; |
| 2576 | char buf[1024]; |
| 2577 | int apIndex; |
| 2578 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2579 | if (NULL == output_string) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2580 | return RETURN_ERR; |
| 2581 | |
| 2582 | apIndex=(radioIndex==0)?0:1; |
| 2583 | |
| 2584 | snprintf(cmd, sizeof(cmd), "iwconfig %s | grep \"Bit Rate\" | cut -d':' -f2 | cut -d' ' -f1,2", interface_name); |
| 2585 | _syscmd(cmd,buf, sizeof(buf)); |
| 2586 | |
| 2587 | snprintf(output_string, 64, "%s", buf); |
| 2588 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2589 | return RETURN_OK; |
| 2590 | } |
| 2591 | #endif |
| 2592 | |
| 2593 | |
| 2594 | //Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz" |
| 2595 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 2596 | INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string) //RDKB |
| 2597 | { |
| 2598 | wifi_band band = band_invalid; |
| 2599 | |
| 2600 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2601 | if (NULL == output_string) |
| 2602 | return RETURN_ERR; |
| 2603 | |
| 2604 | band = wifi_index_to_band(radioIndex); |
| 2605 | |
| 2606 | memset(output_string, 0, 10); |
| 2607 | if (band == band_2_4) |
| 2608 | strcpy(output_string, "2.4GHz"); |
| 2609 | else if (band == band_5) |
| 2610 | strcpy(output_string, "5GHz"); |
| 2611 | else if (band == band_6) |
| 2612 | strcpy(output_string, "6GHz"); |
| 2613 | else |
| 2614 | return RETURN_ERR; |
| 2615 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2616 | |
| 2617 | return RETURN_OK; |
| 2618 | #if 0 |
| 2619 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 2620 | char str[MAX_BUF_SIZE]={'\0'}; |
| 2621 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 2622 | char *ch=NULL; |
| 2623 | char *ch2=NULL; |
| 2624 | |
| 2625 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2626 | if (NULL == output_string) |
| 2627 | return RETURN_ERR; |
| 2628 | |
| 2629 | |
| 2630 | sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 2631 | |
| 2632 | if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR) |
| 2633 | { |
| 2634 | printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2635 | return RETURN_ERR; |
| 2636 | } |
| 2637 | ch=strchr(buf,'\n'); |
| 2638 | *ch='\0'; |
| 2639 | ch=strchr(buf,'='); |
| 2640 | if(ch==NULL) |
| 2641 | return RETURN_ERR; |
| 2642 | |
| 2643 | |
| 2644 | ch++; |
| 2645 | |
| 2646 | /* prepend 0 for channel with single digit. for ex, 6 would be 06 */ |
| 2647 | strcpy(buf,"0"); |
| 2648 | if(strlen(ch) == 1) |
| 2649 | ch=strcat(buf,ch); |
| 2650 | |
| 2651 | |
| 2652 | sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 2653 | |
| 2654 | if(_syscmd(cmd,str,64) == RETURN_ERR) |
| 2655 | { |
| 2656 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2657 | return RETURN_ERR; |
| 2658 | } |
| 2659 | |
| 2660 | |
| 2661 | ch2=strchr(str,'\n'); |
| 2662 | //replace \n with \0 |
| 2663 | *ch2='\0'; |
| 2664 | ch2=strchr(str,'='); |
| 2665 | if(ch2==NULL) |
| 2666 | { |
| 2667 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2668 | return RETURN_ERR; |
| 2669 | } |
| 2670 | else |
| 2671 | wifi_dbg_printf("%s",ch2+1); |
| 2672 | |
| 2673 | |
| 2674 | ch2++; |
| 2675 | |
| 2676 | |
| 2677 | sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch); |
| 2678 | |
| 2679 | memset(buf,'\0',sizeof(buf)); |
| 2680 | if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR) |
| 2681 | { |
| 2682 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2683 | return RETURN_ERR; |
| 2684 | } |
| 2685 | if (strstr(buf,"2.4") != NULL ) |
| 2686 | strcpy(output_string,"2.4GHz"); |
| 2687 | else if(strstr(buf,"5.") != NULL ) |
| 2688 | strcpy(output_string,"5GHz"); |
| 2689 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2690 | |
| 2691 | return RETURN_OK; |
| 2692 | #endif |
| 2693 | } |
| 2694 | |
| 2695 | //Get the frequency band at which the radio is operating, eg: "2.4GHz" |
| 2696 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 2697 | INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181 |
| 2698 | { |
| 2699 | wifi_band band = band_invalid; |
| 2700 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2701 | if (NULL == output_string) |
| 2702 | return RETURN_ERR; |
| 2703 | band = wifi_index_to_band(radioIndex); |
| 2704 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2705 | if (band == band_2_4) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2706 | snprintf(output_string, 64, "2.4GHz"); |
| 2707 | else if (band == band_5) |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2708 | snprintf(output_string, 64, "5GHz"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2709 | else if (band == band_6) |
| 2710 | snprintf(output_string, 64, "6GHz"); |
| 2711 | |
| 2712 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2713 | |
| 2714 | return RETURN_OK; |
| 2715 | #if 0 |
| 2716 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2717 | char buf[MAX_BUF_SIZE]={'\0'}; |
| 2718 | char str[MAX_BUF_SIZE]={'\0'}; |
| 2719 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 2720 | char *ch=NULL; |
| 2721 | char *ch2=NULL; |
| 2722 | char ch1[5]="0"; |
| 2723 | |
| 2724 | sprintf(cmd,"grep 'channel=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 2725 | |
| 2726 | if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR) |
| 2727 | { |
| 2728 | printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2729 | return RETURN_ERR; |
| 2730 | } |
| 2731 | |
| 2732 | ch=strchr(buf,'\n'); |
| 2733 | *ch='\0'; |
| 2734 | ch=strchr(buf,'='); |
| 2735 | if(ch==NULL) |
| 2736 | return RETURN_ERR; |
| 2737 | ch++; |
| 2738 | |
| 2739 | if(strlen(ch)==1) |
| 2740 | { |
| 2741 | strcat(ch1,ch); |
| 2742 | |
| 2743 | } |
| 2744 | else |
| 2745 | { |
| 2746 | strcpy(ch1,ch); |
| 2747 | } |
| 2748 | |
| 2749 | |
| 2750 | |
| 2751 | sprintf(cmd,"grep 'interface=' %s%d.conf",CONFIG_PREFIX,radioIndex); |
| 2752 | if(_syscmd(cmd,str,64) == RETURN_ERR) |
| 2753 | { |
| 2754 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2755 | return RETURN_ERR; |
| 2756 | } |
| 2757 | |
| 2758 | |
| 2759 | ch2=strchr(str,'\n'); |
| 2760 | //replace \n with \0 |
| 2761 | *ch2='\0'; |
| 2762 | ch2=strchr(str,'='); |
| 2763 | if(ch2==NULL) |
| 2764 | { |
| 2765 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2766 | return RETURN_ERR; |
| 2767 | } |
| 2768 | else |
| 2769 | wifi_dbg_printf("%s",ch2+1); |
| 2770 | ch2++; |
| 2771 | |
| 2772 | |
| 2773 | sprintf(cmd,"iwlist %s frequency|grep 'Channel %s'",ch2,ch1); |
| 2774 | memset(buf,'\0',sizeof(buf)); |
| 2775 | if(_syscmd(cmd,buf,sizeof(buf))==RETURN_ERR) |
| 2776 | { |
| 2777 | wifi_dbg_printf("\nError %d:%s:%s\n",__LINE__,__func__,__FILE__); |
| 2778 | return RETURN_ERR; |
| 2779 | } |
| 2780 | |
| 2781 | |
| 2782 | if(strstr(buf,"2.4")!=NULL) |
| 2783 | { |
| 2784 | strcpy(output_string,"2.4GHz"); |
| 2785 | } |
| 2786 | if(strstr(buf,"5.")!=NULL) |
| 2787 | { |
| 2788 | strcpy(output_string,"5GHz"); |
| 2789 | } |
| 2790 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2791 | return RETURN_OK; |
| 2792 | #endif |
| 2793 | } |
| 2794 | |
| 2795 | //Get the Supported Radio Mode. eg: "b,g,n"; "n,ac" |
| 2796 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 2797 | INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181 |
| 2798 | { |
| 2799 | char cmd[128]={0}; |
| 2800 | char buf[128]={0}; |
| 2801 | char temp_output[128] = {0}; |
| 2802 | wifi_band band; |
| 2803 | int phyId = 0; |
| 2804 | |
| 2805 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2806 | if (NULL == output_string) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2807 | return RETURN_ERR; |
| 2808 | |
| 2809 | band = wifi_index_to_band(radioIndex); |
| 2810 | if (band == band_2_4) { |
| 2811 | strcat(temp_output, "b,g,"); |
| 2812 | } else if (band == band_5) { |
| 2813 | strcat(temp_output, "a,"); |
| 2814 | } |
| 2815 | phyId = radio_index_to_phy(radioIndex); |
| 2816 | // ht capabilities |
| 2817 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep '[^PHY|MAC|VHT].Capabilities' | head -n 1 | cut -d ':' -f2 | sed 's/^.//' | tr -d '\\n'", phyId); |
| 2818 | _syscmd(cmd, buf, sizeof(buf)); |
| 2819 | if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) { |
| 2820 | strcat(temp_output, "n,"); |
| 2821 | } |
| 2822 | |
| 2823 | // vht capabilities |
| 2824 | if (band == band_5) { |
| 2825 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId); |
| 2826 | _syscmd(cmd, buf, sizeof(buf)); |
| 2827 | if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) { |
| 2828 | strcat(temp_output, "ac,"); |
| 2829 | } |
| 2830 | } |
| 2831 | |
| 2832 | // he capabilities |
| 2833 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'HE MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId); |
| 2834 | _syscmd(cmd, buf, sizeof(buf)); |
| 2835 | if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) { |
| 2836 | strcat(temp_output, "ax,"); |
| 2837 | } |
| 2838 | |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 2839 | // eht capabilities |
| 2840 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'EHT MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId); |
| 2841 | _syscmd(cmd, buf, sizeof(buf)); |
| 2842 | if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) { |
| 2843 | strcat(temp_output, "be,"); |
| 2844 | } |
| 2845 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2846 | // Remove the last comma |
| 2847 | if (strlen(temp_output) != 0) |
| 2848 | temp_output[strlen(temp_output)-1] = '\0'; |
| 2849 | strncpy(output_string, temp_output, strlen(temp_output)); |
| 2850 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2851 | return RETURN_OK; |
| 2852 | } |
| 2853 | |
| 2854 | //Get the radio operating mode, and pure mode flag. eg: "ac" |
| 2855 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 2856 | INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly) //RDKB |
| 2857 | { |
| 2858 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2859 | if (NULL == output_string) |
| 2860 | return RETURN_ERR; |
| 2861 | |
| 2862 | if (radioIndex == 0) { |
| 2863 | snprintf(output_string, 64, "n"); //"ht" needs to be translated to "n" or others |
| 2864 | *gOnly = FALSE; |
| 2865 | *nOnly = TRUE; |
| 2866 | *acOnly = FALSE; |
| 2867 | } else { |
| 2868 | snprintf(output_string, 64, "ac"); //"vht" needs to be translated to "ac" |
| 2869 | *gOnly = FALSE; |
| 2870 | *nOnly = FALSE; |
| 2871 | *acOnly = FALSE; |
| 2872 | } |
| 2873 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2874 | |
| 2875 | return RETURN_OK; |
| 2876 | #if 0 |
| 2877 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 2878 | char buf[64] = {0}; |
| 2879 | char config_file[MAX_BUF_SIZE] = {0}; |
| 2880 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2881 | if ((NULL == output_string) || (NULL == gOnly) || (NULL == nOnly) || (NULL == acOnly)) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2882 | return RETURN_ERR; |
| 2883 | |
| 2884 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 2885 | wifi_hostapdRead(config_file, "hw_mode", buf, sizeof(buf)); |
| 2886 | |
| 2887 | wifi_dbg_printf("\nhw_mode=%s\n",buf); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 2888 | if (strlen(buf) == 0) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2889 | { |
| 2890 | wifi_dbg_printf("\nwifi_hostapdRead returned none\n"); |
| 2891 | return RETURN_ERR; |
| 2892 | } |
| 2893 | if(strcmp(buf,"g")==0) |
| 2894 | { |
| 2895 | wifi_dbg_printf("\nG\n"); |
| 2896 | *gOnly=TRUE; |
| 2897 | *nOnly=FALSE; |
| 2898 | *acOnly=FALSE; |
| 2899 | } |
| 2900 | else if(strcmp(buf,"n")==0) |
| 2901 | { |
| 2902 | wifi_dbg_printf("\nN\n"); |
| 2903 | *gOnly=FALSE; |
| 2904 | *nOnly=TRUE; |
| 2905 | *acOnly=FALSE; |
| 2906 | } |
| 2907 | else if(strcmp(buf,"ac")==0) |
| 2908 | { |
| 2909 | wifi_dbg_printf("\nac\n"); |
| 2910 | *gOnly=FALSE; |
| 2911 | *nOnly=FALSE; |
| 2912 | *acOnly=TRUE; |
| 2913 | } |
| 2914 | /* hostapd-5G.conf has "a" as hw_mode */ |
| 2915 | else if(strcmp(buf,"a")==0) |
| 2916 | { |
| 2917 | wifi_dbg_printf("\na\n"); |
| 2918 | *gOnly=FALSE; |
| 2919 | *nOnly=FALSE; |
| 2920 | *acOnly=FALSE; |
| 2921 | } |
| 2922 | else |
| 2923 | wifi_dbg_printf("\nInvalid Mode %s\n", buf); |
| 2924 | |
| 2925 | //for a,n mode |
| 2926 | if(radioIndex == 1) |
| 2927 | { |
| 2928 | wifi_hostapdRead(config_file, "ieee80211n", buf, sizeof(buf)); |
| 2929 | if(strcmp(buf,"1")==0) |
| 2930 | { |
| 2931 | strncpy(output_string, "n", 1); |
| 2932 | *nOnly=FALSE; |
| 2933 | } |
| 2934 | } |
| 2935 | |
| 2936 | wifi_dbg_printf("\nReturning from getRadioStandard\n"); |
| 2937 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 2938 | return RETURN_OK; |
| 2939 | #endif |
| 2940 | } |
| 2941 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 2942 | enum WIFI_MODE { |
| 2943 | WMODE_INVALID = 0, |
| 2944 | WMODE_A = 1 << 0, |
| 2945 | WMODE_B = 1 << 1, |
| 2946 | WMODE_G = 1 << 2, |
| 2947 | WMODE_GN = 1 << 3, |
| 2948 | WMODE_AN = 1 << 4, |
| 2949 | WMODE_AC = 1 << 5, |
| 2950 | WMODE_AX_24G = 1 << 6, |
| 2951 | WMODE_AX_5G = 1 << 7, |
| 2952 | WMODE_AX_6G = 1 << 8, |
| 2953 | WMODE_BE_24G = 1 << 9, |
| 2954 | WMODE_BE_5G = 1 << 10, |
| 2955 | WMODE_BE_6G = 1 << 11, |
| 2956 | /* |
| 2957 | * total types of supported wireless mode, |
| 2958 | * add this value once yow add new type |
| 2959 | */ |
| 2960 | WMODE_COMP = 12, |
| 2961 | }; |
| 2962 | |
| 2963 | #define RADIO_MODE_LEN 32 |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2964 | |
| 2965 | int get_radio_mode_handler(struct nl_msg *msg, void *cb) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2966 | { |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2967 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 2968 | struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1]; |
| 2969 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 2970 | unsigned int *phymode; |
| 2971 | int err = 0; |
| 2972 | struct mtk_nl80211_cb_data *cb_data = cb; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2973 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2974 | if (!msg || !cb_data) { |
| 2975 | wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data); |
| 2976 | return NL_SKIP; |
| 2977 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2978 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2979 | err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 2980 | genlmsg_attrlen(gnlh, 0), NULL); |
| 2981 | if (err < 0) { |
| 2982 | wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n"); |
| 2983 | return NL_SKIP; |
| 2984 | } |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 2985 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2986 | if (tb[NL80211_ATTR_VENDOR_DATA]) { |
| 2987 | err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX, |
| 2988 | tb[NL80211_ATTR_VENDOR_DATA], NULL); |
| 2989 | if (err < 0) |
| 2990 | return NL_SKIP; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 2991 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 2992 | if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) { |
| 2993 | phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]); |
| 2994 | |
| 2995 | memset(cb_data->out_buf, 0, cb_data->out_len); |
| 2996 | memmove(cb_data->out_buf, phymode, sizeof(unsigned int)); |
| 2997 | } |
| 2998 | } else |
| 2999 | wifi_debug(DEBUG_ERROR, "No Stats from driver.\n"); |
| 3000 | |
| 3001 | return NL_OK; |
| 3002 | } |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3003 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3004 | void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode) |
| 3005 | { |
| 3006 | wifi_band band; |
| 3007 | unsigned char radio_mode_tem_len; |
| 3008 | |
| 3009 | band = wifi_index_to_band(radioIndex); |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3010 | // puremode is a bit map |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3011 | *pureMode = 0; |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3012 | memset(output_string, 0, RADIO_MODE_LEN); |
| 3013 | |
| 3014 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3015 | |
| 3016 | switch (band) { |
| 3017 | case band_2_4: |
| 3018 | if (phymode & WMODE_B) { |
| 3019 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,"); |
| 3020 | *pureMode |= WIFI_MODE_B; |
| 3021 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3022 | } |
| 3023 | if (phymode & WMODE_G) { |
| 3024 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,"); |
| 3025 | *pureMode |= WIFI_MODE_G; |
| 3026 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3027 | } |
| 3028 | if (phymode & WMODE_GN) { |
| 3029 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,"); |
| 3030 | *pureMode |= WIFI_MODE_N; |
| 3031 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3032 | } |
| 3033 | if (phymode & WMODE_AX_24G) { |
| 3034 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,"); |
| 3035 | *pureMode |= WIFI_MODE_AX; |
| 3036 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3037 | } |
| 3038 | if (phymode & WMODE_BE_24G) { |
| 3039 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,"); |
| 3040 | *pureMode |= WIFI_MODE_BE; |
| 3041 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3042 | } |
| 3043 | break; |
| 3044 | case band_5: |
| 3045 | if (phymode & WMODE_A) { |
| 3046 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,"); |
| 3047 | *pureMode |= WIFI_MODE_A; |
| 3048 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3049 | } |
| 3050 | if (phymode & WMODE_AN) { |
| 3051 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,"); |
| 3052 | *pureMode |= WIFI_MODE_N; |
| 3053 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3054 | } |
| 3055 | if (phymode & WMODE_AC) { |
| 3056 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,"); |
| 3057 | *pureMode |= WIFI_MODE_AC; |
| 3058 | } |
| 3059 | if (phymode & WMODE_AX_5G) { |
| 3060 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,"); |
| 3061 | *pureMode |= WIFI_MODE_AX; |
| 3062 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3063 | } |
| 3064 | if (phymode & WMODE_BE_5G) { |
| 3065 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,"); |
| 3066 | *pureMode |= WIFI_MODE_BE; |
| 3067 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3068 | } |
| 3069 | break; |
| 3070 | case band_6: |
| 3071 | if (phymode & WMODE_AX_6G) { |
| 3072 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,"); |
| 3073 | *pureMode |= WIFI_MODE_AX; |
| 3074 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3075 | } |
| 3076 | if (phymode & WMODE_BE_6G) { |
| 3077 | snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,"); |
| 3078 | *pureMode |= WIFI_MODE_BE; |
| 3079 | radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string); |
| 3080 | } |
| 3081 | break; |
| 3082 | default: |
| 3083 | fprintf(stderr, "%s band_idx invalid\n", __func__); |
| 3084 | break; |
| 3085 | } |
| 3086 | |
| 3087 | /* Remove the last comma */ |
| 3088 | if (strlen(output_string) != 0) |
| 3089 | output_string[strlen(output_string)-1] = '\0'; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3090 | |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3091 | } |
| 3092 | |
| 3093 | INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode) |
| 3094 | { |
| 3095 | unsigned int phymode; |
| 3096 | char interface_name[IF_NAME_SIZE] = {0}; |
| 3097 | struct mtk_nl80211_param params; |
| 3098 | int ret = -1; |
| 3099 | unsigned int if_idx = 0; |
| 3100 | struct unl unl_ins; |
| 3101 | struct nl_msg *msg = NULL; |
| 3102 | struct nlattr * msg_data = NULL; |
| 3103 | struct mtk_nl80211_param param; |
| 3104 | struct mtk_nl80211_cb_data cb_data; |
| 3105 | |
| 3106 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3107 | if(NULL == output_string || NULL == pureMode) |
| 3108 | return RETURN_ERR; |
| 3109 | |
| 3110 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 3111 | return RETURN_ERR; |
| 3112 | |
| 3113 | if_idx = if_nametoindex(interface_name); |
| 3114 | if (!if_idx) { |
| 3115 | wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name); |
| 3116 | return RETURN_ERR; |
| 3117 | } |
| 3118 | /*init mtk nl80211 vendor cmd*/ |
| 3119 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO; |
| 3120 | param.if_type = NL80211_ATTR_IFINDEX; |
| 3121 | param.if_idx = if_idx; |
| 3122 | |
| 3123 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 3124 | if (ret) { |
| 3125 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 3126 | return RETURN_ERR; |
| 3127 | } |
| 3128 | |
| 3129 | /*add mtk vendor cmd data*/ |
| 3130 | if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) { |
| 3131 | wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n"); |
| 3132 | nlmsg_free(msg); |
| 3133 | goto err; |
| 3134 | } |
| 3135 | |
| 3136 | /*send mtk nl80211 vendor msg*/ |
| 3137 | cb_data.out_buf = (char *)&phymode; |
| 3138 | cb_data.out_len = sizeof(unsigned int); |
| 3139 | |
| 3140 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data); |
| 3141 | |
| 3142 | if (ret) { |
| 3143 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 3144 | goto err; |
| 3145 | } |
| 3146 | /*deinit mtk nl80211 vendor msg*/ |
| 3147 | mtk_nl80211_deint(&unl_ins); |
| 3148 | |
| 3149 | phymode_to_puremode(radioIndex, output_string, pureMode, phymode); |
| 3150 | wifi_debug(DEBUG_NOTICE,"send cmd success\n"); |
| 3151 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3152 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3153 | return RETURN_OK; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3154 | err: |
| 3155 | mtk_nl80211_deint(&unl_ins); |
| 3156 | wifi_debug(DEBUG_ERROR,"send cmd fails\n"); |
| 3157 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3158 | } |
| 3159 | |
| 3160 | // Set the radio operating mode, and pure mode flag. |
| 3161 | INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag) //RDKB |
| 3162 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3163 | WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3164 | if (strcmp (channelMode,"11A") == 0) |
| 3165 | { |
| 3166 | writeBandWidth(radioIndex,"20MHz"); |
| 3167 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 3168 | printf("\nChannel Mode is 802.11a (5GHz)\n"); |
| 3169 | } |
| 3170 | else if (strcmp (channelMode,"11NAHT20") == 0) |
| 3171 | { |
| 3172 | writeBandWidth(radioIndex,"20MHz"); |
| 3173 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 3174 | printf("\nChannel Mode is 802.11n-20MHz(5GHz)\n"); |
| 3175 | } |
| 3176 | else if (strcmp (channelMode,"11NAHT40PLUS") == 0) |
| 3177 | { |
| 3178 | writeBandWidth(radioIndex,"40MHz"); |
| 3179 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 3180 | printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n"); |
| 3181 | } |
| 3182 | else if (strcmp (channelMode,"11NAHT40MINUS") == 0) |
| 3183 | { |
| 3184 | writeBandWidth(radioIndex,"40MHz"); |
| 3185 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 3186 | printf("\nChannel Mode is 802.11n-40MHz(5GHz)\n"); |
| 3187 | } |
| 3188 | else if (strcmp (channelMode,"11ACVHT20") == 0) |
| 3189 | { |
| 3190 | writeBandWidth(radioIndex,"20MHz"); |
| 3191 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 3192 | printf("\nChannel Mode is 802.11ac-20MHz(5GHz)\n"); |
| 3193 | } |
| 3194 | else if (strcmp (channelMode,"11ACVHT40PLUS") == 0) |
| 3195 | { |
| 3196 | writeBandWidth(radioIndex,"40MHz"); |
| 3197 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 3198 | printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n"); |
| 3199 | } |
| 3200 | else if (strcmp (channelMode,"11ACVHT40MINUS") == 0) |
| 3201 | { |
| 3202 | writeBandWidth(radioIndex,"40MHz"); |
| 3203 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 3204 | printf("\nChannel Mode is 802.11ac-40MHz(5GHz)\n"); |
| 3205 | } |
| 3206 | else if (strcmp (channelMode,"11ACVHT80") == 0) |
| 3207 | { |
| 3208 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz"); |
| 3209 | printf("\nChannel Mode is 802.11ac-80MHz(5GHz)\n"); |
| 3210 | } |
| 3211 | else if (strcmp (channelMode,"11ACVHT160") == 0) |
| 3212 | { |
| 3213 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz"); |
| 3214 | printf("\nChannel Mode is 802.11ac-160MHz(5GHz)\n"); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3215 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3216 | else if (strcmp (channelMode,"11B") == 0) |
| 3217 | { |
| 3218 | writeBandWidth(radioIndex,"20MHz"); |
| 3219 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 3220 | printf("\nChannel Mode is 802.11b(2.4GHz)\n"); |
| 3221 | } |
| 3222 | else if (strcmp (channelMode,"11G") == 0) |
| 3223 | { |
| 3224 | writeBandWidth(radioIndex,"20MHz"); |
| 3225 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 3226 | printf("\nChannel Mode is 802.11g(2.4GHz)\n"); |
| 3227 | } |
| 3228 | else if (strcmp (channelMode,"11NGHT20") == 0) |
| 3229 | { |
| 3230 | writeBandWidth(radioIndex,"20MHz"); |
| 3231 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz"); |
| 3232 | printf("\nChannel Mode is 802.11n-20MHz(2.4GHz)\n"); |
| 3233 | } |
| 3234 | else if (strcmp (channelMode,"11NGHT40PLUS") == 0) |
| 3235 | { |
| 3236 | writeBandWidth(radioIndex,"40MHz"); |
| 3237 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 3238 | printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n"); |
| 3239 | } |
| 3240 | else if (strcmp (channelMode,"11NGHT40MINUS") == 0) |
| 3241 | { |
| 3242 | writeBandWidth(radioIndex,"40MHz"); |
| 3243 | wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz"); |
| 3244 | printf("\nChannel Mode is 802.11n-40MHz(2.4GHz)\n"); |
| 3245 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3246 | else |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3247 | { |
| 3248 | return RETURN_ERR; |
| 3249 | } |
| 3250 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3251 | |
| 3252 | return RETURN_OK; |
| 3253 | } |
| 3254 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3255 | typedef enum _RT_802_11_PHY_MODE { |
| 3256 | PHY_11BG_MIXED = 0, |
| 3257 | PHY_11B = 1, |
| 3258 | PHY_11A = 2, |
| 3259 | PHY_11ABG_MIXED = 3, |
| 3260 | PHY_11G = 4, |
| 3261 | PHY_11ABGN_MIXED = 5, /* both band 5 */ |
| 3262 | PHY_11N_2_4G = 6, /* 11n-only with 2.4G band 6 */ |
| 3263 | PHY_11GN_MIXED = 7, /* 2.4G band 7 */ |
| 3264 | PHY_11AN_MIXED = 8, /* 5G band 8 */ |
| 3265 | PHY_11BGN_MIXED = 9, /* if check 802.11b. 9 */ |
| 3266 | PHY_11AGN_MIXED = 10, /* if check 802.11b. 10 */ |
| 3267 | PHY_11N_5G = 11, /* 11n-only with 5G band 11 */ |
| 3268 | PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */ |
| 3269 | PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed */ |
| 3270 | PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */ |
| 3271 | PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */ |
| 3272 | PHY_11AX_24G = 16, |
| 3273 | PHY_11AX_5G = 17, |
| 3274 | PHY_11AX_6G = 18, |
| 3275 | PHY_11AX_24G_6G = 19, |
| 3276 | PHY_11AX_5G_6G = 20, |
| 3277 | PHY_11AX_24G_5G_6G = 21, |
| 3278 | PHY_11BE_24G = 22, |
| 3279 | PHY_11BE_5G = 23, |
| 3280 | PHY_11BE_6G = 24, |
| 3281 | PHY_11BE_24G_6G = 25, |
| 3282 | PHY_11BE_5G_6G = 26, |
| 3283 | PHY_11BE_24G_5G_6G = 27, |
| 3284 | PHY_MODE_MAX, |
| 3285 | } RT_802_11_PHY_MODE; |
| 3286 | |
| 3287 | unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode) |
| 3288 | { |
| 3289 | int band_idx = 0; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3290 | unsigned char wireless_mode = PHY_MODE_MAX; |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3291 | |
| 3292 | band_idx = radio_index_to_band(radioIndex); |
| 3293 | |
| 3294 | switch (band_idx) { |
| 3295 | case band_2_4: |
| 3296 | if (pureMode == (WIFI_MODE_G | WIFI_MODE_N)) |
| 3297 | wireless_mode = PHY_11GN_MIXED; |
| 3298 | if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N)) |
| 3299 | wireless_mode = PHY_11BGN_MIXED; |
| 3300 | if (pureMode & WIFI_MODE_AX) |
| 3301 | wireless_mode = PHY_11AX_24G; |
| 3302 | if (pureMode & WIFI_MODE_BE) |
| 3303 | wireless_mode = PHY_11BE_24G; |
| 3304 | break; |
| 3305 | case band_5: |
| 3306 | if (pureMode == WIFI_MODE_N) |
| 3307 | wireless_mode = PHY_11N_5G; |
| 3308 | if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC))) |
| 3309 | wireless_mode = PHY_11VHT_N_MIXED; |
| 3310 | if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC)) |
| 3311 | wireless_mode = PHY_11VHT_N_A_MIXED; |
| 3312 | if (pureMode & WIFI_MODE_AX) |
| 3313 | wireless_mode = PHY_11AX_5G; |
| 3314 | if (pureMode & WIFI_MODE_BE) |
| 3315 | wireless_mode = PHY_11BE_5G; |
| 3316 | break; |
| 3317 | case band_6: |
| 3318 | if (pureMode & WIFI_MODE_AX) |
| 3319 | wireless_mode = PHY_11AX_6G; |
| 3320 | if (pureMode & WIFI_MODE_BE) |
| 3321 | wireless_mode = PHY_11BE_6G; |
| 3322 | break; |
| 3323 | default: |
| 3324 | fprintf(stderr, "%s band_idx invalid\n", __func__); |
| 3325 | break; |
| 3326 | } |
| 3327 | |
| 3328 | return wireless_mode; |
| 3329 | } |
| 3330 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3331 | // Set the radio operating mode, and pure mode flag. |
| 3332 | INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode) |
| 3333 | { |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3334 | unsigned char wireless_mode = PHY_MODE_MAX; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3335 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3336 | char interface_name[IF_NAME_SIZE] = {0}; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3337 | int ret = -1; |
| 3338 | unsigned int if_idx = 0; |
| 3339 | struct unl unl_ins; |
| 3340 | struct nl_msg *msg = NULL; |
| 3341 | struct nlattr * msg_data = NULL; |
| 3342 | struct mtk_nl80211_param param; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3343 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3344 | WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, channelMode, pureMode, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3345 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3346 | wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3347 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3348 | if (wireless_mode == PHY_MODE_MAX) { |
| 3349 | fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode); |
| 3350 | return RETURN_ERR; |
| 3351 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3352 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3353 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 3354 | return RETURN_ERR; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3355 | |
| 3356 | if_idx = if_nametoindex(interface_name); |
| 3357 | if (!if_idx) { |
| 3358 | wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name); |
| 3359 | return RETURN_ERR; |
| 3360 | } |
| 3361 | /*init mtk nl80211 vendor cmd*/ |
| 3362 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS; |
| 3363 | param.if_type = NL80211_ATTR_IFINDEX; |
| 3364 | param.if_idx = if_idx; |
| 3365 | |
| 3366 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 3367 | if (ret) { |
| 3368 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 3369 | return RETURN_ERR; |
| 3370 | } |
| 3371 | |
| 3372 | /*add mtk vendor cmd data*/ |
| 3373 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, wireless_mode)) { |
| 3374 | wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n"); |
| 3375 | nlmsg_free(msg); |
| 3376 | goto err; |
| 3377 | } |
| 3378 | /*send mtk nl80211 vendor msg*/ |
| 3379 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 3380 | if (ret) { |
| 3381 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 3382 | goto err; |
| 3383 | } |
| 3384 | /*deinit mtk nl80211 vendor msg*/ |
| 3385 | mtk_nl80211_deint(&unl_ins); |
| 3386 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3387 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3388 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3389 | |
| 3390 | return RETURN_OK; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3391 | err: |
| 3392 | mtk_nl80211_deint(&unl_ins); |
| 3393 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 3394 | return RETURN_ERR; |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3395 | } |
| 3396 | |
| 3397 | INT wifi_setRadioMode_by_dat(INT radioIndex, UINT pureMode) |
| 3398 | { |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 3399 | unsigned char wireless_mode = PHY_MODE_MAX; |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3400 | char interface_name[IF_NAME_SIZE] = {0}; |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3401 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 3402 | char dat_file[MAX_BUF_SIZE] = {0}; |
| 3403 | struct params params={0}; |
| 3404 | |
| 3405 | WIFI_ENTRY_EXIT_DEBUG("Inside %s_%d:%d\n", __func__, pureMode, __LINE__); |
| 3406 | |
| 3407 | wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode); |
| 3408 | |
| 3409 | if (wireless_mode == PHY_MODE_MAX) { |
| 3410 | fprintf(stderr, "%s wireless_mode invalid pureMode = %x\n", __func__, pureMode); |
| 3411 | return RETURN_ERR; |
| 3412 | } |
| 3413 | |
| 3414 | params.name = "WirelessMode"; |
| 3415 | snprintf(buf, sizeof(buf), "%d", wireless_mode); |
| 3416 | params.value = buf; |
| 3417 | |
| 3418 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex); |
| 3419 | wifi_datfileWrite(dat_file, ¶ms, 1); |
| 3420 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3421 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3422 | |
| 3423 | return RETURN_OK; |
| 3424 | } |
| 3425 | |
| 3426 | INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) { |
| 3427 | |
| 3428 | char config_file[64] = {0}; |
| 3429 | char buf[64] = {0}; |
| 3430 | struct params params = {0}; |
| 3431 | wifi_band band = band_invalid; |
| 3432 | |
| 3433 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3434 | |
| 3435 | band = wifi_index_to_band(radioIndex); |
| 3436 | |
| 3437 | if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6)) |
| 3438 | return RETURN_ERR; |
| 3439 | else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4) |
| 3440 | return RETURN_ERR; |
| 3441 | else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid) |
| 3442 | return RETURN_ERR; |
| 3443 | |
| 3444 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 3445 | params.name = "hw_mode"; |
| 3446 | params.value = hw_mode; |
| 3447 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 3448 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 3449 | |
| 3450 | if (band == band_2_4) { |
| 3451 | if (strncmp(hw_mode, "b", 1) == 0) { |
| 3452 | wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B); |
| 3453 | snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11"); |
| 3454 | wifi_setRadioOperationalDataTransmitRates(radioIndex, buf); |
| 3455 | snprintf(buf, sizeof(buf), "%s", "1,2"); |
| 3456 | wifi_setRadioBasicDataTransmitRates(radioIndex, buf); |
| 3457 | } else { |
| 3458 | // We don't set mode here, because we don't know whitch mode should be set (g, n or ax?). |
| 3459 | |
| 3460 | snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54"); |
| 3461 | wifi_setRadioOperationalDataTransmitRates(radioIndex, buf); |
| 3462 | snprintf(buf, sizeof(buf), "%s", "6,12,24"); |
| 3463 | wifi_setRadioBasicDataTransmitRates(radioIndex, buf); |
| 3464 | } |
| 3465 | } |
| 3466 | |
| 3467 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3468 | return RETURN_OK; |
| 3469 | } |
| 3470 | |
| 3471 | INT wifi_setNoscan(INT radioIndex, CHAR *noscan) |
| 3472 | { |
| 3473 | char config_file[64] = {0}; |
| 3474 | struct params params = {0}; |
| 3475 | wifi_band band = band_invalid; |
| 3476 | |
| 3477 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3478 | |
| 3479 | band = wifi_index_to_band(radioIndex); |
| 3480 | if (band != band_2_4) |
| 3481 | return RETURN_OK; |
| 3482 | |
| 3483 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 3484 | params.name = "noscan"; |
| 3485 | params.value = noscan; |
| 3486 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 3487 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 3488 | |
| 3489 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3490 | return RETURN_OK; |
| 3491 | } |
| 3492 | |
| 3493 | //Get the list of supported channel. eg: "1-11" |
| 3494 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 3495 | INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string) //RDKB |
| 3496 | { |
| 3497 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3498 | if (NULL == output_string) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3499 | return RETURN_ERR; |
| 3500 | char cmd[256] = {0}; |
| 3501 | char buf[128] = {0}; |
| 3502 | BOOL dfs_enable = false; |
| 3503 | int phyId = 0; |
| 3504 | |
| 3505 | // Parse possible channel number and separate them with commas. |
| 3506 | wifi_getRadioDfsEnable(radioIndex, &dfs_enable); |
| 3507 | phyId = radio_index_to_phy(radioIndex); |
| 3508 | // Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency. |
| 3509 | if (dfs_enable) |
| 3510 | snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3511 | else |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3512 | snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v 'radar\\|no IR\\|5340\\|5480' | cut -d '[' -f2 | cut -d ']' -f1 | tr '\\n' ',' | sed 's/.$//'", phyId); |
| 3513 | |
| 3514 | _syscmd(cmd,buf,sizeof(buf)); |
| 3515 | strncpy(output_string, buf, sizeof(buf)); |
| 3516 | |
| 3517 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3518 | return RETURN_OK; |
| 3519 | } |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3520 | //Getting current radio extension channel |
| 3521 | INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value) |
| 3522 | { |
| 3523 | CHAR buf[150] = {0}; |
| 3524 | CHAR cmd[150] = {0}; |
| 3525 | |
| 3526 | wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf)); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 3527 | if (strncmp(buf, "Below", 5) == 0) //below |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3528 | strcpy(Value,"BelowControlChannel"); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 3529 | if(strncmp(buf, "Above", 5) == 0) //above |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3530 | strcpy(Value,"AboveControlChannel"); |
| 3531 | return RETURN_OK; |
| 3532 | } |
developer | f6a8754 | 2023-05-16 15:47:28 +0800 | [diff] [blame] | 3533 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3534 | //Get the list for used channel. eg: "1,6,9,11" |
| 3535 | //The output_string is a max length 256 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 3536 | INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string) //RDKB |
| 3537 | { |
| 3538 | char interface_name[16] = {0}; |
| 3539 | char cmd[128] = {0}; |
| 3540 | char buf[128] = {0}; |
| 3541 | char config_file[64] = {0}; |
| 3542 | int channel = 0; |
| 3543 | int freq = 0; |
| 3544 | int bandwidth = 0; |
| 3545 | int center_freq = 0; |
| 3546 | int center_channel = 0; |
| 3547 | int channel_delta = 0; |
| 3548 | wifi_band band = band_invalid; |
| 3549 | |
| 3550 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 3551 | |
| 3552 | if (NULL == output_string) |
| 3553 | return RETURN_ERR; |
| 3554 | |
| 3555 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 3556 | return RETURN_ERR; |
| 3557 | sprintf(cmd, "iw %s info | grep channel | sed -e 's/[^0-9 ]//g'", interface_name); |
| 3558 | _syscmd(cmd, buf, sizeof(buf)); |
| 3559 | if (strlen(buf) == 0) { |
| 3560 | fprintf(stderr, "%s: failed to get channel information from iw.\n", __func__); |
| 3561 | return RETURN_ERR; |
| 3562 | } |
| 3563 | sscanf(buf, "%d %d %d %*d %d", &channel, &freq, &bandwidth, ¢er_freq); |
| 3564 | |
| 3565 | if (bandwidth == 20) { |
| 3566 | snprintf(output_string, 256, "%d", channel); |
| 3567 | return RETURN_OK; |
| 3568 | } |
| 3569 | |
| 3570 | center_channel = ieee80211_frequency_to_channel(center_freq); |
| 3571 | |
| 3572 | band = wifi_index_to_band(radioIndex); |
| 3573 | if (band == band_2_4 && bandwidth == 40) { |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3574 | sprintf(config_file, "%s%d.dat", LOGAN_DAT_FILE, band); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3575 | memset(buf, 0, sizeof(buf)); |
| 3576 | wifi_halgetRadioExtChannel(config_file, buf); // read ht_capab for HT40+ or - |
| 3577 | |
| 3578 | if (strncmp(buf, "AboveControlChannel", strlen("AboveControlChannel")) == 0 && channel < 10) { |
| 3579 | snprintf(output_string, 256, "%d,%d", channel, channel+4); |
| 3580 | } else if (strncmp(buf, "BelowControlChannel", strlen("BelowControlChannel")) == 0 && channel > 4) { |
| 3581 | snprintf(output_string, 256, "%d,%d", channel-4, channel); |
| 3582 | } else { |
| 3583 | fprintf(stderr, "%s: invalid channel %d set with %s\n.", __func__, channel, buf); |
| 3584 | return RETURN_ERR; |
| 3585 | } |
| 3586 | } else if (band == band_5 || band == band_6){ |
| 3587 | // to minus 20 is an offset, because frequence of a channel have a range. We need to use offset to calculate correct channel. |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3588 | // example: bandwidth 80: center is 42 (5210), channels are "36,40,44,48" (5170-5250). The delta should be 6. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3589 | channel_delta = (bandwidth-20)/10; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3590 | memset(output_string, 0, 256); |
| 3591 | for (int i = center_channel-channel_delta; i <= center_channel+channel_delta; i+=4) { |
| 3592 | // If i is not the last channel, we add a comma. |
| 3593 | snprintf(buf, sizeof(buf), "%d%s", i, i==center_channel+channel_delta?"":","); |
| 3594 | strncat(output_string, buf, strlen(buf)); |
| 3595 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3596 | } else |
| 3597 | return RETURN_ERR; |
| 3598 | |
| 3599 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3600 | return RETURN_OK; |
| 3601 | } |
| 3602 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3603 | //Get the running channel number |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3604 | INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong) //RDKB |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3605 | { |
| 3606 | char channel_str[16] = {0}; |
| 3607 | char config_file[128] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3608 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3609 | |
| 3610 | if (output_ulong == NULL) |
| 3611 | return RETURN_ERR; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3612 | band = wifi_index_to_band(radioIndex); |
| 3613 | snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 3614 | wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3615 | |
| 3616 | *output_ulong = strtoul(channel_str, NULL, 10); |
| 3617 | |
| 3618 | return RETURN_OK; |
| 3619 | } |
| 3620 | |
| 3621 | |
| 3622 | INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB |
| 3623 | { |
| 3624 | char cmd[1024] = {0}, buf[5] = {0}; |
| 3625 | char interface_name[16] = {0}; |
| 3626 | |
| 3627 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3628 | if (NULL == output_ulong) |
| 3629 | return RETURN_ERR; |
| 3630 | |
| 3631 | snprintf(cmd, sizeof(cmd), "iw dev %s info |grep channel | cut -d ' ' -f2",interface_name); |
| 3632 | if (wifi_getApName(apIndex,interface_name) != RETURN_OK) |
| 3633 | return RETURN_ERR; |
| 3634 | _syscmd(cmd,buf,sizeof(buf)); |
| 3635 | *output_ulong = (strlen(buf) >= 1)? atol(buf): 0; |
| 3636 | if (*output_ulong == 0) { |
| 3637 | return RETURN_ERR; |
| 3638 | } |
| 3639 | |
| 3640 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3641 | return RETURN_OK; |
| 3642 | } |
| 3643 | |
| 3644 | //Storing the previous channel value |
| 3645 | INT wifi_storeprevchanval(INT radioIndex) |
| 3646 | { |
| 3647 | char buf[256] = {0}; |
| 3648 | char output[4]={'\0'}; |
| 3649 | char config_file[MAX_BUF_SIZE] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3650 | wifi_band band = band_invalid; |
| 3651 | |
| 3652 | band = wifi_index_to_band(radioIndex); |
| 3653 | if (band == band_invalid) { |
| 3654 | return RETURN_ERR; |
| 3655 | wifi_dbg_printf("[%s]: Invalid radio index", __func__); |
| 3656 | } |
| 3657 | snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band); |
| 3658 | wifi_datfileRead(config_file, "Channel", output, sizeof(output)); |
| 3659 | |
| 3660 | if(band == band_2_4) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3661 | sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval2G_AutoChannelEnable"); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3662 | else if(band == band_5) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3663 | sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval5G_AutoChannelEnable"); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3664 | else |
| 3665 | sprintf(buf,"%s%s%s","echo ",output," > /var/prevchanval6G_AutoChannelEnable"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3666 | system(buf); |
| 3667 | Radio_flag = FALSE; |
| 3668 | return RETURN_OK; |
| 3669 | } |
| 3670 | |
| 3671 | //Set the running channel number |
| 3672 | INT wifi_setRadioChannel(INT radioIndex, ULONG channel) //RDKB //AP only |
| 3673 | { |
| 3674 | // We only write hostapd config here |
| 3675 | char str_channel[8]={0}; |
| 3676 | char *list_channel; |
| 3677 | char config_file[128] = {0}; |
| 3678 | char possible_channels[256] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3679 | char config_file_dat[128] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3680 | int max_radio_num = 0; |
| 3681 | struct params list = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3682 | struct params dat = {0}; |
| 3683 | struct params acs = {0}; |
| 3684 | wifi_band band = band_invalid; |
| 3685 | bool acs_channel = false; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3686 | |
| 3687 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3688 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3689 | if (channel == 0) |
| 3690 | acs_channel = true; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3691 | // Check valid |
| 3692 | sprintf(str_channel, "%lu", channel); |
| 3693 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3694 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3695 | wifi_getRadioPossibleChannels(radioIndex, possible_channels); |
| 3696 | list_channel = strtok(possible_channels, ","); |
| 3697 | while(true) |
| 3698 | { |
| 3699 | if(list_channel == NULL) { // input not in the list |
| 3700 | fprintf(stderr, "%s: Channel %s is not in possible list\n", __func__, str_channel); |
| 3701 | return RETURN_ERR; |
| 3702 | } |
| 3703 | if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0) |
| 3704 | break; |
| 3705 | list_channel = strtok(NULL, ","); |
| 3706 | } |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3707 | /* |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3708 | list.name = "channel"; |
| 3709 | list.value = str_channel; |
| 3710 | wifi_getMaxRadioNumber(&max_radio_num); |
| 3711 | for(int i=0; i<=MAX_APS/max_radio_num;i++) |
| 3712 | { |
| 3713 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i)); |
| 3714 | wifi_hostapdWrite(config_file, &list, 1); |
| 3715 | } |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 3716 | */ |
| 3717 | dat.name = "Channel"; |
| 3718 | dat.value = str_channel; |
| 3719 | band = wifi_index_to_band(radioIndex); |
| 3720 | snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 3721 | wifi_datfileWrite(config_file_dat, &dat, 1); |
| 3722 | if (acs_channel == true) { |
| 3723 | acs.name = "AutoChannelSelect"; |
| 3724 | acs.value = "3"; |
| 3725 | } else { |
| 3726 | acs.name = "AutoChannelSelect"; |
| 3727 | acs.value = "0"; |
| 3728 | } |
| 3729 | wifi_datfileWrite(config_file_dat, &acs, 1); |
developer | c0772e6 | 2023-05-18 15:10:48 +0800 | [diff] [blame] | 3730 | wifi_reloadAp(radioIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3731 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 3732 | return RETURN_OK; |
| 3733 | } |
| 3734 | |
| 3735 | INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel) |
| 3736 | { |
| 3737 | struct params list[2]; |
| 3738 | char str_idx[16]; |
| 3739 | char config_file[64]; |
| 3740 | int max_num_radios = 0; |
| 3741 | wifi_band band = band_invalid; |
| 3742 | |
| 3743 | band = wifi_index_to_band(radioIndex); |
| 3744 | if (band == band_2_4) |
| 3745 | return RETURN_OK; |
| 3746 | |
| 3747 | snprintf(str_idx, sizeof(str_idx), "%lu", channel); |
| 3748 | list[0].name = "vht_oper_centr_freq_seg0_idx"; |
| 3749 | list[0].value = str_idx; |
| 3750 | list[1].name = "he_oper_centr_freq_seg0_idx"; |
| 3751 | list[1].value = str_idx; |
| 3752 | |
| 3753 | wifi_getMaxRadioNumber(&max_num_radios); |
| 3754 | for(int i=0; i<=MAX_APS/max_num_radios; i++) |
| 3755 | { |
| 3756 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_num_radios*i)); |
| 3757 | if (band == band_6) |
| 3758 | wifi_hostapdWrite(config_file, &list[1], 1); |
| 3759 | else |
| 3760 | wifi_hostapdWrite(config_file, list, 2); |
| 3761 | } |
| 3762 | |
| 3763 | return RETURN_OK; |
| 3764 | } |
| 3765 | |
| 3766 | //Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio |
| 3767 | //This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS)) |
| 3768 | INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB |
| 3769 | { |
| 3770 | //Set to wifi config only. Wait for wifi reset to apply. |
| 3771 | char buf[256] = {0}; |
| 3772 | char str_channel[256] = {0}; |
| 3773 | int count = 0; |
| 3774 | ULONG Value = 0; |
| 3775 | FILE *fp = NULL; |
| 3776 | if(enable == TRUE) |
| 3777 | { |
| 3778 | wifi_setRadioChannel(radioIndex,Value); |
| 3779 | } |
| 3780 | return RETURN_OK; |
| 3781 | } |
| 3782 | |
| 3783 | INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool) |
| 3784 | { |
| 3785 | if (output_bool == NULL) |
| 3786 | return RETURN_ERR; |
| 3787 | |
| 3788 | *output_bool = TRUE; |
| 3789 | |
| 3790 | return RETURN_OK; |
| 3791 | } |
| 3792 | |
| 3793 | INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) //RDKB |
| 3794 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3795 | if (NULL == output_bool) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3796 | return RETURN_ERR; |
| 3797 | *output_bool=FALSE; |
| 3798 | return RETURN_OK; |
| 3799 | } |
| 3800 | |
| 3801 | INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool) //RDKB |
| 3802 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3803 | if (NULL == output_bool) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3804 | return RETURN_ERR; |
| 3805 | *output_bool=FALSE; |
| 3806 | return RETURN_OK; |
| 3807 | } |
| 3808 | |
| 3809 | INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable) //RDKB |
| 3810 | { |
| 3811 | //Set to wifi config only. Wait for wifi reset to apply. |
| 3812 | return RETURN_OK; |
| 3813 | } |
| 3814 | |
| 3815 | INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable) |
| 3816 | { |
| 3817 | return RETURN_OK; |
| 3818 | } |
| 3819 | |
| 3820 | INT wifi_factoryResetAP(int apIndex) |
| 3821 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 3822 | char ap_config_file[MAX_CMD_SIZE] = {0}; |
| 3823 | char cmd[MAX_CMD_SIZE] = {0}; |
| 3824 | char ret_buf[MAX_BUF_SIZE] = {0}; |
| 3825 | int radio_idx = 0; |
| 3826 | int bss_idx = 0; |
| 3827 | char ssid[32] = {0}; |
| 3828 | char interface[IF_NAME_SIZE] = {0}; |
| 3829 | char psk_file[MAX_CMD_SIZE] = {0}; |
| 3830 | struct params params[3] = {0}; |
| 3831 | char *band_str[3] = {"2G", "5G", "6G"}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3832 | |
| 3833 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3834 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 3835 | /*del old config file*/ |
| 3836 | snprintf(ap_config_file, MAX_CMD_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 3837 | snprintf(cmd, MAX_CMD_SIZE, "rm %s", ap_config_file); |
| 3838 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3839 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 3840 | memset(cmd, 0, sizeof(cmd)); |
| 3841 | memset(ret_buf, 0, sizeof(ret_buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3842 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 3843 | vap_index_to_array_index(apIndex, &radio_idx, &bss_idx); |
| 3844 | |
| 3845 | /*prepare new config file*/ |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 3846 | snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file); |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 3847 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 3848 | |
| 3849 | if (radio_idx == band_2_4) { |
| 3850 | snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx); |
| 3851 | snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx); |
| 3852 | } else if (radio_idx == band_5) { |
| 3853 | snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx); |
| 3854 | snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx); |
| 3855 | } else if (radio_idx == band_6) { |
| 3856 | snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx); |
| 3857 | snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx); |
| 3858 | } |
| 3859 | |
| 3860 | /* fix wpa_psk_file path */ |
| 3861 | snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", apIndex); |
| 3862 | |
| 3863 | params[0].name = "ssid"; |
| 3864 | params[0].value = ssid; |
| 3865 | params[1].name = "interface"; |
| 3866 | params[1].value = interface; |
| 3867 | params[2].name = "wpa_psk_file"; |
| 3868 | params[2].value = psk_file; |
| 3869 | |
| 3870 | wifi_hostapdWrite(ap_config_file, params, 3); |
| 3871 | |
| 3872 | /*clear psk file*/ |
| 3873 | memset(cmd, 0, sizeof(cmd)); |
| 3874 | memset(ret_buf, 0, sizeof(ret_buf)); |
| 3875 | |
| 3876 | snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex); |
| 3877 | |
| 3878 | if (access(psk_file, F_OK) != 0) { |
| 3879 | snprintf(cmd, MAX_CMD_SIZE, "touch %s", psk_file); |
| 3880 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 3881 | } else { |
| 3882 | snprintf(cmd, MAX_CMD_SIZE, "echo '' > %s", psk_file); |
| 3883 | _syscmd(cmd, ret_buf, sizeof(ret_buf)); |
| 3884 | } |
| 3885 | |
| 3886 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3887 | |
| 3888 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3889 | } |
| 3890 | |
| 3891 | //To set Band Steering AP group |
| 3892 | //To-do |
| 3893 | INT wifi_setBandSteeringApGroup(char *ApGroup) |
| 3894 | { |
| 3895 | return RETURN_OK; |
| 3896 | } |
| 3897 | |
| 3898 | INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval) |
| 3899 | { |
| 3900 | char config_file[128] = {'\0'}; |
| 3901 | char buf[128] = {'\0'}; |
| 3902 | |
| 3903 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3904 | if (dtimInterval == NULL) |
| 3905 | return RETURN_ERR; |
| 3906 | |
| 3907 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
developer | 885b56c | 2023-05-22 15:02:46 +0800 | [diff] [blame] | 3908 | wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3909 | |
| 3910 | if (strlen(buf) == 0) { |
| 3911 | *dtimInterval = 2; |
| 3912 | } else { |
| 3913 | *dtimInterval = strtoul(buf, NULL, 10); |
| 3914 | } |
| 3915 | |
| 3916 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3917 | return RETURN_OK; |
| 3918 | } |
| 3919 | |
| 3920 | INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval) |
| 3921 | { |
| 3922 | struct params params={0}; |
| 3923 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 3924 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 3925 | |
| 3926 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 3927 | if (dtimInterval < 1 || dtimInterval > 255) { |
| 3928 | WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval); |
| 3929 | return RETURN_ERR; |
| 3930 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3931 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3932 | params.name = "dtim_period"; |
| 3933 | snprintf(buf, sizeof(buf), "%d", dtimInterval); |
| 3934 | params.value = buf; |
| 3935 | |
| 3936 | sprintf(config_file,"%s%d.conf", CONFIG_PREFIX, apIndex); |
| 3937 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 3938 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 3939 | |
| 3940 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 3941 | return RETURN_OK; |
| 3942 | } |
| 3943 | |
| 3944 | //Check if the driver support the Dfs |
| 3945 | INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181 |
| 3946 | { |
| 3947 | wifi_band band = band_invalid; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3948 | if (NULL == output_bool) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3949 | return RETURN_ERR; |
| 3950 | *output_bool=FALSE; |
| 3951 | |
| 3952 | band = wifi_index_to_band(radioIndex); |
| 3953 | if (band == band_5) |
| 3954 | *output_bool = TRUE; |
| 3955 | return RETURN_OK; |
| 3956 | } |
| 3957 | |
| 3958 | //The output_string is a max length 256 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 3959 | //The value of this parameter is a comma seperated list of channel number |
| 3960 | INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool) //RDKB |
| 3961 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3962 | if (NULL == output_pool) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3963 | return RETURN_ERR; |
| 3964 | if (radioIndex==1) |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3965 | return RETURN_OK;//TODO need to handle for 5GHz band, i think |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3966 | snprintf(output_pool, 256, "1,2,3,4,5,6,7,8,9,10,11"); |
| 3967 | |
| 3968 | return RETURN_OK; |
| 3969 | } |
| 3970 | |
| 3971 | INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool) //RDKB |
| 3972 | { |
| 3973 | //Set to wifi config. And apply instantly. |
| 3974 | return RETURN_OK; |
| 3975 | } |
| 3976 | |
| 3977 | INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds) |
| 3978 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3979 | if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3980 | return RETURN_ERR; |
| 3981 | *output_interval_seconds=1800; |
| 3982 | *output_dwell_milliseconds=40; |
| 3983 | |
| 3984 | return RETURN_OK; |
| 3985 | } |
| 3986 | |
| 3987 | INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds) |
| 3988 | { |
| 3989 | //Set to wifi config. And apply instantly. |
| 3990 | return RETURN_OK; |
| 3991 | } |
| 3992 | |
| 3993 | INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool) //Tr181 |
| 3994 | { |
| 3995 | if (output_bool == NULL) |
| 3996 | return RETURN_ERR; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 3997 | *output_bool = true; |
| 3998 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 3999 | } |
| 4000 | |
| 4001 | INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable) //Tr181 |
| 4002 | { |
| 4003 | return RETURN_OK; |
| 4004 | } |
| 4005 | |
| 4006 | //Get the Dfs enable status |
| 4007 | INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool) //Tr181 |
| 4008 | { |
| 4009 | char buf[16] = {0}; |
| 4010 | FILE *f = NULL; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4011 | char config_file_dat[128] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4012 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4013 | |
| 4014 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4015 | |
| 4016 | if (output_bool == NULL) |
| 4017 | return RETURN_ERR; |
developer | f6a8754 | 2023-05-16 15:47:28 +0800 | [diff] [blame] | 4018 | *output_bool = TRUE; // default |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4019 | band = wifi_index_to_band(radioIndex); |
| 4020 | snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 4021 | |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4022 | wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf)); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4023 | |
| 4024 | if (strncmp(buf, "0", 1) == 0) |
| 4025 | *output_bool = FALSE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4026 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4027 | return RETURN_OK; |
| 4028 | } |
| 4029 | |
| 4030 | //Set the Dfs enable status |
| 4031 | INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable) //Tr181 |
| 4032 | { |
| 4033 | char config_file[128] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4034 | char config_dat_file[128] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4035 | FILE *f = NULL; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4036 | struct params dat = {0}; |
| 4037 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4038 | |
| 4039 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4040 | |
| 4041 | f = fopen(DFS_ENABLE_FILE, "w"); |
| 4042 | if (f == NULL) |
| 4043 | return RETURN_ERR; |
| 4044 | fprintf(f, "%d", enable); |
| 4045 | fclose(f); |
| 4046 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4047 | wifi_setRadioIEEE80211hEnabled(radioIndex, enable); |
| 4048 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4049 | dat.name = "DfsEnable"; |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4050 | dat.value = enable?"1":"0"; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4051 | band = wifi_index_to_band(radioIndex); |
| 4052 | snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 4053 | wifi_datfileWrite(config_dat_file, &dat, 1); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4054 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4055 | return RETURN_OK; |
| 4056 | } |
| 4057 | |
| 4058 | //Check if the driver support the AutoChannelRefreshPeriod |
| 4059 | INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181 |
| 4060 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4061 | if (NULL == output_bool) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4062 | return RETURN_ERR; |
| 4063 | *output_bool=FALSE; //not support |
| 4064 | |
| 4065 | return RETURN_OK; |
| 4066 | } |
| 4067 | |
| 4068 | //Get the ACS refresh period in seconds |
| 4069 | INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181 |
| 4070 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4071 | if (NULL == output_ulong) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4072 | return RETURN_ERR; |
| 4073 | *output_ulong=300; |
| 4074 | |
| 4075 | return RETURN_OK; |
| 4076 | } |
| 4077 | |
| 4078 | //Set the ACS refresh period in seconds |
| 4079 | INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181 |
| 4080 | { |
| 4081 | return RETURN_ERR; |
| 4082 | } |
| 4083 | |
| 4084 | //Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160" |
| 4085 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 4086 | INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181 |
| 4087 | { |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4088 | char cmd[MAX_CMD_SIZE] = {0}, buf[64] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4089 | char extchannel[128] = {0}; |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4090 | char interface_name[64] = {0}; |
| 4091 | int ret = 0, len=0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4092 | BOOL radio_enable = FALSE; |
| 4093 | wifi_band band; |
| 4094 | |
| 4095 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4096 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4097 | if (NULL == output_string) { |
| 4098 | WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4099 | return RETURN_ERR; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4100 | } |
| 4101 | if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) { |
| 4102 | WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4103 | return RETURN_ERR; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4104 | } |
| 4105 | if (radio_enable != TRUE) { |
| 4106 | WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4107 | return RETURN_OK; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4108 | } |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4109 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 4110 | return RETURN_ERR; |
| 4111 | /*IW command get BW320 to do*/ |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4112 | |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4113 | snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name); |
| 4114 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 4115 | len = strlen(buf); |
| 4116 | if((ret != 0) || (len == 0)) |
| 4117 | { |
| 4118 | WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__); |
| 4119 | return RETURN_ERR; |
| 4120 | } |
| 4121 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4122 | band = wifi_index_to_band(radioIndex); |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4123 | if (band == band_2_4 && strncmp(buf, "20", 2) == 0) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4124 | wifi_getRadioExtChannel(radioIndex, extchannel); |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4125 | if (strncmp(extchannel, "Auto", 4) != 0) // not auto means we have set HT40+/- |
| 4126 | snprintf(buf, sizeof(buf), "40"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4127 | } |
developer | 8666b31 | 2023-03-24 14:05:31 +0800 | [diff] [blame] | 4128 | snprintf(output_string, 64, "%sMHz", buf); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4129 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4130 | |
| 4131 | return RETURN_OK; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4132 | } |
| 4133 | |
| 4134 | enum mwctl_chan_width { |
| 4135 | MWCTL_CHAN_WIDTH_20, |
| 4136 | MWCTL_CHAN_WIDTH_40, |
| 4137 | MWCTL_CHAN_WIDTH_80, |
| 4138 | MWCTL_CHAN_WIDTH_160, |
| 4139 | MWCTL_CHAN_WIDTH_320, |
| 4140 | }; |
| 4141 | |
| 4142 | struct bw_option { |
| 4143 | unsigned int bandwith; |
| 4144 | enum mwctl_chan_width mode; |
| 4145 | }; |
| 4146 | |
| 4147 | struct bw_option bw_opt[] = { |
| 4148 | {20, MWCTL_CHAN_WIDTH_20}, |
| 4149 | {40, MWCTL_CHAN_WIDTH_40}, |
| 4150 | {80, MWCTL_CHAN_WIDTH_80}, |
| 4151 | {160, MWCTL_CHAN_WIDTH_160}, |
| 4152 | {320, MWCTL_CHAN_WIDTH_320}, |
| 4153 | }; |
| 4154 | |
| 4155 | INT wifi_setChannel_netlink(INT radioIndex, UINT* channel, UINT *bandwidth) |
| 4156 | { |
| 4157 | int ret = -1; |
| 4158 | int i; |
| 4159 | struct unl unl_ins; |
| 4160 | struct nl_msg *msg = NULL; |
| 4161 | struct nlattr * msg_data = NULL; |
| 4162 | struct mtk_nl80211_param param; |
| 4163 | bool b_match = FALSE; |
| 4164 | |
| 4165 | /*init mtk nl80211 vendor cmd*/ |
| 4166 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL; |
| 4167 | param.if_type = NL80211_ATTR_WIPHY; |
| 4168 | param.if_idx = radio_index_to_phy(radioIndex); |
| 4169 | |
| 4170 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 4171 | if (ret) { |
| 4172 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 4173 | return RETURN_ERR; |
| 4174 | } |
| 4175 | |
| 4176 | /*add mtk vendor cmd data*/ |
| 4177 | if (channel != NULL) |
| 4178 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) { |
| 4179 | wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n"); |
| 4180 | nlmsg_free(msg); |
| 4181 | goto err; |
| 4182 | } |
| 4183 | |
| 4184 | if (bandwidth != NULL) { |
| 4185 | for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) { |
| 4186 | if (bw_opt[i].bandwith == *bandwidth) { |
| 4187 | b_match = true; |
| 4188 | if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) { |
| 4189 | wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n"); |
| 4190 | nlmsg_free(msg); |
| 4191 | goto err; |
| 4192 | } |
| 4193 | break; |
| 4194 | } |
| 4195 | } |
| 4196 | |
| 4197 | if (!b_match) { |
| 4198 | wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n"); |
| 4199 | nlmsg_free(msg); |
| 4200 | goto err; |
| 4201 | } |
| 4202 | } |
| 4203 | |
| 4204 | /*send mtk nl80211 vendor msg*/ |
| 4205 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 4206 | if (ret) { |
| 4207 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 4208 | goto err; |
| 4209 | } |
| 4210 | /*deinit mtk nl80211 vendor msg*/ |
| 4211 | mtk_nl80211_deint(&unl_ins); |
| 4212 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
| 4213 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4214 | |
| 4215 | return RETURN_OK; |
| 4216 | err: |
| 4217 | mtk_nl80211_deint(&unl_ins); |
| 4218 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 4219 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4220 | } |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4221 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4222 | //Set the Operating Channel Bandwidth. |
| 4223 | INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181 //AP only |
| 4224 | { |
| 4225 | char config_file[128]; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4226 | char ht_value[16]; |
| 4227 | char vht_value[16]; |
| 4228 | char eht_value[16]; |
| 4229 | struct params dat[3]; |
| 4230 | wifi_band band = band_invalid; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4231 | unsigned int bw = 20; |
| 4232 | int ret = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4233 | |
| 4234 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4235 | |
| 4236 | if(NULL == bandwidth) |
| 4237 | return RETURN_ERR; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4238 | band = wifi_index_to_band(radioIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4239 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4240 | if(strstr(bandwidth,"320") != NULL) { |
| 4241 | snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40); |
| 4242 | snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160); |
| 4243 | snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4244 | bw = 320; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4245 | } else if(strstr(bandwidth,"160") != NULL) { |
| 4246 | snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40); |
| 4247 | snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160); |
| 4248 | snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4249 | bw = 160; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4250 | } else if(strstr(bandwidth,"80") != NULL) { |
| 4251 | snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40); |
| 4252 | snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80); |
| 4253 | snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4254 | bw = 80; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4255 | } else if(strstr(bandwidth,"40") != NULL) { |
| 4256 | snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40); |
| 4257 | snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040); |
| 4258 | snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40); |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4259 | bw = 40; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4260 | } else if(strstr(bandwidth,"20") != NULL) { |
| 4261 | snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20); |
| 4262 | snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040); |
| 4263 | snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4264 | bw = 20; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4265 | } else { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4266 | fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth); |
| 4267 | return RETURN_ERR; |
| 4268 | } |
| 4269 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4270 | snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 4271 | dat[0].name = "HT_BW"; |
| 4272 | dat[0].value = ht_value; |
| 4273 | dat[1].name = "VHT_BW"; |
| 4274 | dat[1].value = vht_value; |
| 4275 | dat[2].name = "EHT_ApBw"; |
| 4276 | dat[2].value = eht_value; |
| 4277 | wifi_datfileWrite(config_file, dat, 3); |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4278 | ret = wifi_setChannel_netlink(radioIndex, NULL, &bw); |
| 4279 | if (ret != RETURN_OK) { |
| 4280 | fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__); |
| 4281 | return RETURN_ERR; |
| 4282 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4283 | |
| 4284 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4285 | return RETURN_OK; |
| 4286 | } |
| 4287 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4288 | //Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only) |
| 4289 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 4290 | INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181 |
| 4291 | { |
| 4292 | char config_file[64] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4293 | char config_dat_file[64] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4294 | char mode_str[16] = {0}; |
| 4295 | char buf[64] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4296 | char cmd[MAX_CMD_SIZE] = {0}; |
| 4297 | char interface_name[64] = {0}; |
| 4298 | int ret = 0, len=0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4299 | wifi_band band; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4300 | ULONG channel = 0; |
| 4301 | int centr_channel = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4302 | UINT mode_map = 0; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4303 | int freq=0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4304 | |
| 4305 | if (output_string == NULL) |
| 4306 | return RETURN_ERR; |
| 4307 | |
| 4308 | wifi_getRadioMode(radioIndex, mode_str, &mode_map); |
| 4309 | |
| 4310 | band = wifi_index_to_band(radioIndex); |
| 4311 | if (band == band_invalid) |
| 4312 | return RETURN_ERR; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4313 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 4314 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4315 | |
| 4316 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 4317 | |
| 4318 | snprintf(output_string, 64, "Auto"); |
developer | 23e7128 | 2023-01-18 10:25:19 +0800 | [diff] [blame] | 4319 | if (band == band_2_4 || (!(mode_map&WIFI_MODE_AC) && !(mode_map&WIFI_MODE_AX))) { |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4320 | // 2G band or ac and ax mode is disable, we will check HT_EXTCHA |
| 4321 | snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 4322 | wifi_halgetRadioExtChannel(config_dat_file, output_string); |
developer | 23e7128 | 2023-01-18 10:25:19 +0800 | [diff] [blame] | 4323 | if (!(mode_map&WIFI_MODE_N)) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4324 | snprintf(output_string, 64, "Auto"); |
| 4325 | } else { |
| 4326 | // 5G and 6G band with ac or ax mode. |
| 4327 | wifi_getRadioChannel(radioIndex, &channel); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4328 | snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d ' ' -f9 | tr -d '\\n'", interface_name); |
| 4329 | |
| 4330 | ret = _syscmd(cmd, buf, sizeof(buf)); |
| 4331 | len = strlen(buf); |
| 4332 | if((ret != 0) || (len == 0)) |
| 4333 | { |
| 4334 | WIFI_ENTRY_EXIT_DEBUG("failed with Command %s %s:%d\n",cmd,__func__, __LINE__); |
| 4335 | return RETURN_ERR; |
| 4336 | } |
| 4337 | sscanf(buf, "%d", &freq); |
| 4338 | centr_channel = ieee80211_frequency_to_channel(freq); |
| 4339 | if (centr_channel > (int)channel) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4340 | snprintf(output_string, 64, "AboveControlChannel"); |
| 4341 | else |
| 4342 | snprintf(output_string, 64, "BelowControlChannel"); |
| 4343 | } |
| 4344 | |
| 4345 | return RETURN_OK; |
| 4346 | } |
| 4347 | |
| 4348 | //Set the extension channel. |
| 4349 | INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181 //AP only |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4350 | { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4351 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4352 | struct params params={0}; |
| 4353 | char config_file[64] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4354 | char config_dat_file[64] = {0}; |
| 4355 | char ext_channel[64] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4356 | char buf[128] = {0}; |
| 4357 | char cmd[128] = {0}; |
| 4358 | int max_radio_num =0, ret = 0, bandwidth = 0; |
| 4359 | unsigned long channel = 0, centr_channel = 0; |
| 4360 | bool stbcEnable = FALSE; |
| 4361 | params.name = "ht_capab"; |
| 4362 | wifi_band band; |
| 4363 | |
| 4364 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 4365 | snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file); |
| 4366 | _syscmd(cmd, buf, sizeof(buf)); |
| 4367 | if (strlen(buf) != 0) |
| 4368 | stbcEnable = TRUE; |
| 4369 | if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK) |
| 4370 | return RETURN_ERR; |
| 4371 | bandwidth = strtol(buf, NULL, 10); |
| 4372 | // TDK expected to get error with 20MHz |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4373 | // we handle 20MHz in function wifi_RemoveRadioExtChannel(). |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4374 | if (bandwidth == 20 || strstr(buf, "80+80") != NULL) |
| 4375 | return RETURN_ERR; |
| 4376 | |
| 4377 | band = wifi_index_to_band(radioIndex); |
| 4378 | if (band == band_invalid) |
| 4379 | return RETURN_ERR; |
| 4380 | |
| 4381 | if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) |
| 4382 | return RETURN_ERR; |
| 4383 | |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4384 | snprintf(buf, sizeof(buf), "HT%d", bandwidth); |
| 4385 | ret = util_get_sec_chan_offset(channel, buf); |
| 4386 | if (ret == -EINVAL) |
| 4387 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4388 | |
| 4389 | if(NULL!= strstr(string,"Above")) { |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4390 | if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1)) |
| 4391 | return RETURN_OK; |
| 4392 | strcpy(ext_channel, "Above"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4393 | } else if(NULL!= strstr(string,"Below")) { |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4394 | if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1)) |
| 4395 | return RETURN_OK; |
| 4396 | strcpy(ext_channel, "Below"); |
| 4397 | } else { |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4398 | printf("%s: invalid EXT_CHA:%s\n", __func__, string); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 4399 | return RETURN_ERR; |
| 4400 | } |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4401 | params.name = "HT_EXTCHA"; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4402 | params.value = ext_channel; |
| 4403 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4404 | snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 4405 | wifi_datfileWrite(config_dat_file, ¶ms, 1); |
| 4406 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4407 | wifi_getMaxRadioNumber(&max_radio_num); |
| 4408 | for(int i=0; i<=MAX_APS/max_radio_num; i++) |
| 4409 | { |
| 4410 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex+(max_radio_num*i)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4411 | wifi_setRadioSTBCEnable(radioIndex+(max_radio_num*i), stbcEnable); |
| 4412 | } |
| 4413 | |
| 4414 | //Set to wifi config only. Wait for wifi reset or wifi_pushRadioChannel to apply. |
| 4415 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4416 | return RETURN_OK; |
| 4417 | } |
| 4418 | |
| 4419 | //Get the guard interval value. eg "400nsec" or "800nsec" |
| 4420 | //The output_string is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 4421 | INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string) //Tr181 |
| 4422 | { |
| 4423 | wifi_guard_interval_t GI; |
| 4424 | |
| 4425 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4426 | |
| 4427 | if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR) |
| 4428 | return RETURN_ERR; |
| 4429 | |
| 4430 | if (GI == wifi_guard_interval_400) |
| 4431 | strcpy(output_string, "400nsec"); |
| 4432 | else if (GI == wifi_guard_interval_800) |
| 4433 | strcpy(output_string, "800nsec"); |
| 4434 | else if (GI == wifi_guard_interval_1600) |
| 4435 | strcpy(output_string, "1600nsec"); |
| 4436 | else if (GI == wifi_guard_interval_3200) |
| 4437 | strcpy(output_string, "3200nsec"); |
| 4438 | else |
| 4439 | strcpy(output_string, "Auto"); |
| 4440 | |
| 4441 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4442 | return RETURN_OK; |
| 4443 | } |
| 4444 | |
| 4445 | //Set the guard interval value. |
| 4446 | INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string) //Tr181 |
| 4447 | { |
| 4448 | wifi_guard_interval_t GI; |
| 4449 | int ret = 0; |
| 4450 | |
| 4451 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4452 | |
| 4453 | if (strcmp(string, "400nsec") == 0) |
| 4454 | GI = wifi_guard_interval_400; |
| 4455 | else if (strcmp(string , "800nsec") == 0) |
| 4456 | GI = wifi_guard_interval_800; |
| 4457 | else if (strcmp(string , "1600nsec") == 0) |
| 4458 | GI = wifi_guard_interval_1600; |
| 4459 | else if (strcmp(string , "3200nsec") == 0) |
| 4460 | GI = wifi_guard_interval_3200; |
| 4461 | else |
| 4462 | GI = wifi_guard_interval_auto; |
| 4463 | |
| 4464 | ret = wifi_setGuardInterval(radioIndex, GI); |
| 4465 | |
| 4466 | if (ret == RETURN_ERR) { |
| 4467 | wifi_dbg_printf("%s: wifi_setGuardInterval return error\n", __func__); |
| 4468 | return RETURN_ERR; |
| 4469 | } |
| 4470 | |
| 4471 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4472 | return RETURN_OK; |
| 4473 | } |
| 4474 | |
| 4475 | //Get the Modulation Coding Scheme index, eg: "-1", "1", "15" |
| 4476 | INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181 |
| 4477 | { |
| 4478 | char buf[32]={0}; |
| 4479 | char mcs_file[64] = {0}; |
| 4480 | char cmd[64] = {0}; |
| 4481 | int mode_bitmap = 0; |
| 4482 | |
| 4483 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4484 | if(output_int == NULL) |
| 4485 | return RETURN_ERR; |
| 4486 | snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex); |
| 4487 | |
| 4488 | snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mcs_file); |
| 4489 | _syscmd(cmd, buf, sizeof(buf)); |
| 4490 | if (strlen(buf) > 0) |
| 4491 | *output_int = strtol(buf, NULL, 10); |
| 4492 | else { |
| 4493 | // output the max MCS for the current radio mode |
| 4494 | if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) { |
| 4495 | wifi_dbg_printf("%s: wifi_getradiomode return error.\n", __func__); |
| 4496 | return RETURN_ERR; |
| 4497 | } |
| 4498 | if (mode_bitmap & WIFI_MODE_AX) { |
| 4499 | *output_int = 11; |
| 4500 | } else if (mode_bitmap & WIFI_MODE_AC) { |
| 4501 | *output_int = 9; |
| 4502 | } else if (mode_bitmap & WIFI_MODE_N) { |
| 4503 | *output_int = 7; |
| 4504 | } |
| 4505 | } |
| 4506 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4507 | |
| 4508 | return RETURN_OK; |
| 4509 | } |
| 4510 | |
| 4511 | //Set the Modulation Coding Scheme index |
| 4512 | INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181 |
| 4513 | { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4514 | /*Only HE mode can specify MCS capability. We don't support MCS in HT mode, |
| 4515 | because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4516 | char config_file[64] = {0}; |
| 4517 | char set_value[16] = {0}; |
| 4518 | char mcs_file[32] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4519 | struct params set_config = {0}; |
| 4520 | FILE *f = NULL; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4521 | INT nss = 0; |
| 4522 | int ant_bitmap = 0; |
| 4523 | unsigned short cal_value = 0; |
| 4524 | UCHAR tval = 0, i = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4525 | |
| 4526 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4527 | |
| 4528 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 4529 | |
| 4530 | // -1 means auto |
| 4531 | if (MCS > 15 || MCS < -1) { |
| 4532 | fprintf(stderr, "%s: invalid MCS %d\n", __func__, MCS); |
| 4533 | return RETURN_ERR; |
| 4534 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4535 | wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/ |
| 4536 | for(; ant_bitmap > 0; ant_bitmap >>= 1) |
| 4537 | nss += 1; |
| 4538 | //printf("%s:nss = %d\n", __func__, nss); |
| 4539 | /*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning: |
| 4540 | 0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4541 | if (MCS > 9 || MCS == -1) |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4542 | tval = 2;/*one stream value*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4543 | else if (MCS > 7) |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4544 | tval = 1; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4545 | else |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4546 | tval = 0; |
| 4547 | for (i = 0; i < nss; i++) |
| 4548 | cal_value |= (tval << (2*i)); |
| 4549 | snprintf(set_value, sizeof(set_value), "%x", cal_value); |
| 4550 | WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value); |
| 4551 | set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4552 | set_config.value = set_value; |
| 4553 | |
| 4554 | wifi_hostapdWrite(config_file, &set_config, 1); |
| 4555 | wifi_hostapdProcessUpdate(radioIndex, &set_config, 1); |
| 4556 | |
| 4557 | // For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not. |
| 4558 | snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex); |
| 4559 | f = fopen(mcs_file, "w"); |
| 4560 | if (f == NULL) { |
| 4561 | fprintf(stderr, "%s: fopen failed\n", __func__); |
| 4562 | return RETURN_ERR; |
| 4563 | } |
| 4564 | fprintf(f, "%d", MCS); |
| 4565 | fclose(f); |
| 4566 | |
| 4567 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4568 | return RETURN_OK; |
| 4569 | } |
| 4570 | |
| 4571 | //Get supported Transmit Power list, eg : "0,25,50,75,100" |
| 4572 | //The output_list is a max length 64 octet string that is allocated by the RDKB code. Implementations must ensure that strings are not longer than this. |
| 4573 | INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181 |
| 4574 | { |
| 4575 | if (NULL == output_list) |
| 4576 | return RETURN_ERR; |
| 4577 | snprintf(output_list, 64,"0,25,50,75,100"); |
| 4578 | return RETURN_OK; |
| 4579 | } |
| 4580 | |
| 4581 | //Get current Transmit Power in dBm units. |
| 4582 | //The transmite power level is in units of full power for this radio. |
| 4583 | INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong) //RDKB |
| 4584 | { |
| 4585 | char interface_name[16] = {0}; |
| 4586 | char cmd[128]={0}; |
| 4587 | char buf[16]={0}; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4588 | char pwr_file[128]={0}; |
| 4589 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4590 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4591 | |
| 4592 | if(output_ulong == NULL) |
| 4593 | return RETURN_ERR; |
| 4594 | |
| 4595 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 4596 | return RETURN_ERR; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4597 | /* |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4598 | snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name); |
| 4599 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4600 | *output_ulong = strtol(buf, NULL, 10); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4601 | */ |
| 4602 | snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex); |
| 4603 | snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", pwr_file); |
| 4604 | _syscmd(cmd, buf, sizeof(buf)); |
| 4605 | if (strlen(buf) > 0) |
| 4606 | *output_ulong = strtol(buf, NULL, 10); |
| 4607 | else |
| 4608 | *output_ulong = 100; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4609 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4610 | return RETURN_OK; |
| 4611 | } |
| 4612 | |
| 4613 | //Set Transmit Power |
| 4614 | //The transmite power level is in units of full power for this radio. |
| 4615 | INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower) //RDKB |
| 4616 | { |
| 4617 | char interface_name[16] = {0}; |
| 4618 | char *support; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4619 | char buf[128]={0}; |
| 4620 | char txpower_str[64] = {0}; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4621 | char pwr_file[128]={0}; |
| 4622 | FILE *f = NULL; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4623 | int if_idx, ret = 0; |
| 4624 | struct nl_msg *msg = NULL; |
| 4625 | struct nlattr * msg_data = NULL; |
| 4626 | struct mtk_nl80211_param param; |
| 4627 | struct unl unl_ins; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4628 | |
| 4629 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4630 | |
| 4631 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 4632 | return RETURN_ERR; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4633 | // Get the Tx power supported list and check that is the input in the list |
| 4634 | snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower); |
| 4635 | wifi_getRadioTransmitPowerSupported(radioIndex, buf); |
| 4636 | support = strtok(buf, ","); |
| 4637 | while(true) |
| 4638 | { |
| 4639 | if(support == NULL) { // input not in the list |
| 4640 | wifi_dbg_printf("Input value is invalid.\n"); |
| 4641 | return RETURN_ERR; |
| 4642 | } |
| 4643 | if (strncmp(txpower_str, support, strlen(support)) == 0) { |
| 4644 | break; |
| 4645 | } |
| 4646 | support = strtok(NULL, ","); |
| 4647 | } |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4648 | |
| 4649 | if_idx = if_nametoindex(interface_name); |
| 4650 | /*init mtk nl80211 vendor cmd*/ |
| 4651 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER; |
| 4652 | param.if_type = NL80211_ATTR_IFINDEX; |
| 4653 | param.if_idx = if_idx; |
| 4654 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 4655 | if (ret) { |
| 4656 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 4657 | return RETURN_ERR; |
| 4658 | } |
| 4659 | /*add mtk vendor cmd data*/ |
| 4660 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) { |
| 4661 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 4662 | nlmsg_free(msg); |
| 4663 | goto err; |
| 4664 | } |
| 4665 | |
| 4666 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) { |
| 4667 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 4668 | nlmsg_free(msg); |
| 4669 | goto err; |
| 4670 | } |
| 4671 | |
| 4672 | /*send mtk nl80211 vendor msg*/ |
| 4673 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 4674 | if (ret) { |
| 4675 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 4676 | goto err; |
| 4677 | } |
| 4678 | /*deinit mtk nl80211 vendor msg*/ |
| 4679 | mtk_nl80211_deint(&unl_ins); |
| 4680 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
| 4681 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4682 | snprintf(pwr_file, sizeof(pwr_file), "%s%d.txt", POWER_PERCENTAGE, radioIndex); |
| 4683 | f = fopen(pwr_file, "w"); |
| 4684 | if (f == NULL) { |
| 4685 | fprintf(stderr, "%s: fopen failed\n", __func__); |
| 4686 | return RETURN_ERR; |
| 4687 | } |
| 4688 | fprintf(f, "%d", TransmitPower); |
| 4689 | fclose(f); |
| 4690 | /* snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4691 | _syscmd(cmd, buf, sizeof(buf)); |
| 4692 | maximum_tx = strtol(buf, NULL, 10); |
| 4693 | |
| 4694 | // Get the Tx power supported list and check that is the input in the list |
| 4695 | snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower); |
| 4696 | wifi_getRadioTransmitPowerSupported(radioIndex, buf); |
| 4697 | support = strtok(buf, ","); |
| 4698 | while(true) |
| 4699 | { |
| 4700 | if(support == NULL) { // input not in the list |
| 4701 | wifi_dbg_printf("Input value is invalid.\n"); |
| 4702 | return RETURN_ERR; |
| 4703 | } |
| 4704 | if (strncmp(txpower_str, support, strlen(support)) == 0) { |
| 4705 | break; |
| 4706 | } |
| 4707 | support = strtok(NULL, ","); |
| 4708 | } |
| 4709 | txpower = TransmitPower*maximum_tx/100; |
| 4710 | phyId = radio_index_to_phy(radioIndex); |
| 4711 | snprintf(cmd, sizeof(cmd), "iw phy phy%d set txpower fixed %d00", phyId, txpower); |
| 4712 | _syscmd(cmd, buf, sizeof(buf)); |
| 4713 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 4714 | */ |
| 4715 | return RETURN_OK; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 4716 | err: |
| 4717 | mtk_nl80211_deint(&unl_ins); |
| 4718 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 4719 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4720 | } |
| 4721 | |
| 4722 | //get 80211h Supported. 80211h solves interference with satellites and radar using the same 5 GHz frequency band |
| 4723 | INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported) //Tr181 |
| 4724 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4725 | if (NULL == Supported) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4726 | return RETURN_ERR; |
| 4727 | *Supported = TRUE; |
| 4728 | |
| 4729 | return RETURN_OK; |
| 4730 | } |
| 4731 | |
| 4732 | //Get 80211h feature enable |
| 4733 | INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181 |
| 4734 | { |
| 4735 | char buf[64]={'\0'}; |
| 4736 | char config_file[64] = {'\0'}; |
| 4737 | |
| 4738 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4739 | if(enable == NULL) |
| 4740 | return RETURN_ERR; |
| 4741 | |
| 4742 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4743 | /* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */ |
| 4744 | wifi_datfileRead(config_file, "IEEE80211H", buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4745 | |
| 4746 | if (strncmp(buf, "1", 1) == 0) |
| 4747 | *enable = TRUE; |
| 4748 | else |
| 4749 | *enable = FALSE; |
| 4750 | |
| 4751 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4752 | return RETURN_OK; |
| 4753 | } |
| 4754 | |
| 4755 | //Set 80211h feature enable |
| 4756 | INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable) //Tr181 |
| 4757 | { |
| 4758 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4759 | struct params params={'\0'}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4760 | struct params dat={0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4761 | char config_file[MAX_BUF_SIZE] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4762 | char config_dat_file[MAX_BUF_SIZE] = {0}; |
| 4763 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4764 | |
| 4765 | params.name = "ieee80211h"; |
| 4766 | |
| 4767 | if (enable) { |
| 4768 | params.value = "1"; |
| 4769 | } else { |
| 4770 | params.value = "0"; |
| 4771 | } |
| 4772 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4773 | dat.name = "IEEE80211H"; |
| 4774 | dat.value = params.value; |
| 4775 | |
| 4776 | band = wifi_index_to_band(radioIndex); |
| 4777 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 4778 | snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4779 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 4780 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 4781 | wifi_datfileWrite(config_dat_file, &dat, 1); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4782 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 4783 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4784 | return RETURN_OK; |
| 4785 | } |
| 4786 | |
| 4787 | //Indicates the Carrier Sense ranges supported by the radio. It is measured in dBm. Refer section A.2.3.2 of CableLabs Wi-Fi MGMT Specification. |
| 4788 | INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output) //P3 |
| 4789 | { |
| 4790 | if (NULL == output) |
| 4791 | return RETURN_ERR; |
| 4792 | *output=100; |
| 4793 | |
| 4794 | return RETURN_OK; |
| 4795 | } |
| 4796 | |
| 4797 | //The RSSI signal level at which CS/CCA detects a busy condition. This attribute enables APs to increase minimum sensitivity to avoid detecting busy condition from multiple/weak Wi-Fi sources in dense Wi-Fi environments. It is measured in dBm. Refer section A.2.3.2 of CableLabs Wi-Fi MGMT Specification. |
| 4798 | INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output) //P3 |
| 4799 | { |
| 4800 | if (NULL == output) |
| 4801 | return RETURN_ERR; |
| 4802 | *output = -99; |
| 4803 | |
| 4804 | return RETURN_OK; |
| 4805 | } |
| 4806 | |
| 4807 | INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold) //P3 |
| 4808 | { |
| 4809 | return RETURN_ERR; |
| 4810 | } |
| 4811 | |
| 4812 | |
| 4813 | //Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012]. |
| 4814 | INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output) |
| 4815 | { |
| 4816 | char interface_name[16] = {0}; |
| 4817 | char cmd[MAX_BUF_SIZE]={'\0'}; |
| 4818 | char buf[MAX_CMD_SIZE]={'\0'}; |
| 4819 | |
| 4820 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4821 | if(output == NULL) |
| 4822 | return RETURN_ERR; |
| 4823 | |
| 4824 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 4825 | return RETURN_ERR; |
| 4826 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name); |
| 4827 | _syscmd(cmd, buf, sizeof(buf)); |
| 4828 | *output = atoi(buf); |
| 4829 | |
| 4830 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4831 | return RETURN_OK; |
| 4832 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4833 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4834 | INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod) |
| 4835 | { |
| 4836 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4837 | struct params params={'\0'}; |
| 4838 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 4839 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 4840 | |
| 4841 | if (BeaconPeriod < 15 || BeaconPeriod > 65535) |
| 4842 | return RETURN_ERR; |
| 4843 | |
| 4844 | params.name = "beacon_int"; |
| 4845 | snprintf(buf, sizeof(buf), "%u", BeaconPeriod); |
| 4846 | params.value = buf; |
| 4847 | |
| 4848 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 4849 | wifi_hostapdWrite(config_file, ¶ms, 1); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4850 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4851 | wifi_hostapdProcessUpdate(radioIndex, ¶ms, 1); |
| 4852 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4853 | return RETURN_OK; |
| 4854 | } |
| 4855 | |
| 4856 | //Comma-separated list of strings. The set of data rates, in Mbps, that have to be supported by all stations that desire to join this BSS. The stations have to be able to receive and transmit at each of the data rates listed inBasicDataTransmitRates. For example, a value of "1,2", indicates that stations support 1 Mbps and 2 Mbps. Most control packets use a data rate in BasicDataTransmitRates. |
| 4857 | INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output) |
| 4858 | { |
| 4859 | //TODO: need to revisit below implementation |
| 4860 | char *temp; |
| 4861 | char temp_output[128] = {0}; |
| 4862 | char temp_TransmitRates[64] = {0}; |
| 4863 | char config_file[64] = {0}; |
| 4864 | |
| 4865 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4866 | if (NULL == output) |
| 4867 | return RETURN_ERR; |
| 4868 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
| 4869 | wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 4870 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 4871 | if (strlen(temp_TransmitRates) == 0) { // config not set, use supported rate |
| 4872 | wifi_getRadioSupportedDataTransmitRates(radioIndex, output); |
| 4873 | } else { |
| 4874 | temp = strtok(temp_TransmitRates," "); |
| 4875 | while(temp!=NULL) |
| 4876 | { |
| 4877 | // Convert 100 kbps to Mbps |
| 4878 | temp[strlen(temp)-1]=0; |
| 4879 | if((temp[0]=='5') && (temp[1]=='\0')) |
| 4880 | { |
| 4881 | temp="5.5"; |
| 4882 | } |
| 4883 | strcat(temp_output,temp); |
| 4884 | temp = strtok(NULL," "); |
| 4885 | if(temp!=NULL) |
| 4886 | { |
| 4887 | strcat(temp_output,","); |
| 4888 | } |
| 4889 | } |
| 4890 | strcpy(output,temp_output); |
| 4891 | } |
| 4892 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4893 | return RETURN_OK; |
| 4894 | } |
| 4895 | |
| 4896 | INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates) |
| 4897 | { |
| 4898 | char *temp; |
| 4899 | char temp1[128]; |
| 4900 | char temp_output[128]; |
| 4901 | char temp_TransmitRates[128]; |
| 4902 | char set[128]; |
| 4903 | char sub_set[128]; |
| 4904 | int set_count=0,subset_count=0; |
| 4905 | int set_index=0,subset_index=0; |
| 4906 | char *token; |
| 4907 | int flag=0, i=0; |
| 4908 | struct params params={'\0'}; |
| 4909 | char config_file[MAX_BUF_SIZE] = {0}; |
| 4910 | wifi_band band = wifi_index_to_band(radioIndex); |
| 4911 | |
| 4912 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 4913 | if(NULL == TransmitRates) |
| 4914 | return RETURN_ERR; |
| 4915 | strcpy(sub_set,TransmitRates); |
| 4916 | |
| 4917 | //Allow only supported Data transmit rate to be set |
| 4918 | wifi_getRadioSupportedDataTransmitRates(radioIndex,set); |
| 4919 | token = strtok(sub_set,","); |
| 4920 | while( token != NULL ) /* split the basic rate to be set, by comma */ |
| 4921 | { |
| 4922 | sub_set[subset_count]=atoi(token); |
| 4923 | subset_count++; |
| 4924 | token=strtok(NULL,","); |
| 4925 | } |
| 4926 | token=strtok(set,","); |
| 4927 | while(token!=NULL) /* split the supported rate by comma */ |
| 4928 | { |
| 4929 | set[set_count]=atoi(token); |
| 4930 | set_count++; |
| 4931 | token=strtok(NULL,","); |
| 4932 | } |
| 4933 | for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */ |
| 4934 | { |
| 4935 | for(set_index=0;set_index < set_count;set_index++) |
| 4936 | { |
| 4937 | flag=0; |
| 4938 | if(sub_set[subset_index]==set[set_index]) |
| 4939 | break; |
| 4940 | else |
| 4941 | flag=1; /* No match found */ |
| 4942 | } |
| 4943 | if(flag==1) |
| 4944 | return RETURN_ERR; //If value not found return Error |
| 4945 | } |
| 4946 | strcpy(temp_TransmitRates,TransmitRates); |
| 4947 | |
| 4948 | for(i=0;i<strlen(temp_TransmitRates);i++) |
| 4949 | { |
| 4950 | //if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32)) |
| 4951 | if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==',')) |
| 4952 | { |
| 4953 | continue; |
| 4954 | } |
| 4955 | else |
| 4956 | { |
| 4957 | return RETURN_ERR; |
| 4958 | } |
| 4959 | } |
| 4960 | strcpy(temp_output,""); |
| 4961 | temp = strtok(temp_TransmitRates,","); |
| 4962 | while(temp!=NULL) |
| 4963 | { |
| 4964 | strcpy(temp1,temp); |
| 4965 | if(band == band_5) |
| 4966 | { |
| 4967 | if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0)) |
| 4968 | { |
| 4969 | return RETURN_ERR; |
| 4970 | } |
| 4971 | } |
| 4972 | |
| 4973 | if(strcmp(temp,"5.5")==0) |
| 4974 | { |
| 4975 | strcpy(temp1,"55"); |
| 4976 | } |
| 4977 | else |
| 4978 | { |
| 4979 | strcat(temp1,"0"); |
| 4980 | } |
| 4981 | strcat(temp_output,temp1); |
| 4982 | temp = strtok(NULL,","); |
| 4983 | if(temp!=NULL) |
| 4984 | { |
| 4985 | strcat(temp_output," "); |
| 4986 | } |
| 4987 | } |
| 4988 | strcpy(TransmitRates,temp_output); |
| 4989 | |
| 4990 | params.name= "basic_rates"; |
| 4991 | params.value =TransmitRates; |
| 4992 | |
| 4993 | wifi_dbg_printf("\n%s:",__func__); |
| 4994 | wifi_dbg_printf("\nparams.value=%s\n",params.value); |
| 4995 | wifi_dbg_printf("\n******************Transmit rates=%s\n",TransmitRates); |
| 4996 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,radioIndex); |
| 4997 | wifi_hostapdWrite(config_file,¶ms,1); |
| 4998 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 4999 | return RETURN_OK; |
| 5000 | } |
| 5001 | |
| 5002 | //passing the hostapd configuration file and get the virtual interface of xfinity(2g) |
| 5003 | INT wifi_GetInterfaceName_virtualInterfaceName_2G(char interface_name[50]) |
| 5004 | { |
| 5005 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 5006 | FILE *fp = NULL; |
| 5007 | char path[256] = {0}, output_string[256] = {0}; |
| 5008 | int count = 0; |
| 5009 | char *interface = NULL; |
| 5010 | |
| 5011 | fp = popen("cat /nvram/hostapd0.conf | grep -w bss", "r"); |
| 5012 | if (fp == NULL) |
| 5013 | { |
| 5014 | printf("Failed to run command in Function %s\n", __FUNCTION__); |
| 5015 | return RETURN_ERR; |
| 5016 | } |
| 5017 | if (fgets(path, sizeof(path) - 1, fp) != NULL) |
| 5018 | { |
| 5019 | interface = strchr(path, '='); |
| 5020 | |
| 5021 | if (interface != NULL) |
| 5022 | { |
| 5023 | strcpy(output_string, interface + 1); |
| 5024 | for (count = 0; output_string[count] != '\n' || output_string[count] != '\0'; count++) |
| 5025 | interface_name[count] = output_string[count]; |
| 5026 | |
| 5027 | interface_name[count] = '\0'; |
| 5028 | } |
| 5029 | } |
| 5030 | pclose(fp); |
| 5031 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 5032 | return RETURN_OK; |
| 5033 | } |
| 5034 | |
| 5035 | INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct) |
| 5036 | { |
| 5037 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 5038 | output_struct->radio_BytesSent = 0; |
| 5039 | output_struct->radio_BytesReceived = 0; |
| 5040 | output_struct->radio_PacketsSent = 0; |
| 5041 | output_struct->radio_PacketsReceived = 0; |
| 5042 | output_struct->radio_ErrorsSent = 0; |
| 5043 | output_struct->radio_ErrorsReceived = 0; |
| 5044 | output_struct->radio_DiscardPacketsSent = 0; |
| 5045 | output_struct->radio_DiscardPacketsReceived = 0; |
| 5046 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 5047 | return RETURN_OK; |
| 5048 | } |
| 5049 | |
| 5050 | |
| 5051 | INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats) |
| 5052 | { |
| 5053 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 5054 | CHAR buf[MAX_CMD_SIZE] = {0}; |
| 5055 | CHAR Value[MAX_BUF_SIZE] = {0}; |
| 5056 | FILE *fp = NULL; |
| 5057 | |
| 5058 | if (ifname == NULL || strlen(ifname) <= 1) |
| 5059 | return RETURN_OK; |
| 5060 | |
| 5061 | snprintf(buf, sizeof(buf), "ifconfig -a %s > /tmp/Radio_Stats.txt", ifname); |
| 5062 | system(buf); |
| 5063 | |
| 5064 | fp = fopen("/tmp/Radio_Stats.txt", "r"); |
| 5065 | if(fp == NULL) |
| 5066 | { |
| 5067 | printf("/tmp/Radio_Stats.txt not exists \n"); |
| 5068 | return RETURN_ERR; |
| 5069 | } |
| 5070 | fclose(fp); |
| 5071 | |
| 5072 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 5073 | File_Reading(buf, Value); |
| 5074 | pStats->radio_PacketsReceived = strtoul(Value, NULL, 10); |
| 5075 | |
| 5076 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 5077 | File_Reading(buf, Value); |
| 5078 | pStats->radio_PacketsSent = strtoul(Value, NULL, 10); |
| 5079 | |
| 5080 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 5081 | File_Reading(buf, Value); |
| 5082 | pStats->radio_BytesReceived = strtoul(Value, NULL, 10); |
| 5083 | |
| 5084 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 5085 | File_Reading(buf, Value); |
| 5086 | pStats->radio_BytesSent = strtoul(Value, NULL, 10); |
| 5087 | |
| 5088 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 5089 | File_Reading(buf, Value); |
| 5090 | pStats->radio_ErrorsReceived = strtoul(Value, NULL, 10); |
| 5091 | |
| 5092 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 5093 | File_Reading(buf, Value); |
| 5094 | pStats->radio_ErrorsSent = strtoul(Value, NULL, 10); |
| 5095 | |
| 5096 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 5097 | File_Reading(buf, Value); |
| 5098 | pStats->radio_DiscardPacketsReceived = strtoul(Value, NULL, 10); |
| 5099 | |
| 5100 | sprintf(buf, "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 5101 | File_Reading(buf, Value); |
| 5102 | pStats->radio_DiscardPacketsSent = strtoul(Value, NULL, 10); |
| 5103 | |
| 5104 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 5105 | return RETURN_OK; |
| 5106 | } |
| 5107 | |
| 5108 | INT GetIfacestatus(CHAR *interface_name, CHAR *status) |
| 5109 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 5110 | CHAR buf[MAX_CMD_SIZE] = {0}; |
| 5111 | INT count = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5112 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 5113 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 5114 | |
| 5115 | if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) { |
| 5116 | sprintf(buf, "%s%s%s%s%s", "ifconfig -a ", interface_name, " | grep ", interface_name, " | wc -l"); |
| 5117 | File_Reading(buf, status); |
| 5118 | } |
| 5119 | |
| 5120 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 5121 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5122 | } |
| 5123 | |
| 5124 | //Get detail radio traffic static info |
| 5125 | INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181 |
| 5126 | { |
| 5127 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5128 | #if 0 |
| 5129 | //ifconfig radio_x |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5130 | output_struct->radio_BytesSent=250; //The total number of bytes transmitted out of the interface, including framing characters. |
| 5131 | output_struct->radio_BytesReceived=168; //The total number of bytes received on the interface, including framing characters. |
| 5132 | output_struct->radio_PacketsSent=25; //The total number of packets transmitted out of the interface. |
| 5133 | output_struct->radio_PacketsReceived=20; //The total number of packets received on the interface. |
| 5134 | |
| 5135 | output_struct->radio_ErrorsSent=0; //The total number of outbound packets that could not be transmitted because of errors. |
| 5136 | output_struct->radio_ErrorsReceived=0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol. |
| 5137 | output_struct->radio_DiscardPacketsSent=0; //The total number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space. |
| 5138 | output_struct->radio_DiscardPacketsReceived=0; //The total number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being delivered. One possible reason for discarding such a packet could be to free up buffer space. |
| 5139 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5140 | output_struct->radio_PLCPErrorCount=0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5141 | output_struct->radio_FCSErrorCount=0; //The number of packets that were received with a detected FCS error. This parameter is based on dot11FCSErrorCount from [Annex C/802.11-2012]. |
| 5142 | output_struct->radio_InvalidMACCount=0; //The number of packets that were received with a detected invalid MAC header error. |
| 5143 | output_struct->radio_PacketsOtherReceived=0; //The number of packets that were received, but which were destined for a MAC address that is not associated with this interface. |
| 5144 | output_struct->radio_NoiseFloor=-99; //The noise floor for this radio channel where a recoverable signal can be obtained. Expressed as a signed integer in the range (-110:0). Measurement should capture all energy (in dBm) from sources other than Wi-Fi devices as well as interference from Wi-Fi devices too weak to be decoded. Measured in dBm |
| 5145 | output_struct->radio_ChannelUtilization=35; //Percentage of time the channel was occupied by the radios own activity (Activity Factor) or the activity of other radios. Channel utilization MUST cover all user traffic, management traffic, and time the radio was unavailable for CSMA activities, including DIFS intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage |
| 5146 | output_struct->radio_ActivityFactor=2; //Percentage of time that the radio was transmitting or receiving Wi-Fi packets to/from associated clients. Activity factor MUST include all traffic that deals with communication between the radio and clients associated to the radio as well as management overhead for the radio, including NAV timers, beacons, probe responses,time for receiving devices to send an ACK, SIFC intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage |
| 5147 | output_struct->radio_CarrierSenseThreshold_Exceeded=20; //Percentage of time that the radio was unable to transmit or receive Wi-Fi packets to/from associated clients due to energy detection (ED) on the channel or clear channel assessment (CCA). The metric is calculated and updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage |
| 5148 | output_struct->radio_RetransmissionMetirc=0; //Percentage of packets that had to be re-transmitted. Multiple re-transmissions of the same packet count as one. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in percentage |
| 5149 | |
| 5150 | output_struct->radio_MaximumNoiseFloorOnChannel=-1; //Maximum Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm |
| 5151 | output_struct->radio_MinimumNoiseFloorOnChannel=-1; //Minimum Noise on the channel. The metric is updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm |
| 5152 | output_struct->radio_MedianNoiseFloorOnChannel=-1; //Median Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm |
| 5153 | output_struct->radio_StatisticsStartTime=0; //The date and time at which the collection of the current set of statistics started. This time must be updated whenever the radio statistics are reset. |
| 5154 | |
| 5155 | return RETURN_OK; |
| 5156 | #endif |
| 5157 | |
| 5158 | CHAR interface_name[64] = {0}; |
| 5159 | BOOL iface_status = FALSE; |
| 5160 | wifi_radioTrafficStats2_t radioTrafficStats = {0}; |
| 5161 | |
| 5162 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 5163 | if (NULL == output_struct) |
| 5164 | return RETURN_ERR; |
| 5165 | |
| 5166 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 5167 | return RETURN_ERR; |
| 5168 | |
| 5169 | wifi_getApEnable(radioIndex, &iface_status); |
| 5170 | |
| 5171 | if (iface_status == TRUE) |
| 5172 | wifi_halGetIfStats(interface_name, &radioTrafficStats); |
| 5173 | else |
| 5174 | wifi_halGetIfStatsNull(&radioTrafficStats); // just set some transmission statistic value to 0 |
| 5175 | |
| 5176 | output_struct->radio_BytesSent = radioTrafficStats.radio_BytesSent; |
| 5177 | output_struct->radio_BytesReceived = radioTrafficStats.radio_BytesReceived; |
| 5178 | output_struct->radio_PacketsSent = radioTrafficStats.radio_PacketsSent; |
| 5179 | output_struct->radio_PacketsReceived = radioTrafficStats.radio_PacketsReceived; |
| 5180 | output_struct->radio_ErrorsSent = radioTrafficStats.radio_ErrorsSent; |
| 5181 | output_struct->radio_ErrorsReceived = radioTrafficStats.radio_ErrorsReceived; |
| 5182 | output_struct->radio_DiscardPacketsSent = radioTrafficStats.radio_DiscardPacketsSent; |
| 5183 | output_struct->radio_DiscardPacketsReceived = radioTrafficStats.radio_DiscardPacketsReceived; |
| 5184 | |
| 5185 | output_struct->radio_PLCPErrorCount = 0; //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error. |
| 5186 | output_struct->radio_FCSErrorCount = 0; //The number of packets that were received with a detected FCS error. This parameter is based on dot11FCSErrorCount from [Annex C/802.11-2012]. |
| 5187 | output_struct->radio_InvalidMACCount = 0; //The number of packets that were received with a detected invalid MAC header error. |
| 5188 | output_struct->radio_PacketsOtherReceived = 0; //The number of packets that were received, but which were destined for a MAC address that is not associated with this interface. |
| 5189 | output_struct->radio_NoiseFloor = -99; //The noise floor for this radio channel where a recoverable signal can be obtained. Expressed as a signed integer in the range (-110:0). Measurement should capture all energy (in dBm) from sources other than Wi-Fi devices as well as interference from Wi-Fi devices too weak to be decoded. Measured in dBm |
| 5190 | output_struct->radio_ChannelUtilization = 35; //Percentage of time the channel was occupied by the radio\92s own activity (Activity Factor) or the activity of other radios. Channel utilization MUST cover all user traffic, management traffic, and time the radio was unavailable for CSMA activities, including DIFS intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage |
| 5191 | output_struct->radio_ActivityFactor = 2; //Percentage of time that the radio was transmitting or receiving Wi-Fi packets to/from associated clients. Activity factor MUST include all traffic that deals with communication between the radio and clients associated to the radio as well as management overhead for the radio, including NAV timers, beacons, probe responses,time for receiving devices to send an ACK, SIFC intervals, etc. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage |
| 5192 | output_struct->radio_CarrierSenseThreshold_Exceeded = 20; //Percentage of time that the radio was unable to transmit or receive Wi-Fi packets to/from associated clients due to energy detection (ED) on the channel or clear channel assessment (CCA). The metric is calculated and updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in Percentage |
| 5193 | output_struct->radio_RetransmissionMetirc = 0; //Percentage of packets that had to be re-transmitted. Multiple re-transmissions of the same packet count as one. The metric is calculated and updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected from the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in percentage |
| 5194 | |
| 5195 | output_struct->radio_MaximumNoiseFloorOnChannel = -1; //Maximum Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm |
| 5196 | output_struct->radio_MinimumNoiseFloorOnChannel = -1; //Minimum Noise on the channel. The metric is updated in this Parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm |
| 5197 | output_struct->radio_MedianNoiseFloorOnChannel = -1; //Median Noise on the channel during the measuring interval. The metric is updated in this parameter at the end of the interval defined by "Radio Statistics Measuring Interval". The calculation of this metric MUST only use the data collected in the just completed interval. If this metric is queried before it has been updated with an initial calculation, it MUST return -1. Units in dBm |
| 5198 | output_struct->radio_StatisticsStartTime = 0; //The date and time at which the collection of the current set of statistics started. This time must be updated whenever the radio statistics are reset. |
| 5199 | |
| 5200 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 5201 | |
| 5202 | return RETURN_OK; |
| 5203 | } |
| 5204 | |
| 5205 | //Set radio traffic static Measureing rules |
| 5206 | INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181 |
| 5207 | { |
| 5208 | //zqiu: If the RadioTrafficStats process running, and the new value is different from old value, the process needs to be reset. The Statistics date, such as MaximumNoiseFloorOnChannel, MinimumNoiseFloorOnChannel and MedianNoiseFloorOnChannel need to be reset. And the "StatisticsStartTime" must be reset to the current time. Units in Seconds |
| 5209 | // Else, save the MeasuringRate and MeasuringInterval for future usage |
| 5210 | |
| 5211 | return RETURN_OK; |
| 5212 | } |
| 5213 | |
| 5214 | //To start or stop RadioTrafficStats |
| 5215 | INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable) |
| 5216 | { |
| 5217 | //zqiu: If the RadioTrafficStats process running |
| 5218 | // if(enable) |
| 5219 | // return RETURN_OK. |
| 5220 | // else |
| 5221 | // Stop RadioTrafficStats process |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5222 | // Else |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5223 | // if(enable) |
| 5224 | // Start RadioTrafficStats process with MeasuringRate and MeasuringInterval, and reset "StatisticsStartTime" to the current time, Units in Seconds |
| 5225 | // else |
| 5226 | // return RETURN_OK. |
| 5227 | |
| 5228 | return RETURN_OK; |
| 5229 | } |
| 5230 | |
| 5231 | //Clients associated with the AP over a specific interval. The histogram MUST have a range from -110to 0 dBm and MUST be divided in bins of 3 dBM, with bins aligning on the -110 dBm end of the range. Received signal levels equal to or greater than the smaller boundary of a bin and less than the larger boundary are included in the respective bin. The bin associated with the client?s current received signal level MUST be incremented when a client associates with the AP. Additionally, the respective bins associated with each connected client?s current received signal level MUST be incremented at the interval defined by "Radio Statistics Measuring Rate". The histogram?s bins MUST NOT be incremented at any other time. The histogram data collected during the interval MUST be published to the parameter only at the end of the interval defined by "Radio Statistics Measuring Interval". The underlying histogram data MUST be cleared at the start of each interval defined by "Radio Statistics Measuring Interval?. If any of the parameter's representing this histogram is queried before the histogram has been updated with an initial set of data, it MUST return -1. Units dBm |
| 5232 | INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181 |
| 5233 | { |
| 5234 | //zqiu: Please ignor signalIndex. |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5235 | if (NULL == SignalLevel) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5236 | return RETURN_ERR; |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 5237 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5238 | *SignalLevel=(radioIndex==0)?-19:-19; |
| 5239 | |
| 5240 | return RETURN_OK; |
| 5241 | } |
| 5242 | |
| 5243 | //Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0) |
| 5244 | INT wifi_applyRadioSettings(INT radioIndex) |
| 5245 | { |
| 5246 | return RETURN_OK; |
| 5247 | } |
| 5248 | |
| 5249 | //Get the radio index assocated with this SSID entry |
| 5250 | INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex) |
| 5251 | { |
| 5252 | if(NULL == radioIndex) |
| 5253 | return RETURN_ERR; |
| 5254 | int max_radio_num = 0; |
| 5255 | wifi_getMaxRadioNumber(&max_radio_num); |
| 5256 | *radioIndex = ssidIndex%max_radio_num; |
| 5257 | return RETURN_OK; |
| 5258 | } |
| 5259 | |
| 5260 | //Device.WiFi.SSID.{i}.Enable |
| 5261 | //Get SSID enable configuration parameters (not the SSID enable status) |
| 5262 | INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181 |
| 5263 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5264 | if (NULL == output_bool) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5265 | return RETURN_ERR; |
| 5266 | |
| 5267 | return wifi_getApEnable(ssidIndex, output_bool); |
| 5268 | } |
| 5269 | |
| 5270 | //Device.WiFi.SSID.{i}.Enable |
| 5271 | //Set SSID enable configuration parameters |
| 5272 | INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181 |
| 5273 | { |
| 5274 | return wifi_setApEnable(ssidIndex, enable); |
| 5275 | } |
| 5276 | |
| 5277 | //Device.WiFi.SSID.{i}.Status |
| 5278 | //Get the SSID enable status |
| 5279 | INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181 |
| 5280 | { |
| 5281 | char cmd[MAX_CMD_SIZE]={0}; |
| 5282 | char buf[MAX_BUF_SIZE]={0}; |
| 5283 | BOOL output_bool; |
| 5284 | |
| 5285 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5286 | if (NULL == output_string) |
| 5287 | return RETURN_ERR; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5288 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5289 | wifi_getApEnable(ssidIndex,&output_bool); |
| 5290 | snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled"); |
| 5291 | |
| 5292 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5293 | return RETURN_OK; |
| 5294 | } |
| 5295 | |
| 5296 | // Outputs a 32 byte or less string indicating the SSID name. Sring buffer must be preallocated by the caller. |
| 5297 | INT wifi_getSSIDName(INT apIndex, CHAR *output) |
| 5298 | { |
| 5299 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5300 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5301 | if (NULL == output) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5302 | return RETURN_ERR; |
| 5303 | |
| 5304 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5305 | wifi_hostapdRead(config_file,"ssid",output,32); |
| 5306 | |
| 5307 | wifi_dbg_printf("\n[%s]: SSID Name is : %s",__func__,output); |
| 5308 | return RETURN_OK; |
| 5309 | } |
| 5310 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5311 | // Set a max 32 byte string and sets an internal variable to the SSID name |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5312 | INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string) |
| 5313 | { |
| 5314 | char str[MAX_BUF_SIZE]={'\0'}; |
| 5315 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 5316 | struct params params; |
| 5317 | char config_file[MAX_BUF_SIZE] = {0}; |
| 5318 | |
| 5319 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5320 | if(NULL == ssid_string || strlen(ssid_string) >= 32 || strlen(ssid_string) == 0 ) |
| 5321 | return RETURN_ERR; |
| 5322 | |
| 5323 | params.name = "ssid"; |
| 5324 | params.value = ssid_string; |
| 5325 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 5326 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 5327 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 5328 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5329 | |
| 5330 | return RETURN_OK; |
| 5331 | } |
| 5332 | |
| 5333 | //Get the BSSID |
| 5334 | INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string) //RDKB |
| 5335 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 5336 | char cmd[MAX_CMD_SIZE] = {0}; |
| 5337 | char inf_name[IF_NAME_SIZE] = {0}; |
| 5338 | char conf_file[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5339 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 5340 | if (!output_string) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5341 | return RETURN_ERR; |
| 5342 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 5343 | if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK) |
| 5344 | return RETURN_ERR; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 5345 | |
developer | 5b2f10c | 2023-05-25 17:02:21 +0800 | [diff] [blame] | 5346 | if (ssidIndex < 0 || ssidIndex > MAX_APS) { |
| 5347 | wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex); |
| 5348 | strncpy(output_string, "\0", 1); |
| 5349 | return RETURN_ERR; |
| 5350 | } |
| 5351 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name); |
| 5352 | _syscmd(cmd, output_string, 64); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 5353 | |
developer | 5b2f10c | 2023-05-25 17:02:21 +0800 | [diff] [blame] | 5354 | /* if hostapd does not control interface even if this interface has been brought up, |
| 5355 | * try to get its mac address by iw command. |
| 5356 | */ |
| 5357 | if(strlen(output_string) == 0) { |
| 5358 | memset(cmd, 0, sizeof(cmd)); |
| 5359 | snprintf(cmd, sizeof(cmd), "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name); |
| 5360 | _syscmd(cmd, output_string, 64); |
| 5361 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5362 | |
developer | 5b2f10c | 2023-05-25 17:02:21 +0800 | [diff] [blame] | 5363 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5364 | } |
| 5365 | |
| 5366 | //Get the MAC address associated with this Wifi SSID |
| 5367 | INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181 |
| 5368 | { |
| 5369 | wifi_getBaseBSSID(ssidIndex,output_string); |
| 5370 | return RETURN_OK; |
| 5371 | } |
| 5372 | |
| 5373 | //Get the basic SSID traffic static info |
| 5374 | //Apply SSID and AP (in the case of Acess Point devices) to the hardware |
| 5375 | //Not all implementations may need this function. If not needed for a particular implementation simply return no-error (0) |
| 5376 | INT wifi_applySSIDSettings(INT ssidIndex) |
| 5377 | { |
| 5378 | char interface_name[16] = {0}; |
| 5379 | BOOL status = false; |
| 5380 | char cmd[MAX_CMD_SIZE] = {0}; |
| 5381 | char buf[MAX_CMD_SIZE] = {0}; |
| 5382 | int apIndex, ret; |
| 5383 | int max_radio_num = 0; |
| 5384 | int radioIndex = 0; |
| 5385 | |
| 5386 | wifi_getMaxRadioNumber(&max_radio_num); |
| 5387 | |
| 5388 | radioIndex = ssidIndex % max_radio_num; |
| 5389 | |
| 5390 | wifi_getApEnable(ssidIndex,&status); |
| 5391 | // Do not apply when ssid index is disabled |
| 5392 | if (status == false) |
| 5393 | return RETURN_OK; |
| 5394 | |
| 5395 | /* Doing full remove and add for ssid Index |
| 5396 | * Not all hostapd options are supported with reload |
| 5397 | * for example macaddr_acl |
| 5398 | */ |
| 5399 | if(wifi_setApEnable(ssidIndex,false) != RETURN_OK) |
| 5400 | return RETURN_ERR; |
| 5401 | |
| 5402 | ret = wifi_setApEnable(ssidIndex,true); |
| 5403 | |
| 5404 | /* Workaround for hostapd issue with multiple bss definitions |
| 5405 | * when first created interface will be removed |
| 5406 | * then all vaps other vaps on same phy are removed |
| 5407 | * after calling setApEnable to false readd all enabled vaps */ |
| 5408 | for(int i=0; i < MAX_APS/max_radio_num; i++) { |
| 5409 | apIndex = max_radio_num*i+radioIndex; |
| 5410 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 5411 | return RETURN_ERR; |
| 5412 | snprintf(cmd, sizeof(cmd), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name); |
| 5413 | _syscmd(cmd, buf, sizeof(buf)); |
| 5414 | if(*buf == '1') |
| 5415 | wifi_setApEnable(apIndex, true); |
| 5416 | } |
| 5417 | |
| 5418 | return ret; |
| 5419 | } |
| 5420 | |
| 5421 | struct channels_noise { |
| 5422 | int channel; |
| 5423 | int noise; |
| 5424 | }; |
| 5425 | |
| 5426 | // Return noise array for each channel |
| 5427 | int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num) |
| 5428 | { |
| 5429 | char interface_name[16] = {0}; |
| 5430 | FILE *f = NULL; |
| 5431 | char cmd[128] = {0}; |
| 5432 | char line[256] = {0}; |
| 5433 | size_t len = 0; |
| 5434 | ssize_t read = 0; |
| 5435 | int tmp = 0, arr_index = -1; |
| 5436 | |
| 5437 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 5438 | return RETURN_ERR; |
| 5439 | sprintf(cmd, "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name); |
| 5440 | |
| 5441 | if ((f = popen(cmd, "r")) == NULL) { |
| 5442 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 5443 | return RETURN_ERR; |
| 5444 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5445 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5446 | while(fgets(line, sizeof(line), f) != NULL) { |
| 5447 | if(arr_index < channels_num){ |
| 5448 | sscanf(line, "%d", &tmp); |
| 5449 | if (tmp > 0) { // channel frequency, the first line must be frequency |
| 5450 | arr_index++; |
| 5451 | channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp); |
| 5452 | } else { // noise |
| 5453 | channels_noise_arr[arr_index].noise = tmp; |
| 5454 | } |
| 5455 | }else{ |
| 5456 | break; |
| 5457 | } |
| 5458 | } |
| 5459 | pclose(f); |
| 5460 | return RETURN_OK; |
| 5461 | } |
| 5462 | |
| 5463 | //Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list |
| 5464 | //HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array" |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5465 | INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181 |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5466 | { |
| 5467 | int index = -1; |
| 5468 | wifi_neighbor_ap2_t *scan_array = NULL; |
| 5469 | char cmd[256]={0}; |
| 5470 | char buf[128]={0}; |
| 5471 | char file_name[32] = {0}; |
| 5472 | char filter_SSID[32] = {0}; |
| 5473 | char line[256] = {0}; |
| 5474 | char interface_name[16] = {0}; |
| 5475 | char *ret = NULL; |
| 5476 | int freq=0; |
| 5477 | FILE *f = NULL; |
| 5478 | size_t len=0; |
| 5479 | int channels_num = 0; |
| 5480 | int vht_channel_width = 0; |
| 5481 | int get_noise_ret = RETURN_ERR; |
| 5482 | bool filter_enable = false; |
| 5483 | bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd. |
| 5484 | int phyId = 0; |
| 5485 | |
| 5486 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__); |
| 5487 | |
| 5488 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 5489 | return RETURN_ERR; |
| 5490 | |
| 5491 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radioIndex); |
| 5492 | f = fopen(file_name, "r"); |
| 5493 | if (f != NULL) { |
| 5494 | fgets(filter_SSID, sizeof(file_name), f); |
| 5495 | if (strlen(filter_SSID) != 0) |
| 5496 | filter_enable = true; |
| 5497 | fclose(f); |
| 5498 | } |
| 5499 | |
| 5500 | phyId = radio_index_to_phy(radioIndex); |
| 5501 | snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId); |
| 5502 | _syscmd(cmd, buf, sizeof(buf)); |
| 5503 | channels_num = strtol(buf, NULL, 10); |
| 5504 | |
| 5505 | |
| 5506 | |
| 5507 | sprintf(cmd, "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \ |
| 5508 | // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name); |
| 5509 | fprintf(stderr, "cmd: %s\n", cmd); |
| 5510 | if ((f = popen(cmd, "r")) == NULL) { |
| 5511 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 5512 | return RETURN_ERR; |
| 5513 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5514 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5515 | struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise)); |
| 5516 | get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5517 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5518 | ret = fgets(line, sizeof(line), f); |
| 5519 | while (ret != NULL) { |
| 5520 | if(strstr(line, "BSS") != NULL) { // new neighbor info |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 5521 | // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 5522 | // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop. |
| 5523 | // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS. |
| 5524 | |
| 5525 | if (!filter_BSS) { |
| 5526 | index++; |
| 5527 | wifi_neighbor_ap2_t *tmp; |
| 5528 | tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1)); |
| 5529 | if (tmp == NULL) { // no more memory to use |
| 5530 | index--; |
| 5531 | wifi_dbg_printf("%s: realloc failed\n", __func__); |
| 5532 | break; |
| 5533 | } |
| 5534 | scan_array = tmp; |
| 5535 | } |
| 5536 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 5537 | |
| 5538 | filter_BSS = false; |
| 5539 | sscanf(line, "BSS %17s", scan_array[index].ap_BSSID); |
| 5540 | strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure")); |
| 5541 | strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None")); |
| 5542 | strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None")); |
| 5543 | } else if (strstr(line, "freq") != NULL) { |
| 5544 | sscanf(line," freq: %d", &freq); |
| 5545 | scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq); |
| 5546 | |
| 5547 | if (freq >= 2412 && freq <= 2484) { |
| 5548 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")); |
| 5549 | strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g")); |
| 5550 | strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g")); |
| 5551 | } |
| 5552 | else if (freq >= 5160 && freq <= 5805) { |
| 5553 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")); |
| 5554 | strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a")); |
| 5555 | strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a")); |
| 5556 | } |
| 5557 | |
| 5558 | scan_array[index].ap_Noise = 0; |
| 5559 | if (get_noise_ret == RETURN_OK) { |
| 5560 | for (int i = 0; i < channels_num; i++) { |
| 5561 | if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) { |
| 5562 | scan_array[index].ap_Noise = channels_noise_arr[i].noise; |
| 5563 | break; |
| 5564 | } |
| 5565 | } |
| 5566 | } |
| 5567 | } else if (strstr(line, "beacon interval") != NULL) { |
| 5568 | sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)); |
| 5569 | } else if (strstr(line, "signal") != NULL) { |
| 5570 | sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)); |
| 5571 | } else if (strstr(line,"SSID") != NULL) { |
| 5572 | sscanf(line," SSID: %s", scan_array[index].ap_SSID); |
| 5573 | if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) { |
| 5574 | filter_BSS = true; |
| 5575 | } |
| 5576 | } else if (strstr(line, "Supported rates") != NULL) { |
| 5577 | char SRate[80] = {0}, *tmp = NULL; |
| 5578 | memset(buf, 0, sizeof(buf)); |
| 5579 | strcpy(SRate, line); |
| 5580 | tmp = strtok(SRate, ":"); |
| 5581 | tmp = strtok(NULL, ":"); |
| 5582 | strcpy(buf, tmp); |
| 5583 | memset(SRate, 0, sizeof(SRate)); |
| 5584 | |
| 5585 | tmp = strtok(buf, " \n"); |
| 5586 | while (tmp != NULL) { |
| 5587 | strcat(SRate, tmp); |
| 5588 | if (SRate[strlen(SRate) - 1] == '*') { |
| 5589 | SRate[strlen(SRate) - 1] = '\0'; |
| 5590 | } |
| 5591 | strcat(SRate, ","); |
| 5592 | |
| 5593 | tmp = strtok(NULL, " \n"); |
| 5594 | } |
| 5595 | SRate[strlen(SRate) - 1] = '\0'; |
| 5596 | strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate); |
| 5597 | } else if (strstr(line, "DTIM") != NULL) { |
| 5598 | sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf); |
| 5599 | } else if (strstr(line, "VHT capabilities") != NULL) { |
| 5600 | strcat(scan_array[index].ap_SupportedStandards, ",ac"); |
| 5601 | strcpy(scan_array[index].ap_OperatingStandards, "ac"); |
| 5602 | } else if (strstr(line, "HT capabilities") != NULL) { |
| 5603 | strcat(scan_array[index].ap_SupportedStandards, ",n"); |
| 5604 | strcpy(scan_array[index].ap_OperatingStandards, "n"); |
| 5605 | } else if (strstr(line, "VHT operation") != NULL) { |
| 5606 | ret = fgets(line, sizeof(line), f); |
| 5607 | sscanf(line," * channel width: %d", &vht_channel_width); |
| 5608 | if(vht_channel_width == 1) { |
| 5609 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80"); |
| 5610 | } else { |
| 5611 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40"); |
| 5612 | } |
| 5613 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 5614 | continue; |
| 5615 | } else if (strstr(line, "HT operation") != NULL) { |
| 5616 | ret = fgets(line, sizeof(line), f); |
| 5617 | sscanf(line," * secondary channel offset: %s", &buf); |
| 5618 | if (!strcmp(buf, "above")) { |
| 5619 | //40Mhz + |
| 5620 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G"); |
| 5621 | } |
| 5622 | else if (!strcmp(buf, "below")) { |
| 5623 | //40Mhz - |
| 5624 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G"); |
| 5625 | } else { |
| 5626 | //20Mhz |
| 5627 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G"); |
| 5628 | } |
| 5629 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 5630 | continue; |
| 5631 | } else if (strstr(line, "HE capabilities") != NULL) { |
| 5632 | strcat(scan_array[index].ap_SupportedStandards, ",ax"); |
| 5633 | strcpy(scan_array[index].ap_OperatingStandards, "ax"); |
| 5634 | ret = fgets(line, sizeof(line), f); |
| 5635 | if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) { |
| 5636 | if (strstr(line, "HE40/2.4GHz") != NULL) |
| 5637 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS"); |
| 5638 | else |
| 5639 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20"); |
| 5640 | } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) { |
| 5641 | if (strstr(line, "HE80/5GHz") != NULL) { |
| 5642 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80"); |
| 5643 | ret = fgets(line, sizeof(line), f); |
| 5644 | } else |
| 5645 | continue; |
| 5646 | if (strstr(line, "HE160/5GHz") != NULL) |
| 5647 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160"); |
| 5648 | } |
| 5649 | continue; |
| 5650 | } else if (strstr(line, "WPA") != NULL) { |
| 5651 | strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA"); |
| 5652 | } else if (strstr(line, "RSN") != NULL) { |
| 5653 | strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN"); |
| 5654 | } else if (strstr(line, "Group cipher") != NULL) { |
| 5655 | sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode); |
| 5656 | if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) { |
| 5657 | strcpy(scan_array[index].ap_EncryptionMode, "AES"); |
| 5658 | } |
| 5659 | } |
| 5660 | ret = fgets(line, sizeof(line), f); |
| 5661 | } |
| 5662 | |
| 5663 | if (!filter_BSS) { |
| 5664 | *output_array_size = index + 1; |
| 5665 | } else { |
| 5666 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 5667 | *output_array_size = index; |
| 5668 | } |
| 5669 | *neighbor_ap_array = scan_array; |
| 5670 | pclose(f); |
| 5671 | free(channels_noise_arr); |
| 5672 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5673 | return RETURN_OK; |
| 5674 | } |
| 5675 | |
| 5676 | //>> Deprecated: used for old RDKB code. |
| 5677 | INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct) |
| 5678 | { |
| 5679 | INT status = RETURN_ERR; |
| 5680 | |
| 5681 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5682 | output_struct->wifi_PLCPErrorCount = 0; |
| 5683 | output_struct->wifi_FCSErrorCount = 0; |
| 5684 | output_struct->wifi_InvalidMACCount = 0; |
| 5685 | output_struct->wifi_PacketsOtherReceived = 0; |
| 5686 | output_struct->wifi_Noise = 0; |
| 5687 | status = RETURN_OK; |
| 5688 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5689 | return status; |
| 5690 | } |
| 5691 | |
| 5692 | INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct) |
| 5693 | { |
| 5694 | char interface_name[16] = {0}; |
| 5695 | char cmd[128] = {0}; |
| 5696 | char buf[1280] = {0}; |
| 5697 | char *pos = NULL; |
| 5698 | |
| 5699 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5700 | if (NULL == output_struct) |
| 5701 | return RETURN_ERR; |
| 5702 | |
| 5703 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 5704 | return RETURN_ERR; |
| 5705 | |
| 5706 | memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t)); |
| 5707 | |
| 5708 | snprintf(cmd, sizeof(cmd), "ifconfig %s", interface_name); |
| 5709 | _syscmd(cmd, buf, sizeof(buf)); |
| 5710 | |
| 5711 | pos = buf; |
| 5712 | if ((pos = strstr(pos, "RX packets:")) == NULL) |
| 5713 | return RETURN_ERR; |
| 5714 | output_struct->wifi_PacketsReceived = atoi(pos+strlen("RX packets:")); |
| 5715 | |
| 5716 | if ((pos = strstr(pos, "TX packets:")) == NULL) |
| 5717 | return RETURN_ERR; |
| 5718 | output_struct->wifi_PacketsSent = atoi(pos+strlen("TX packets:")); |
| 5719 | |
| 5720 | if ((pos = strstr(pos, "RX bytes:")) == NULL) |
| 5721 | return RETURN_ERR; |
| 5722 | output_struct->wifi_BytesReceived = atoi(pos+strlen("RX bytes:")); |
| 5723 | |
| 5724 | if ((pos = strstr(pos, "TX bytes:")) == NULL) |
| 5725 | return RETURN_ERR; |
| 5726 | output_struct->wifi_BytesSent = atoi(pos+strlen("TX bytes:")); |
| 5727 | |
| 5728 | sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l | tr -d '\n'", interface_name); |
| 5729 | _syscmd(cmd, buf, sizeof(buf)); |
| 5730 | sscanf(buf, "%lu", &output_struct->wifi_Associations); |
| 5731 | |
| 5732 | #if 0 |
| 5733 | //TODO: need to revisit below implementation |
| 5734 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5735 | char interface_name[MAX_BUF_SIZE] = {0}; |
| 5736 | char interface_status[MAX_BUF_SIZE] = {0}; |
| 5737 | char Value[MAX_BUF_SIZE] = {0}; |
| 5738 | char buf[MAX_CMD_SIZE] = {0}; |
| 5739 | char cmd[MAX_CMD_SIZE] = {0}; |
| 5740 | FILE *fp = NULL; |
| 5741 | |
| 5742 | if (NULL == output_struct) { |
| 5743 | return RETURN_ERR; |
| 5744 | } |
| 5745 | |
| 5746 | memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t)); |
| 5747 | |
| 5748 | if((apIndex == 0) || (apIndex == 1) || (apIndex == 4) || (apIndex == 5)) |
| 5749 | { |
| 5750 | if(apIndex == 0) //private_wifi for 2.4G |
| 5751 | { |
| 5752 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd0.conf"); |
| 5753 | } |
| 5754 | else if(apIndex == 1) //private_wifi for 5G |
| 5755 | { |
| 5756 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd1.conf"); |
| 5757 | } |
| 5758 | else if(apIndex == 4) //public_wifi for 2.4G |
| 5759 | { |
| 5760 | sprintf(cmd,"%s","cat /nvram/hostapd0.conf | grep bss="); |
| 5761 | if(_syscmd(cmd,buf,sizeof(buf)) == RETURN_ERR) |
| 5762 | { |
| 5763 | return RETURN_ERR; |
| 5764 | } |
| 5765 | if(buf[0] == '#')//tp-link |
| 5766 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd4.conf"); |
| 5767 | else//tenda |
| 5768 | wifi_GetInterfaceName_virtualInterfaceName_2G(interface_name); |
| 5769 | } |
| 5770 | else if(apIndex == 5) //public_wifi for 5G |
| 5771 | { |
| 5772 | wifi_GetInterfaceName(interface_name,"/nvram/hostapd5.conf"); |
| 5773 | } |
| 5774 | |
| 5775 | GetIfacestatus(interface_name, interface_status); |
| 5776 | |
| 5777 | if(0 != strcmp(interface_status, "1")) |
| 5778 | return RETURN_ERR; |
| 5779 | |
| 5780 | snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name); |
| 5781 | system(cmd); |
| 5782 | |
| 5783 | fp = fopen("/tmp/SSID_Stats.txt", "r"); |
| 5784 | if(fp == NULL) |
| 5785 | { |
| 5786 | printf("/tmp/SSID_Stats.txt not exists \n"); |
| 5787 | return RETURN_ERR; |
| 5788 | } |
| 5789 | fclose(fp); |
| 5790 | |
| 5791 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 5792 | File_Reading(buf, Value); |
| 5793 | output_struct->wifi_PacketsReceived = strtoul(Value, NULL, 10); |
| 5794 | |
| 5795 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 5796 | File_Reading(buf, Value); |
| 5797 | output_struct->wifi_PacketsSent = strtoul(Value, NULL, 10); |
| 5798 | |
| 5799 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1"); |
| 5800 | File_Reading(buf, Value); |
| 5801 | output_struct->wifi_BytesReceived = strtoul(Value, NULL, 10); |
| 5802 | |
| 5803 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 5804 | File_Reading(buf, Value); |
| 5805 | output_struct->wifi_BytesSent = strtoul(Value, NULL, 10); |
| 5806 | |
| 5807 | /* There is no specific parameter from caller to associate the value wifi_Associations */ |
| 5808 | //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name); |
| 5809 | //_syscmd(cmd, buf, sizeof(buf)); |
| 5810 | //sscanf(buf,"%lu", &output_struct->wifi_Associations); |
| 5811 | } |
| 5812 | #endif |
| 5813 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5814 | return RETURN_OK; |
| 5815 | } |
| 5816 | |
| 5817 | INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct) |
| 5818 | { |
| 5819 | char interface_name[MAX_BUF_SIZE] = {0}; |
| 5820 | char interface_status[MAX_BUF_SIZE] = {0}; |
| 5821 | char Value[MAX_BUF_SIZE] = {0}; |
| 5822 | char buf[MAX_CMD_SIZE] = {0}; |
| 5823 | char cmd[MAX_CMD_SIZE] = {0}; |
| 5824 | FILE *fp = NULL; |
| 5825 | |
| 5826 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5827 | if (NULL == output_struct) |
| 5828 | return RETURN_ERR; |
| 5829 | |
| 5830 | memset(output_struct, 0, sizeof(wifi_trafficStats_t)); |
| 5831 | |
| 5832 | if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK) |
| 5833 | return RETURN_ERR; |
| 5834 | GetIfacestatus(interface_name, interface_status); |
| 5835 | |
| 5836 | if(0 != strcmp(interface_status, "1")) |
| 5837 | return RETURN_ERR; |
| 5838 | |
| 5839 | snprintf(cmd, sizeof(cmd), "ifconfig %s > /tmp/SSID_Stats.txt", interface_name); |
| 5840 | system(cmd); |
| 5841 | |
| 5842 | fp = fopen("/tmp/SSID_Stats.txt", "r"); |
| 5843 | if(fp == NULL) |
| 5844 | { |
| 5845 | printf("/tmp/SSID_Stats.txt not exists \n"); |
| 5846 | return RETURN_ERR; |
| 5847 | } |
| 5848 | fclose(fp); |
| 5849 | |
| 5850 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 5851 | File_Reading(buf, Value); |
| 5852 | output_struct->wifi_ErrorsReceived = strtoul(Value, NULL, 10); |
| 5853 | |
| 5854 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1"); |
| 5855 | File_Reading(buf, Value); |
| 5856 | output_struct->wifi_ErrorsSent = strtoul(Value, NULL, 10); |
| 5857 | |
| 5858 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 5859 | File_Reading(buf, Value); |
| 5860 | output_struct->wifi_DiscardedPacketsReceived = strtoul(Value, NULL, 10); |
| 5861 | |
| 5862 | sprintf(buf, "cat /tmp/SSID_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1"); |
| 5863 | File_Reading(buf, Value); |
| 5864 | output_struct->wifi_DiscardedPacketsSent = strtoul(Value, NULL, 10); |
| 5865 | |
| 5866 | output_struct->wifi_UnicastPacketsSent = 0; |
| 5867 | output_struct->wifi_UnicastPacketsReceived = 0; |
| 5868 | output_struct->wifi_MulticastPacketsSent = 0; |
| 5869 | output_struct->wifi_MulticastPacketsReceived = 0; |
| 5870 | output_struct->wifi_BroadcastPacketsSent = 0; |
| 5871 | output_struct->wifi_BroadcastPacketsRecevied = 0; |
| 5872 | output_struct->wifi_UnknownPacketsReceived = 0; |
| 5873 | |
| 5874 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5875 | return RETURN_OK; |
| 5876 | } |
| 5877 | |
| 5878 | INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct) |
| 5879 | { |
| 5880 | INT status = RETURN_ERR; |
| 5881 | |
| 5882 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5883 | //Below values should get updated from hal |
| 5884 | output_struct->wifi_RetransCount=0; |
| 5885 | output_struct->wifi_FailedRetransCount=0; |
| 5886 | output_struct->wifi_RetryCount=0; |
| 5887 | output_struct->wifi_MultipleRetryCount=0; |
| 5888 | output_struct->wifi_ACKFailureCount=0; |
| 5889 | output_struct->wifi_AggregatedPacketCount=0; |
| 5890 | |
| 5891 | status = RETURN_OK; |
| 5892 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5893 | |
| 5894 | return status; |
| 5895 | } |
| 5896 | |
| 5897 | INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size) |
| 5898 | { |
| 5899 | INT status = RETURN_ERR; |
| 5900 | UINT index; |
| 5901 | wifi_neighbor_ap_t *pt=NULL; |
| 5902 | |
| 5903 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 5904 | *output_array_size=2; |
| 5905 | //zqiu: HAL alloc the array and return to caller. Caller response to free it. |
| 5906 | *neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size); |
| 5907 | for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) { |
| 5908 | strcpy(pt->ap_Radio,""); |
| 5909 | strcpy(pt->ap_SSID,""); |
| 5910 | strcpy(pt->ap_BSSID,""); |
| 5911 | strcpy(pt->ap_Mode,""); |
| 5912 | pt->ap_Channel=1; |
| 5913 | pt->ap_SignalStrength=0; |
| 5914 | strcpy(pt->ap_SecurityModeEnabled,""); |
| 5915 | strcpy(pt->ap_EncryptionMode,""); |
| 5916 | strcpy(pt->ap_OperatingFrequencyBand,""); |
| 5917 | strcpy(pt->ap_SupportedStandards,""); |
| 5918 | strcpy(pt->ap_OperatingStandards,""); |
| 5919 | strcpy(pt->ap_OperatingChannelBandwidth,""); |
| 5920 | pt->ap_BeaconPeriod=1; |
| 5921 | pt->ap_Noise=0; |
| 5922 | strcpy(pt->ap_BasicDataTransferRates,""); |
| 5923 | strcpy(pt->ap_SupportedDataTransferRates,""); |
| 5924 | pt->ap_DTIMPeriod=1; |
| 5925 | pt->ap_ChannelUtilization = 1; |
| 5926 | } |
| 5927 | |
| 5928 | status = RETURN_OK; |
| 5929 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 5930 | |
| 5931 | return status; |
| 5932 | } |
| 5933 | |
| 5934 | //----------------- AP HAL ------------------------------- |
| 5935 | |
| 5936 | //>> Deprecated: used for old RDKB code. |
| 5937 | INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct) |
| 5938 | { |
| 5939 | if (NULL == output_ulong || NULL == output_struct) |
| 5940 | return RETURN_ERR; |
| 5941 | *output_ulong = 0; |
| 5942 | *output_struct = NULL; |
| 5943 | return RETURN_OK; |
| 5944 | } |
| 5945 | |
| 5946 | #ifdef HAL_NETLINK_IMPL |
| 5947 | static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) { |
| 5948 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 5949 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 5950 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 5951 | struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 5952 | char mac_addr[20]; |
| 5953 | static int count=0; |
| 5954 | int rate=0; |
| 5955 | |
| 5956 | wifi_device_info_t *out = (wifi_device_info_t*)arg; |
| 5957 | |
| 5958 | nla_parse(tb, |
| 5959 | NL80211_ATTR_MAX, |
| 5960 | genlmsg_attrdata(gnlh, 0), |
| 5961 | genlmsg_attrlen(gnlh, 0), |
| 5962 | NULL); |
| 5963 | |
| 5964 | if(!tb[NL80211_ATTR_STA_INFO]) { |
| 5965 | fprintf(stderr, "sta stats missing!\n"); |
| 5966 | return NL_SKIP; |
| 5967 | } |
| 5968 | |
| 5969 | |
| 5970 | if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) { |
| 5971 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 5972 | return NL_SKIP; |
| 5973 | } |
| 5974 | |
| 5975 | //devIndex starts from 1 |
| 5976 | if( ++count == out->wifi_devIndex ) |
| 5977 | { |
| 5978 | mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); |
| 5979 | //Getting the mac addrress |
| 5980 | mac_addr_aton(out->wifi_devMacAddress,mac_addr); |
| 5981 | |
| 5982 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { |
| 5983 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 5984 | return NL_SKIP; |
| 5985 | } |
| 5986 | |
| 5987 | if(sinfo[NL80211_STA_INFO_TX_BITRATE]) { |
| 5988 | if(rinfo[NL80211_RATE_INFO_BITRATE]) |
| 5989 | rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); |
| 5990 | out->wifi_devTxRate = rate/10; |
| 5991 | } |
| 5992 | |
| 5993 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) { |
| 5994 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 5995 | return NL_SKIP; |
| 5996 | } |
| 5997 | |
| 5998 | if(sinfo[NL80211_STA_INFO_RX_BITRATE]) { |
| 5999 | if(rinfo[NL80211_RATE_INFO_BITRATE]) |
| 6000 | rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]); |
| 6001 | out->wifi_devRxRate = rate/10; |
| 6002 | } |
| 6003 | if(sinfo[NL80211_STA_INFO_SIGNAL_AVG]) |
| 6004 | out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]); |
| 6005 | |
| 6006 | out->wifi_devAssociatedDeviceAuthentiationState = 1; |
| 6007 | count = 0; //starts the count for next cycle |
| 6008 | return NL_STOP; |
| 6009 | } |
| 6010 | |
| 6011 | return NL_SKIP; |
| 6012 | |
| 6013 | } |
| 6014 | #endif |
| 6015 | |
| 6016 | INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct) |
| 6017 | { |
| 6018 | #ifdef HAL_NETLINK_IMPL |
| 6019 | Netlink nl = {0}; |
| 6020 | char if_name[10] = {0}; |
| 6021 | char interface_name[16] = {0}; |
| 6022 | |
| 6023 | wifi_device_info_t info = {0}; |
| 6024 | info.wifi_devIndex = devIndex; |
| 6025 | |
| 6026 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 6027 | return RETURN_ERR; |
| 6028 | |
| 6029 | snprintf(if_name,sizeof(if_name),"%s", interface_name); |
| 6030 | |
| 6031 | nl.id = initSock80211(&nl); |
| 6032 | |
| 6033 | if (nl.id < 0) { |
| 6034 | fprintf(stderr, "Error initializing netlink \n"); |
| 6035 | return -1; |
| 6036 | } |
| 6037 | |
| 6038 | struct nl_msg* msg = nlmsg_alloc(); |
| 6039 | |
| 6040 | if (!msg) { |
| 6041 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 6042 | nlfree(&nl); |
| 6043 | return -2; |
| 6044 | } |
| 6045 | |
| 6046 | genlmsg_put(msg, |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 6047 | NL_AUTO_PID, |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6048 | NL_AUTO_SEQ, |
| 6049 | nl.id, |
| 6050 | 0, |
| 6051 | NLM_F_DUMP, |
| 6052 | NL80211_CMD_GET_STATION, |
| 6053 | 0); |
| 6054 | |
| 6055 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 6056 | nl_send_auto_complete(nl.socket, msg); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6057 | nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info); |
| 6058 | nl_recvmsgs(nl.socket, nl.cb); |
| 6059 | nlmsg_free(msg); |
| 6060 | nlfree(&nl); |
| 6061 | |
| 6062 | output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState; |
| 6063 | output_struct->wifi_devRxRate = info.wifi_devRxRate; |
| 6064 | output_struct->wifi_devTxRate = info.wifi_devTxRate; |
| 6065 | output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength; |
| 6066 | memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress)); |
| 6067 | return RETURN_OK; |
| 6068 | #else |
| 6069 | //iw utility to retrieve station information |
| 6070 | #define ASSODEVFILE "/tmp/AssociatedDevice_Stats.txt" |
| 6071 | #define SIGNALFILE "/tmp/wifi_signalstrength.txt" |
| 6072 | #define MACFILE "/tmp/wifi_AssoMac.txt" |
| 6073 | #define TXRATEFILE "/tmp/wifi_txrate.txt" |
| 6074 | #define RXRATEFILE "/tmp/wifi_rxrate.txt" |
| 6075 | FILE *file = NULL; |
| 6076 | char if_name[10] = {'\0'}; |
| 6077 | char pipeCmd[256] = {'\0'}; |
| 6078 | char line[256] = {0}; |
| 6079 | char interface_name[16] = {0}; |
| 6080 | int count = 0, device = 0; |
| 6081 | |
| 6082 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 6083 | return RETURN_ERR; |
| 6084 | |
| 6085 | snprintf(if_name,sizeof(if_name),"%s", interface_name); |
| 6086 | |
| 6087 | sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", if_name, if_name); |
| 6088 | file = popen(pipeCmd, "r"); |
| 6089 | |
| 6090 | if(file == NULL) |
| 6091 | return RETURN_ERR; //popen failed |
| 6092 | |
| 6093 | fgets(line, sizeof line, file); |
| 6094 | device = atoi(line); |
| 6095 | pclose(file); |
| 6096 | |
| 6097 | if(device == 0) |
| 6098 | return RETURN_ERR; //No devices are connected |
| 6099 | |
| 6100 | sprintf(pipeCmd,"iw dev %s station dump > "ASSODEVFILE, if_name); |
| 6101 | system(pipeCmd); |
| 6102 | |
| 6103 | system("cat "ASSODEVFILE" | grep 'signal avg' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' > "SIGNALFILE); |
| 6104 | |
| 6105 | system("cat "ASSODEVFILE" | grep Station | cut -d ' ' -f 2 > "MACFILE); |
| 6106 | |
| 6107 | system("cat "ASSODEVFILE" | grep 'tx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "TXRATEFILE); |
| 6108 | |
| 6109 | system("cat "ASSODEVFILE" | grep 'rx bitrate' | cut -d ' ' -f2 | cut -d ':' -f2 | cut -f 2 | tr -s '\n' | cut -d '.' -f1 > "RXRATEFILE); |
| 6110 | |
| 6111 | //devIndex starts from 1, ++count |
| 6112 | if((file = fopen(SIGNALFILE, "r")) != NULL ) |
| 6113 | { |
| 6114 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 6115 | { |
| 6116 | if (++count == devIndex) |
| 6117 | { |
| 6118 | output_struct->wifi_devSignalStrength = atoi(line); |
| 6119 | break; |
| 6120 | } |
| 6121 | } |
| 6122 | fclose(file); |
| 6123 | } |
| 6124 | else |
| 6125 | fprintf(stderr,"fopen wifi_signalstrength.txt failed"); |
| 6126 | |
| 6127 | if((file = fopen(MACFILE, "r")) != NULL ) |
| 6128 | { |
| 6129 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 6130 | { |
| 6131 | if (++count == devIndex) |
| 6132 | { |
| 6133 | sscanf(line, "%02x:%02x:%02x:%02x:%02x:%02x",&output_struct->wifi_devMacAddress[0],&output_struct->wifi_devMacAddress[1],&output_struct->wifi_devMacAddress[2],&output_struct->wifi_devMacAddress[3],&output_struct->wifi_devMacAddress[4],&output_struct->wifi_devMacAddress[5]); |
| 6134 | break; |
| 6135 | } |
| 6136 | } |
| 6137 | fclose(file); |
| 6138 | } |
| 6139 | else |
| 6140 | fprintf(stderr,"fopen wifi_AssoMac.txt failed"); |
| 6141 | |
| 6142 | if((file = fopen(TXRATEFILE, "r")) != NULL ) |
| 6143 | { |
| 6144 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 6145 | { |
| 6146 | if (++count == devIndex) |
| 6147 | { |
| 6148 | output_struct->wifi_devTxRate = atoi(line); |
| 6149 | break; |
| 6150 | } |
| 6151 | } |
| 6152 | fclose(file); |
| 6153 | } |
| 6154 | else |
| 6155 | fprintf(stderr,"fopen wifi_txrate.txt failed"); |
| 6156 | |
| 6157 | if((file = fopen(RXRATEFILE, "r")) != NULL) |
| 6158 | { |
| 6159 | for(count =0;fgets(line, sizeof line, file) != NULL;) |
| 6160 | { |
| 6161 | if (++count == devIndex) |
| 6162 | { |
| 6163 | output_struct->wifi_devRxRate = atoi(line); |
| 6164 | break; |
| 6165 | } |
| 6166 | } |
| 6167 | fclose(file); |
| 6168 | } |
| 6169 | else |
| 6170 | fprintf(stderr,"fopen wifi_rxrate.txt failed"); |
| 6171 | |
| 6172 | output_struct->wifi_devAssociatedDeviceAuthentiationState = 1; |
| 6173 | |
| 6174 | return RETURN_OK; |
| 6175 | #endif |
| 6176 | } |
| 6177 | |
| 6178 | INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device) |
| 6179 | { |
| 6180 | if (NULL == device) |
| 6181 | return RETURN_ERR; |
| 6182 | return RETURN_OK; |
| 6183 | } |
| 6184 | //<< |
| 6185 | |
| 6186 | |
| 6187 | //--------------wifi_ap_hal----------------------------- |
| 6188 | //enables CTS protection for the radio used by this AP |
| 6189 | INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable) |
| 6190 | { |
| 6191 | //save config and Apply instantly |
| 6192 | return RETURN_ERR; |
| 6193 | } |
| 6194 | |
| 6195 | // enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap |
| 6196 | INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable) |
| 6197 | { |
| 6198 | char config_file[64] = {'\0'}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 6199 | char config_dat_file[64] = {'\0'}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6200 | char buf[64] = {'\0'}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 6201 | struct params list = {0}; |
| 6202 | struct params dat = {0}; |
| 6203 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6204 | |
| 6205 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6206 | list.name = "ht_coex"; |
| 6207 | snprintf(buf, sizeof(buf), "%d", enable); |
| 6208 | list.value = buf; |
| 6209 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 6210 | dat.name = "HT_BSSCoexistence"; |
| 6211 | dat.value = buf; |
| 6212 | |
| 6213 | band = wifi_index_to_band(apIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6214 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 6215 | snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6216 | wifi_hostapdWrite(config_file, &list, 1); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 6217 | wifi_datfileWrite(config_dat_file, &dat, 1); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6218 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 6219 | |
| 6220 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6221 | |
| 6222 | return RETURN_OK; |
| 6223 | } |
| 6224 | |
| 6225 | //P3 // sets the fragmentation threshold in bytes for the radio used by this ap |
| 6226 | INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold) |
| 6227 | { |
| 6228 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 6229 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 6230 | struct params list; |
| 6231 | |
| 6232 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6233 | if (threshold < 256 || threshold > 2346 ) |
| 6234 | return RETURN_ERR; |
| 6235 | list.name = "fragm_threshold"; |
| 6236 | snprintf(buf, sizeof(buf), "%d", threshold); |
| 6237 | list.value = buf; |
| 6238 | |
| 6239 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 6240 | wifi_hostapdWrite(config_file, &list, 1); |
| 6241 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 6242 | |
| 6243 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6244 | |
| 6245 | return RETURN_OK; |
| 6246 | } |
| 6247 | |
| 6248 | // enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled |
| 6249 | INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable) |
| 6250 | { |
| 6251 | char config_file[64] = {'\0'}; |
| 6252 | char cmd[512] = {'\0'}; |
| 6253 | char buf[512] = {'\0'}; |
| 6254 | char stbc_config[16] = {'\0'}; |
| 6255 | wifi_band band; |
| 6256 | int iterator = 0; |
| 6257 | BOOL current_stbc = FALSE; |
| 6258 | int ant_count = 0; |
| 6259 | int ant_bitmap = 0; |
| 6260 | struct params list; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6261 | char dat_file[64] = {'\0'}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6262 | |
| 6263 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6264 | |
| 6265 | band = wifi_index_to_band(radioIndex); |
| 6266 | if (band == band_invalid) |
| 6267 | return RETURN_ERR; |
| 6268 | |
| 6269 | if (band == band_2_4) |
| 6270 | iterator = 1; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6271 | else if ((band == band_5) || (band == band_6)) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6272 | iterator = 2; |
| 6273 | else |
| 6274 | return RETURN_OK; |
| 6275 | |
| 6276 | wifi_getRadioTxChainMask(radioIndex, &ant_bitmap); |
| 6277 | for (; ant_bitmap > 0; ant_bitmap >>= 1) |
| 6278 | ant_count += ant_bitmap & 1; |
| 6279 | |
| 6280 | if (ant_count == 1 && STBC_Enable == TRUE) { |
| 6281 | fprintf(stderr, "%s: can not enable STBC when using only one antenna\n", __func__); |
| 6282 | return RETURN_OK; |
| 6283 | } |
| 6284 | |
| 6285 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 6286 | |
| 6287 | // set ht and vht config |
| 6288 | for (int i = 0; i < iterator; i++) { |
| 6289 | memset(stbc_config, 0, sizeof(stbc_config)); |
| 6290 | memset(cmd, 0, sizeof(cmd)); |
| 6291 | memset(buf, 0, sizeof(buf)); |
| 6292 | list.name = (i == 0)?"ht_capab":"vht_capab"; |
| 6293 | snprintf(stbc_config, sizeof(stbc_config), "%s", list.name); |
| 6294 | snprintf(cmd, sizeof(cmd), "cat %s | grep -E '^%s' | grep 'STBC'", config_file, stbc_config); |
| 6295 | _syscmd(cmd, buf, sizeof(buf)); |
| 6296 | if (strlen(buf) != 0) |
| 6297 | current_stbc = TRUE; |
| 6298 | if (current_stbc == STBC_Enable) |
| 6299 | continue; |
| 6300 | |
| 6301 | if (STBC_Enable == TRUE) { |
| 6302 | // Append the STBC flags in capab config |
| 6303 | memset(cmd, 0, sizeof(cmd)); |
| 6304 | if (i == 0) |
| 6305 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file); |
| 6306 | else |
| 6307 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file); |
| 6308 | _syscmd(cmd, buf, sizeof(buf)); |
| 6309 | } else if (STBC_Enable == FALSE) { |
| 6310 | // Remove the STBC flags and remain other flags in capab |
| 6311 | memset(cmd, 0, sizeof(cmd)); |
| 6312 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file); |
| 6313 | _syscmd(cmd, buf, sizeof(buf)); |
| 6314 | memset(cmd, 0, sizeof(cmd)); |
| 6315 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file); |
| 6316 | _syscmd(cmd, buf, sizeof(buf)); |
| 6317 | } |
| 6318 | wifi_hostapdRead(config_file, list.name, buf, sizeof(buf)); |
| 6319 | list.value = buf; |
| 6320 | wifi_hostapdProcessUpdate(radioIndex, &list, 1); |
| 6321 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6322 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 6323 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file); |
| 6324 | _syscmd(cmd, buf, sizeof(buf)); |
| 6325 | if ((band == band_5) || (band == band_6)) { |
| 6326 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file); |
| 6327 | _syscmd(cmd, buf, sizeof(buf)); |
| 6328 | } |
| 6329 | /*wifi_reloadAp(radioIndex); |
| 6330 | the caller do this.*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6331 | |
| 6332 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6333 | return RETURN_OK; |
| 6334 | } |
| 6335 | |
| 6336 | // outputs A-MSDU enable status, 0 == not enabled, 1 == enabled |
| 6337 | INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool) |
| 6338 | { |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6339 | char dat_file[128] = {0}; |
| 6340 | BOOL enable; |
| 6341 | wifi_band band; |
| 6342 | char amdus_buff[8] = {'\0'}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6343 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6344 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6345 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6346 | band = wifi_index_to_band(radioIndex); |
| 6347 | if (band == band_invalid) { |
| 6348 | printf("%s:Band Error\n", __func__); |
| 6349 | return RETURN_ERR; |
| 6350 | } |
| 6351 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 6352 | wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff)); |
| 6353 | if (strncmp(amdus_buff, "1", 1) == 0) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6354 | *output_bool = TRUE; |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6355 | else |
| 6356 | *output_bool = FALSE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6357 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6358 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6359 | |
| 6360 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6361 | } |
| 6362 | |
| 6363 | // enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled |
| 6364 | INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable) |
| 6365 | { |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6366 | char dat_file[128] = {0}; |
| 6367 | BOOL enable; |
| 6368 | wifi_band band; |
| 6369 | char amdus_buff[8] = {'\0'}; |
| 6370 | struct params params = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6371 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6372 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6373 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6374 | band = wifi_index_to_band(radioIndex); |
| 6375 | if (band == band_invalid) { |
| 6376 | printf("%s:Band Error\n", __func__); |
| 6377 | return RETURN_ERR; |
| 6378 | } |
| 6379 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 6380 | wifi_datfileRead(dat_file, "HT_AMSDU", amdus_buff, sizeof(amdus_buff)); |
| 6381 | if (strncmp(amdus_buff, "1", 1) == 0) |
| 6382 | enable = TRUE; |
| 6383 | else |
| 6384 | enable = FALSE; |
| 6385 | if (amsduEnable == enable) |
| 6386 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6387 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6388 | params.name = "HT_AMSDU"; |
| 6389 | if (amsduEnable) |
| 6390 | params.value = "1"; |
| 6391 | else |
| 6392 | params.value = "0"; |
| 6393 | wifi_datfileWrite(dat_file, ¶ms, 1); |
| 6394 | wifi_reloadAp(radioIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6395 | |
developer | 2c22d83 | 2023-05-18 17:46:26 +0800 | [diff] [blame] | 6396 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6397 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6398 | return RETURN_OK; |
| 6399 | } |
| 6400 | |
| 6401 | //P2 // outputs the number of Tx streams |
| 6402 | INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int) |
| 6403 | { |
| 6404 | char buf[8] = {0}; |
| 6405 | char cmd[128] = {0}; |
| 6406 | int phyId = 0; |
| 6407 | |
| 6408 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6409 | |
| 6410 | phyId = radio_index_to_phy(radioIndex); |
| 6411 | snprintf(cmd, sizeof(cmd), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId); |
| 6412 | _syscmd(cmd, buf, sizeof(buf)); |
| 6413 | |
| 6414 | *output_int = (INT)strtol(buf, NULL, 16); |
| 6415 | |
| 6416 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6417 | |
| 6418 | return RETURN_OK; |
| 6419 | } |
| 6420 | |
| 6421 | INT fitChainMask(INT radioIndex, int antcount) |
| 6422 | { |
| 6423 | char buf[128] = {0}; |
| 6424 | char cmd[128] = {0}; |
| 6425 | char config_file[64] = {0}; |
| 6426 | wifi_band band; |
| 6427 | struct params list[2] = {0}; |
| 6428 | |
| 6429 | band = wifi_index_to_band(radioIndex); |
| 6430 | if (band == band_invalid) |
| 6431 | return RETURN_ERR; |
| 6432 | |
| 6433 | list[0].name = "he_mu_beamformer"; |
| 6434 | list[1].name = "he_su_beamformer"; |
| 6435 | |
| 6436 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 6437 | if (antcount == 1) { |
| 6438 | // remove config about multiple antennas |
| 6439 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file); |
| 6440 | _syscmd(cmd, buf, sizeof(buf)); |
| 6441 | |
| 6442 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file); |
| 6443 | _syscmd(cmd, buf, sizeof(buf)); |
| 6444 | |
| 6445 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file); |
| 6446 | _syscmd(cmd, buf, sizeof(buf)); |
| 6447 | |
| 6448 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file); |
| 6449 | _syscmd(cmd, buf, sizeof(buf)); |
| 6450 | |
| 6451 | list[0].value = "0"; |
| 6452 | list[1].value = "0"; |
| 6453 | } else { |
| 6454 | // If we only set RX STBC means STBC is enable and TX STBC is disable when last time set one antenna. so we need to add it back. |
| 6455 | if (band == band_2_4 || band == band_5) { |
| 6456 | snprintf(cmd, sizeof(cmd), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file); |
| 6457 | _syscmd(cmd, buf, sizeof(buf)); |
| 6458 | if (strlen(buf) > 0) { |
| 6459 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file); |
| 6460 | _syscmd(cmd, buf, sizeof(buf)); |
| 6461 | } |
| 6462 | } |
| 6463 | if (band == band_5) { |
| 6464 | snprintf(cmd, sizeof(cmd), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file); |
| 6465 | _syscmd(cmd, buf, sizeof(buf)); |
| 6466 | if (strlen(buf) > 0) { |
| 6467 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file); |
| 6468 | _syscmd(cmd, buf, sizeof(buf)); |
| 6469 | } |
| 6470 | } |
| 6471 | |
| 6472 | snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file); |
| 6473 | _syscmd(cmd, buf, sizeof(buf)); |
| 6474 | if (strlen(buf) == 0) { |
| 6475 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file); |
| 6476 | _syscmd(cmd, buf, sizeof(buf)); |
| 6477 | } |
| 6478 | |
| 6479 | snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file); |
| 6480 | _syscmd(cmd, buf, sizeof(buf)); |
| 6481 | if (strlen(buf) == 0) { |
| 6482 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file); |
| 6483 | _syscmd(cmd, buf, sizeof(buf)); |
| 6484 | } |
| 6485 | |
| 6486 | snprintf(cmd, sizeof(cmd), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file); |
| 6487 | _syscmd(cmd, buf, sizeof(buf)); |
| 6488 | if (strlen(buf) == 0) { |
| 6489 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file); |
| 6490 | } else { |
| 6491 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file); |
| 6492 | } |
| 6493 | _syscmd(cmd, buf, sizeof(buf)); |
| 6494 | |
| 6495 | list[0].value = "1"; |
| 6496 | list[1].value = "1"; |
| 6497 | } |
| 6498 | wifi_hostapdWrite(config_file, list, 2); |
| 6499 | } |
| 6500 | |
| 6501 | //P2 // sets the number of Tx streams to an enviornment variable |
| 6502 | INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams) |
| 6503 | { |
| 6504 | char cmd[128] = {0}; |
| 6505 | char buf[128] = {0}; |
| 6506 | int phyId = 0; |
| 6507 | int cur_mask = 0; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6508 | int antcountmsk = 0; |
| 6509 | INT cur_nss = 0; |
| 6510 | UCHAR dat_file[64] = {0}; |
| 6511 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6512 | |
| 6513 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6514 | |
| 6515 | if (numStreams <= 0) { |
| 6516 | fprintf(stderr, "%s: chainmask is not supported %d.\n", __func__, numStreams); |
| 6517 | return RETURN_ERR; |
| 6518 | } |
| 6519 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6520 | wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value |
| 6521 | for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams. |
| 6522 | cur_nss += 1; |
| 6523 | WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams); |
| 6524 | if (cur_nss == numStreams) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6525 | return RETURN_OK; |
| 6526 | |
| 6527 | wifi_setRadioEnable(radioIndex, FALSE); |
| 6528 | |
| 6529 | phyId = radio_index_to_phy(radioIndex); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6530 | //iw need mask value. |
| 6531 | for (;numStreams > 0; numStreams--) |
| 6532 | antcountmsk |= 0x1 << (numStreams - 1); |
| 6533 | snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6534 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6535 | if (strlen(buf) > 0) { |
| 6536 | fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf); |
| 6537 | return RETURN_ERR; |
| 6538 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6539 | band = wifi_index_to_band(radioIndex); |
| 6540 | if (band == band_invalid) { |
| 6541 | printf("%s:Band Error\n", __func__); |
| 6542 | return RETURN_ERR; |
| 6543 | } |
| 6544 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 6545 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file); |
| 6546 | _syscmd(cmd, buf, sizeof(buf)); |
| 6547 | if (strlen(buf) > 0) { |
| 6548 | fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf); |
| 6549 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6550 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 6551 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file); |
| 6552 | _syscmd(cmd, buf, sizeof(buf)); |
| 6553 | if (strlen(buf) > 0) { |
| 6554 | fprintf(stderr, "%s: cmd %s error, output: %s\n", __func__, cmd, buf); |
| 6555 | return RETURN_ERR; |
| 6556 | } |
| 6557 | fitChainMask(radioIndex, numStreams); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6558 | wifi_setRadioEnable(radioIndex, TRUE); |
| 6559 | |
| 6560 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6561 | return RETURN_OK; |
| 6562 | } |
| 6563 | |
| 6564 | //P2 // outputs the number of Rx streams |
| 6565 | INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int) |
| 6566 | { |
| 6567 | char buf[8] = {0}; |
| 6568 | char cmd[128] = {0}; |
| 6569 | int phyId = 0; |
| 6570 | |
| 6571 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6572 | |
| 6573 | phyId = radio_index_to_phy(radioIndex); |
| 6574 | sprintf(cmd, "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId); |
| 6575 | _syscmd(cmd, buf, sizeof(buf)); |
| 6576 | |
| 6577 | *output_int = (INT)strtol(buf, NULL, 16); |
| 6578 | |
| 6579 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6580 | |
| 6581 | return RETURN_OK; |
| 6582 | } |
| 6583 | |
| 6584 | //P2 // sets the number of Rx streams to an enviornment variable |
| 6585 | INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams) |
| 6586 | { |
| 6587 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 6588 | if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) { |
| 6589 | fprintf(stderr, "%s: wifi_setRadioTxChainMask return error.\n", __func__); |
| 6590 | return RETURN_ERR; |
| 6591 | } |
| 6592 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 6593 | return RETURN_ERR; |
| 6594 | } |
| 6595 | |
| 6596 | //Get radio RDG enable setting |
| 6597 | INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool) |
| 6598 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 6599 | if (NULL == output_bool) |
| 6600 | return RETURN_ERR; |
| 6601 | |
| 6602 | *output_bool = TRUE; |
| 6603 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6604 | } |
| 6605 | |
| 6606 | //Get radio RDG enable setting |
| 6607 | INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool) |
| 6608 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 6609 | char cmd[MAX_CMD_SIZE] = {0}; |
| 6610 | char buf[MAX_BUF_SIZE] = {0}; |
| 6611 | char rdg_status[2] = {0}; |
| 6612 | char dat_file[MAX_CMD_SIZE] = {0}; |
| 6613 | struct params params = {0}; |
| 6614 | |
| 6615 | if (NULL == output_bool) |
| 6616 | return RETURN_ERR; |
| 6617 | |
| 6618 | /*prepare dat file path*/ |
| 6619 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex); |
| 6620 | |
| 6621 | wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status)); |
| 6622 | if (!strncmp(rdg_status, "1", sizeof(rdg_status))) |
| 6623 | *output_bool = TRUE; |
| 6624 | else |
| 6625 | *output_bool = FALSE; |
| 6626 | |
| 6627 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6628 | } |
| 6629 | |
| 6630 | //Set radio RDG enable setting |
| 6631 | INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable) |
| 6632 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 6633 | char cmd[MAX_CMD_SIZE] = {0}; |
| 6634 | char buf[MAX_BUF_SIZE] = {0}; |
| 6635 | char dat_file[MAX_CMD_SIZE] = {0}; |
| 6636 | struct params params = {0}; |
| 6637 | |
| 6638 | /*prepare dat file path*/ |
| 6639 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex); |
| 6640 | |
| 6641 | params.name = "HT_RDG"; |
| 6642 | |
| 6643 | if (enable) { |
| 6644 | params.value = "1"; |
| 6645 | } else { |
| 6646 | params.value = "0"; |
| 6647 | } |
| 6648 | |
| 6649 | wifi_datfileWrite(dat_file, ¶ms, 1); |
| 6650 | |
| 6651 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6652 | } |
| 6653 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6654 | |
| 6655 | int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6656 | { |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6657 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 6658 | struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1]; |
| 6659 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 6660 | unsigned char status; |
| 6661 | unsigned char *out_status = data; |
| 6662 | int err = 0; |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 6663 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6664 | err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 6665 | genlmsg_attrlen(gnlh, 0), NULL); |
| 6666 | if (err < 0){ |
| 6667 | wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n"); |
| 6668 | return err; |
| 6669 | } |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 6670 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6671 | if (tb[NL80211_ATTR_VENDOR_DATA]) { |
| 6672 | err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX, |
| 6673 | tb[NL80211_ATTR_VENDOR_DATA], NULL); |
| 6674 | if (err < 0){ |
| 6675 | wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n"); |
| 6676 | return err; |
| 6677 | } |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 6678 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6679 | if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) { |
| 6680 | status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]); |
| 6681 | if (status == 0) { |
| 6682 | wifi_debug(DEBUG_NOTICE, "disabled\n"); |
| 6683 | } else { |
| 6684 | wifi_debug(DEBUG_NOTICE, "enabled\n"); |
| 6685 | } |
| 6686 | *out_status = status; |
| 6687 | } |
| 6688 | } |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 6689 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6690 | return 0; |
| 6691 | } |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 6692 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6693 | int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data) |
| 6694 | { |
| 6695 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 6696 | struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1]; |
| 6697 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 6698 | unsigned char status; |
| 6699 | unsigned char *out_status = data; |
| 6700 | int err = 0; |
| 6701 | |
| 6702 | err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 6703 | genlmsg_attrlen(gnlh, 0), NULL); |
| 6704 | if (err < 0) { |
| 6705 | wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n"); |
| 6706 | return err; |
| 6707 | } |
| 6708 | |
| 6709 | if (tb[NL80211_ATTR_VENDOR_DATA]) { |
| 6710 | err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX, |
| 6711 | tb[NL80211_ATTR_VENDOR_DATA], NULL); |
| 6712 | if (err < 0) { |
| 6713 | wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n"); |
| 6714 | return err; |
| 6715 | } |
| 6716 | |
| 6717 | if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) { |
| 6718 | status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]); |
| 6719 | if (status == 0) { |
| 6720 | wifi_debug(DEBUG_NOTICE, "disabled\n"); |
| 6721 | } else { |
| 6722 | wifi_debug(DEBUG_NOTICE, "enabled\n"); |
| 6723 | } |
| 6724 | *out_status = status; |
| 6725 | } |
| 6726 | } |
| 6727 | |
| 6728 | return NL_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6729 | } |
| 6730 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6731 | INT mtk_wifi_get_ba_decl_auto_status( |
| 6732 | INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool) |
| 6733 | { |
| 6734 | char inf_name[IF_NAME_SIZE] = {0}; |
| 6735 | struct mtk_nl80211_param params; |
| 6736 | unsigned int if_idx = 0; |
| 6737 | int ret = -1; |
| 6738 | struct unl unl_ins; |
| 6739 | struct nl_msg *msg = NULL; |
| 6740 | struct nlattr * msg_data = NULL; |
| 6741 | struct mtk_nl80211_param param; |
| 6742 | |
| 6743 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 6744 | return RETURN_ERR; |
| 6745 | if_idx = if_nametoindex(inf_name); |
| 6746 | if (!if_idx) { |
| 6747 | wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name); |
| 6748 | return RETURN_ERR; |
| 6749 | } |
| 6750 | /*init mtk nl80211 vendor cmd*/ |
| 6751 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA; |
| 6752 | param.if_type = NL80211_ATTR_IFINDEX; |
| 6753 | param.if_idx = if_idx; |
| 6754 | |
| 6755 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 6756 | if (ret) { |
| 6757 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 6758 | return RETURN_ERR; |
| 6759 | } |
| 6760 | /*add mtk vendor cmd data*/ |
| 6761 | if (nla_put_u8(msg, vendor_data_attr, 0xf)) { |
| 6762 | wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr); |
| 6763 | nlmsg_free(msg); |
| 6764 | goto err; |
| 6765 | } |
| 6766 | |
| 6767 | /*send mtk nl80211 vendor msg*/ |
| 6768 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool); |
| 6769 | if (ret) { |
| 6770 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 6771 | goto err; |
| 6772 | } |
| 6773 | /*deinit mtk nl80211 vendor msg*/ |
| 6774 | mtk_nl80211_deint(&unl_ins); |
| 6775 | wifi_debug(DEBUG_NOTICE,"send cmd success, get output_bool:%d\n", *output_bool); |
| 6776 | return RETURN_OK; |
| 6777 | err: |
| 6778 | mtk_nl80211_deint(&unl_ins); |
| 6779 | wifi_debug(DEBUG_ERROR,"send cmd fails\n"); |
| 6780 | return RETURN_ERR; |
| 6781 | } |
| 6782 | //Get radio ADDBA enable setting |
| 6783 | INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool) |
| 6784 | { |
| 6785 | if (output_bool == NULL) { |
| 6786 | wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n"); |
| 6787 | return RETURN_ERR; |
| 6788 | } |
| 6789 | if (mtk_wifi_get_ba_decl_auto_status(radioIndex, |
| 6790 | MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) { |
| 6791 | wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n", |
| 6792 | MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO); |
| 6793 | return RETURN_ERR; |
| 6794 | } |
| 6795 | wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool); |
| 6796 | return RETURN_OK; |
| 6797 | } |
| 6798 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6799 | //Set radio ADDBA enable setting |
| 6800 | INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable) |
| 6801 | { |
| 6802 | return RETURN_ERR; |
| 6803 | } |
| 6804 | |
| 6805 | //Get radio auto block ack enable setting |
| 6806 | INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool) |
| 6807 | { |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6808 | if (output_bool == NULL) { |
| 6809 | wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n"); |
| 6810 | return RETURN_ERR; |
| 6811 | } |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 6812 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6813 | if (mtk_wifi_get_ba_decl_auto_status(radioIndex, |
| 6814 | MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, |
| 6815 | mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) { |
| 6816 | wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n", |
| 6817 | MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO); |
| 6818 | return RETURN_ERR; |
| 6819 | } |
| 6820 | wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool); |
| 6821 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6822 | } |
| 6823 | |
| 6824 | //Set radio auto block ack enable setting |
| 6825 | INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable) |
| 6826 | { |
| 6827 | return RETURN_ERR; |
| 6828 | } |
| 6829 | |
| 6830 | //Get radio 11n pure mode enable support |
| 6831 | INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool) |
| 6832 | { |
| 6833 | if (NULL == output_bool) |
| 6834 | return RETURN_ERR; |
| 6835 | *output_bool = TRUE; |
| 6836 | return RETURN_OK; |
| 6837 | } |
| 6838 | |
| 6839 | //Get radio 11n pure mode enable setting |
| 6840 | INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool) |
| 6841 | { |
| 6842 | if (NULL == output_bool) |
| 6843 | return RETURN_ERR; |
| 6844 | *output_bool = TRUE; |
| 6845 | return RETURN_OK; |
| 6846 | } |
| 6847 | |
| 6848 | //Set radio 11n pure mode enable setting |
| 6849 | INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable) |
| 6850 | { |
| 6851 | return RETURN_ERR; |
| 6852 | } |
| 6853 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6854 | |
| 6855 | int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6856 | { |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6857 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 6858 | struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1]; |
| 6859 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 6860 | unsigned char status = 0, *out_status = data; |
| 6861 | int err = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6862 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6863 | err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 6864 | genlmsg_attrlen(gnlh, 0), NULL); |
| 6865 | if (err < 0) { |
| 6866 | wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n"); |
| 6867 | return err; |
| 6868 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6869 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6870 | if (tb[NL80211_ATTR_VENDOR_DATA]) { |
| 6871 | err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX, |
| 6872 | tb[NL80211_ATTR_VENDOR_DATA], NULL); |
| 6873 | if (err < 0){ |
| 6874 | wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n"); |
| 6875 | return err; |
| 6876 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6877 | |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6878 | if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) { |
| 6879 | status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]); |
| 6880 | if (status == 0) { |
| 6881 | wifi_debug(DEBUG_NOTICE, "disabled\n"); |
| 6882 | } else { |
| 6883 | wifi_debug(DEBUG_NOTICE, "enabled\n"); |
| 6884 | } |
| 6885 | *out_status = status; |
| 6886 | wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status); |
| 6887 | } |
| 6888 | } |
| 6889 | |
| 6890 | return 0; |
| 6891 | } |
| 6892 | |
| 6893 | INT mtk_wifi_set_igmp_en_status( |
| 6894 | INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, |
| 6895 | unsigned char in_en_stat, BOOL *output_bool) |
| 6896 | { |
| 6897 | char inf_name[IF_NAME_SIZE] = {0}; |
| 6898 | struct mtk_nl80211_param params; |
| 6899 | unsigned int if_idx = 0; |
| 6900 | int ret = -1; |
| 6901 | struct unl unl_ins; |
| 6902 | struct nl_msg *msg = NULL; |
| 6903 | struct nlattr * msg_data = NULL; |
| 6904 | struct mtk_nl80211_param param; |
| 6905 | |
| 6906 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 6907 | return RETURN_ERR; |
| 6908 | if_idx = if_nametoindex(inf_name); |
| 6909 | if (!if_idx) { |
| 6910 | wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name); |
| 6911 | return RETURN_ERR; |
| 6912 | } |
| 6913 | /*init mtk nl80211 vendor cmd*/ |
| 6914 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING; |
| 6915 | param.if_type = NL80211_ATTR_IFINDEX; |
| 6916 | param.if_idx = if_idx; |
| 6917 | |
| 6918 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 6919 | if (ret) { |
| 6920 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 6921 | return RETURN_ERR; |
| 6922 | } |
| 6923 | /*add mtk vendor cmd data*/ |
| 6924 | if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) { |
| 6925 | wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr); |
| 6926 | nlmsg_free(msg); |
| 6927 | goto err; |
| 6928 | } |
| 6929 | |
| 6930 | /*send mtk nl80211 vendor msg*/ |
| 6931 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool); |
| 6932 | if (ret) { |
| 6933 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 6934 | goto err; |
| 6935 | } |
| 6936 | /*deinit mtk nl80211 vendor msg*/ |
| 6937 | mtk_nl80211_deint(&unl_ins); |
| 6938 | if (output_bool) { |
| 6939 | wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool); |
| 6940 | } else { |
| 6941 | wifi_debug(DEBUG_NOTICE, "send cmd success.\n"); |
| 6942 | } |
| 6943 | return RETURN_OK; |
| 6944 | err: |
| 6945 | mtk_nl80211_deint(&unl_ins); |
| 6946 | wifi_debug(DEBUG_ERROR,"send cmd fails\n"); |
| 6947 | return RETURN_ERR; |
| 6948 | } |
| 6949 | |
| 6950 | |
| 6951 | //Get radio IGMP snooping enable setting |
| 6952 | INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool) |
| 6953 | { |
| 6954 | if (output_bool == NULL) { |
| 6955 | wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n"); |
| 6956 | return RETURN_ERR; |
| 6957 | } |
| 6958 | if (mtk_wifi_set_igmp_en_status |
| 6959 | (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE, |
| 6960 | mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) { |
| 6961 | wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n"); |
| 6962 | return RETURN_ERR; |
| 6963 | } |
| 6964 | wifi_debug(DEBUG_ERROR, "send cmd success: get igmp status:(%d)\n", *output_bool); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6965 | return RETURN_OK; |
| 6966 | } |
| 6967 | |
| 6968 | //Set radio IGMP snooping enable setting |
| 6969 | INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable) |
| 6970 | { |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 6971 | if (mtk_wifi_set_igmp_en_status |
| 6972 | (radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE, |
| 6973 | NULL, enable, NULL) != RETURN_OK) { |
| 6974 | wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n"); |
| 6975 | return RETURN_ERR; |
| 6976 | } |
| 6977 | wifi_debug(DEBUG_ERROR, "send cmd success: set igmp enable(%d)\n", enable); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6978 | return RETURN_OK; |
| 6979 | } |
| 6980 | |
| 6981 | //Get the Reset count of radio |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 6982 | INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6983 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 6984 | if (NULL == output_int) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6985 | return RETURN_ERR; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 6986 | *output_int = get_radio_reset_cnt(radioIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 6987 | |
| 6988 | return RETURN_OK; |
| 6989 | } |
| 6990 | |
| 6991 | |
| 6992 | //--------------------------------------------------------------------------------------------------- |
| 6993 | // |
| 6994 | // Additional Wifi AP level APIs used for Access Point devices |
| 6995 | // |
| 6996 | //--------------------------------------------------------------------------------------------------- |
| 6997 | |
| 6998 | // creates a new ap and pushes these parameters to the hardware |
| 6999 | INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid) |
| 7000 | { |
| 7001 | // Deprecated when use hal version 3, use wifi_createVap() instead. |
| 7002 | return RETURN_OK; |
| 7003 | } |
| 7004 | |
| 7005 | // deletes this ap entry on the hardware, clears all internal variables associaated with this ap |
| 7006 | INT wifi_deleteAp(INT apIndex) |
| 7007 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7008 | char interface_name[16] = {0}; |
| 7009 | char buf[MAX_BUF_SIZE]; |
| 7010 | char cmd[MAX_CMD_SIZE]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7011 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7012 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 7013 | return RETURN_ERR; |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 7014 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7015 | snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name); |
| 7016 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7017 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7018 | wifi_removeApSecVaribles(apIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7019 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7020 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7021 | } |
| 7022 | |
| 7023 | // Outputs a 16 byte or less name assocated with the AP. String buffer must be pre-allocated by the caller |
| 7024 | INT wifi_getApName(INT apIndex, CHAR *output_string) |
| 7025 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7026 | char interface_name[IF_NAME_SIZE] = {0}; |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 7027 | int radio_idx = 0; |
| 7028 | int bss_idx = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7029 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7030 | if(!output_string) |
| 7031 | return RETURN_ERR; |
| 7032 | |
| 7033 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) { |
| 7034 | vap_index_to_array_index(apIndex, &radio_idx, &bss_idx); |
| 7035 | |
| 7036 | snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx); // For wifiagent generating data model. |
| 7037 | } else |
| 7038 | snprintf(output_string, IF_NAME_SIZE, "%s", interface_name); |
| 7039 | |
| 7040 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7041 | } |
| 7042 | |
| 7043 | // Outputs the index number in that corresponds to the SSID string |
| 7044 | INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int) |
| 7045 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7046 | char cmd [128] = {0}; |
| 7047 | char buf[32] = {0}; |
| 7048 | char ap_idx = 0; |
| 7049 | char *apIndex_str = NULL; |
| 7050 | char radio_idx = 0; |
| 7051 | char bss_idx = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7052 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7053 | snprintf(cmd, sizeof(cmd), "grep -rn ^interface=%s$ /nvram/hostapd*.conf | cut -d '.' -f1 | cut -d 'd' -f2 | tr -d '\\n'", |
| 7054 | inputSsidString); |
| 7055 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7056 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7057 | if (strlen(buf)) { |
| 7058 | apIndex_str = strtok(buf, "\n"); |
| 7059 | *output_int = strtoul(apIndex_str, NULL, 10); |
| 7060 | return RETURN_OK; |
| 7061 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7062 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7063 | /* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/ |
| 7064 | if (strstr(inputSsidString, PREFIX_WIFI6G)) { |
| 7065 | bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G)); |
| 7066 | radio_idx = 2; |
| 7067 | } else if (strstr(inputSsidString, PREFIX_WIFI5G)) { |
| 7068 | bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G)); |
| 7069 | radio_idx = 1; |
| 7070 | } else if (strstr(inputSsidString, PREFIX_WIFI2G)) { |
| 7071 | bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G)); |
| 7072 | radio_idx = 0; |
| 7073 | } else { |
| 7074 | printf("%s: hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n", |
| 7075 | __func__, inputSsidString, ap_idx); |
| 7076 | *output_int = -1; |
| 7077 | return RETURN_ERR; |
| 7078 | } |
| 7079 | |
| 7080 | ap_idx = array_index_to_vap_index(radio_idx, bss_idx); |
| 7081 | |
| 7082 | if (ap_idx >= 0 && ap_idx < MAX_VAP) { |
| 7083 | printf("%s: hostapd conf not find, inf(%s), use inf idx(%d).\n", |
| 7084 | __func__, inputSsidString, ap_idx); |
| 7085 | *output_int = ap_idx; |
| 7086 | return RETURN_OK; |
| 7087 | } |
| 7088 | |
| 7089 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7090 | } |
| 7091 | |
| 7092 | INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int) |
| 7093 | { |
| 7094 | return wifi_getIndexFromName(inputSsidString, output_int); |
| 7095 | } |
| 7096 | |
| 7097 | // Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i" |
| 7098 | INT wifi_getApBeaconType(INT apIndex, CHAR *output_string) |
| 7099 | { |
| 7100 | char buf[MAX_BUF_SIZE] = {0}; |
| 7101 | char cmd[MAX_CMD_SIZE] = {0}; |
| 7102 | char config_file[MAX_BUF_SIZE] = {0}; |
| 7103 | |
| 7104 | if(NULL == output_string) |
| 7105 | return RETURN_ERR; |
| 7106 | |
| 7107 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7108 | wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf)); |
| 7109 | if((strcmp(buf,"3")==0)) |
| 7110 | snprintf(output_string, 32, "WPAand11i"); |
| 7111 | else if((strcmp(buf,"2")==0)) |
| 7112 | snprintf(output_string, 32, "11i"); |
| 7113 | else if((strcmp(buf,"1")==0)) |
| 7114 | snprintf(output_string, 32, "WPA"); |
| 7115 | else |
| 7116 | snprintf(output_string, 32, "None"); |
| 7117 | |
| 7118 | return RETURN_OK; |
| 7119 | } |
| 7120 | |
| 7121 | // Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i" |
| 7122 | INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString) |
| 7123 | { |
| 7124 | char config_file[MAX_BUF_SIZE] = {0}; |
| 7125 | struct params list; |
| 7126 | |
| 7127 | if (NULL == beaconTypeString) |
| 7128 | return RETURN_ERR; |
| 7129 | list.name = "wpa"; |
| 7130 | list.value = "0"; |
| 7131 | |
| 7132 | if((strcmp(beaconTypeString,"WPAand11i")==0)) |
| 7133 | list.value="3"; |
| 7134 | else if((strcmp(beaconTypeString,"11i")==0)) |
| 7135 | list.value="2"; |
| 7136 | else if((strcmp(beaconTypeString,"WPA")==0)) |
| 7137 | list.value="1"; |
| 7138 | |
| 7139 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7140 | wifi_hostapdWrite(config_file, &list, 1); |
| 7141 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 7142 | //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply |
| 7143 | return RETURN_OK; |
| 7144 | } |
| 7145 | |
| 7146 | // sets the beacon interval on the hardware for this AP |
| 7147 | INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval) |
| 7148 | { |
| 7149 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7150 | struct params params={'\0'}; |
| 7151 | char buf[MAX_BUF_SIZE] = {'\0'}; |
| 7152 | char config_file[MAX_BUF_SIZE] = {'\0'}; |
| 7153 | |
| 7154 | params.name = "beacon_int"; |
| 7155 | snprintf(buf, sizeof(buf), "%u", beaconInterval); |
| 7156 | params.value = buf; |
| 7157 | |
| 7158 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 7159 | wifi_hostapdWrite(config_file, ¶ms, 1); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 7160 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7161 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 7162 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7163 | return RETURN_OK; |
| 7164 | } |
| 7165 | |
| 7166 | INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval) |
| 7167 | { |
| 7168 | if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK) |
| 7169 | return RETURN_ERR; |
| 7170 | return RETURN_OK; |
| 7171 | } |
| 7172 | |
| 7173 | // Get the packet size threshold supported. |
| 7174 | INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool) |
| 7175 | { |
| 7176 | //save config and apply instantly |
| 7177 | if (NULL == output_bool) |
| 7178 | return RETURN_ERR; |
| 7179 | *output_bool = TRUE; |
| 7180 | return RETURN_OK; |
| 7181 | } |
| 7182 | |
| 7183 | // sets the packet size threshold in bytes to apply RTS/CTS backoff rules. |
| 7184 | INT wifi_setApRtsThreshold(INT apIndex, UINT threshold) |
| 7185 | { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7186 | char buf[16] = {0}; |
| 7187 | char config_file[128] = {0}; |
| 7188 | struct params param = {0}; |
| 7189 | |
| 7190 | if (threshold > 65535) { |
| 7191 | fprintf(stderr, "%s: rts threshold %u is too big.\n", __func__, threshold); |
| 7192 | return RETURN_ERR; |
| 7193 | } |
| 7194 | |
developer | 23e7128 | 2023-01-18 10:25:19 +0800 | [diff] [blame] | 7195 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7196 | snprintf(buf, sizeof(buf), "%u", threshold); |
| 7197 | param.name = "rts_threshold"; |
| 7198 | param.value = buf; |
| 7199 | wifi_hostapdWrite(config_file, ¶m, 1); |
| 7200 | wifi_hostapdProcessUpdate(apIndex, ¶m, 1); |
| 7201 | wifi_reloadAp(apIndex); |
| 7202 | |
| 7203 | return RETURN_OK; |
| 7204 | } |
| 7205 | |
| 7206 | // outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption" |
| 7207 | INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string) |
| 7208 | { |
| 7209 | if (NULL == output_string) |
| 7210 | return RETURN_ERR; |
| 7211 | snprintf(output_string, 32, "TKIPandAESEncryption"); |
| 7212 | return RETURN_OK; |
| 7213 | |
| 7214 | } |
| 7215 | |
| 7216 | // outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption" |
| 7217 | INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string) |
| 7218 | { |
| 7219 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7220 | char *param_name = NULL; |
| 7221 | char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0}; |
| 7222 | |
| 7223 | if(NULL == output_string) |
| 7224 | return RETURN_ERR; |
| 7225 | |
| 7226 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7227 | wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf)); |
| 7228 | |
| 7229 | if(strcmp(buf,"0")==0) |
| 7230 | { |
| 7231 | printf("%s: wpa_mode is %s ......... \n", __func__, buf); |
| 7232 | snprintf(output_string, 32, "None"); |
| 7233 | return RETURN_OK; |
| 7234 | } |
| 7235 | else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0)) |
| 7236 | param_name = "rsn_pairwise"; |
| 7237 | else if((strcmp(buf,"1")==0)) |
| 7238 | param_name = "wpa_pairwise"; |
| 7239 | else |
| 7240 | return RETURN_ERR; |
| 7241 | memset(output_string,'\0',32); |
| 7242 | wifi_hostapdRead(config_file,param_name,output_string,32); |
| 7243 | if (strlen(output_string) == 0) { // rsn_pairwise is optional. When it is empty use wpa_pairwise instead. |
| 7244 | param_name = "wpa_pairwise"; |
| 7245 | memset(output_string, '\0', 32); |
| 7246 | wifi_hostapdRead(config_file, param_name, output_string, 32); |
| 7247 | } |
| 7248 | wifi_dbg_printf("\n%s output_string=%s",__func__,output_string); |
| 7249 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 7250 | if(strcmp(output_string,"TKIP CCMP") == 0) |
| 7251 | strncpy(output_string,"TKIPandAESEncryption", strlen("TKIPandAESEncryption")); |
| 7252 | else if(strcmp(output_string,"TKIP") == 0) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7253 | strncpy(output_string,"TKIPEncryption", strlen("TKIPEncryption")); |
| 7254 | else if(strcmp(output_string,"CCMP") == 0) |
| 7255 | strncpy(output_string,"AESEncryption", strlen("AESEncryption")); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7256 | |
| 7257 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7258 | return RETURN_OK; |
| 7259 | } |
| 7260 | |
| 7261 | // sets the encyption mode enviornment variable. Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption" |
| 7262 | INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode) |
| 7263 | { |
| 7264 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7265 | struct params params={'\0'}; |
| 7266 | char output_string[32]; |
| 7267 | char config_file[MAX_BUF_SIZE] = {0}; |
| 7268 | |
| 7269 | memset(output_string,'\0',32); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 7270 | wifi_getApBeaconType(apIndex,output_string); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7271 | |
| 7272 | if(strcmp(encMode, "TKIPEncryption") == 0) |
| 7273 | params.value = "TKIP"; |
| 7274 | else if(strcmp(encMode,"AESEncryption") == 0) |
| 7275 | params.value = "CCMP"; |
| 7276 | else if(strcmp(encMode,"TKIPandAESEncryption") == 0) |
| 7277 | params.value = "TKIP CCMP"; |
| 7278 | |
| 7279 | if((strcmp(output_string,"WPAand11i")==0)) |
| 7280 | { |
| 7281 | params.name = "wpa_pairwise"; |
| 7282 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7283 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 7284 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 7285 | |
| 7286 | params.name = "rsn_pairwise"; |
| 7287 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7288 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 7289 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 7290 | |
| 7291 | return RETURN_OK; |
| 7292 | } |
| 7293 | else if((strcmp(output_string,"11i")==0)) |
| 7294 | { |
| 7295 | params.name = "rsn_pairwise"; |
| 7296 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7297 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 7298 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 7299 | return RETURN_OK; |
| 7300 | } |
| 7301 | else if((strcmp(output_string,"WPA")==0)) |
| 7302 | { |
| 7303 | params.name = "wpa_pairwise"; |
| 7304 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7305 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 7306 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 7307 | return RETURN_OK; |
| 7308 | } |
| 7309 | |
| 7310 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7311 | return RETURN_OK; |
| 7312 | } |
| 7313 | |
| 7314 | // deletes internal security varable settings for this ap |
| 7315 | INT wifi_removeApSecVaribles(INT apIndex) |
| 7316 | { |
| 7317 | //TODO: remove the entry in hostapd config file |
| 7318 | //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/nvram\\/etc\\/wpa2\\/WSC_%s.conf//g' /tmp/conf_filename", interface_name); |
| 7319 | //_syscmd(cmd, buf, sizeof(buf)); |
| 7320 | |
| 7321 | //snprintf(cmd,sizeof(cmd), "sed -i 's/\\/tmp\\//sec%s//g' /tmp/conf_filename", interface_name); |
| 7322 | //_syscmd(cmd, buf, sizeof(buf)); |
| 7323 | return RETURN_ERR; |
| 7324 | } |
| 7325 | |
| 7326 | // changes the hardware settings to disable encryption on this ap |
| 7327 | INT wifi_disableApEncryption(INT apIndex) |
| 7328 | { |
| 7329 | //Apply instantly |
| 7330 | return RETURN_ERR; |
| 7331 | } |
| 7332 | |
| 7333 | // set the authorization mode on this ap |
| 7334 | // mode mapping as: 1: open, 2: shared, 4:auto |
| 7335 | INT wifi_setApAuthMode(INT apIndex, INT mode) |
| 7336 | { |
| 7337 | struct params params={0}; |
| 7338 | char config_file[64] = {0}; |
| 7339 | int ret; |
| 7340 | |
| 7341 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 7342 | |
| 7343 | wifi_dbg_printf("\n%s algo_mode=%d", __func__, mode); |
| 7344 | params.name = "auth_algs"; |
| 7345 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 7346 | if ((mode & 1 && mode & 2) || mode & 4) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7347 | params.value = "3"; |
| 7348 | else if (mode & 2) |
| 7349 | params.value = "2"; |
| 7350 | else if (mode & 1) |
| 7351 | params.value = "1"; |
| 7352 | else |
| 7353 | params.value = "0"; |
| 7354 | |
| 7355 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 7356 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 7357 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 7358 | wifi_reloadAp(apIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7359 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 7360 | |
| 7361 | return RETURN_OK; |
| 7362 | } |
| 7363 | |
| 7364 | // sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication" |
| 7365 | INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode) |
| 7366 | { |
| 7367 | //save to wifi config, and wait for wifi restart to apply |
| 7368 | struct params params={'\0'}; |
| 7369 | char config_file[MAX_BUF_SIZE] = {0}; |
| 7370 | int ret; |
| 7371 | |
| 7372 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 7373 | if(authMode == NULL) |
| 7374 | return RETURN_ERR; |
| 7375 | |
| 7376 | wifi_dbg_printf("\n%s AuthMode=%s",__func__,authMode); |
| 7377 | params.name = "wpa_key_mgmt"; |
| 7378 | |
| 7379 | if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0)) |
| 7380 | params.value = "WPA-PSK"; |
| 7381 | else if(strcmp(authMode,"EAPAuthentication") == 0) |
| 7382 | params.value = "WPA-EAP"; |
| 7383 | else if (strcmp(authMode, "SAEAuthentication") == 0) |
| 7384 | params.value = "SAE"; |
| 7385 | else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0) |
| 7386 | params.value = "WPA-EAP-SUITE-B-192"; |
| 7387 | else if (strcmp(authMode, "PSK-SAEAuthentication") == 0) |
| 7388 | params.value = "WPA-PSK WPA-PSK-SHA256 SAE"; |
developer | 3086e2f | 2023-01-17 09:40:01 +0800 | [diff] [blame] | 7389 | else if (strcmp(authMode, "Enhanced_Open") == 0) |
| 7390 | params.value = "OWE"; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7391 | else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None |
| 7392 | return RETURN_OK; //This is taken careof in beaconType |
| 7393 | |
| 7394 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7395 | ret=wifi_hostapdWrite(config_file,¶ms,1); |
| 7396 | if(!ret) |
| 7397 | ret=wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 7398 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 7399 | |
| 7400 | return ret; |
| 7401 | } |
| 7402 | |
| 7403 | // sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication" |
| 7404 | INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode) |
| 7405 | { |
| 7406 | //save to wifi config, and wait for wifi restart to apply |
| 7407 | char BeaconType[50] = {0}; |
| 7408 | char config_file[MAX_BUF_SIZE] = {0}; |
| 7409 | |
| 7410 | *authMode = 0; |
| 7411 | wifi_getApBeaconType(apIndex,BeaconType); |
| 7412 | printf("%s____%s \n",__FUNCTION__,BeaconType); |
| 7413 | |
| 7414 | if(strcmp(BeaconType,"None") == 0) |
| 7415 | strcpy(authMode,"None"); |
| 7416 | else |
| 7417 | { |
| 7418 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 7419 | wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32); |
| 7420 | wifi_dbg_printf("\n[%s]: AuthMode Name is : %s",__func__,authMode); |
| 7421 | if(strcmp(authMode,"WPA-PSK") == 0) |
| 7422 | strcpy(authMode,"SharedAuthentication"); |
| 7423 | else if(strcmp(authMode,"WPA-EAP") == 0) |
| 7424 | strcpy(authMode,"EAPAuthentication"); |
| 7425 | } |
| 7426 | |
| 7427 | return RETURN_OK; |
| 7428 | } |
| 7429 | |
| 7430 | // Outputs the number of stations associated per AP |
| 7431 | INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong) |
| 7432 | { |
| 7433 | char interface_name[16] = {0}; |
| 7434 | char cmd[128]={0}; |
| 7435 | char buf[128]={0}; |
| 7436 | BOOL status = false; |
| 7437 | |
| 7438 | if(apIndex > MAX_APS) |
| 7439 | return RETURN_ERR; |
| 7440 | |
| 7441 | wifi_getApEnable(apIndex,&status); |
| 7442 | if (!status) |
| 7443 | return RETURN_OK; |
| 7444 | |
| 7445 | //sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method |
| 7446 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 7447 | return RETURN_ERR; |
| 7448 | sprintf(cmd, "hostapd_cli -i %s list_sta | wc -l", interface_name); |
| 7449 | _syscmd(cmd, buf, sizeof(buf)); |
| 7450 | sscanf(buf,"%lu", output_ulong); |
| 7451 | |
| 7452 | return RETURN_OK; |
| 7453 | } |
| 7454 | |
| 7455 | // manually removes any active wi-fi association with the device specified on this ap |
| 7456 | INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac) |
| 7457 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7458 | char inf_name[16] = {0}; |
| 7459 | char cmd[MAX_CMD_SIZE] = {0}; |
| 7460 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7461 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7462 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7463 | return RETURN_ERR; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7464 | |
| 7465 | snprintf(cmd, sizeof(cmd),"hostapd_cli -i %s disassociate %s", inf_name, client_mac); |
| 7466 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7467 | |
| 7468 | return RETURN_OK; |
| 7469 | } |
| 7470 | |
| 7471 | // outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex |
| 7472 | INT wifi_getApRadioIndex(INT apIndex, INT *output_int) |
| 7473 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7474 | int max_radio_num = 0; |
| 7475 | |
| 7476 | if(NULL == output_int) |
| 7477 | return RETURN_ERR; |
| 7478 | |
| 7479 | wifi_getMaxRadioNumber(&max_radio_num); |
| 7480 | *output_int = apIndex % max_radio_num; |
| 7481 | |
| 7482 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7483 | } |
| 7484 | |
| 7485 | // sets the radio index for the specific ap |
| 7486 | INT wifi_setApRadioIndex(INT apIndex, INT radioIndex) |
| 7487 | { |
| 7488 | //set to config only and wait for wifi reset to apply settings |
| 7489 | return RETURN_ERR; |
| 7490 | } |
| 7491 | |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7492 | |
| 7493 | #define MAX_ACL_DUMP_LEN 4096 |
| 7494 | int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb) |
| 7495 | { |
| 7496 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 7497 | struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1]; |
| 7498 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 7499 | char *show_str = NULL; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7500 | int err = 0; |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7501 | unsigned short acl_result_len = 0; |
| 7502 | struct mtk_nl80211_cb_data *cb_data = cb; |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7503 | if (!msg || !cb_data) { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7504 | wifi_debug(DEBUG_ERROR, "msg(0x%lx) or cb_data(0x%lx) is null,error.\n", msg, cb_data); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7505 | return NL_SKIP; |
| 7506 | } |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7507 | err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 7508 | genlmsg_attrlen(gnlh, 0), NULL); |
| 7509 | if (err < 0) { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7510 | wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n"); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7511 | return NL_SKIP; |
| 7512 | } |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7513 | if (tb[NL80211_ATTR_VENDOR_DATA]) { |
| 7514 | err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX, |
| 7515 | tb[NL80211_ATTR_VENDOR_DATA], NULL); |
| 7516 | if (err < 0) |
| 7517 | return NL_SKIP; |
| 7518 | if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) { |
| 7519 | acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]); |
| 7520 | show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]); |
| 7521 | if (acl_result_len > MAX_ACL_DUMP_LEN) { |
| 7522 | wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n"); |
| 7523 | return NL_SKIP; |
| 7524 | } else if (*(show_str + acl_result_len - 1) != '\0') { |
| 7525 | wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n"); |
| 7526 | *(show_str + acl_result_len - 1) = '\0'; |
| 7527 | } |
| 7528 | wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str); |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7529 | |
| 7530 | if (cb_data->out_len >= acl_result_len) { |
| 7531 | memset(cb_data->out_buf, 0, cb_data->out_len); |
| 7532 | /*skip the first line: 'policy=1\n' to find the acl mac addrs*/ |
| 7533 | memmove(cb_data->out_buf, show_str, acl_result_len); |
| 7534 | wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf); |
| 7535 | } else { |
| 7536 | memset(cb_data->out_buf, 0, cb_data->out_len); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7537 | } |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7538 | } else |
| 7539 | wifi_debug(DEBUG_ERROR, "no acl result attr\n"); |
| 7540 | } else |
| 7541 | wifi_debug(DEBUG_ERROR, "no any acl result from driver\n"); |
| 7542 | return NL_OK; |
| 7543 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7544 | // Get the ACL MAC list per AP |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7545 | INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7546 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7547 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7548 | struct mtk_nl80211_param params; |
| 7549 | unsigned int if_idx = 0; |
| 7550 | int ret = -1; |
| 7551 | struct unl unl_ins; |
| 7552 | struct nl_msg *msg = NULL; |
| 7553 | struct nlattr * msg_data = NULL; |
| 7554 | struct mtk_nl80211_param param; |
| 7555 | struct mtk_nl80211_cb_data cb_data; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7556 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 7557 | return RETURN_ERR; |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7558 | if_idx = if_nametoindex(inf_name); |
| 7559 | if (!if_idx) { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7560 | wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7561 | return RETURN_ERR; |
| 7562 | } |
| 7563 | /*init mtk nl80211 vendor cmd*/ |
| 7564 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL; |
| 7565 | param.if_type = NL80211_ATTR_IFINDEX; |
| 7566 | param.if_idx = if_idx; |
| 7567 | |
| 7568 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 7569 | if (ret) { |
| 7570 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 7571 | return RETURN_ERR; |
| 7572 | } |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7573 | /*add mtk vendor cmd data*/ |
| 7574 | if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7575 | wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n"); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7576 | nlmsg_free(msg); |
| 7577 | goto err; |
| 7578 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7579 | |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7580 | /*send mtk nl80211 vendor msg*/ |
| 7581 | cb_data.out_buf = macArray; |
| 7582 | cb_data.out_len = buf_size; |
| 7583 | |
| 7584 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data); |
| 7585 | if (ret) { |
| 7586 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 7587 | goto err; |
| 7588 | } |
| 7589 | /*deinit mtk nl80211 vendor msg*/ |
| 7590 | mtk_nl80211_deint(&unl_ins); |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7591 | wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7592 | return RETURN_OK; |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7593 | err: |
| 7594 | mtk_nl80211_deint(&unl_ins); |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7595 | wifi_debug(DEBUG_ERROR,"send cmd fails\n"); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 7596 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7597 | } |
| 7598 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7599 | INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size) |
| 7600 | { |
| 7601 | char *mac_arry_buf = NULL; |
| 7602 | |
| 7603 | mac_arry_buf = malloc(buf_size); |
| 7604 | if (!mac_arry_buf) { |
| 7605 | wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n"); |
| 7606 | return RETURN_ERR; |
| 7607 | } |
| 7608 | memset(mac_arry_buf, 0, buf_size); |
| 7609 | if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) { |
| 7610 | wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n"); |
| 7611 | free(mac_arry_buf); |
| 7612 | mac_arry_buf = NULL; |
| 7613 | return RETURN_ERR; |
| 7614 | } |
| 7615 | /* |
| 7616 | mtk format to wifi hal format: |
| 7617 | "policy=1 |
| 7618 | 00:11:22:33:44:55 |
| 7619 | 00:11:22:33:44:66 |
| 7620 | " |
| 7621 | --> |
| 7622 | "00:11:22:33:44:55 |
| 7623 | 00:11:22:33:44:66 |
| 7624 | " |
| 7625 | */ |
| 7626 | memset(macArray, 0, buf_size); |
| 7627 | if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) { |
| 7628 | memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1); |
| 7629 | wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray); |
| 7630 | } |
| 7631 | free(mac_arry_buf); |
| 7632 | mac_arry_buf = NULL; |
| 7633 | return RETURN_OK; |
| 7634 | } |
| 7635 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7636 | INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size) |
| 7637 | { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7638 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7639 | wifi_getApAclDevices(apIndex, macArray, buf_size); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7640 | |
| 7641 | return RETURN_OK; |
| 7642 | } |
| 7643 | |
| 7644 | |
| 7645 | // Get the list of stations associated per AP |
| 7646 | INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size) |
| 7647 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7648 | char interface_name[IF_NAME_SIZE] = {0}; |
| 7649 | char cmd[MAX_CMD_SIZE]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7650 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7651 | if(apIndex > 3) //Currently supporting apIndex upto 3 |
| 7652 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7653 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7654 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 7655 | return RETURN_ERR; |
| 7656 | |
| 7657 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s list_sta", interface_name); |
| 7658 | _syscmd(cmd, macArray, buf_size); |
| 7659 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7660 | } |
| 7661 | |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7662 | int hex2num(char c) |
| 7663 | { |
| 7664 | if (c >= '0' && c <= '9') |
| 7665 | return c - '0'; |
| 7666 | if (c >= 'a' && c <= 'f') |
| 7667 | return c - 'a' + 10; |
| 7668 | if (c >= 'A' && c <= 'F') |
| 7669 | return c - 'A' + 10; |
| 7670 | return -1; |
| 7671 | } |
| 7672 | |
| 7673 | /** |
| 7674 | * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format) |
| 7675 | * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455) |
| 7676 | * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes) |
| 7677 | * Returns: Characters used (> 0) on success, -1 on failure |
| 7678 | */ |
| 7679 | int hwaddr_aton2(const char *txt, unsigned char *addr) |
| 7680 | { |
| 7681 | int i; |
| 7682 | const char *pos = txt; |
| 7683 | |
| 7684 | for (i = 0; i < 6; i++) { |
| 7685 | int a, b; |
| 7686 | |
| 7687 | while (*pos == ':' || *pos == '.' || *pos == '-') |
| 7688 | pos++; |
| 7689 | |
| 7690 | a = hex2num(*pos++); |
| 7691 | if (a < 0) |
| 7692 | return -1; |
| 7693 | b = hex2num(*pos++); |
| 7694 | if (b < 0) |
| 7695 | return -1; |
| 7696 | *addr++ = (a << 4) | b; |
| 7697 | } |
| 7698 | |
| 7699 | return pos - txt; |
| 7700 | } |
| 7701 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7702 | // adds the mac address to the filter list |
| 7703 | //DeviceMacAddress is in XX:XX:XX:XX:XX:XX format |
| 7704 | INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress) |
| 7705 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7706 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7707 | int if_idx, ret = 0; |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 7708 | struct nl_msg *msg = NULL; |
| 7709 | struct nlattr * msg_data = NULL; |
| 7710 | struct mtk_nl80211_param param; |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7711 | unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33}; |
| 7712 | struct unl unl_ins; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7713 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 7714 | return RETURN_ERR; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7715 | if (!DeviceMacAddress) |
| 7716 | return RETURN_ERR; |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7717 | if (hwaddr_aton2(DeviceMacAddress, mac) < 0) { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7718 | wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7719 | return RETURN_ERR; |
| 7720 | } |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7721 | if_idx = if_nametoindex(inf_name); |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7722 | if (!if_idx) { |
| 7723 | wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name); |
| 7724 | return RETURN_ERR; |
| 7725 | } |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 7726 | /*init mtk nl80211 vendor cmd*/ |
| 7727 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL; |
| 7728 | param.if_type = NL80211_ATTR_IFINDEX; |
| 7729 | param.if_idx = if_idx; |
| 7730 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 7731 | if (ret) { |
| 7732 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7733 | return RETURN_ERR; |
| 7734 | } |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 7735 | /*add mtk vendor cmd data*/ |
| 7736 | if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7737 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7738 | nlmsg_free(msg); |
| 7739 | goto err; |
| 7740 | } |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 7741 | /*send mtk nl80211 vendor msg*/ |
| 7742 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 7743 | if (ret) { |
| 7744 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7745 | goto err; |
| 7746 | } |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 7747 | /*deinit mtk nl80211 vendor msg*/ |
| 7748 | mtk_nl80211_deint(&unl_ins); |
| 7749 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7750 | return RETURN_OK; |
| 7751 | err: |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 7752 | mtk_nl80211_deint(&unl_ins); |
| 7753 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 7754 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7755 | } |
| 7756 | |
| 7757 | // deletes the mac address from the filter list |
| 7758 | //DeviceMacAddress is in XX:XX:XX:XX:XX:XX format |
| 7759 | INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress) |
| 7760 | { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7761 | struct unl unl_ins; |
| 7762 | int if_idx = 0, ret = 0; |
| 7763 | struct nl_msg *msg = NULL; |
| 7764 | struct nlattr * msg_data = NULL; |
| 7765 | struct mtk_nl80211_param param; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7766 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7767 | unsigned char mac[ETH_ALEN] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7768 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7769 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 7770 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7771 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7772 | if (!DeviceMacAddress) |
| 7773 | return RETURN_ERR; |
| 7774 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7775 | if (hwaddr_aton2(DeviceMacAddress, mac) < 0) { |
| 7776 | wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress); |
| 7777 | return RETURN_ERR; |
| 7778 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7779 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7780 | if_idx = if_nametoindex(inf_name); |
| 7781 | if (!if_idx) { |
| 7782 | wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name); |
| 7783 | return RETURN_ERR; |
| 7784 | } |
| 7785 | /*init mtk nl80211 vendor cmd*/ |
| 7786 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL; |
| 7787 | param.if_type = NL80211_ATTR_IFINDEX; |
| 7788 | param.if_idx = if_idx; |
| 7789 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 7790 | if (ret) { |
| 7791 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 7792 | return RETURN_ERR; |
| 7793 | } |
| 7794 | /*add mtk vendor cmd data*/ |
| 7795 | if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) { |
| 7796 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 7797 | nlmsg_free(msg); |
| 7798 | goto err; |
| 7799 | } |
| 7800 | /*send mtk nl80211 vendor msg*/ |
| 7801 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 7802 | if (ret) { |
| 7803 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 7804 | goto err; |
| 7805 | } |
| 7806 | /*deinit mtk nl80211 vendor msg*/ |
| 7807 | mtk_nl80211_deint(&unl_ins); |
| 7808 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
| 7809 | return RETURN_OK; |
| 7810 | err: |
| 7811 | mtk_nl80211_deint(&unl_ins); |
| 7812 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 7813 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7814 | } |
| 7815 | |
| 7816 | // outputs the number of devices in the filter list |
| 7817 | INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint) |
| 7818 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7819 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7820 | char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0}; |
| 7821 | UINT buf_size = 1024; |
| 7822 | UINT sta_num = 0; |
| 7823 | unsigned char mac[ETH_ALEN] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7824 | if(output_uint == NULL) |
| 7825 | return RETURN_ERR; |
| 7826 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7827 | mac_arry = (char *)malloc(buf_size); |
| 7828 | if (mac_arry == NULL) { |
| 7829 | wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n"); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7830 | return RETURN_ERR; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7831 | } |
| 7832 | memset(mac_arry, buf_size, 0); |
| 7833 | /*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/ |
| 7834 | if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) { |
| 7835 | wifi_debug(DEBUG_ERROR, "get acl list entries fails\n"); |
| 7836 | return RETURN_ERR; |
| 7837 | } |
| 7838 | /*count the acl str nums:*/ |
| 7839 | wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7840 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7841 | /*mac addr string format: |
| 7842 | exp1: 00:11:22:33:44:55\0 |
| 7843 | exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0 |
| 7844 | */ |
| 7845 | ptr = mac_arry; |
| 7846 | while (sscanf(ptr, "%17s", mac_str) == 1) { |
| 7847 | if (hwaddr_aton2(mac_str, mac) >= 0) |
| 7848 | sta_num++; |
| 7849 | ptr = strstr(ptr, mac_str) + strlen(mac_str); |
| 7850 | } |
| 7851 | *output_uint = sta_num; |
| 7852 | wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint); |
| 7853 | free(mac_arry); |
| 7854 | mac_arry = NULL; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7855 | return RETURN_OK; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7856 | err: |
| 7857 | free(mac_arry); |
| 7858 | mac_arry = NULL; |
| 7859 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7860 | } |
| 7861 | |
| 7862 | INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface) |
| 7863 | { |
| 7864 | char cmd[128]={'\0'}; |
| 7865 | char buf[128]={'\0'}; |
| 7866 | |
| 7867 | if(strcmp(action,"DENY")==0) |
| 7868 | { |
| 7869 | sprintf(buf,"iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",apIndex,interface,client_mac); |
| 7870 | system(buf); |
| 7871 | return RETURN_OK; |
| 7872 | } |
| 7873 | |
| 7874 | if(strcmp(action,"ALLOW")==0) |
| 7875 | { |
| 7876 | sprintf(buf,"iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",apIndex,interface,client_mac); |
| 7877 | system(buf); |
| 7878 | return RETURN_OK; |
| 7879 | } |
| 7880 | |
| 7881 | return RETURN_ERR; |
| 7882 | |
| 7883 | } |
| 7884 | |
| 7885 | // enable kick for devices on acl black list |
| 7886 | INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable) |
| 7887 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 7888 | char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL; |
| 7889 | char assocArray[MAX_BUF_SIZE] = {0}, *asso = NULL; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7890 | |
| 7891 | wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray)); |
| 7892 | wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray)); |
| 7893 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7894 | /* if there are no devices connected there is nothing to do */ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7895 | if (strlen(assocArray) < 17) |
| 7896 | return RETURN_OK; |
| 7897 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7898 | if (enable == TRUE) { |
| 7899 | /* kick off the MAC which is in ACL array (deny list) */ |
| 7900 | acl = strtok(aclArray, "\n"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7901 | while (acl != NULL) { |
| 7902 | if (strlen(acl) >= 17 && strcasestr(assocArray, acl)) |
| 7903 | wifi_kickApAssociatedDevice(apIndex, acl); |
| 7904 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7905 | acl = strtok(NULL, "\n"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7906 | } |
| 7907 | wifi_setApMacAddressControlMode(apIndex, 2); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7908 | } else |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7909 | wifi_setApMacAddressControlMode(apIndex, 0); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7910 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7911 | return RETURN_OK; |
| 7912 | } |
| 7913 | |
| 7914 | INT wifi_setPreferPrivateConnection(BOOL enable) |
| 7915 | { |
| 7916 | return RETURN_OK; |
| 7917 | } |
| 7918 | |
| 7919 | // sets the mac address filter control mode. 0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist |
| 7920 | INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode) |
| 7921 | { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7922 | int if_idx = 0, ret = 0; |
| 7923 | struct unl unl_ins; |
| 7924 | struct nl_msg *msg = NULL; |
| 7925 | struct nlattr * msg_data = NULL; |
| 7926 | struct mtk_nl80211_param param; |
| 7927 | int acl_policy = -1; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7928 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7929 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7930 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 7931 | return RETURN_ERR; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7932 | if_idx = if_nametoindex(inf_name); |
| 7933 | if (!if_idx) { |
| 7934 | wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name); |
| 7935 | return RETURN_ERR; |
| 7936 | } |
| 7937 | /*init mtk nl80211 vendor cmd*/ |
| 7938 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL; |
| 7939 | param.if_type = NL80211_ATTR_IFINDEX; |
| 7940 | param.if_idx = if_idx; |
| 7941 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 7942 | if (ret) { |
| 7943 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 7944 | return RETURN_ERR; |
| 7945 | } |
| 7946 | /*add mtk vendor cmd data*/ |
| 7947 | if (filterMode == 0) { |
| 7948 | acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE; |
| 7949 | } else if (filterMode == 1) { |
| 7950 | acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST; |
| 7951 | } else if (filterMode == 2) { |
| 7952 | acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST; |
| 7953 | } else { |
| 7954 | wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode); |
| 7955 | nlmsg_free(msg); |
| 7956 | goto err; |
| 7957 | } |
| 7958 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) { |
| 7959 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 7960 | nlmsg_free(msg); |
| 7961 | goto err; |
| 7962 | } |
| 7963 | /*send mtk nl80211 vendor msg*/ |
| 7964 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 7965 | if (ret) { |
| 7966 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 7967 | goto err; |
| 7968 | } |
| 7969 | /*deinit mtk nl80211 vendor msg*/ |
| 7970 | mtk_nl80211_deint(&unl_ins); |
| 7971 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 7972 | return RETURN_OK; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 7973 | err: |
| 7974 | mtk_nl80211_deint(&unl_ins); |
| 7975 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 7976 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 7977 | } |
| 7978 | |
| 7979 | // enables internal gateway VLAN mode. In this mode a Vlan tag is added to upstream (received) data packets before exiting the Wifi driver. VLAN tags in downstream data are stripped from data packets before transmission. Default is FALSE. |
| 7980 | INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled) |
| 7981 | { |
| 7982 | return RETURN_ERR; |
| 7983 | } |
| 7984 | |
| 7985 | // gets the vlan ID for this ap from an internal enviornment variable |
| 7986 | INT wifi_getApVlanID(INT apIndex, INT *output_int) |
| 7987 | { |
| 7988 | if(apIndex==0) |
| 7989 | { |
| 7990 | *output_int=100; |
| 7991 | return RETURN_OK; |
| 7992 | } |
| 7993 | |
| 7994 | return RETURN_ERR; |
| 7995 | } |
| 7996 | |
| 7997 | // sets the vlan ID for this ap to an internal enviornment variable |
| 7998 | INT wifi_setApVlanID(INT apIndex, INT vlanId) |
| 7999 | { |
| 8000 | //save the vlanID to config and wait for wifi reset to apply (wifi up module would read this parameters and tag the AP with vlan id) |
| 8001 | return RETURN_ERR; |
| 8002 | } |
| 8003 | |
| 8004 | // gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters, |
| 8005 | INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet) |
| 8006 | { |
| 8007 | snprintf(bridgeName, 32, "brlan0"); |
| 8008 | snprintf(IP, 32, "10.0.0.1"); |
| 8009 | snprintf(subnet, 32, "255.255.255.0"); |
| 8010 | |
| 8011 | return RETURN_OK; |
| 8012 | } |
| 8013 | |
| 8014 | //sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters |
| 8015 | INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet) |
| 8016 | { |
| 8017 | //save settings, wait for wifi reset or wifi_pushBridgeInfo to apply. |
| 8018 | return RETURN_ERR; |
| 8019 | } |
| 8020 | |
| 8021 | // reset the vlan configuration for this ap |
| 8022 | INT wifi_resetApVlanCfg(INT apIndex) |
| 8023 | { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 8024 | char interface_name[16] = {0}; |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8025 | int if_idx, ret = 0; |
| 8026 | struct nl_msg *msg = NULL; |
| 8027 | struct nlattr * msg_data = NULL; |
| 8028 | struct mtk_nl80211_param param; |
| 8029 | struct unl unl_ins; |
| 8030 | struct vlan_policy_param vlan_param; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8031 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8032 | if (apIndex > MAX_APS) { |
| 8033 | wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex); |
| 8034 | return RETURN_ERR; |
| 8035 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8036 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8037 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8038 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 8039 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8040 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8041 | /*step 1. mwctl dev %s set vlan_tag 0*/ |
| 8042 | if_idx = if_nametoindex(interface_name); |
| 8043 | /*init mtk nl80211 vendor cmd*/ |
| 8044 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN; |
| 8045 | param.if_type = NL80211_ATTR_IFINDEX; |
| 8046 | param.if_idx = if_idx; |
| 8047 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8048 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8049 | if (ret) { |
| 8050 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8051 | return RETURN_ERR; |
| 8052 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8053 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8054 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) { |
| 8055 | printf("Nla put attribute error\n"); |
| 8056 | nlmsg_free(msg); |
| 8057 | goto err; |
| 8058 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8059 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8060 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8061 | if (ret) { |
| 8062 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8063 | goto err; |
| 8064 | } |
| 8065 | mtk_nl80211_deint(&unl_ins); |
| 8066 | wifi_debug(DEBUG_NOTICE, "set vlan_tag 0 cmd success.\n"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8067 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8068 | /*step 2. mwctl dev %s set vlan_priority 0*/ |
| 8069 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8070 | if (ret) { |
| 8071 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8072 | return RETURN_ERR; |
| 8073 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8074 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8075 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) { |
| 8076 | printf("Nla put attribute error\n"); |
| 8077 | nlmsg_free(msg); |
| 8078 | goto err; |
| 8079 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8080 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8081 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8082 | if (ret) { |
| 8083 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8084 | goto err; |
| 8085 | } |
| 8086 | mtk_nl80211_deint(&unl_ins); |
| 8087 | wifi_debug(DEBUG_NOTICE, "set vlan_priority 0 cmd success.\n"); |
| 8088 | |
| 8089 | /*step 3. mwctl dev %s set vlan_id 0*/ |
| 8090 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8091 | if (ret) { |
| 8092 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 8093 | return RETURN_ERR; |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8094 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8095 | |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 8096 | if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) { |
| 8097 | printf("Nla put attribute error\n"); |
| 8098 | nlmsg_free(msg); |
| 8099 | goto err; |
| 8100 | } |
| 8101 | |
| 8102 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8103 | if (ret) { |
| 8104 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8105 | goto err; |
| 8106 | } |
| 8107 | mtk_nl80211_deint(&unl_ins); |
| 8108 | wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n"); |
| 8109 | |
| 8110 | /*step 4. mwctl dev %s set vlan_en 0*/ |
| 8111 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8112 | if (ret) { |
| 8113 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8114 | return RETURN_ERR; |
| 8115 | } |
| 8116 | |
| 8117 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) { |
| 8118 | printf("Nla put attribute error\n"); |
| 8119 | nlmsg_free(msg); |
| 8120 | goto err; |
| 8121 | } |
| 8122 | |
| 8123 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8124 | if (ret) { |
| 8125 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8126 | goto err; |
| 8127 | } |
| 8128 | mtk_nl80211_deint(&unl_ins); |
| 8129 | wifi_debug(DEBUG_NOTICE, "set vlan_id cmd success.\n"); |
| 8130 | |
| 8131 | /*step 5. mwctl dev %s set vlan_policy 0:4*/ |
| 8132 | vlan_param.direction = 0; |
| 8133 | vlan_param.policy = 4; |
| 8134 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8135 | if (ret) { |
| 8136 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8137 | return RETURN_ERR; |
| 8138 | } |
| 8139 | if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) { |
| 8140 | printf("Nla put attribute error\n"); |
| 8141 | nlmsg_free(msg); |
| 8142 | goto err; |
| 8143 | } |
| 8144 | |
| 8145 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8146 | if (ret) { |
| 8147 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8148 | goto err; |
| 8149 | } |
| 8150 | mtk_nl80211_deint(&unl_ins); |
| 8151 | wifi_debug(DEBUG_NOTICE, "set vlan_policy 0:4 cmd success.\n"); |
| 8152 | |
| 8153 | /*step 6. mwctl dev %s set vlan_policy 1:0*/ |
| 8154 | vlan_param.direction = 1; |
| 8155 | vlan_param.policy = 0; |
| 8156 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8157 | if (ret) { |
| 8158 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8159 | return RETURN_ERR; |
| 8160 | } |
| 8161 | |
| 8162 | if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) { |
| 8163 | printf("Nla put attribute error\n"); |
| 8164 | nlmsg_free(msg); |
| 8165 | goto err; |
| 8166 | } |
| 8167 | |
| 8168 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8169 | if (ret) { |
| 8170 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8171 | goto err; |
| 8172 | } |
| 8173 | /*deinit mtk nl80211 vendor msg*/ |
| 8174 | mtk_nl80211_deint(&unl_ins); |
| 8175 | wifi_debug(DEBUG_NOTICE, "set vlan_policy 1:0 cmd success.\n"); |
| 8176 | |
| 8177 | /*TODO need to modify VLAN config in dat file*/ |
| 8178 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8179 | |
| 8180 | return RETURN_OK; |
| 8181 | err: |
| 8182 | mtk_nl80211_deint(&unl_ins); |
| 8183 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 8184 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8185 | } |
| 8186 | |
| 8187 | // creates configuration variables needed for WPA/WPS. These variables are implementation dependent and in some implementations these variables are used by hostapd when it is started. Specific variables that are needed are dependent on the hostapd implementation. These variables are set by WPA/WPS security functions in this wifi HAL. If not needed for a particular implementation this function may simply return no error. |
| 8188 | INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg) |
| 8189 | { |
| 8190 | return RETURN_ERR; |
| 8191 | } |
| 8192 | |
| 8193 | // starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation |
| 8194 | INT wifi_startHostApd() |
| 8195 | { |
| 8196 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8197 | system("systemctl start hostapd.service"); |
| 8198 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8199 | return RETURN_OK; |
| 8200 | //sprintf(cmd, "hostapd -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2"); |
| 8201 | } |
| 8202 | |
| 8203 | // stops hostapd |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 8204 | INT wifi_stopHostApd() |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8205 | { |
| 8206 | char cmd[128] = {0}; |
| 8207 | char buf[128] = {0}; |
| 8208 | |
| 8209 | sprintf(cmd,"systemctl stop hostapd"); |
| 8210 | _syscmd(cmd, buf, sizeof(buf)); |
| 8211 | |
| 8212 | return RETURN_OK; |
| 8213 | } |
| 8214 | |
| 8215 | // restart hostapd dummy function |
| 8216 | INT wifi_restartHostApd() |
| 8217 | { |
| 8218 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8219 | system("systemctl restart hostapd-global"); |
| 8220 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8221 | |
| 8222 | return RETURN_OK; |
| 8223 | } |
| 8224 | |
| 8225 | static int align_hostapd_config(int index) |
| 8226 | { |
| 8227 | ULONG lval; |
| 8228 | wifi_getRadioChannel(index%2, &lval); |
| 8229 | wifi_setRadioChannel(index%2, lval); |
| 8230 | return RETURN_OK; |
| 8231 | } |
| 8232 | |
| 8233 | // sets the AP enable status variable for the specified ap. |
| 8234 | INT wifi_setApEnable(INT apIndex, BOOL enable) |
| 8235 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8236 | char interface_name[16] = {0}; |
| 8237 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8238 | char cmd[MAX_CMD_SIZE] = {0}; |
| 8239 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 8240 | BOOL status = FALSE; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8241 | int max_radio_num = 0; |
| 8242 | int phyId = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8243 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8244 | wifi_getApEnable(apIndex, &status); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8245 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8246 | wifi_getMaxRadioNumber(&max_radio_num); |
| 8247 | if (enable == status) |
| 8248 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8249 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8250 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 8251 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8252 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8253 | if (enable == TRUE) { |
| 8254 | int radioIndex = apIndex % max_radio_num; |
| 8255 | phyId = radio_index_to_phy(radioIndex); |
developer | f3c7d29 | 2023-05-29 17:57:16 +0800 | [diff] [blame^] | 8256 | snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s up", interface_name); |
| 8257 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 8258 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8259 | snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 8260 | snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file); |
| 8261 | _syscmd(cmd, buf, sizeof(buf)); |
| 8262 | } else { |
| 8263 | snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw REMOVE %s", interface_name); |
| 8264 | _syscmd(cmd, buf, sizeof(buf)); |
developer | f3c7d29 | 2023-05-29 17:57:16 +0800 | [diff] [blame^] | 8265 | snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s down", interface_name); |
| 8266 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8267 | } |
| 8268 | snprintf(cmd, MAX_CMD_SIZE, "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s", |
| 8269 | interface_name, interface_name, enable, VAP_STATUS_FILE); |
| 8270 | _syscmd(cmd, buf, sizeof(buf)); |
| 8271 | //Wait for wifi up/down to apply |
| 8272 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8273 | } |
| 8274 | |
| 8275 | // Outputs the setting of the internal variable that is set by wifi_setApEnable(). |
| 8276 | INT wifi_getApEnable(INT apIndex, BOOL *output_bool) |
| 8277 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8278 | char interface_name[IF_NAME_SIZE] = {0}; |
| 8279 | char cmd[MAX_CMD_SIZE] = {0}; |
| 8280 | char buf[MAX_BUF_SIZE] = {0}; |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 8281 | int ret; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8282 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8283 | if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS)) |
| 8284 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8285 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8286 | *output_bool = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8287 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8288 | if ((apIndex >= 0) && (apIndex < MAX_APS)) { |
| 8289 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) { |
| 8290 | *output_bool = FALSE; |
| 8291 | return RETURN_OK; |
| 8292 | } |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 8293 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status", interface_name); |
| 8294 | ret = system(cmd); |
| 8295 | if (ret == 0) |
| 8296 | *output_bool = 1; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8297 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8298 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8299 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8300 | } |
| 8301 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 8302 | // Outputs the AP "Enabled" "Disabled" status from driver |
| 8303 | INT wifi_getApStatus(INT apIndex, CHAR *output_string) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8304 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8305 | char cmd[128] = {0}; |
| 8306 | char buf[128] = {0}; |
| 8307 | BOOL output_bool; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8308 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8309 | if (!output_string) { |
| 8310 | printf("%s: null pointer!", __func__); |
| 8311 | return RETURN_ERR; |
| 8312 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8313 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8314 | wifi_getApEnable(apIndex, &output_bool); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8315 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 8316 | if(output_bool == 1) |
| 8317 | snprintf(output_string, 32, "Up"); |
| 8318 | else |
| 8319 | snprintf(output_string, 32, "Disable"); |
| 8320 | |
| 8321 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8322 | } |
| 8323 | |
| 8324 | //Indicates whether or not beacons include the SSID name. |
| 8325 | // outputs a 1 if SSID on the AP is enabled, else outputs 0 |
| 8326 | INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output) |
| 8327 | { |
| 8328 | //get the running status |
| 8329 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8330 | char buf[16] = {0}; |
| 8331 | |
| 8332 | if (!output) |
| 8333 | return RETURN_ERR; |
| 8334 | |
| 8335 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 8336 | wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf)); |
| 8337 | // default is enable |
| 8338 | if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0) |
| 8339 | *output = TRUE; |
| 8340 | |
| 8341 | return RETURN_OK; |
| 8342 | } |
| 8343 | |
| 8344 | // sets an internal variable for ssid advertisement. Set to 1 to enable, set to 0 to disable |
| 8345 | INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable) |
| 8346 | { |
| 8347 | //store the config, apply instantly |
| 8348 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8349 | struct params list; |
| 8350 | |
| 8351 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8352 | list.name = "ignore_broadcast_ssid"; |
| 8353 | list.value = enable?"0":"1"; |
| 8354 | |
| 8355 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 8356 | wifi_hostapdWrite(config_file, &list, 1); |
| 8357 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
| 8358 | //TODO: call hostapd_cli for dynamic_config_control |
| 8359 | wifi_reloadAp(apIndex); |
| 8360 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8361 | |
| 8362 | return RETURN_OK; |
| 8363 | } |
| 8364 | |
| 8365 | //The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit. |
| 8366 | INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint) |
| 8367 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 8368 | /* get the running status */ |
| 8369 | if(!output_uint) |
| 8370 | return RETURN_ERR; |
| 8371 | |
| 8372 | *output_uint = 15; |
| 8373 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8374 | } |
| 8375 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 8376 | /*Do not support AP retry limit fix*/ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8377 | INT wifi_setApRetryLimit(INT apIndex, UINT number) |
| 8378 | { |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 8379 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8380 | } |
| 8381 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8382 | int get_wmm_cap_status_callback(struct nl_msg *msg, void *data) |
| 8383 | { |
| 8384 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 8385 | struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1]; |
| 8386 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 8387 | unsigned char *status = (unsigned char * *)data; |
| 8388 | int err = 0; |
| 8389 | //u16 acl_result_len = 0; |
| 8390 | |
| 8391 | err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 8392 | genlmsg_attrlen(gnlh, 0), NULL); |
| 8393 | if (err < 0) |
| 8394 | return err; |
| 8395 | |
| 8396 | if (tb[NL80211_ATTR_VENDOR_DATA]) { |
| 8397 | err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX, |
| 8398 | tb[NL80211_ATTR_VENDOR_DATA], NULL); |
| 8399 | if (err < 0) |
| 8400 | return err; |
| 8401 | |
| 8402 | if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) { |
| 8403 | //acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]); |
| 8404 | *status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]); |
| 8405 | } |
| 8406 | } |
| 8407 | |
| 8408 | return 0; |
| 8409 | } |
| 8410 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8411 | //Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC). |
| 8412 | INT wifi_getApWMMCapability(INT apIndex, BOOL *output) |
| 8413 | { |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8414 | int if_idx, ret = 0; |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 8415 | char interface_name[16] = {0}; |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8416 | unsigned char status = 0; |
| 8417 | struct nl_msg *msg = NULL; |
| 8418 | struct nlattr * msg_data = NULL; |
| 8419 | struct mtk_nl80211_param param; |
| 8420 | struct unl unl_ins; |
| 8421 | struct vlan_policy_param vlan_param; |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 8422 | |
| 8423 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8424 | if(!output) |
| 8425 | return RETURN_ERR; |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 8426 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8427 | if (apIndex > MAX_APS) { |
| 8428 | wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex); |
| 8429 | return RETURN_ERR; |
| 8430 | } |
| 8431 | |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 8432 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 8433 | return RETURN_ERR; |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8434 | |
| 8435 | if_idx = if_nametoindex(interface_name); |
| 8436 | /*init mtk nl80211 vendor cmd*/ |
| 8437 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM; |
| 8438 | param.if_type = NL80211_ATTR_IFINDEX; |
| 8439 | param.if_idx = if_idx; |
| 8440 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8441 | |
| 8442 | if (ret) { |
| 8443 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8444 | return RETURN_ERR; |
| 8445 | } |
| 8446 | |
| 8447 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) { |
| 8448 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 8449 | nlmsg_free(msg); |
| 8450 | goto err; |
| 8451 | } |
| 8452 | |
| 8453 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback, |
| 8454 | (void *)&status); |
| 8455 | if (ret) { |
| 8456 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8457 | goto err; |
| 8458 | } |
| 8459 | mtk_nl80211_deint(&unl_ins); |
| 8460 | |
| 8461 | *output = status == 0 ? FALSE : TRUE; |
| 8462 | wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output)); |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 8463 | |
| 8464 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8465 | return RETURN_OK; |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8466 | err: |
| 8467 | mtk_nl80211_deint(&unl_ins); |
| 8468 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 8469 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8470 | } |
| 8471 | |
| 8472 | //Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support. |
| 8473 | INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output) |
| 8474 | { |
| 8475 | //get the running status from driver |
| 8476 | char cmd[128] = {0}; |
| 8477 | char buf[128] = {0}; |
| 8478 | int max_radio_num = 0, radioIndex = 0; |
| 8479 | int phyId = 0; |
| 8480 | |
| 8481 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8482 | |
| 8483 | wifi_getMaxRadioNumber(&max_radio_num); |
| 8484 | radioIndex = apIndex % max_radio_num; |
| 8485 | phyId = radio_index_to_phy(radioIndex); |
| 8486 | snprintf(cmd, sizeof(cmd), "iw phy phy%d info | grep u-APSD", phyId); |
| 8487 | _syscmd(cmd,buf, sizeof(buf)); |
| 8488 | |
| 8489 | if (strlen(buf) > 0) |
| 8490 | *output = true; |
| 8491 | |
| 8492 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8493 | |
| 8494 | return RETURN_OK; |
| 8495 | } |
| 8496 | |
| 8497 | //Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames. |
| 8498 | INT wifi_getApWmmEnable(INT apIndex, BOOL *output) |
| 8499 | { |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8500 | return wifi_getApWMMCapability(apIndex, output); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8501 | } |
| 8502 | |
| 8503 | // enables/disables WMM on the hardwawre for this AP. enable==1, disable == 0 |
| 8504 | INT wifi_setApWmmEnable(INT apIndex, BOOL enable) |
| 8505 | { |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8506 | int if_idx, ret = 0; |
| 8507 | char interface_name[16] = {0}; |
| 8508 | unsigned char status = 0; |
| 8509 | struct nl_msg *msg = NULL; |
| 8510 | struct nlattr * msg_data = NULL; |
| 8511 | struct mtk_nl80211_param param; |
| 8512 | struct unl unl_ins; |
| 8513 | struct vlan_policy_param vlan_param; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8514 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8515 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8516 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8517 | if (apIndex > MAX_APS) { |
| 8518 | wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex); |
| 8519 | return RETURN_ERR; |
| 8520 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8521 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8522 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 8523 | return RETURN_ERR; |
developer | 8e6583c | 2023-05-23 13:36:06 +0800 | [diff] [blame] | 8524 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8525 | if_idx = if_nametoindex(interface_name); |
| 8526 | /*init mtk nl80211 vendor cmd*/ |
| 8527 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM; |
| 8528 | param.if_type = NL80211_ATTR_IFINDEX; |
| 8529 | param.if_idx = if_idx; |
| 8530 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 8531 | |
| 8532 | if (ret) { |
| 8533 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 8534 | return RETURN_ERR; |
| 8535 | } |
| 8536 | |
| 8537 | if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) { |
| 8538 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 8539 | nlmsg_free(msg); |
| 8540 | goto err; |
| 8541 | } |
| 8542 | |
| 8543 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 8544 | if (ret) { |
| 8545 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n"); |
| 8546 | goto err; |
| 8547 | } |
| 8548 | mtk_nl80211_deint(&unl_ins); |
| 8549 | |
| 8550 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8551 | return RETURN_OK; |
| 8552 | err: |
| 8553 | mtk_nl80211_deint(&unl_ins); |
| 8554 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 8555 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8556 | } |
| 8557 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 8558 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8559 | //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. |
| 8560 | INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output) |
| 8561 | { |
| 8562 | //get the running status from driver |
| 8563 | if(!output) |
| 8564 | return RETURN_ERR; |
| 8565 | |
| 8566 | char config_file[128] = {0}; |
| 8567 | char buf[16] = {0}; |
| 8568 | |
| 8569 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 8570 | wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf)); |
| 8571 | if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0) |
| 8572 | *output = TRUE; |
| 8573 | else |
| 8574 | *output = FALSE; |
| 8575 | |
| 8576 | return RETURN_OK; |
| 8577 | } |
| 8578 | |
| 8579 | // enables/disables Automatic Power Save Delivery on the hardwarwe for this AP |
| 8580 | INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable) |
| 8581 | { |
| 8582 | //save config and apply instantly. |
| 8583 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8584 | struct params list; |
| 8585 | |
| 8586 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8587 | list.name = "uapsd_advertisement_enabled"; |
| 8588 | list.value = enable?"1":"0"; |
| 8589 | |
| 8590 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 8591 | wifi_hostapdWrite(config_file, &list, 1); |
| 8592 | wifi_hostapdProcessUpdate(apIndex, &list, 1); |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 8593 | wifi_quick_reload_ap(apIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8594 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8595 | |
| 8596 | return RETURN_OK; |
| 8597 | } |
| 8598 | |
| 8599 | // Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge |
| 8600 | INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy) //RDKB |
| 8601 | { |
| 8602 | char interface_name[16] = {0}; |
| 8603 | // assume class 0->BE, 1->BK, 2->VI, 3->VO |
| 8604 | char cmd[128] = {0}; |
| 8605 | char buf[128] = {0}; |
| 8606 | char ack_filepath[128] = {0}; |
| 8607 | uint16_t bitmap = 0; |
| 8608 | uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0}; |
| 8609 | FILE *f = NULL; |
| 8610 | |
| 8611 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 8612 | |
| 8613 | // Get current setting |
| 8614 | snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex); |
| 8615 | snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", ack_filepath); |
| 8616 | _syscmd(cmd, buf, sizeof(buf)); |
| 8617 | if (strlen(buf) > 0) |
| 8618 | bitmap = strtoul(buf, NULL, 10); |
| 8619 | |
| 8620 | bitmap = strtoul(buf, NULL, 10); |
| 8621 | |
| 8622 | if (ackPolicy == TRUE) { // True, unset this class |
| 8623 | bitmap &= ~class_map[class]; |
| 8624 | } else { // False, set this class |
| 8625 | bitmap |= class_map[class]; |
| 8626 | } |
| 8627 | |
| 8628 | f = fopen(ack_filepath, "w"); |
| 8629 | if (f == NULL) { |
| 8630 | fprintf(stderr, "%s: fopen failed\n", __func__); |
| 8631 | return RETURN_ERR; |
| 8632 | } |
| 8633 | fprintf(f, "%hu", bitmap); |
| 8634 | fclose(f); |
| 8635 | |
| 8636 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 8637 | return RETURN_ERR; |
| 8638 | snprintf(cmd, sizeof(cmd), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap); |
| 8639 | _syscmd(cmd, buf, sizeof(buf)); |
| 8640 | |
| 8641 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 8642 | return RETURN_OK; |
| 8643 | } |
| 8644 | |
| 8645 | //The maximum number of devices that can simultaneously be connected to the access point. A value of 0 means that there is no specific limit. |
| 8646 | INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint) |
| 8647 | { |
| 8648 | //get the running status from driver |
| 8649 | if(!output_uint) |
| 8650 | return RETURN_ERR; |
| 8651 | |
| 8652 | char output[16]={'\0'}; |
| 8653 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8654 | |
| 8655 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 8656 | wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output)); |
| 8657 | if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM; |
| 8658 | else { |
| 8659 | int device_num = atoi(output); |
| 8660 | if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) { |
| 8661 | wifi_dbg_printf("\n[%s]: get max_num_sta error: %d", __func__, device_num); |
| 8662 | return RETURN_ERR; |
| 8663 | } |
| 8664 | else { |
| 8665 | *output_uint = device_num; |
| 8666 | } |
| 8667 | } |
| 8668 | |
| 8669 | return RETURN_OK; |
| 8670 | } |
| 8671 | |
| 8672 | INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number) |
| 8673 | { |
| 8674 | //store to wifi config, apply instantly |
| 8675 | char str[MAX_BUF_SIZE]={'\0'}; |
| 8676 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 8677 | struct params params; |
| 8678 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8679 | |
| 8680 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8681 | if (number > MAX_ASSOCIATED_STA_NUM) { |
| 8682 | WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__); |
| 8683 | return RETURN_ERR; |
| 8684 | } |
| 8685 | sprintf(str, "%d", number); |
| 8686 | params.name = "max_num_sta"; |
| 8687 | params.value = str; |
| 8688 | |
| 8689 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX, apIndex); |
| 8690 | int ret = wifi_hostapdWrite(config_file, ¶ms, 1); |
| 8691 | if (ret) { |
| 8692 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n" |
| 8693 | ,__func__, ret); |
| 8694 | } |
| 8695 | |
| 8696 | ret = wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 8697 | if (ret) { |
| 8698 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n" |
| 8699 | ,__func__, ret); |
| 8700 | } |
| 8701 | wifi_reloadAp(apIndex); |
| 8702 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8703 | |
| 8704 | return RETURN_OK; |
| 8705 | } |
| 8706 | |
| 8707 | //The HighWatermarkThreshold value that is lesser than or equal to MaxAssociatedDevices. Setting this parameter does not actually limit the number of clients that can associate with this access point as that is controlled by MaxAssociatedDevices. MaxAssociatedDevices or 50. The default value of this parameter should be equal to MaxAssociatedDevices. In case MaxAssociatedDevices is 0 (zero), the default value of this parameter should be 50. A value of 0 means that there is no specific limit and Watermark calculation algorithm should be turned off. |
| 8708 | INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint) |
| 8709 | { |
| 8710 | //get the current threshold |
| 8711 | if(!output_uint) |
| 8712 | return RETURN_ERR; |
| 8713 | wifi_getApMaxAssociatedDevices(apIndex, output_uint); |
| 8714 | if (*output_uint == 0) |
| 8715 | *output_uint = 50; |
| 8716 | return RETURN_OK; |
| 8717 | } |
| 8718 | |
| 8719 | INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold) |
| 8720 | { |
| 8721 | //store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time |
| 8722 | if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold)) |
| 8723 | return RETURN_OK; |
| 8724 | return RETURN_ERR; |
| 8725 | } |
| 8726 | |
| 8727 | //Number of times the current total number of associated device has reached the HighWatermarkThreshold value. This calculation can be based on the parameter AssociatedDeviceNumberOfEntries as well. Implementation specifics about this parameter are left to the product group and the device vendors. It can be updated whenever there is a new client association request to the access point. |
| 8728 | INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint) |
| 8729 | { |
| 8730 | if(!output_uint) |
| 8731 | return RETURN_ERR; |
| 8732 | *output_uint = 3; |
| 8733 | return RETURN_OK; |
| 8734 | } |
| 8735 | |
| 8736 | //Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module. |
| 8737 | INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint) |
| 8738 | { |
| 8739 | if(!output_uint) |
| 8740 | return RETURN_ERR; |
| 8741 | *output_uint = 3; |
| 8742 | return RETURN_OK; |
| 8743 | } |
| 8744 | |
| 8745 | //Date and Time at which the maximum number of associated devices ever associated with the access point concurrenlty since the last reset of the device or WiFi module (or in short when was X_COMCAST-COM_AssociatedDevicesHighWatermark updated). This dateTime value is in UTC. |
| 8746 | INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds) |
| 8747 | { |
| 8748 | if(!output_in_seconds) |
| 8749 | return RETURN_ERR; |
| 8750 | *output_in_seconds = 0; |
| 8751 | return RETURN_OK; |
| 8752 | } |
| 8753 | |
| 8754 | //Comma-separated list of strings. Indicates which security modes this AccessPoint instance is capable of supporting. Each list item is an enumeration of: None,WEP-64,WEP-128,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise |
| 8755 | INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output) |
| 8756 | { |
| 8757 | if(!output || apIndex>=MAX_APS) |
| 8758 | return RETURN_ERR; |
| 8759 | //snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise"); |
| 8760 | snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise"); |
| 8761 | return RETURN_OK; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 8762 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8763 | |
| 8764 | //The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled. |
| 8765 | INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output) |
| 8766 | { |
| 8767 | char config_file[128] = {0}; |
| 8768 | char wpa[16] = {0}; |
| 8769 | char key_mgmt[64] = {0}; |
| 8770 | char buf[16] = {0}; |
| 8771 | if (!output) |
| 8772 | return RETURN_ERR; |
| 8773 | |
| 8774 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 8775 | wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa)); |
| 8776 | |
| 8777 | strcpy(output, "None");//Copying "None" to output string for default case |
| 8778 | wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt)); |
| 8779 | if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) { |
| 8780 | if (!strcmp(wpa, "1")) |
| 8781 | snprintf(output, 32, "WPA-Personal"); |
| 8782 | else if (!strcmp(wpa, "2")) |
| 8783 | snprintf(output, 32, "WPA2-Personal"); |
| 8784 | else if (!strcmp(wpa, "3")) |
| 8785 | snprintf(output, 32, "WPA-WPA2-Personal"); |
| 8786 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8787 | } else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) { |
| 8788 | snprintf(output, 32, "WPA3-Enterprise"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8789 | } else if (strstr(key_mgmt, "WPA-EAP")) { |
| 8790 | if (!strcmp(wpa, "1")) |
| 8791 | snprintf(output, 32, "WPA-Enterprise"); |
| 8792 | else if (!strcmp(wpa, "2")) |
| 8793 | snprintf(output, 32, "WPA2-Enterprise"); |
| 8794 | else if (!strcmp(wpa, "3")) |
| 8795 | snprintf(output, 32, "WPA-WPA2-Enterprise"); |
| 8796 | } else if (strstr(key_mgmt, "SAE")) { |
| 8797 | if (strstr(key_mgmt, "WPA-PSK") == NULL) |
| 8798 | snprintf(output, 32, "WPA3-Personal"); |
| 8799 | else |
| 8800 | snprintf(output, 32, "WPA3-Personal-Transition"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8801 | } |
| 8802 | |
| 8803 | //save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply |
| 8804 | return RETURN_OK; |
| 8805 | #if 0 |
| 8806 | //TODO: need to revisit below implementation |
| 8807 | char securityType[32], authMode[32]; |
| 8808 | int enterpriseMode=0; |
| 8809 | |
| 8810 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8811 | if(!output) |
| 8812 | return RETURN_ERR; |
| 8813 | |
| 8814 | wifi_getApBeaconType(apIndex, securityType); |
| 8815 | strcpy(output,"None");//By default, copying "None" to output string |
| 8816 | if (strncmp(securityType,"None", strlen("None")) == 0) |
| 8817 | return RETURN_OK; |
| 8818 | |
| 8819 | wifi_getApBasicAuthenticationMode(apIndex, authMode); |
| 8820 | enterpriseMode = (strncmp(authMode, "EAPAuthentication", strlen("EAPAuthentication")) == 0)? 1: 0; |
| 8821 | |
| 8822 | if (strncmp(securityType, "WPAand11i", strlen("WPAand11i")) == 0) |
| 8823 | snprintf(output, 32, enterpriseMode==1? "WPA-WPA2-Enterprise": "WPA-WPA2-Personal"); |
| 8824 | else if (strncmp(securityType, "WPA", strlen("WPA")) == 0) |
| 8825 | snprintf(output, 32, enterpriseMode==1? "WPA-Enterprise": "WPA-Personal"); |
| 8826 | else if (strncmp(securityType, "11i", strlen("11i")) == 0) |
| 8827 | snprintf(output, 32, enterpriseMode==1? "WPA2-Enterprise": "WPA2-Personal"); |
| 8828 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8829 | |
| 8830 | return RETURN_OK; |
| 8831 | #endif |
| 8832 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 8833 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8834 | INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode) |
| 8835 | { |
| 8836 | char securityType[32]; |
| 8837 | char authMode[32]; |
| 8838 | |
| 8839 | //store settings and wait for wifi up to apply |
| 8840 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 8841 | if(!encMode) |
| 8842 | return RETURN_ERR; |
| 8843 | |
| 8844 | if (strcmp(encMode, "None")==0) |
| 8845 | { |
| 8846 | strcpy(securityType,"None"); |
| 8847 | strcpy(authMode,"None"); |
| 8848 | } |
| 8849 | else if (strcmp(encMode, "WPA-WPA2-Personal")==0) |
| 8850 | { |
| 8851 | strcpy(securityType,"WPAand11i"); |
| 8852 | strcpy(authMode,"PSKAuthentication"); |
| 8853 | } |
| 8854 | else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) |
| 8855 | { |
| 8856 | strcpy(securityType,"WPAand11i"); |
| 8857 | strcpy(authMode,"EAPAuthentication"); |
| 8858 | } |
| 8859 | else if (strcmp(encMode, "WPA-Personal")==0) |
| 8860 | { |
| 8861 | strcpy(securityType,"WPA"); |
| 8862 | strcpy(authMode,"PSKAuthentication"); |
| 8863 | } |
| 8864 | else if (strcmp(encMode, "WPA-Enterprise")==0) |
| 8865 | { |
| 8866 | strcpy(securityType,"WPA"); |
| 8867 | strcpy(authMode,"EAPAuthentication"); |
| 8868 | } |
| 8869 | else if (strcmp(encMode, "WPA2-Personal")==0) |
| 8870 | { |
| 8871 | strcpy(securityType,"11i"); |
| 8872 | strcpy(authMode,"PSKAuthentication"); |
| 8873 | } |
| 8874 | else if (strcmp(encMode, "WPA2-Enterprise")==0) |
| 8875 | { |
| 8876 | strcpy(securityType,"11i"); |
| 8877 | strcpy(authMode,"EAPAuthentication"); |
| 8878 | } |
| 8879 | else if (strcmp(encMode, "WPA3-Personal") == 0) |
| 8880 | { |
| 8881 | strcpy(securityType,"11i"); |
| 8882 | strcpy(authMode,"SAEAuthentication"); |
| 8883 | } |
| 8884 | else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) |
| 8885 | { |
| 8886 | strcpy(securityType, "11i"); |
| 8887 | strcpy(authMode, "PSK-SAEAuthentication"); |
| 8888 | } |
| 8889 | else if (strcmp(encMode, "WPA3-Enterprise") == 0) |
| 8890 | { |
| 8891 | strcpy(securityType,"11i"); |
| 8892 | strcpy(authMode,"EAP_192-bit_Authentication"); |
| 8893 | } |
developer | 3086e2f | 2023-01-17 09:40:01 +0800 | [diff] [blame] | 8894 | else if (strcmp(encMode, "OWE") == 0) |
| 8895 | { |
| 8896 | strcpy(securityType,"11i"); |
| 8897 | strcpy(authMode,"Enhanced_Open"); |
| 8898 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8899 | else |
| 8900 | { |
| 8901 | strcpy(securityType,"None"); |
| 8902 | strcpy(authMode,"None"); |
| 8903 | } |
| 8904 | wifi_setApBeaconType(apIndex, securityType); |
| 8905 | wifi_setApBasicAuthenticationMode(apIndex, authMode); |
| 8906 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 8907 | |
| 8908 | return RETURN_OK; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 8909 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8910 | |
| 8911 | |
| 8912 | //A literal PreSharedKey (PSK) expressed as a hexadecimal string. |
| 8913 | // output_string must be pre-allocated as 64 character string by caller |
| 8914 | // PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value |
| 8915 | INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string) |
| 8916 | { |
| 8917 | char buf[16] = {0}; |
| 8918 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8919 | |
| 8920 | if(output_string==NULL) |
| 8921 | return RETURN_ERR; |
| 8922 | |
| 8923 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 8924 | wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf)); |
| 8925 | |
| 8926 | if(strcmp(buf,"0")==0) |
| 8927 | { |
| 8928 | printf("wpa_mode is %s ......... \n",buf); |
| 8929 | return RETURN_ERR; |
| 8930 | } |
| 8931 | |
| 8932 | wifi_dbg_printf("\nFunc=%s\n",__func__); |
| 8933 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8934 | wifi_hostapdRead(config_file,"wpa_psk",output_string,65); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8935 | wifi_dbg_printf("\noutput_string=%s\n",output_string); |
| 8936 | |
| 8937 | return RETURN_OK; |
| 8938 | } |
| 8939 | |
| 8940 | // sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters |
| 8941 | // PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value |
| 8942 | INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey) |
| 8943 | { |
| 8944 | //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply |
| 8945 | struct params params={'\0'}; |
| 8946 | int ret; |
| 8947 | char config_file[MAX_BUF_SIZE] = {0}; |
| 8948 | |
| 8949 | if(NULL == preSharedKey) |
| 8950 | return RETURN_ERR; |
| 8951 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8952 | params.name = "wpa_psk"; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8953 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8954 | if(strlen(preSharedKey) != 64) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8955 | { |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8956 | wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 64 chars\n"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8957 | return RETURN_ERR; |
| 8958 | } |
| 8959 | params.value = preSharedKey; |
| 8960 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 8961 | ret = wifi_hostapdWrite(config_file, ¶ms, 1); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8962 | if(!ret) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8963 | ret = wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 8964 | wifi_reloadAp(apIndex); |
| 8965 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 8966 | return ret; |
| 8967 | //TODO: call hostapd_cli for dynamic_config_control |
| 8968 | } |
| 8969 | |
| 8970 | //A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes. |
| 8971 | // outputs the passphrase, maximum 63 characters |
| 8972 | INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string) |
| 8973 | { |
| 8974 | char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0}; |
| 8975 | |
| 8976 | wifi_dbg_printf("\nFunc=%s\n",__func__); |
| 8977 | if (NULL == output_string) |
| 8978 | return RETURN_ERR; |
| 8979 | |
| 8980 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 8981 | wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf)); |
| 8982 | if(strcmp(buf,"0")==0) |
| 8983 | { |
| 8984 | printf("wpa_mode is %s ......... \n",buf); |
| 8985 | return RETURN_ERR; |
| 8986 | } |
| 8987 | |
| 8988 | wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64); |
| 8989 | wifi_dbg_printf("\noutput_string=%s\n",output_string); |
| 8990 | |
| 8991 | return RETURN_OK; |
| 8992 | } |
| 8993 | |
| 8994 | // sets the passphrase enviornment variable, max 63 characters |
| 8995 | INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase) |
| 8996 | { |
| 8997 | //save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply |
| 8998 | struct params params={'\0'}; |
| 8999 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9000 | int ret; |
| 9001 | |
| 9002 | if(NULL == passPhrase) |
| 9003 | return RETURN_ERR; |
| 9004 | |
| 9005 | if(strlen(passPhrase)<8 || strlen(passPhrase)>63) |
| 9006 | { |
| 9007 | wifi_dbg_printf("\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n"); |
| 9008 | return RETURN_ERR; |
| 9009 | } |
| 9010 | params.name = "wpa_passphrase"; |
| 9011 | params.value = passPhrase; |
| 9012 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 9013 | ret=wifi_hostapdWrite(config_file,¶ms,1); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9014 | if(!ret) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9015 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9016 | wifi_reloadAp(apIndex); |
| 9017 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9018 | |
| 9019 | return ret; |
| 9020 | } |
| 9021 | |
| 9022 | //When set to true, this AccessPoint instance's WiFi security settings are reset to their factory default values. The affected settings include ModeEnabled, WEPKey, PreSharedKey and KeyPassphrase. |
| 9023 | INT wifi_setApSecurityReset(INT apIndex) |
| 9024 | { |
| 9025 | char original_config_file[64] = {0}; |
| 9026 | char current_config_file[64] = {0}; |
| 9027 | char buf[64] = {0}; |
| 9028 | char cmd[64] = {0}; |
| 9029 | char wpa[4] = {0}; |
| 9030 | char wpa_psk[64] = {0}; |
| 9031 | char wpa_passphrase[64] = {0}; |
| 9032 | char wpa_psk_file[128] = {0}; |
| 9033 | char wpa_key_mgmt[64] = {0}; |
| 9034 | char wpa_pairwise[32] = {0}; |
| 9035 | wifi_band band; |
| 9036 | struct params list[6]; |
| 9037 | |
| 9038 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9039 | |
| 9040 | band = wifi_index_to_band(apIndex); |
| 9041 | if (band == band_2_4) |
| 9042 | sprintf(original_config_file, "/etc/hostapd-2G.conf"); |
| 9043 | else if (band == band_5) |
| 9044 | sprintf(original_config_file, "/etc/hostapd-5G.conf"); |
| 9045 | else if (band == band_6) |
| 9046 | sprintf(original_config_file, "/etc/hostapd-6G.conf"); |
| 9047 | else |
| 9048 | return RETURN_ERR; |
| 9049 | |
| 9050 | wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa)); |
| 9051 | list[0].name = "wpa"; |
| 9052 | list[0].value = wpa; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9053 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9054 | wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk)); |
| 9055 | list[1].name = "wpa_psk"; |
| 9056 | list[1].value = wpa_psk; |
| 9057 | |
| 9058 | wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase)); |
| 9059 | list[2].name = "wpa_passphrase"; |
| 9060 | list[2].value = wpa_passphrase; |
| 9061 | |
| 9062 | wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file)); |
| 9063 | |
| 9064 | if (strlen(wpa_psk_file) == 0) |
| 9065 | strcpy(wpa_psk_file, PSK_FILE); |
| 9066 | |
| 9067 | if (access(wpa_psk_file, F_OK) != 0) { |
| 9068 | sprintf(cmd, "touch %s", wpa_psk_file); |
| 9069 | _syscmd(cmd, buf, sizeof(buf)); |
| 9070 | } |
| 9071 | list[3].name = "wpa_psk_file"; |
| 9072 | list[3].value = wpa_psk_file; |
| 9073 | |
| 9074 | wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt)); |
| 9075 | list[4].name = "wpa_key_mgmt"; |
| 9076 | list[4].value = wpa_key_mgmt; |
| 9077 | |
| 9078 | wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise)); |
| 9079 | list[5].name = "wpa_pairwise"; |
| 9080 | list[5].value = wpa_pairwise; |
| 9081 | |
| 9082 | sprintf(current_config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9083 | wifi_hostapdWrite(current_config_file, list, 6); |
| 9084 | |
| 9085 | wifi_setApEnable(apIndex, FALSE); |
| 9086 | wifi_setApEnable(apIndex, TRUE); |
| 9087 | |
| 9088 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9089 | return RETURN_OK; |
| 9090 | } |
| 9091 | |
| 9092 | //The IP Address and port number of the RADIUS server used for WLAN security. RadiusServerIPAddr is only applicable when ModeEnabled is an Enterprise type (i.e. WPA-Enterprise, WPA2-Enterprise or WPA-WPA2-Enterprise). |
| 9093 | INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output) |
| 9094 | { |
| 9095 | char config_file[64] = {0}; |
| 9096 | char buf[64] = {0}; |
| 9097 | char cmd[256] = {0}; |
| 9098 | |
| 9099 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9100 | |
| 9101 | if(!IP_output || !Port_output || !RadiusSecret_output) |
| 9102 | return RETURN_ERR; |
| 9103 | |
| 9104 | // Read the first matched config |
| 9105 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9106 | sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file); |
| 9107 | _syscmd(cmd, buf, sizeof(buf)); |
| 9108 | strncpy(IP_output, buf, 64); |
| 9109 | |
| 9110 | memset(buf, 0, sizeof(buf)); |
| 9111 | sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file); |
| 9112 | _syscmd(cmd, buf, sizeof(buf)); |
| 9113 | *Port_output = atoi(buf); |
| 9114 | |
| 9115 | memset(buf, 0, sizeof(buf)); |
| 9116 | sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file); |
| 9117 | _syscmd(cmd, buf, sizeof(buf)); |
| 9118 | strncpy(RadiusSecret_output, buf, 64); |
| 9119 | |
| 9120 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9121 | return RETURN_OK; |
| 9122 | } |
| 9123 | |
| 9124 | INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret) |
| 9125 | { |
| 9126 | char config_file[64] = {0}; |
| 9127 | char port_str[8] = {0}; |
| 9128 | char cmd[256] = {0}; |
| 9129 | char buf[128] = {0}; |
| 9130 | |
| 9131 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9132 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9133 | if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK) |
| 9134 | return RETURN_ERR; |
| 9135 | |
| 9136 | if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info |
| 9137 | return RETURN_ERR; |
| 9138 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9139 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9140 | |
| 9141 | snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 1'", config_file); |
| 9142 | _syscmd(cmd, buf, sizeof(buf)); |
| 9143 | memset(cmd, 0, sizeof(cmd)); |
| 9144 | |
| 9145 | snprintf(port_str, sizeof(port_str), "%d", port); |
| 9146 | if (strlen(buf) == 0) |
| 9147 | // Append |
| 9148 | snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n" |
| 9149 | "auth_server_addr=%s\\n" |
| 9150 | "auth_server_port=%s\\n" |
| 9151 | "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file); |
| 9152 | else { |
| 9153 | // Delete the three lines setting after the "# radius 1" comment |
| 9154 | snprintf(cmd, sizeof(cmd), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file); |
| 9155 | _syscmd(cmd, buf, sizeof(buf)); |
| 9156 | memset(cmd, 0, sizeof(cmd)); |
| 9157 | // Use "# radius 1" comment to find the location to insert the radius setting |
| 9158 | snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/" |
| 9159 | "# radius 1\\n" |
| 9160 | "auth_server_addr=%s\\n" |
| 9161 | "auth_server_port=%s\\n" |
| 9162 | "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file); |
| 9163 | } |
| 9164 | if(_syscmd(cmd, buf, sizeof(buf))) { |
| 9165 | wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd); |
| 9166 | return RETURN_ERR; |
| 9167 | } |
| 9168 | |
| 9169 | wifi_reloadAp(apIndex); |
| 9170 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9171 | return RETURN_OK; |
| 9172 | } |
| 9173 | |
| 9174 | INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output) |
| 9175 | { |
| 9176 | char config_file[64] = {0}; |
| 9177 | char buf[64] = {0}; |
| 9178 | char cmd[256] = {0}; |
| 9179 | |
| 9180 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9181 | |
| 9182 | if(!IP_output || !Port_output || !RadiusSecret_output) |
| 9183 | return RETURN_ERR; |
| 9184 | |
| 9185 | // Read the second matched config |
| 9186 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9187 | sprintf(cmd, "cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file); |
| 9188 | _syscmd(cmd, buf, sizeof(buf)); |
| 9189 | strncpy(IP_output, buf, 64); |
| 9190 | |
| 9191 | memset(buf, 0, sizeof(buf)); |
| 9192 | sprintf(cmd, "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file); |
| 9193 | _syscmd(cmd, buf, sizeof(buf)); |
| 9194 | *Port_output = atoi(buf); |
| 9195 | |
| 9196 | memset(buf, 0, sizeof(buf)); |
| 9197 | sprintf(cmd, "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"", config_file); |
| 9198 | _syscmd(cmd, buf, sizeof(buf)); |
| 9199 | strncpy(RadiusSecret_output, buf, 64); |
| 9200 | |
| 9201 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9202 | return RETURN_OK; |
| 9203 | } |
| 9204 | |
| 9205 | INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret) |
| 9206 | { |
| 9207 | char config_file[64] = {0}; |
| 9208 | char port_str[8] = {0}; |
| 9209 | char cmd[256] = {0}; |
| 9210 | char buf[128] = {0}; |
| 9211 | |
| 9212 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9213 | |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9214 | if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK) |
| 9215 | return RETURN_ERR; |
| 9216 | |
| 9217 | if (strstr(buf, "Enterprise") == NULL) // non Enterprise mode sould not set radius server info |
| 9218 | return RETURN_ERR; |
| 9219 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9220 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9221 | |
| 9222 | snprintf(cmd, sizeof(cmd), "cat %s | grep '# radius 2'", config_file); |
| 9223 | _syscmd(cmd, buf, sizeof(buf)); |
| 9224 | memset(cmd, 0, sizeof(cmd)); |
| 9225 | |
| 9226 | snprintf(port_str, sizeof(port_str), "%d", port); |
| 9227 | if (strlen(buf) == 0) |
| 9228 | // Append |
| 9229 | snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n" |
| 9230 | "auth_server_addr=%s\\n" |
| 9231 | "auth_server_port=%s\\n" |
| 9232 | "auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file); |
| 9233 | else { |
| 9234 | // Delete the three lines setting after the "# radius 2" comment |
| 9235 | snprintf(cmd, sizeof(cmd), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file); |
| 9236 | _syscmd(cmd, buf, sizeof(buf)); |
| 9237 | memset(cmd, 0, sizeof(cmd)); |
| 9238 | // Use "# radius 2" comment to find the location to insert the radius setting |
| 9239 | snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/" |
| 9240 | "# radius 2\\n" |
| 9241 | "auth_server_addr=%s\\n" |
| 9242 | "auth_server_port=%s\\n" |
| 9243 | "auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file); |
| 9244 | } |
| 9245 | if(_syscmd(cmd, buf, sizeof(buf))) { |
| 9246 | wifi_dbg_printf("%s: command failed, cmd: %s\n", __func__, cmd); |
| 9247 | return RETURN_ERR; |
| 9248 | } |
| 9249 | |
| 9250 | wifi_reloadAp(apIndex); |
| 9251 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9252 | return RETURN_OK; |
| 9253 | } |
| 9254 | |
| 9255 | //RadiusSettings |
| 9256 | INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output) |
| 9257 | { |
| 9258 | if(!output) |
| 9259 | return RETURN_ERR; |
| 9260 | |
| 9261 | output->RadiusServerRetries = 3; //Number of retries for Radius requests. |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9262 | output->RadiusServerRequestTimeout = 5; //Radius request timeout in seconds after which the request must be retransmitted for the # of retries available. |
| 9263 | output->PMKLifetime = 28800; //Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs). |
| 9264 | output->PMKCaching = FALSE; //Enable or disable caching of PMK. |
| 9265 | output->PMKCacheInterval = 300; //Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes). |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9266 | 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. |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9267 | output->BlacklistTableTimeout = 600; //Time interval in seconds for which a client will continue to be blacklisted once it is marked so. |
| 9268 | output->IdentityRequestRetryInterval = 5; //Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it. |
| 9269 | output->QuietPeriodAfterFailedAuthentication = 5; //The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9270 | //snprintf(output->RadiusSecret, 64, "12345678"); //The secret used for handshaking with the RADIUS server [RFC2865]. When read, this parameter returns an empty string, regardless of the actual value. |
| 9271 | |
| 9272 | return RETURN_OK; |
| 9273 | } |
| 9274 | |
| 9275 | INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input) |
| 9276 | { |
| 9277 | //store the paramters, and apply instantly |
| 9278 | return RETURN_ERR; |
| 9279 | } |
| 9280 | |
| 9281 | //Device.WiFi.AccessPoint.{i}.WPS.Enable |
| 9282 | //Enables or disables WPS functionality for this access point. |
| 9283 | // outputs the WPS enable state of this ap in output_bool |
| 9284 | INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool) |
| 9285 | { |
| 9286 | char interface_name[16] = {0}; |
| 9287 | char buf[MAX_BUF_SIZE] = {0}, cmd[MAX_CMD_SIZE] = {0}, *value; |
| 9288 | if(!output_bool) |
| 9289 | return RETURN_ERR; |
| 9290 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 9291 | return RETURN_ERR; |
| 9292 | sprintf(cmd,"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2", interface_name); |
| 9293 | _syscmd(cmd, buf, sizeof(buf)); |
| 9294 | if(strstr(buf, "configured")) |
| 9295 | *output_bool=TRUE; |
| 9296 | else |
| 9297 | *output_bool=FALSE; |
| 9298 | |
| 9299 | return RETURN_OK; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9300 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9301 | |
| 9302 | //Device.WiFi.AccessPoint.{i}.WPS.Enable |
| 9303 | // sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled |
| 9304 | INT wifi_setApWpsEnable(INT apIndex, BOOL enable) |
| 9305 | { |
| 9306 | char config_file[MAX_BUF_SIZE] = {0}; |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9307 | char buf[128] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9308 | struct params params; |
| 9309 | |
| 9310 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9311 | //store the paramters, and wait for wifi up to apply |
| 9312 | params.name = "wps_state"; |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9313 | if (enable == TRUE) { |
| 9314 | wifi_getApBeaconType(apIndex, buf); |
| 9315 | if (strncmp(buf, "None", 4) == 0) // If ap didn't set encryption |
| 9316 | params.value = "1"; |
| 9317 | else // If ap set encryption |
| 9318 | params.value = "2"; |
| 9319 | } else { |
| 9320 | params.value = "0"; |
| 9321 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9322 | |
| 9323 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9324 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 9325 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 9326 | wifi_reloadAp(apIndex); |
| 9327 | |
| 9328 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9329 | return RETURN_OK; |
| 9330 | } |
| 9331 | |
| 9332 | //Comma-separated list of strings. Indicates WPS configuration methods supported by the device. Each list item is an enumeration of: USBFlashDrive,Ethernet,ExternalNFCToken,IntegratedNFCToken,NFCInterface,PushButton,PIN |
| 9333 | INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output) |
| 9334 | { |
| 9335 | if(!output) |
| 9336 | return RETURN_ERR; |
| 9337 | snprintf(output, 128, "PushButton,PIN"); |
| 9338 | return RETURN_OK; |
| 9339 | } |
| 9340 | |
| 9341 | //Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled |
| 9342 | //Comma-separated list of strings. Each list item MUST be a member of the list reported by the ConfigMethodsSupported parameter. Indicates WPS configuration methods enabled on the device. |
| 9343 | // Outputs a common separated list of the enabled WPS config methods, 64 bytes max |
| 9344 | INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output) |
| 9345 | { |
| 9346 | if(!output) |
| 9347 | return RETURN_ERR; |
| 9348 | snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods |
| 9349 | |
| 9350 | return RETURN_OK; |
| 9351 | } |
| 9352 | |
| 9353 | //Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled |
| 9354 | // sets an enviornment variable that specifies the WPS configuration method(s). methodString is a comma separated list of methods USBFlashDrive,Ethernet,ExternalNFCToken,IntegratedNFCToken,NFCInterface,PushButton,PIN |
| 9355 | INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString) |
| 9356 | { |
| 9357 | //apply instantly. No setting need to be stored. |
| 9358 | char methods[MAX_BUF_SIZE], *token, *next_token; |
| 9359 | char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0}; |
| 9360 | struct params params; |
| 9361 | |
| 9362 | if(!methodString) |
| 9363 | return RETURN_ERR; |
| 9364 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9365 | //store the paramters, and wait for wifi up to apply |
| 9366 | |
| 9367 | snprintf(methods, sizeof(methods), "%s", methodString); |
| 9368 | for(token=methods; *token; token=next_token) |
| 9369 | { |
| 9370 | strtok_r(token, ",", &next_token); |
| 9371 | if(*token=='U' && !strcmp(methods, "USBFlashDrive")) |
| 9372 | snprintf(config_methods, sizeof(config_methods), "%s ", "usba"); |
| 9373 | else if(*token=='E') |
| 9374 | { |
| 9375 | if(!strcmp(methods, "Ethernet")) |
| 9376 | snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet"); |
| 9377 | else if(!strcmp(methods, "ExternalNFCToken")) |
| 9378 | snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token"); |
| 9379 | else |
| 9380 | printf("%s: Unknown WpsConfigMethod\n", __func__); |
| 9381 | } |
| 9382 | else if(*token=='I' && !strcmp(token, "IntegratedNFCToken")) |
| 9383 | snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token"); |
| 9384 | else if(*token=='N' && !strcmp(token, "NFCInterface")) |
| 9385 | snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface"); |
| 9386 | else if(*token=='P' ) |
| 9387 | { |
| 9388 | if(!strcmp(token, "PushButton")) |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 9389 | snprintf(config_methods, sizeof(config_methods), "%s ", "push_button"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9390 | else if(!strcmp(token, "PIN")) |
| 9391 | snprintf(config_methods, sizeof(config_methods), "%s ", "keypad"); |
| 9392 | else |
| 9393 | printf("%s: Unknown WpsConfigMethod\n", __func__); |
| 9394 | } |
| 9395 | else |
| 9396 | printf("%s: Unknown WpsConfigMethod\n", __func__); |
| 9397 | } |
| 9398 | params.name = "config_methods"; |
| 9399 | params.value = config_methods; |
| 9400 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9401 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 9402 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 9403 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9404 | |
| 9405 | return RETURN_OK; |
| 9406 | } |
| 9407 | |
| 9408 | // outputs the pin value, ulong_pin must be allocated by the caller |
| 9409 | INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong) |
| 9410 | { |
| 9411 | char buf[MAX_BUF_SIZE] = {0}; |
| 9412 | char cmd[MAX_CMD_SIZE] = {0}; |
| 9413 | |
| 9414 | if(!output_ulong) |
| 9415 | return RETURN_ERR; |
| 9416 | snprintf(cmd, sizeof(cmd), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex); |
| 9417 | _syscmd(cmd, buf, sizeof(buf)); |
| 9418 | if(strlen(buf) > 0) |
| 9419 | *output_ulong=strtoul(buf, NULL, 10); |
| 9420 | |
| 9421 | return RETURN_OK; |
| 9422 | } |
| 9423 | |
| 9424 | // set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed. |
| 9425 | INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin) |
| 9426 | { |
| 9427 | //set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply |
| 9428 | char ap_pin[16] = {0}; |
| 9429 | char buf[MAX_BUF_SIZE] = {0}; |
| 9430 | char config_file[MAX_BUF_SIZE] = {0}; |
| 9431 | ULONG prev_pin = 0; |
| 9432 | struct params params; |
| 9433 | |
| 9434 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9435 | snprintf(ap_pin, sizeof(ap_pin), "%lu", pin); |
| 9436 | params.name = "ap_pin"; |
| 9437 | params.value = ap_pin; |
| 9438 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 9439 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 9440 | wifi_hostapdProcessUpdate(apIndex, ¶ms, 1); |
| 9441 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9442 | |
| 9443 | return RETURN_OK; |
| 9444 | } |
| 9445 | |
| 9446 | // Output string is either Not configured or Configured, max 32 characters |
| 9447 | INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string) |
| 9448 | { |
| 9449 | char interface_name[16] = {0}; |
| 9450 | char cmd[MAX_CMD_SIZE]; |
| 9451 | char buf[MAX_BUF_SIZE]={0}; |
| 9452 | |
| 9453 | if(!output_string) |
| 9454 | return RETURN_ERR; |
| 9455 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9456 | snprintf(output_string, 32, "Not configured"); |
| 9457 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 9458 | return RETURN_ERR; |
| 9459 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name); |
| 9460 | _syscmd(cmd, buf, sizeof(buf)); |
| 9461 | |
| 9462 | if(!strncmp(buf, "configured", 10)) |
| 9463 | snprintf(output_string, 32, "Configured"); |
| 9464 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9465 | |
| 9466 | return RETURN_OK; |
| 9467 | } |
| 9468 | |
| 9469 | // sets the WPS pin for this AP |
| 9470 | INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin) |
| 9471 | { |
| 9472 | char interface_name[16] = {0}; |
| 9473 | char cmd[MAX_CMD_SIZE]; |
| 9474 | char buf[MAX_BUF_SIZE]={0}; |
| 9475 | BOOL enable; |
| 9476 | |
| 9477 | wifi_getApEnable(apIndex, &enable); |
| 9478 | if (!enable) |
| 9479 | return RETURN_ERR; |
| 9480 | wifi_getApWpsEnable(apIndex, &enable); |
| 9481 | if (!enable) |
| 9482 | return RETURN_ERR; |
| 9483 | |
| 9484 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 9485 | return RETURN_ERR; |
| 9486 | snprintf(cmd, 64, "hostapd_cli -i%s wps_pin any %s", interface_name, pin); |
| 9487 | _syscmd(cmd, buf, sizeof(buf)); |
| 9488 | if((strstr(buf, "OK"))!=NULL) |
| 9489 | return RETURN_OK; |
| 9490 | |
| 9491 | return RETURN_ERR; |
| 9492 | } |
| 9493 | |
| 9494 | // This function is called when the WPS push button has been pressed for this AP |
| 9495 | INT wifi_setApWpsButtonPush(INT apIndex) |
| 9496 | { |
| 9497 | char cmd[MAX_CMD_SIZE]; |
| 9498 | char buf[MAX_BUF_SIZE]={0}; |
| 9499 | char interface_name[16] = {0}; |
| 9500 | BOOL enable=FALSE; |
| 9501 | |
| 9502 | wifi_getApEnable(apIndex, &enable); |
| 9503 | if (!enable) |
| 9504 | return RETURN_ERR; |
| 9505 | |
| 9506 | wifi_getApWpsEnable(apIndex, &enable); |
| 9507 | if (!enable) |
| 9508 | return RETURN_ERR; |
| 9509 | |
| 9510 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 9511 | return RETURN_ERR; |
| 9512 | |
| 9513 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name); |
| 9514 | _syscmd(cmd, buf, sizeof(buf)); |
| 9515 | |
| 9516 | if((strstr(buf, "OK"))!=NULL) |
| 9517 | return RETURN_OK; |
| 9518 | return RETURN_ERR; |
| 9519 | } |
| 9520 | |
| 9521 | // cancels WPS mode for this AP |
| 9522 | INT wifi_cancelApWPS(INT apIndex) |
| 9523 | { |
| 9524 | char interface_name[16] = {0}; |
| 9525 | char cmd[MAX_CMD_SIZE]; |
| 9526 | char buf[MAX_BUF_SIZE]={0}; |
| 9527 | |
| 9528 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 9529 | return RETURN_ERR; |
| 9530 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i%s wps_cancel", interface_name); |
| 9531 | _syscmd(cmd,buf, sizeof(buf)); |
| 9532 | |
| 9533 | if((strstr(buf, "OK"))!=NULL) |
| 9534 | return RETURN_OK; |
| 9535 | return RETURN_ERR; |
| 9536 | } |
| 9537 | |
| 9538 | //Device.WiFi.AccessPoint.{i}.AssociatedDevice.* |
| 9539 | //HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array" |
| 9540 | INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size) |
| 9541 | { |
| 9542 | char interface_name[16] = {0}; |
| 9543 | FILE *f = NULL; |
| 9544 | int read_flag=0, auth_temp=0, mac_temp=0,i=0; |
| 9545 | char cmd[256] = {0}, buf[2048] = {0}; |
| 9546 | char *param = NULL, *value = NULL, *line=NULL; |
| 9547 | size_t len = 0; |
| 9548 | ssize_t nread = 0; |
| 9549 | wifi_associated_dev_t *dev=NULL; |
| 9550 | |
| 9551 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9552 | *associated_dev_array = NULL; |
| 9553 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 9554 | return RETURN_ERR; |
| 9555 | sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name); |
| 9556 | _syscmd(cmd,buf,sizeof(buf)); |
| 9557 | *output_array_size = atoi(buf); |
| 9558 | |
| 9559 | if (*output_array_size <= 0) |
| 9560 | return RETURN_OK; |
| 9561 | |
| 9562 | dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t)); |
| 9563 | *associated_dev_array = dev; |
| 9564 | sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name); |
| 9565 | _syscmd(cmd,buf,sizeof(buf)); |
| 9566 | f = fopen("/tmp/connected_devices.txt", "r"); |
| 9567 | if (f==NULL) |
| 9568 | { |
| 9569 | *output_array_size=0; |
| 9570 | return RETURN_ERR; |
| 9571 | } |
| 9572 | while ((getline(&line, &len, f)) != -1) |
| 9573 | { |
| 9574 | param = strtok(line,"="); |
| 9575 | value = strtok(NULL,"="); |
| 9576 | |
| 9577 | if( strcmp("flags",param) == 0 ) |
| 9578 | { |
| 9579 | value[strlen(value)-1]='\0'; |
| 9580 | if(strstr (value,"AUTHORIZED") != NULL ) |
| 9581 | { |
| 9582 | dev[auth_temp].cli_AuthenticationState = 1; |
| 9583 | dev[auth_temp].cli_Active = 1; |
| 9584 | auth_temp++; |
| 9585 | read_flag=1; |
| 9586 | } |
| 9587 | } |
| 9588 | if(read_flag==1) |
| 9589 | { |
| 9590 | if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 ) |
| 9591 | { |
| 9592 | value[strlen(value)-1]='\0'; |
| 9593 | sscanf(value, "%x:%x:%x:%x:%x:%x", |
| 9594 | (unsigned int *)&dev[mac_temp].cli_MACAddress[0], |
| 9595 | (unsigned int *)&dev[mac_temp].cli_MACAddress[1], |
| 9596 | (unsigned int *)&dev[mac_temp].cli_MACAddress[2], |
| 9597 | (unsigned int *)&dev[mac_temp].cli_MACAddress[3], |
| 9598 | (unsigned int *)&dev[mac_temp].cli_MACAddress[4], |
| 9599 | (unsigned int *)&dev[mac_temp].cli_MACAddress[5] ); |
| 9600 | mac_temp++; |
| 9601 | read_flag=0; |
| 9602 | } |
| 9603 | } |
| 9604 | } |
| 9605 | *output_array_size = auth_temp; |
| 9606 | auth_temp=0; |
| 9607 | mac_temp=0; |
| 9608 | free(line); |
| 9609 | fclose(f); |
| 9610 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9611 | return RETURN_OK; |
| 9612 | } |
| 9613 | |
| 9614 | #define MACADDRESS_SIZE 6 |
| 9615 | |
| 9616 | INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 9617 | { |
| 9618 | FILE *fp = NULL; |
| 9619 | char str[MAX_BUF_SIZE] = {0}; |
| 9620 | int wificlientindex = 0 ; |
| 9621 | int count = 0; |
| 9622 | int signalstrength = 0; |
| 9623 | int arr[MACADDRESS_SIZE] = {0}; |
| 9624 | unsigned char mac[MACADDRESS_SIZE] = {0}; |
| 9625 | UINT wifi_count = 0; |
| 9626 | char virtual_interface_name[MAX_BUF_SIZE] = {0}; |
| 9627 | char pipeCmd[MAX_CMD_SIZE] = {0}; |
| 9628 | |
| 9629 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 9630 | *output_array_size = 0; |
| 9631 | *associated_dev_array = NULL; |
| 9632 | |
| 9633 | sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name); |
| 9634 | fp = popen(pipeCmd, "r"); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9635 | if (fp == NULL) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9636 | { |
| 9637 | printf("Failed to run command inside function %s\n",__FUNCTION__ ); |
| 9638 | return RETURN_ERR; |
| 9639 | } |
| 9640 | |
| 9641 | /* Read the output a line at a time - output it. */ |
| 9642 | fgets(str, sizeof(str)-1, fp); |
| 9643 | wifi_count = (unsigned int) atoi ( str ); |
| 9644 | *output_array_size = wifi_count; |
| 9645 | printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex); |
| 9646 | pclose(fp); |
| 9647 | |
| 9648 | if(wifi_count == 0) |
| 9649 | { |
| 9650 | return RETURN_OK; |
| 9651 | } |
| 9652 | else |
| 9653 | { |
| 9654 | wifi_associated_dev3_t* temp = NULL; |
| 9655 | temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ; |
| 9656 | if(temp == NULL) |
| 9657 | { |
| 9658 | printf("Error Statement. Insufficient memory \n"); |
| 9659 | return RETURN_ERR; |
| 9660 | } |
| 9661 | |
| 9662 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name); |
| 9663 | system(pipeCmd); |
| 9664 | memset(pipeCmd,0,sizeof(pipeCmd)); |
| 9665 | if(apIndex == 0) |
| 9666 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name); |
| 9667 | else if(apIndex == 1) |
| 9668 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name); |
| 9669 | system(pipeCmd); |
| 9670 | |
| 9671 | fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r"); |
| 9672 | if(fp == NULL) |
| 9673 | { |
| 9674 | printf("/tmp/AssociatedDevice_Stats.txt not exists \n"); |
| 9675 | free(temp); |
| 9676 | return RETURN_ERR; |
| 9677 | } |
| 9678 | fclose(fp); |
| 9679 | |
| 9680 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2"); |
| 9681 | fp = popen(pipeCmd, "r"); |
| 9682 | if(fp) |
| 9683 | { |
| 9684 | for(count =0 ; count < wifi_count; count++) |
| 9685 | { |
| 9686 | fgets(str, MAX_BUF_SIZE, fp); |
| 9687 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 9688 | { |
| 9689 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 9690 | { |
| 9691 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 9692 | |
| 9693 | } |
| 9694 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 9695 | printf("MAC %d = %X:%X:%X:%X:%X:%X \n", count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]); |
| 9696 | } |
| 9697 | temp[count].cli_AuthenticationState = 1; //TODO |
| 9698 | temp[count].cli_Active = 1; //TODO |
| 9699 | } |
| 9700 | pclose(fp); |
| 9701 | } |
| 9702 | |
| 9703 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt"); |
| 9704 | fp = popen(pipeCmd, "r"); |
| 9705 | if(fp) |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9706 | { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9707 | pclose(fp); |
| 9708 | } |
| 9709 | fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r"); |
| 9710 | if(fp) |
| 9711 | { |
| 9712 | for(count =0 ; count < wifi_count ;count++) |
| 9713 | { |
| 9714 | fgets(str, MAX_BUF_SIZE, fp); |
| 9715 | signalstrength = atoi(str); |
| 9716 | temp[count].cli_SignalStrength = signalstrength; |
| 9717 | temp[count].cli_RSSI = signalstrength; |
| 9718 | temp[count].cli_SNR = signalstrength + 95; |
| 9719 | } |
| 9720 | pclose(fp); |
| 9721 | } |
| 9722 | |
| 9723 | |
| 9724 | if((apIndex == 0) || (apIndex == 4)) |
| 9725 | { |
| 9726 | for(count =0 ; count < wifi_count ;count++) |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9727 | { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9728 | strcpy(temp[count].cli_OperatingStandard,"g"); |
| 9729 | strcpy(temp[count].cli_OperatingChannelBandwidth,"20MHz"); |
| 9730 | } |
| 9731 | |
| 9732 | //BytesSent |
| 9733 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt"); |
| 9734 | fp = popen(pipeCmd, "r"); |
| 9735 | if(fp) |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 9736 | { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9737 | pclose(fp); |
| 9738 | } |
| 9739 | fp = popen("cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2","r"); |
| 9740 | if(fp) |
| 9741 | { |
| 9742 | for (count = 0; count < wifi_count; count++) |
| 9743 | { |
| 9744 | fgets(str, MAX_BUF_SIZE, fp); |
| 9745 | temp[count].cli_BytesSent = strtoul(str, NULL, 10); |
| 9746 | } |
| 9747 | pclose(fp); |
| 9748 | } |
| 9749 | |
| 9750 | //BytesReceived |
| 9751 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt"); |
| 9752 | fp = popen(pipeCmd, "r"); |
| 9753 | if (fp) |
| 9754 | { |
| 9755 | pclose(fp); |
| 9756 | } |
| 9757 | fp = popen("cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 9758 | if (fp) |
| 9759 | { |
| 9760 | for (count = 0; count < wifi_count; count++) |
| 9761 | { |
| 9762 | fgets(str, MAX_BUF_SIZE, fp); |
| 9763 | temp[count].cli_BytesReceived = strtoul(str, NULL, 10); |
| 9764 | } |
| 9765 | pclose(fp); |
| 9766 | } |
| 9767 | |
| 9768 | //PacketsSent |
| 9769 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt"); |
| 9770 | fp = popen(pipeCmd, "r"); |
| 9771 | if (fp) |
| 9772 | { |
| 9773 | pclose(fp); |
| 9774 | } |
| 9775 | |
| 9776 | fp = popen("cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2", "r"); |
| 9777 | if (fp) |
| 9778 | { |
| 9779 | for (count = 0; count < wifi_count; count++) |
| 9780 | { |
| 9781 | fgets(str, MAX_BUF_SIZE, fp); |
| 9782 | temp[count].cli_PacketsSent = strtoul(str, NULL, 10); |
| 9783 | } |
| 9784 | pclose(fp); |
| 9785 | } |
| 9786 | |
| 9787 | //PacketsReceived |
| 9788 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt"); |
| 9789 | fp = popen(pipeCmd, "r"); |
| 9790 | if (fp) |
| 9791 | { |
| 9792 | pclose(fp); |
| 9793 | } |
| 9794 | fp = popen("cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 9795 | if (fp) |
| 9796 | { |
| 9797 | for (count = 0; count < wifi_count; count++) |
| 9798 | { |
| 9799 | fgets(str, MAX_BUF_SIZE, fp); |
| 9800 | temp[count].cli_PacketsReceived = strtoul(str, NULL, 10); |
| 9801 | } |
| 9802 | pclose(fp); |
| 9803 | } |
| 9804 | |
| 9805 | //ErrorsSent |
| 9806 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt"); |
| 9807 | fp = popen(pipeCmd, "r"); |
| 9808 | if (fp) |
| 9809 | { |
| 9810 | pclose(fp); |
| 9811 | } |
| 9812 | fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r"); |
| 9813 | if (fp) |
| 9814 | { |
| 9815 | for (count = 0; count < wifi_count; count++) |
| 9816 | { |
| 9817 | fgets(str, MAX_BUF_SIZE, fp); |
| 9818 | temp[count].cli_ErrorsSent = strtoul(str, NULL, 10); |
| 9819 | } |
| 9820 | pclose(fp); |
| 9821 | } |
| 9822 | |
| 9823 | //ErrorsSent |
| 9824 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt"); |
| 9825 | fp = popen(pipeCmd, "r"); |
| 9826 | if (fp) |
| 9827 | { |
| 9828 | pclose(fp); |
| 9829 | } |
| 9830 | fp = popen("cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2", "r"); |
| 9831 | if (fp) |
| 9832 | { |
| 9833 | for (count = 0; count < wifi_count; count++) |
| 9834 | { |
| 9835 | fgets(str, MAX_BUF_SIZE, fp); |
| 9836 | temp[count].cli_ErrorsSent = strtoul(str, NULL, 10); |
| 9837 | } |
| 9838 | pclose(fp); |
| 9839 | } |
| 9840 | |
| 9841 | //LastDataDownlinkRate |
| 9842 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt"); |
| 9843 | fp = popen(pipeCmd, "r"); |
| 9844 | if (fp) |
| 9845 | { |
| 9846 | pclose(fp); |
| 9847 | } |
| 9848 | fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r"); |
| 9849 | if (fp) |
| 9850 | { |
| 9851 | for (count = 0; count < wifi_count; count++) |
| 9852 | { |
| 9853 | fgets(str, MAX_BUF_SIZE, fp); |
| 9854 | temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10); |
| 9855 | temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps |
| 9856 | } |
| 9857 | pclose(fp); |
| 9858 | } |
| 9859 | |
| 9860 | //LastDataUplinkRate |
| 9861 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt"); |
| 9862 | fp = popen(pipeCmd, "r"); |
| 9863 | if (fp) |
| 9864 | { |
| 9865 | pclose(fp); |
| 9866 | } |
| 9867 | fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 9868 | if (fp) |
| 9869 | { |
| 9870 | for (count = 0; count < wifi_count; count++) |
| 9871 | { |
| 9872 | fgets(str, MAX_BUF_SIZE, fp); |
| 9873 | temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10); |
| 9874 | temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps |
| 9875 | } |
| 9876 | pclose(fp); |
| 9877 | } |
| 9878 | |
| 9879 | } |
| 9880 | else if ((apIndex == 1) || (apIndex == 5)) |
| 9881 | { |
| 9882 | for (count = 0; count < wifi_count; count++) |
| 9883 | { |
| 9884 | strcpy(temp[count].cli_OperatingStandard, "a"); |
| 9885 | strcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz"); |
| 9886 | temp[count].cli_BytesSent = 0; |
| 9887 | temp[count].cli_BytesReceived = 0; |
| 9888 | temp[count].cli_LastDataUplinkRate = 0; |
| 9889 | temp[count].cli_LastDataDownlinkRate = 0; |
| 9890 | temp[count].cli_PacketsSent = 0; |
| 9891 | temp[count].cli_PacketsReceived = 0; |
| 9892 | temp[count].cli_ErrorsSent = 0; |
| 9893 | } |
| 9894 | } |
| 9895 | |
| 9896 | for (count = 0; count < wifi_count; count++) |
| 9897 | { |
| 9898 | temp[count].cli_Retransmissions = 0; |
| 9899 | temp[count].cli_DataFramesSentAck = 0; |
| 9900 | temp[count].cli_DataFramesSentNoAck = 0; |
| 9901 | temp[count].cli_MinRSSI = 0; |
| 9902 | temp[count].cli_MaxRSSI = 0; |
| 9903 | strncpy(temp[count].cli_InterferenceSources, "", 64); |
| 9904 | memset(temp[count].cli_IPAddress, 0, 64); |
| 9905 | temp[count].cli_RetransCount = 0; |
| 9906 | temp[count].cli_FailedRetransCount = 0; |
| 9907 | temp[count].cli_RetryCount = 0; |
| 9908 | temp[count].cli_MultipleRetryCount = 0; |
| 9909 | } |
| 9910 | *associated_dev_array = temp; |
| 9911 | } |
| 9912 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 9913 | return RETURN_OK; |
| 9914 | } |
| 9915 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 9916 | int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9917 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 9918 | char cmd[MAX_CMD_SIZE] = {0}; |
| 9919 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9920 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 9921 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 9922 | |
| 9923 | snprintf(cmd, MAX_CMD_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'", |
| 9924 | interface_name); |
| 9925 | _syscmd(cmd, buf, MAX_BUF_SIZE); |
| 9926 | |
| 9927 | strcpy(wifi_status, buf); /* TBD: check wifi_status mem lenth and replace with strcpy later */ |
| 9928 | |
| 9929 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9930 | return RETURN_OK; |
| 9931 | } |
| 9932 | |
| 9933 | /* #define HOSTAPD_STA_PARAM_ENTRIES 29 |
| 9934 | struct hostapd_sta_param { |
| 9935 | char key[50]; |
| 9936 | char value[100]; |
| 9937 | } |
| 9938 | |
| 9939 | static char * hostapd_st_get_param(struct hostapd_sta_param * params, char *key){ |
| 9940 | int i = 0; |
| 9941 | |
| 9942 | while(i<HOSTAPD_STA_PARAM_ENTRIES) { |
| 9943 | if (strncmp(params[i].key,key,50) == 0){ |
| 9944 | return ¶ms[i].value; |
| 9945 | } |
| 9946 | i++; |
| 9947 | } |
| 9948 | return NULL; |
| 9949 | |
| 9950 | } */ |
| 9951 | |
| 9952 | static unsigned int count_occurences(const char *buf, const char *word) |
| 9953 | { |
| 9954 | unsigned int n = 0; |
| 9955 | char *ptr = strstr(buf, word); |
| 9956 | |
| 9957 | while (ptr++) { |
| 9958 | n++; |
| 9959 | ptr = strstr(ptr, word); |
| 9960 | } |
| 9961 | |
| 9962 | wifi_dbg_printf("%s: found %u of '%s'\n", __FUNCTION__, n, word); |
| 9963 | return n; |
| 9964 | } |
| 9965 | |
| 9966 | static const char *get_line_from_str_buf(const char *buf, char *line) |
| 9967 | { |
| 9968 | int i; |
| 9969 | int n = strlen(buf); |
| 9970 | |
| 9971 | for (i = 0; i < n; i++) { |
| 9972 | line[i] = buf[i]; |
| 9973 | if (buf[i] == '\n') { |
| 9974 | line[i] = '\0'; |
| 9975 | return &buf[i + 1]; |
| 9976 | } |
| 9977 | } |
| 9978 | |
| 9979 | return NULL; |
| 9980 | } |
| 9981 | |
| 9982 | INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 9983 | { |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 9984 | char interface_name[16] = {0}; |
| 9985 | FILE *f = NULL; |
| 9986 | int auth_temp= -1; |
| 9987 | char cmd[256] = {0}, buf[2048] = {0}; |
| 9988 | char *param = NULL, *value = NULL, *line=NULL; |
| 9989 | size_t len = 0; |
| 9990 | wifi_associated_dev3_t *dev=NULL; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9991 | |
| 9992 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 9993 | *associated_dev_array = NULL; |
| 9994 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9995 | return RETURN_ERR; |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 9996 | sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name); |
| 9997 | _syscmd(cmd, buf, sizeof(buf)); |
| 9998 | *output_array_size = atoi(buf); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 9999 | |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 10000 | if (*output_array_size <= 0) |
| 10001 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10002 | |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 10003 | dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t)); |
| 10004 | *associated_dev_array = dev; |
| 10005 | sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name); |
| 10006 | _syscmd(cmd,buf,sizeof(buf)); |
| 10007 | f = fopen("/tmp/diagnostic3_devices.txt", "r"); |
| 10008 | if (f == NULL) |
| 10009 | { |
| 10010 | *output_array_size=0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10011 | return RETURN_ERR; |
| 10012 | } |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 10013 | while ((getline(&line, &len, f)) != -1) |
| 10014 | { |
| 10015 | param = strtok(line, "="); |
| 10016 | value = strtok(NULL, "="); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10017 | |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 10018 | if( strcmp("flags",param) == 0 ) |
| 10019 | { |
| 10020 | value[strlen(value)-1]='\0'; |
| 10021 | if(strstr (value,"AUTHORIZED") != NULL ) |
| 10022 | { |
| 10023 | auth_temp++; |
| 10024 | dev[auth_temp].cli_AuthenticationState = 1; |
| 10025 | dev[auth_temp].cli_Active = 1; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10026 | } |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 10027 | } else if (auth_temp < 0) { |
| 10028 | continue; |
| 10029 | } else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 ) |
| 10030 | { |
| 10031 | value[strlen(value)-1]='\0'; |
| 10032 | sscanf(value, "%x:%x:%x:%x:%x:%x", |
| 10033 | (unsigned int *)&dev[auth_temp].cli_MACAddress[0], |
| 10034 | (unsigned int *)&dev[auth_temp].cli_MACAddress[1], |
| 10035 | (unsigned int *)&dev[auth_temp].cli_MACAddress[2], |
| 10036 | (unsigned int *)&dev[auth_temp].cli_MACAddress[3], |
| 10037 | (unsigned int *)&dev[auth_temp].cli_MACAddress[4], |
| 10038 | (unsigned int *)&dev[auth_temp].cli_MACAddress[5]); |
| 10039 | } else if (strcmp("signal", param) == 0) { |
| 10040 | value[strlen(value)-1]='\0'; |
| 10041 | sscanf(value, "%d", &dev[auth_temp].cli_RSSI); |
| 10042 | dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10043 | } |
developer | 0d26f2c | 2023-05-25 19:46:36 +0800 | [diff] [blame] | 10044 | } |
| 10045 | if (line) |
| 10046 | free(line); |
| 10047 | fclose(f); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10048 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10049 | return RETURN_OK; |
| 10050 | } |
| 10051 | |
| 10052 | #if 0 |
| 10053 | //To-do |
| 10054 | INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 10055 | { |
| 10056 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10057 | |
| 10058 | //Using different approach to get required WiFi Parameters from system available commands |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10059 | #if 0 |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10060 | FILE *f; |
| 10061 | int read_flag=0, auth_temp=0, mac_temp=0,i=0; |
| 10062 | char cmd[256], buf[2048]; |
| 10063 | char *param , *value, *line=NULL; |
| 10064 | size_t len = 0; |
| 10065 | ssize_t nread; |
| 10066 | wifi_associated_dev3_t *dev=NULL; |
| 10067 | *associated_dev_array = NULL; |
| 10068 | sprintf(cmd, "hostapd_cli -i%s all_sta | grep AUTHORIZED | wc -l", interface_name); |
| 10069 | _syscmd(cmd,buf,sizeof(buf)); |
| 10070 | *output_array_size = atoi(buf); |
| 10071 | |
| 10072 | if (*output_array_size <= 0) |
| 10073 | return RETURN_OK; |
| 10074 | |
| 10075 | dev=(wifi_associated_dev3_t *) AnscAllocateMemory(*output_array_size * sizeof(wifi_associated_dev3_t)); |
| 10076 | *associated_dev_array = dev; |
| 10077 | sprintf(cmd, "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt", interface_name); |
| 10078 | _syscmd(cmd,buf,sizeof(buf)); |
| 10079 | f = fopen("/tmp/connected_devices.txt", "r"); |
| 10080 | if (f==NULL) |
| 10081 | { |
| 10082 | *output_array_size=0; |
| 10083 | return RETURN_ERR; |
| 10084 | } |
| 10085 | while ((nread = getline(&line, &len, f)) != -1) |
| 10086 | { |
| 10087 | param = strtok(line,"="); |
| 10088 | value = strtok(NULL,"="); |
| 10089 | |
| 10090 | if( strcmp("flags",param) == 0 ) |
| 10091 | { |
| 10092 | value[strlen(value)-1]='\0'; |
| 10093 | if(strstr (value,"AUTHORIZED") != NULL ) |
| 10094 | { |
| 10095 | dev[auth_temp].cli_AuthenticationState = 1; |
| 10096 | dev[auth_temp].cli_Active = 1; |
| 10097 | auth_temp++; |
| 10098 | read_flag=1; |
| 10099 | } |
| 10100 | } |
| 10101 | if(read_flag==1) |
| 10102 | { |
| 10103 | if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 ) |
| 10104 | { |
| 10105 | value[strlen(value)-1]='\0'; |
| 10106 | sscanf(value, "%x:%x:%x:%x:%x:%x", |
| 10107 | (unsigned int *)&dev[mac_temp].cli_MACAddress[0], |
| 10108 | (unsigned int *)&dev[mac_temp].cli_MACAddress[1], |
| 10109 | (unsigned int *)&dev[mac_temp].cli_MACAddress[2], |
| 10110 | (unsigned int *)&dev[mac_temp].cli_MACAddress[3], |
| 10111 | (unsigned int *)&dev[mac_temp].cli_MACAddress[4], |
| 10112 | (unsigned int *)&dev[mac_temp].cli_MACAddress[5] ); |
| 10113 | |
| 10114 | } |
| 10115 | else if( strcmp("rx_packets",param) == 0 ) |
| 10116 | { |
| 10117 | sscanf(value, "%d", &(dev[mac_temp].cli_PacketsReceived)); |
| 10118 | } |
| 10119 | |
| 10120 | else if( strcmp("tx_packets",param) == 0 ) |
| 10121 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10122 | sscanf(value, "%d", &(dev[mac_temp].cli_PacketsSent)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10123 | } |
| 10124 | |
| 10125 | else if( strcmp("rx_bytes",param) == 0 ) |
| 10126 | { |
| 10127 | sscanf(value, "%d", &(dev[mac_temp].cli_BytesReceived)); |
| 10128 | } |
| 10129 | |
| 10130 | else if( strcmp("tx_bytes",param) == 0 ) |
| 10131 | { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10132 | sscanf(value, "%d", &(dev[mac_temp].cli_BytesSent)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10133 | mac_temp++; |
| 10134 | read_flag=0; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10135 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10136 | } |
| 10137 | } |
| 10138 | |
| 10139 | *output_array_size = auth_temp; |
| 10140 | auth_temp=0; |
| 10141 | mac_temp=0; |
| 10142 | free(line); |
| 10143 | fclose(f); |
| 10144 | #endif |
| 10145 | char interface_name[MAX_BUF_SIZE] = {0}; |
| 10146 | char wifi_status[MAX_BUF_SIZE] = {0}; |
| 10147 | char hostapdconf[MAX_BUF_SIZE] = {0}; |
| 10148 | |
| 10149 | wifi_associated_dev3_t *dev_array = NULL; |
| 10150 | ULONG wifi_count = 0; |
| 10151 | |
| 10152 | *associated_dev_array = NULL; |
| 10153 | *output_array_size = 0; |
| 10154 | |
| 10155 | printf("wifi_getApAssociatedDeviceDiagnosticResult3 apIndex = %d \n", apIndex); |
| 10156 | //if(apIndex == 0 || apIndex == 1 || apIndex == 4 || apIndex == 5) // These are availble in RPI. |
| 10157 | { |
| 10158 | sprintf(hostapdconf, "/nvram/hostapd%d.conf", apIndex); |
| 10159 | |
| 10160 | wifi_GetInterfaceName(interface_name, hostapdconf); |
| 10161 | |
| 10162 | if(strlen(interface_name) > 1) |
| 10163 | { |
| 10164 | wifihal_interfacestatus(wifi_status,interface_name); |
| 10165 | if(strcmp(wifi_status,"RUNNING") == 0) |
| 10166 | { |
| 10167 | wifihal_AssociatedDevicesstats3(apIndex,interface_name,&dev_array,&wifi_count); |
| 10168 | |
| 10169 | *associated_dev_array = dev_array; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10170 | *output_array_size = wifi_count; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10171 | } |
| 10172 | else |
| 10173 | { |
| 10174 | *associated_dev_array = NULL; |
| 10175 | } |
| 10176 | } |
| 10177 | } |
| 10178 | |
| 10179 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10180 | return RETURN_OK; |
| 10181 | } |
| 10182 | #endif |
| 10183 | |
| 10184 | /* getIPAddress function */ |
| 10185 | /** |
| 10186 | * @description Returning IpAddress of the Matched String |
| 10187 | * |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10188 | * @param |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10189 | * @str Having MacAddress |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10190 | * @ipaddr Having ipaddr |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10191 | * @return The status of the operation |
| 10192 | * @retval RETURN_OK if successful |
| 10193 | * @retval RETURN_ERR if any error is detected |
| 10194 | * |
| 10195 | */ |
| 10196 | |
| 10197 | INT getIPAddress(char *str,char *ipaddr) |
| 10198 | { |
| 10199 | FILE *fp = NULL; |
| 10200 | char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0}; |
| 10201 | int LeaseTime = 0,ret = 0; |
| 10202 | if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL ) |
| 10203 | { |
| 10204 | return RETURN_ERR; |
| 10205 | } |
| 10206 | |
| 10207 | while ( fgets(buf, sizeof(buf), fp)!= NULL ) |
| 10208 | { |
| 10209 | /* |
| 10210 | Sample:sss |
| 10211 | 1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6 |
| 10212 | 1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6 |
| 10213 | */ |
| 10214 | ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT, |
| 10215 | &(LeaseTime), |
| 10216 | phyAddr, |
| 10217 | ipAddr, |
| 10218 | hostName |
| 10219 | ); |
| 10220 | if(ret != 4) |
| 10221 | continue; |
| 10222 | if(strcmp(str,phyAddr) == 0) |
| 10223 | strcpy(ipaddr,ipAddr); |
| 10224 | } |
| 10225 | fclose(fp); |
| 10226 | return RETURN_OK; |
| 10227 | } |
| 10228 | |
| 10229 | /* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */ |
| 10230 | /** |
| 10231 | * @description Returning Inactive wireless connected clients informations |
| 10232 | * |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10233 | * @param |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10234 | * @filename Holding private_wifi 2g/5g content files |
| 10235 | * @associated_dev_array Having inactiv wireless clients informations |
| 10236 | * @output_array_size Returning Inactive wireless counts |
| 10237 | * @return The status of the operation |
| 10238 | * @retval RETURN_OK if successful |
| 10239 | * @retval RETURN_ERR if any error is detected |
| 10240 | * |
| 10241 | */ |
| 10242 | |
| 10243 | INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size) |
| 10244 | { |
| 10245 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10246 | int count = 0,maccount = 0,i = 0,wificlientindex = 0; |
| 10247 | FILE *fp = NULL; |
| 10248 | int arr[MACADDRESS_SIZE] = {0}; |
| 10249 | unsigned char mac[MACADDRESS_SIZE] = {0}; |
| 10250 | char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0}; |
| 10251 | sprintf(buf,"cat %s | grep Station | sort | uniq | wc -l",filename); |
| 10252 | fp = popen(buf,"r"); |
| 10253 | if(fp == NULL) |
| 10254 | return RETURN_ERR; |
| 10255 | else |
| 10256 | { |
| 10257 | fgets(path,sizeof(path),fp); |
| 10258 | maccount = atoi(path); |
| 10259 | } |
| 10260 | pclose(fp); |
| 10261 | *output_array_size = maccount; |
| 10262 | wifi_associated_dev3_t* temp = NULL; |
| 10263 | temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t)); |
| 10264 | *associated_dev_array = temp; |
| 10265 | if(temp == NULL) |
| 10266 | { |
| 10267 | printf("Error Statement. Insufficient memory \n"); |
| 10268 | return RETURN_ERR; |
| 10269 | } |
| 10270 | memset(buf,0,sizeof(buf)); |
| 10271 | sprintf(buf,"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename); |
| 10272 | fp = popen(buf,"r"); |
| 10273 | if (fp == NULL) { |
| 10274 | fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf); |
| 10275 | return RETURN_ERR; |
| 10276 | } |
| 10277 | for(count = 0; count < maccount ; count++) |
| 10278 | { |
| 10279 | fgets(path,sizeof(path),fp); |
| 10280 | for(i = 0; path[i]!='\n';i++) |
| 10281 | str[i]=path[i]; |
| 10282 | str[i]='\0'; |
| 10283 | getIPAddress(str,ipaddr); |
| 10284 | memset(buf,0,sizeof(buf)); |
| 10285 | if(strlen(ipaddr) > 0) |
| 10286 | { |
| 10287 | sprintf(buf,"ping -q -c 1 -W 1 \"%s\" > /dev/null 2>&1",ipaddr); |
| 10288 | if (WEXITSTATUS(system(buf)) != 0) //InActive wireless clients info |
| 10289 | { |
| 10290 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 10291 | { |
| 10292 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 10293 | { |
| 10294 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 10295 | |
| 10296 | } |
| 10297 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 10298 | fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]); |
| 10299 | } |
| 10300 | temp[count].cli_AuthenticationState = 0; //TODO |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10301 | temp[count].cli_Active = 0; //TODO |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10302 | temp[count].cli_SignalStrength = 0; |
| 10303 | } |
| 10304 | else //Active wireless clients info |
| 10305 | { |
| 10306 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 10307 | { |
| 10308 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 10309 | { |
| 10310 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 10311 | |
| 10312 | } |
| 10313 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 10314 | fprintf(stderr,"%sMAC %d = %X:%X:%X:%X:%X:%X \n", __FUNCTION__,count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]); |
| 10315 | } |
| 10316 | temp[count].cli_Active = 1; |
| 10317 | } |
| 10318 | } |
| 10319 | memset(ipaddr,0,sizeof(ipaddr)); |
| 10320 | } |
| 10321 | pclose(fp); |
| 10322 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10323 | return RETURN_OK; |
| 10324 | } |
| 10325 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering object |
| 10326 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o |
| 10327 | //To get Band Steering Capability |
| 10328 | INT wifi_getBandSteeringCapability(BOOL *support) |
| 10329 | { |
| 10330 | *support = FALSE; |
| 10331 | return RETURN_OK; |
| 10332 | } |
| 10333 | |
| 10334 | |
| 10335 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w |
| 10336 | //To get Band Steering enable status |
| 10337 | INT wifi_getBandSteeringEnable(BOOL *enable) |
| 10338 | { |
| 10339 | *enable = FALSE; |
| 10340 | return RETURN_OK; |
| 10341 | } |
| 10342 | |
| 10343 | //To turn on/off Band steering |
| 10344 | INT wifi_setBandSteeringEnable(BOOL enable) |
| 10345 | { |
| 10346 | return RETURN_OK; |
| 10347 | } |
| 10348 | |
| 10349 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w |
| 10350 | //To get Band Steering AP group |
| 10351 | INT wifi_getBandSteeringApGroup(char *output_ApGroup) |
| 10352 | { |
| 10353 | if (NULL == output_ApGroup) |
| 10354 | return RETURN_ERR; |
| 10355 | |
| 10356 | strcpy(output_ApGroup, "1,2"); |
| 10357 | return RETURN_OK; |
| 10358 | } |
| 10359 | |
| 10360 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w |
| 10361 | //to set and read the band steering BandUtilizationThreshold parameters |
| 10362 | INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold) |
| 10363 | { |
| 10364 | return RETURN_ERR; |
| 10365 | } |
| 10366 | |
| 10367 | INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold) |
| 10368 | { |
| 10369 | return RETURN_ERR; |
| 10370 | } |
| 10371 | |
| 10372 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w |
| 10373 | //to set and read the band steering RSSIThreshold parameters |
| 10374 | INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold) |
| 10375 | { |
| 10376 | return RETURN_ERR; |
| 10377 | } |
| 10378 | |
| 10379 | INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold) |
| 10380 | { |
| 10381 | return RETURN_ERR; |
| 10382 | } |
| 10383 | |
| 10384 | |
| 10385 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w |
| 10386 | //to set and read the band steering physical modulation rate threshold parameters |
| 10387 | INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold) |
| 10388 | { |
| 10389 | //If chip is not support, return -1 |
| 10390 | return RETURN_ERR; |
| 10391 | } |
| 10392 | |
| 10393 | INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold) |
| 10394 | { |
| 10395 | //If chip is not support, return -1 |
| 10396 | return RETURN_ERR; |
| 10397 | } |
| 10398 | |
| 10399 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w |
| 10400 | //to set and read the inactivity time (in seconds) for steering under overload condition |
| 10401 | INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold) |
| 10402 | { |
| 10403 | return RETURN_ERR; |
| 10404 | } |
| 10405 | |
| 10406 | INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold) |
| 10407 | { |
| 10408 | return RETURN_ERR; |
| 10409 | } |
| 10410 | |
| 10411 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w |
| 10412 | //to set and read the inactivity time (in seconds) for steering under Idle condition |
| 10413 | INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold) |
| 10414 | { |
| 10415 | return RETURN_ERR; |
| 10416 | } |
| 10417 | |
| 10418 | INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold) |
| 10419 | { |
| 10420 | return RETURN_ERR; |
| 10421 | } |
| 10422 | |
| 10423 | //Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o |
| 10424 | //pClientMAC[64] |
| 10425 | //pSourceSSIDIndex[64] |
| 10426 | //pDestSSIDIndex[64] |
| 10427 | //pSteeringReason[256] |
| 10428 | INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason) |
| 10429 | { |
| 10430 | //if no steering or redord_index is out of boundary, return -1. pSteeringTime returns the UTC time in seconds. pClientMAC is pre allocated as 64bytes. pSteeringReason returns the predefined steering trigger reason |
| 10431 | *pSteeringTime=time(NULL); |
| 10432 | *pSteeringReason = 0; //TODO: need to assign correct steering reason (INT numeric, i suppose) |
| 10433 | return RETURN_OK; |
| 10434 | } |
| 10435 | |
| 10436 | INT wifi_ifConfigDown(INT apIndex) |
| 10437 | { |
| 10438 | INT status = RETURN_OK; |
| 10439 | char cmd[64]; |
| 10440 | |
| 10441 | snprintf(cmd, sizeof(cmd), "ifconfig ath%d down", apIndex); |
| 10442 | printf("%s: %s\n", __func__, cmd); |
| 10443 | system(cmd); |
| 10444 | |
| 10445 | return status; |
| 10446 | } |
| 10447 | |
| 10448 | INT wifi_ifConfigUp(INT apIndex) |
| 10449 | { |
| 10450 | char interface_name[16] = {0}; |
| 10451 | char cmd[128]; |
| 10452 | char buf[1024]; |
| 10453 | |
| 10454 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 10455 | return RETURN_ERR; |
| 10456 | snprintf(cmd, sizeof(cmd), "ifconfig %s up 2>/dev/null", interface_name); |
| 10457 | _syscmd(cmd, buf, sizeof(buf)); |
| 10458 | return 0; |
| 10459 | } |
| 10460 | |
| 10461 | //>> Deprecated. Replace with wifi_applyRadioSettings |
| 10462 | INT wifi_pushBridgeInfo(INT apIndex) |
| 10463 | { |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 10464 | char ip[32] = {0}; |
| 10465 | char subnet[32] = {0}; |
| 10466 | char bridge[32] = {0}; |
| 10467 | char cmd[128] = {0}; |
| 10468 | char buf[1024] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10469 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 10470 | wifi_getApBridgeInfo(apIndex, bridge, ip, subnet); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10471 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 10472 | snprintf(cmd, sizeof(cmd), "ifconfig %s %s netmask %s ", bridge, ip, subnet); |
| 10473 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10474 | |
developer | b297756 | 2023-05-24 17:54:12 +0800 | [diff] [blame] | 10475 | return 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10476 | } |
| 10477 | |
| 10478 | INT wifi_pushChannel(INT radioIndex, UINT channel) |
| 10479 | { |
| 10480 | char interface_name[16] = {0}; |
| 10481 | char cmd[128]; |
| 10482 | char buf[1024]; |
| 10483 | int apIndex; |
| 10484 | |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10485 | apIndex=(radioIndex==0)?0:1; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10486 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 10487 | return RETURN_ERR; |
| 10488 | snprintf(cmd, sizeof(cmd), "iwconfig %s freq %d",interface_name,channel); |
| 10489 | _syscmd(cmd,buf, sizeof(buf)); |
| 10490 | |
| 10491 | return 0; |
| 10492 | } |
| 10493 | |
| 10494 | INT wifi_pushChannelMode(INT radioIndex) |
| 10495 | { |
| 10496 | //Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly |
| 10497 | return RETURN_ERR; |
| 10498 | } |
| 10499 | |
| 10500 | INT wifi_pushDefaultValues(INT radioIndex) |
| 10501 | { |
| 10502 | //Apply Comcast specified default radio settings instantly |
| 10503 | //AMPDU=1 |
| 10504 | //AMPDUFrames=32 |
| 10505 | //AMPDULim=50000 |
| 10506 | //txqueuelen=1000 |
| 10507 | |
| 10508 | return RETURN_ERR; |
| 10509 | } |
| 10510 | |
| 10511 | INT wifi_pushTxChainMask(INT radioIndex) |
| 10512 | { |
| 10513 | //Apply default TxChainMask instantly |
| 10514 | return RETURN_ERR; |
| 10515 | } |
| 10516 | |
| 10517 | INT wifi_pushRxChainMask(INT radioIndex) |
| 10518 | { |
| 10519 | //Apply default RxChainMask instantly |
| 10520 | return RETURN_ERR; |
| 10521 | } |
| 10522 | |
| 10523 | INT wifi_pushSSID(INT apIndex, CHAR *ssid) |
| 10524 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 10525 | INT status; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10526 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 10527 | status = wifi_setSSIDName(apIndex, ssid); |
| 10528 | wifi_quick_reload_ap(apIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10529 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 10530 | return status; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10531 | } |
| 10532 | |
| 10533 | INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable) |
| 10534 | { |
| 10535 | //Apply default Ssid Advertisement instantly |
| 10536 | return RETURN_ERR; |
| 10537 | } |
| 10538 | |
| 10539 | INT wifi_getRadioUpTime(INT radioIndex, ULONG *output) |
| 10540 | { |
developer | e82c0ca | 2023-05-10 16:25:35 +0800 | [diff] [blame] | 10541 | time_t now; |
| 10542 | |
| 10543 | time(&now); |
| 10544 | if (now > radio_up_time[radioIndex]) |
| 10545 | *output = now - radio_up_time[radioIndex]; |
| 10546 | else { |
| 10547 | *output = 0; |
| 10548 | return RETURN_ERR; |
| 10549 | } |
| 10550 | |
| 10551 | return RETURN_OK; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10552 | } |
| 10553 | |
| 10554 | INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled) |
| 10555 | { |
| 10556 | return RETURN_OK; |
| 10557 | } |
| 10558 | |
| 10559 | INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int) |
| 10560 | { |
| 10561 | return RETURN_OK; |
| 10562 | } |
| 10563 | |
| 10564 | //To-do |
| 10565 | INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string) |
| 10566 | { |
| 10567 | char output[16]={'\0'}; |
| 10568 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10569 | |
| 10570 | if (!output_string) |
| 10571 | return RETURN_ERR; |
| 10572 | |
| 10573 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 10574 | wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output)); |
| 10575 | |
| 10576 | if (strlen(output) == 0) |
| 10577 | snprintf(output_string, 64, "Disabled"); |
| 10578 | else if (strncmp(output, "0", 1) == 0) |
| 10579 | snprintf(output_string, 64, "Disabled"); |
| 10580 | else if (strncmp(output, "1", 1) == 0) |
| 10581 | snprintf(output_string, 64, "Optional"); |
| 10582 | else if (strncmp(output, "2", 1) == 0) |
| 10583 | snprintf(output_string, 64, "Required"); |
| 10584 | else { |
| 10585 | wifi_dbg_printf("\n[%s]: Unexpected ieee80211w=%s", __func__, output); |
| 10586 | return RETURN_ERR; |
| 10587 | } |
| 10588 | |
| 10589 | wifi_dbg_printf("\n[%s]: ieee80211w is : %s", __func__, output); |
| 10590 | return RETURN_OK; |
| 10591 | } |
| 10592 | INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig) |
| 10593 | { |
| 10594 | char str[MAX_BUF_SIZE]={'\0'}; |
| 10595 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 10596 | struct params params; |
| 10597 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10598 | |
| 10599 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10600 | if(NULL == MfpConfig || strlen(MfpConfig) >= 32 ) |
| 10601 | return RETURN_ERR; |
| 10602 | |
| 10603 | params.name = "ieee80211w"; |
| 10604 | if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0) |
| 10605 | params.value = "0"; |
| 10606 | else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0) |
| 10607 | params.value = "1"; |
| 10608 | else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0) |
| 10609 | params.value = "2"; |
| 10610 | else{ |
| 10611 | wifi_dbg_printf("%s: invalid MfpConfig. Input has to be Disabled, Optional or Required \n", __func__); |
| 10612 | return RETURN_ERR; |
| 10613 | } |
| 10614 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 10615 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 10616 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 10617 | return RETURN_OK; |
| 10618 | } |
| 10619 | INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool) |
| 10620 | { |
| 10621 | char output[16]={'\0'}; |
| 10622 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10623 | |
| 10624 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | c0772e6 | 2023-05-18 15:10:48 +0800 | [diff] [blame] | 10625 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 10626 | wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10627 | |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 10628 | if (output == NULL) |
| 10629 | *output_bool = FALSE; |
| 10630 | else if (strncmp(output, "1", 1) == 0) |
| 10631 | *output_bool = TRUE; |
| 10632 | else if (strncmp(output, "2", 1) == 0) |
| 10633 | *output_bool = TRUE; |
| 10634 | else if (strncmp(output, "3", 1) == 0) |
| 10635 | *output_bool = TRUE; |
| 10636 | else |
| 10637 | *output_bool = FALSE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10638 | WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__); |
| 10639 | |
| 10640 | return RETURN_OK; |
| 10641 | } |
| 10642 | |
| 10643 | INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled) |
| 10644 | { |
| 10645 | return RETURN_OK; |
| 10646 | } |
| 10647 | |
| 10648 | INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval) |
| 10649 | { |
| 10650 | return RETURN_OK; |
| 10651 | } |
| 10652 | |
| 10653 | INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled) |
| 10654 | { |
| 10655 | return RETURN_OK; |
| 10656 | } |
| 10657 | |
| 10658 | INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output) |
| 10659 | { |
| 10660 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10661 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10662 | |
| 10663 | if (NULL == output) |
| 10664 | return RETURN_ERR; |
| 10665 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex); |
| 10666 | wifi_hostapdRead(config_file,"hw_mode",output,64); |
| 10667 | |
| 10668 | if(strcmp(output,"b")==0) |
| 10669 | sprintf(output, "%s", "1,2,5.5,11"); |
| 10670 | else if (strcmp(output,"a")==0) |
| 10671 | sprintf(output, "%s", "6,9,11,12,18,24,36,48,54"); |
| 10672 | else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) |
| 10673 | sprintf(output, "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54"); |
| 10674 | |
| 10675 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10676 | return RETURN_OK; |
| 10677 | } |
| 10678 | |
| 10679 | INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output) |
| 10680 | { |
| 10681 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10682 | char *temp; |
| 10683 | char temp_output[128]; |
| 10684 | char temp_TransmitRates[128]; |
| 10685 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10686 | |
| 10687 | if (NULL == output) |
| 10688 | return RETURN_ERR; |
| 10689 | |
| 10690 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex); |
| 10691 | wifi_hostapdRead(config_file,"supported_rates",output,64); |
| 10692 | |
| 10693 | if (strlen(output) == 0) { |
| 10694 | wifi_getRadioSupportedDataTransmitRates(wlanIndex, output); |
| 10695 | return RETURN_OK; |
| 10696 | } |
| 10697 | strcpy(temp_TransmitRates,output); |
| 10698 | strcpy(temp_output,""); |
| 10699 | temp = strtok(temp_TransmitRates," "); |
| 10700 | while(temp!=NULL) |
| 10701 | { |
| 10702 | temp[strlen(temp)-1]=0; |
| 10703 | if((temp[0]=='5') && (temp[1]=='\0')) |
| 10704 | { |
| 10705 | temp="5.5"; |
| 10706 | } |
| 10707 | strcat(temp_output,temp); |
| 10708 | temp = strtok(NULL," "); |
| 10709 | if(temp!=NULL) |
| 10710 | { |
| 10711 | strcat(temp_output,","); |
| 10712 | } |
| 10713 | } |
| 10714 | strcpy(output,temp_output); |
| 10715 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10716 | |
| 10717 | return RETURN_OK; |
| 10718 | } |
| 10719 | |
| 10720 | INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output) |
| 10721 | { |
| 10722 | return RETURN_OK; |
| 10723 | } |
| 10724 | |
| 10725 | |
| 10726 | INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output) |
| 10727 | { |
| 10728 | int i=0; |
| 10729 | char *temp; |
| 10730 | char temp1[128] = {0}; |
| 10731 | char temp_output[128] = {0}; |
| 10732 | char temp_TransmitRates[128] = {0}; |
| 10733 | struct params params={'\0'}; |
| 10734 | char config_file[MAX_BUF_SIZE] = {0}; |
| 10735 | wifi_band band = wifi_index_to_band(wlanIndex); |
| 10736 | |
| 10737 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 10738 | if(NULL == output) |
| 10739 | return RETURN_ERR; |
| 10740 | strcpy(temp_TransmitRates,output); |
| 10741 | |
| 10742 | for(i=0;i<strlen(temp_TransmitRates);i++) |
| 10743 | { |
| 10744 | if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==',')) |
| 10745 | { |
| 10746 | continue; |
| 10747 | } |
| 10748 | else |
| 10749 | { |
| 10750 | return RETURN_ERR; |
| 10751 | } |
| 10752 | } |
| 10753 | strcpy(temp_output,""); |
| 10754 | temp = strtok(temp_TransmitRates,","); |
| 10755 | while(temp!=NULL) |
| 10756 | { |
| 10757 | strcpy(temp1,temp); |
| 10758 | if(band == band_5) |
| 10759 | { |
| 10760 | if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0)) |
| 10761 | { |
| 10762 | return RETURN_ERR; |
| 10763 | } |
| 10764 | } |
| 10765 | |
| 10766 | if(strcmp(temp,"5.5")==0) |
| 10767 | { |
| 10768 | strcpy(temp1,"55"); |
| 10769 | } |
| 10770 | else |
| 10771 | { |
| 10772 | strcat(temp1,"0"); |
| 10773 | } |
| 10774 | strcat(temp_output,temp1); |
| 10775 | temp = strtok(NULL,","); |
| 10776 | if(temp!=NULL) |
| 10777 | { |
| 10778 | strcat(temp_output," "); |
| 10779 | } |
| 10780 | } |
| 10781 | strcpy(output,temp_output); |
| 10782 | |
| 10783 | params.name = "supported_rates"; |
| 10784 | params.value = output; |
| 10785 | |
| 10786 | wifi_dbg_printf("\n%s:",__func__); |
| 10787 | wifi_dbg_printf("params.value=%s\n",params.value); |
| 10788 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,wlanIndex); |
| 10789 | wifi_hostapdWrite(config_file,¶ms,1); |
| 10790 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 10791 | |
| 10792 | return RETURN_OK; |
| 10793 | } |
| 10794 | |
| 10795 | |
| 10796 | static char *sncopy(char *dst, int dst_sz, const char *src) |
| 10797 | { |
| 10798 | if (src && dst && dst_sz > 0) { |
| 10799 | strncpy(dst, src, dst_sz); |
| 10800 | dst[dst_sz - 1] = '\0'; |
| 10801 | } |
| 10802 | return dst; |
| 10803 | } |
| 10804 | |
| 10805 | static int util_get_sec_chan_offset(int channel, const char* ht_mode) |
| 10806 | { |
| 10807 | if (0 == strcmp(ht_mode, "HT40") || |
| 10808 | 0 == strcmp(ht_mode, "HT80") || |
| 10809 | 0 == strcmp(ht_mode, "HT160")) { |
| 10810 | switch (channel) { |
| 10811 | case 1 ... 7: |
| 10812 | case 36: |
| 10813 | case 44: |
| 10814 | case 52: |
| 10815 | case 60: |
| 10816 | case 100: |
| 10817 | case 108: |
| 10818 | case 116: |
| 10819 | case 124: |
| 10820 | case 132: |
| 10821 | case 140: |
| 10822 | case 149: |
| 10823 | case 157: |
| 10824 | return 1; |
| 10825 | case 8 ... 13: |
| 10826 | case 40: |
| 10827 | case 48: |
| 10828 | case 56: |
| 10829 | case 64: |
| 10830 | case 104: |
| 10831 | case 112: |
| 10832 | case 120: |
| 10833 | case 128: |
| 10834 | case 136: |
| 10835 | case 144: |
| 10836 | case 153: |
| 10837 | case 161: |
| 10838 | return -1; |
| 10839 | default: |
| 10840 | return -EINVAL; |
| 10841 | } |
| 10842 | } |
| 10843 | |
| 10844 | return -EINVAL; |
| 10845 | } |
| 10846 | |
| 10847 | static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode) |
| 10848 | { |
| 10849 | int idx = channel%8; |
| 10850 | if (0 == strcmp(ht_mode, "HT40") || |
| 10851 | 0 == strcmp(ht_mode, "HT80") || |
| 10852 | 0 == strcmp(ht_mode, "HT160")) { |
| 10853 | switch (idx) { |
| 10854 | case 1: |
| 10855 | return 1; |
| 10856 | case 5: |
| 10857 | return -1; |
| 10858 | default: |
| 10859 | return -EINVAL; |
| 10860 | } |
| 10861 | } |
| 10862 | |
| 10863 | return -EINVAL; |
| 10864 | } |
| 10865 | static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len) |
| 10866 | { |
| 10867 | if (NULL == hw_mode) return; |
| 10868 | |
| 10869 | if (0 == strcmp(hw_mode, "ac")) |
| 10870 | sncopy(bw_mode, bw_mode_len, "ht vht"); |
| 10871 | |
| 10872 | if (0 == strcmp(hw_mode, "n")) |
| 10873 | sncopy(bw_mode, bw_mode_len, "ht"); |
| 10874 | |
| 10875 | return; |
| 10876 | } |
| 10877 | |
| 10878 | static int util_chan_to_freq(int chan) |
| 10879 | { |
| 10880 | if (chan == 14) |
| 10881 | return 2484; |
| 10882 | else if (chan < 14) |
| 10883 | return 2407 + chan * 5; |
| 10884 | else if (chan >= 182 && chan <= 196) |
| 10885 | return 4000 + chan * 5; |
| 10886 | else |
| 10887 | return 5000 + chan * 5; |
| 10888 | return 0; |
| 10889 | } |
| 10890 | |
| 10891 | static int util_6G_chan_to_freq(int chan) |
| 10892 | { |
| 10893 | if (chan) |
| 10894 | return 5950 + chan * 5; |
| 10895 | else |
| 10896 | return 0; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 10897 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 10898 | } |
| 10899 | const int *util_unii_5g_chan2list(int chan, int width) |
| 10900 | { |
| 10901 | static const int lists[] = { |
| 10902 | // <width>, <chan1>, <chan2>..., 0, |
| 10903 | 20, 36, 0, |
| 10904 | 20, 40, 0, |
| 10905 | 20, 44, 0, |
| 10906 | 20, 48, 0, |
| 10907 | 20, 52, 0, |
| 10908 | 20, 56, 0, |
| 10909 | 20, 60, 0, |
| 10910 | 20, 64, 0, |
| 10911 | 20, 100, 0, |
| 10912 | 20, 104, 0, |
| 10913 | 20, 108, 0, |
| 10914 | 20, 112, 0, |
| 10915 | 20, 116, 0, |
| 10916 | 20, 120, 0, |
| 10917 | 20, 124, 0, |
| 10918 | 20, 128, 0, |
| 10919 | 20, 132, 0, |
| 10920 | 20, 136, 0, |
| 10921 | 20, 140, 0, |
| 10922 | 20, 144, 0, |
| 10923 | 20, 149, 0, |
| 10924 | 20, 153, 0, |
| 10925 | 20, 157, 0, |
| 10926 | 20, 161, 0, |
| 10927 | 20, 165, 0, |
| 10928 | 40, 36, 40, 0, |
| 10929 | 40, 44, 48, 0, |
| 10930 | 40, 52, 56, 0, |
| 10931 | 40, 60, 64, 0, |
| 10932 | 40, 100, 104, 0, |
| 10933 | 40, 108, 112, 0, |
| 10934 | 40, 116, 120, 0, |
| 10935 | 40, 124, 128, 0, |
| 10936 | 40, 132, 136, 0, |
| 10937 | 40, 140, 144, 0, |
| 10938 | 40, 149, 153, 0, |
| 10939 | 40, 157, 161, 0, |
| 10940 | 80, 36, 40, 44, 48, 0, |
| 10941 | 80, 52, 56, 60, 64, 0, |
| 10942 | 80, 100, 104, 108, 112, 0, |
| 10943 | 80, 116, 120, 124, 128, 0, |
| 10944 | 80, 132, 136, 140, 144, 0, |
| 10945 | 80, 149, 153, 157, 161, 0, |
| 10946 | 160, 36, 40, 44, 48, 52, 56, 60, 64, 0, |
| 10947 | 160, 100, 104, 108, 112, 116, 120, 124, 128, 0, |
| 10948 | -1 // final delimiter |
| 10949 | }; |
| 10950 | const int *start; |
| 10951 | const int *p; |
| 10952 | |
| 10953 | for (p = lists; *p != -1; p++) { |
| 10954 | if (*p == width) { |
| 10955 | for (start = ++p; *p != 0; p++) { |
| 10956 | if (*p == chan) |
| 10957 | return start; |
| 10958 | } |
| 10959 | } |
| 10960 | // move to the end of channel list of given width |
| 10961 | while (*p != 0) { |
| 10962 | p++; |
| 10963 | } |
| 10964 | } |
| 10965 | |
| 10966 | return NULL; |
| 10967 | } |
| 10968 | |
| 10969 | static int util_unii_5g_centerfreq(const char *ht_mode, int channel) |
| 10970 | { |
| 10971 | if (NULL == ht_mode) |
| 10972 | return 0; |
| 10973 | |
| 10974 | const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20"); |
| 10975 | const int *chans = util_unii_5g_chan2list(channel, width); |
| 10976 | int sum = 0; |
| 10977 | int cnt = 0; |
| 10978 | |
| 10979 | if (NULL == chans) |
| 10980 | return 0; |
| 10981 | |
| 10982 | while (*chans) { |
| 10983 | sum += *chans; |
| 10984 | cnt++; |
| 10985 | chans++; |
| 10986 | } |
| 10987 | if (cnt == 0) |
| 10988 | return 0; |
| 10989 | return sum / cnt; |
| 10990 | } |
| 10991 | |
| 10992 | static int util_unii_6g_centerfreq(const char *ht_mode, int channel) |
| 10993 | { |
| 10994 | if (NULL == ht_mode) |
| 10995 | return 0; |
| 10996 | |
| 10997 | int width = strtol((ht_mode + 2), NULL, 10); |
| 10998 | |
| 10999 | int idx = 0 ; |
| 11000 | int centerchan = 0; |
| 11001 | int chan_ofs = 1; |
| 11002 | |
| 11003 | if (width == 40){ |
| 11004 | idx = ((channel/4) + chan_ofs)%2; |
| 11005 | switch (idx) { |
| 11006 | case 0: |
| 11007 | centerchan = (channel - 2); |
| 11008 | break; |
| 11009 | case 1: |
| 11010 | centerchan = (channel + 2); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11011 | break; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11012 | default: |
| 11013 | return -EINVAL; |
| 11014 | } |
| 11015 | }else if (width == 80){ |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11016 | idx = ((channel/4) + chan_ofs)%4; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11017 | switch (idx) { |
| 11018 | case 0: |
| 11019 | centerchan = (channel - 6); |
| 11020 | break; |
| 11021 | case 1: |
| 11022 | centerchan = (channel + 6); |
| 11023 | break; |
| 11024 | case 2: |
| 11025 | centerchan = (channel + 2); |
| 11026 | break; |
| 11027 | case 3: |
| 11028 | centerchan = (channel - 2); |
| 11029 | break; |
| 11030 | default: |
| 11031 | return -EINVAL; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11032 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11033 | }else if (width == 160){ |
| 11034 | switch (channel) { |
| 11035 | case 1 ... 29: |
| 11036 | centerchan = 15; |
| 11037 | break; |
| 11038 | case 33 ... 61: |
| 11039 | centerchan = 47; |
| 11040 | break; |
| 11041 | case 65 ... 93: |
| 11042 | centerchan = 79; |
| 11043 | break; |
| 11044 | case 97 ... 125: |
| 11045 | centerchan = 111; |
| 11046 | break; |
| 11047 | case 129 ... 157: |
| 11048 | centerchan = 143; |
| 11049 | break; |
| 11050 | case 161 ... 189: |
| 11051 | centerchan = 175; |
| 11052 | break; |
| 11053 | case 193 ... 221: |
| 11054 | centerchan = 207; |
| 11055 | break; |
| 11056 | default: |
| 11057 | return -EINVAL; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11058 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11059 | } |
| 11060 | return centerchan; |
| 11061 | } |
| 11062 | static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size) |
| 11063 | { |
| 11064 | BOOL onlyG, onlyN, onlyA; |
| 11065 | CHAR tmp[64]; |
| 11066 | int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA); |
| 11067 | if (ret == RETURN_OK) { |
| 11068 | sncopy(hw_mode, hw_mode_size, tmp); |
| 11069 | } |
| 11070 | return ret; |
| 11071 | } |
| 11072 | |
| 11073 | INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count) |
| 11074 | { |
| 11075 | // Sample commands: |
| 11076 | // hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht |
| 11077 | // hostapd_cli -i wifi0 chan_switch 30 2437 |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11078 | int freq = 0, ret = 0; |
| 11079 | char center_freq1_str[32] = ""; // center_freq1=%d |
| 11080 | char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht |
| 11081 | char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d |
| 11082 | char hw_mode[16] = ""; // n|ac |
| 11083 | char bw_mode[16] = ""; // ht|ht vht |
| 11084 | char ht_mode[16] = ""; // HT20|HT40|HT80|HT160 |
| 11085 | char interface_name[16] = {0}; |
| 11086 | int sec_chan_offset; |
| 11087 | int width; |
| 11088 | char config_file[64] = {0}; |
| 11089 | BOOL stbcEnable = FALSE; |
| 11090 | char *ext_str = "None"; |
| 11091 | wifi_band band = band_invalid; |
| 11092 | int center_chan = 0; |
| 11093 | int center_freq1 = 0; |
| 11094 | |
| 11095 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radioIndex); |
| 11096 | |
| 11097 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 11098 | return RETURN_ERR; |
| 11099 | |
| 11100 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11101 | |
| 11102 | band = wifi_index_to_band(radioIndex); |
| 11103 | |
| 11104 | width = channel_width_MHz > 20 ? channel_width_MHz : 20; |
| 11105 | |
| 11106 | // Get radio mode HT20|HT40|HT80 etc. |
| 11107 | if (channel){ |
| 11108 | if (band == band_6){ |
| 11109 | freq = util_6G_chan_to_freq(channel); |
| 11110 | }else{ |
| 11111 | freq = util_chan_to_freq(channel); |
| 11112 | } |
| 11113 | snprintf(ht_mode, sizeof(ht_mode), "HT%d", width); |
| 11114 | |
| 11115 | // Provide bandwith if specified |
| 11116 | if (channel_width_MHz > 20) { |
| 11117 | // Select bandwidth mode from hardware n --> ht | ac --> ht vht |
| 11118 | util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode)); |
| 11119 | util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode)); |
| 11120 | |
| 11121 | snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode); |
| 11122 | }else if (channel_width_MHz == 20){ |
| 11123 | snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width); |
| 11124 | } |
| 11125 | |
| 11126 | |
| 11127 | if (channel_width_MHz > 20) { |
| 11128 | if (band == band_6){ |
| 11129 | center_chan = util_unii_6g_centerfreq(ht_mode, channel); |
| 11130 | if(center_chan){ |
| 11131 | center_freq1 = util_6G_chan_to_freq(center_chan); |
| 11132 | } |
| 11133 | }else{ |
| 11134 | center_chan = util_unii_5g_centerfreq(ht_mode, channel); |
| 11135 | if(center_chan){ |
| 11136 | center_freq1 = util_chan_to_freq(center_chan); |
| 11137 | } |
| 11138 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11139 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11140 | if (center_freq1) |
| 11141 | snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11142 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11143 | } |
| 11144 | |
| 11145 | // Find channel offset +1/-1 for wide modes (HT40|HT80|HT160) |
| 11146 | if (band == band_6){ |
| 11147 | sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode); |
| 11148 | }else{ |
| 11149 | sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode); |
| 11150 | } |
| 11151 | if (sec_chan_offset != -EINVAL) |
| 11152 | snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset); |
| 11153 | |
| 11154 | // Only the first AP, other are hanging on the same radio |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 11155 | ret = wifi_setChannel_netlink(radioIndex, &channel, NULL); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 11156 | if (ret != RETURN_OK) { |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 11157 | fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 11158 | return RETURN_ERR; |
| 11159 | } |
| 11160 | /* wifi_dbg_printf("execute: '%s'\n", cmd); |
developer | f6a8754 | 2023-05-16 15:47:28 +0800 | [diff] [blame] | 11161 | ret = _syscmd(cmd, buf, sizeof(buf)); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 11162 | wifi_reloadAp(radioIndex); */ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11163 | |
| 11164 | ret = wifi_setRadioChannel(radioIndex, channel); |
| 11165 | if (ret != RETURN_OK) { |
| 11166 | fprintf(stderr, "%s: wifi_setRadioChannel return error.\n", __func__); |
| 11167 | return RETURN_ERR; |
| 11168 | } |
| 11169 | |
developer | 262f4cb | 2023-05-24 12:22:04 +0800 | [diff] [blame] | 11170 | if (sec_chan_offset == 1) |
| 11171 | ext_str = "Above"; |
| 11172 | else if (sec_chan_offset == -1) |
| 11173 | ext_str = "Below"; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11174 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 11175 | /*wifi_setRadioCenterChannel(radioIndex, center_chan); */ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11176 | |
| 11177 | } else { |
| 11178 | if (channel_width_MHz > 20) |
| 11179 | ext_str = "Above"; |
| 11180 | } |
| 11181 | |
| 11182 | wifi_setRadioExtChannel(radioIndex, ext_str); |
| 11183 | |
| 11184 | char mhz_str[16]; |
| 11185 | snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width); |
| 11186 | wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str); |
| 11187 | |
| 11188 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11189 | |
| 11190 | return RETURN_OK; |
| 11191 | } |
| 11192 | |
| 11193 | INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) |
| 11194 | { |
| 11195 | int index = -1; |
| 11196 | wifi_neighbor_ap2_t *scan_array = NULL; |
| 11197 | char cmd[256]={0}; |
| 11198 | char buf[128]={0}; |
| 11199 | char file_name[32] = {0}; |
| 11200 | char filter_SSID[32] = {0}; |
| 11201 | char line[256] = {0}; |
| 11202 | char interface_name[16] = {0}; |
| 11203 | char *ret = NULL; |
| 11204 | int freq=0; |
| 11205 | FILE *f = NULL; |
| 11206 | size_t len=0; |
| 11207 | int channels_num = 0; |
| 11208 | int vht_channel_width = 0; |
| 11209 | int get_noise_ret = RETURN_ERR; |
| 11210 | bool filter_enable = false; |
| 11211 | bool filter_BSS = false; // The flag determine whether the BSS information need to be filterd. |
| 11212 | int phyId = 0; |
| 11213 | |
| 11214 | WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__); |
| 11215 | |
| 11216 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index); |
| 11217 | f = fopen(file_name, "r"); |
| 11218 | if (f != NULL) { |
| 11219 | fgets(filter_SSID, sizeof(file_name), f); |
| 11220 | if (strlen(filter_SSID) != 0) |
| 11221 | filter_enable = true; |
| 11222 | fclose(f); |
| 11223 | } |
| 11224 | |
| 11225 | if (wifi_GetInterfaceName(radio_index, interface_name) != RETURN_OK) |
| 11226 | return RETURN_ERR; |
| 11227 | |
| 11228 | phyId = radio_index_to_phy(radio_index); |
| 11229 | |
| 11230 | snprintf(cmd, sizeof(cmd), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId); |
| 11231 | _syscmd(cmd, buf, sizeof(buf)); |
| 11232 | channels_num = strtol(buf, NULL, 10); |
| 11233 | |
| 11234 | sprintf(cmd, "iw dev %s scan dump | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \ |
| 11235 | // WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name); |
| 11236 | fprintf(stderr, "cmd: %s\n", cmd); |
| 11237 | if ((f = popen(cmd, "r")) == NULL) { |
| 11238 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 11239 | return RETURN_ERR; |
| 11240 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11241 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11242 | struct channels_noise *channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise)); |
| 11243 | get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11244 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11245 | ret = fgets(line, sizeof(line), f); |
| 11246 | while (ret != NULL) { |
| 11247 | if(strstr(line, "BSS") != NULL) { // new neighbor info |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 11248 | // The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11249 | // And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop. |
| 11250 | // If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS. |
| 11251 | |
| 11252 | if (!filter_BSS) { |
| 11253 | index++; |
| 11254 | wifi_neighbor_ap2_t *tmp; |
| 11255 | tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1)); |
| 11256 | if (tmp == NULL) { // no more memory to use |
| 11257 | index--; |
| 11258 | wifi_dbg_printf("%s: realloc failed\n", __func__); |
| 11259 | break; |
| 11260 | } |
| 11261 | scan_array = tmp; |
| 11262 | } |
| 11263 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 11264 | |
| 11265 | filter_BSS = false; |
| 11266 | sscanf(line, "BSS %17s", scan_array[index].ap_BSSID); |
| 11267 | strncpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure")); |
| 11268 | strncpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None")); |
| 11269 | strncpy(scan_array[index].ap_EncryptionMode, "None", strlen("None")); |
| 11270 | } else if (strstr(line, "freq") != NULL) { |
| 11271 | sscanf(line," freq: %d", &freq); |
| 11272 | scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq); |
| 11273 | |
| 11274 | if (freq >= 2412 && freq <= 2484) { |
| 11275 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")); |
| 11276 | strncpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g")); |
| 11277 | strncpy(scan_array[index].ap_OperatingStandards, "g", strlen("g")); |
| 11278 | } |
| 11279 | else if (freq >= 5160 && freq <= 5805) { |
| 11280 | strncpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")); |
| 11281 | strncpy(scan_array[index].ap_SupportedStandards, "a", strlen("a")); |
| 11282 | strncpy(scan_array[index].ap_OperatingStandards, "a", strlen("a")); |
| 11283 | } |
| 11284 | |
| 11285 | scan_array[index].ap_Noise = 0; |
| 11286 | if (get_noise_ret == RETURN_OK) { |
| 11287 | for (int i = 0; i < channels_num; i++) { |
| 11288 | if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) { |
| 11289 | scan_array[index].ap_Noise = channels_noise_arr[i].noise; |
| 11290 | break; |
| 11291 | } |
| 11292 | } |
| 11293 | } |
| 11294 | } else if (strstr(line, "beacon interval") != NULL) { |
| 11295 | sscanf(line," beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)); |
| 11296 | } else if (strstr(line, "signal") != NULL) { |
| 11297 | sscanf(line," signal: %d", &(scan_array[index].ap_SignalStrength)); |
| 11298 | } else if (strstr(line,"SSID") != NULL) { |
| 11299 | sscanf(line," SSID: %s", scan_array[index].ap_SSID); |
| 11300 | if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) { |
| 11301 | filter_BSS = true; |
| 11302 | } |
| 11303 | } else if (strstr(line, "Supported rates") != NULL) { |
| 11304 | char SRate[80] = {0}, *tmp = NULL; |
| 11305 | memset(buf, 0, sizeof(buf)); |
| 11306 | strcpy(SRate, line); |
| 11307 | tmp = strtok(SRate, ":"); |
| 11308 | tmp = strtok(NULL, ":"); |
| 11309 | strcpy(buf, tmp); |
| 11310 | memset(SRate, 0, sizeof(SRate)); |
| 11311 | |
| 11312 | tmp = strtok(buf, " \n"); |
| 11313 | while (tmp != NULL) { |
| 11314 | strcat(SRate, tmp); |
| 11315 | if (SRate[strlen(SRate) - 1] == '*') { |
| 11316 | SRate[strlen(SRate) - 1] = '\0'; |
| 11317 | } |
| 11318 | strcat(SRate, ","); |
| 11319 | |
| 11320 | tmp = strtok(NULL, " \n"); |
| 11321 | } |
| 11322 | SRate[strlen(SRate) - 1] = '\0'; |
| 11323 | strcpy(scan_array[index].ap_SupportedDataTransferRates, SRate); |
| 11324 | } else if (strstr(line, "DTIM") != NULL) { |
| 11325 | sscanf(line,"DTIM Period %d", scan_array[index].ap_DTIMPeriod, buf); |
| 11326 | } else if (strstr(line, "VHT capabilities") != NULL) { |
| 11327 | strcat(scan_array[index].ap_SupportedStandards, ",ac"); |
| 11328 | strcpy(scan_array[index].ap_OperatingStandards, "ac"); |
| 11329 | } else if (strstr(line, "HT capabilities") != NULL) { |
| 11330 | strcat(scan_array[index].ap_SupportedStandards, ",n"); |
| 11331 | strcpy(scan_array[index].ap_OperatingStandards, "n"); |
| 11332 | } else if (strstr(line, "VHT operation") != NULL) { |
| 11333 | ret = fgets(line, sizeof(line), f); |
| 11334 | sscanf(line," * channel width: %d", &vht_channel_width); |
| 11335 | if(vht_channel_width == 1) { |
| 11336 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80"); |
| 11337 | } else { |
| 11338 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40"); |
| 11339 | } |
| 11340 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 11341 | continue; |
| 11342 | } else if (strstr(line, "HT operation") != NULL) { |
| 11343 | ret = fgets(line, sizeof(line), f); |
| 11344 | sscanf(line," * secondary channel offset: %s", &buf); |
| 11345 | if (!strcmp(buf, "above")) { |
| 11346 | //40Mhz + |
| 11347 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G"); |
| 11348 | } |
| 11349 | else if (!strcmp(buf, "below")) { |
| 11350 | //40Mhz - |
| 11351 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G"); |
| 11352 | } else { |
| 11353 | //20Mhz |
| 11354 | snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G"); |
| 11355 | } |
| 11356 | if (strstr(line, "BSS") != NULL) // prevent to get the next neighbor information |
| 11357 | continue; |
| 11358 | } else if (strstr(line, "HE capabilities") != NULL) { |
| 11359 | strcat(scan_array[index].ap_SupportedStandards, ",ax"); |
| 11360 | strcpy(scan_array[index].ap_OperatingStandards, "ax"); |
| 11361 | ret = fgets(line, sizeof(line), f); |
| 11362 | if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) { |
| 11363 | if (strstr(line, "HE40/2.4GHz") != NULL) |
| 11364 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS"); |
| 11365 | else |
| 11366 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20"); |
| 11367 | } else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) { |
| 11368 | if (strstr(line, "HE80/5GHz") != NULL) { |
| 11369 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80"); |
| 11370 | ret = fgets(line, sizeof(line), f); |
| 11371 | } else |
| 11372 | continue; |
| 11373 | if (strstr(line, "HE160/5GHz") != NULL) |
| 11374 | strcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160"); |
| 11375 | } |
| 11376 | continue; |
| 11377 | } else if (strstr(line, "WPA") != NULL) { |
| 11378 | strcpy(scan_array[index].ap_SecurityModeEnabled, "WPA"); |
| 11379 | } else if (strstr(line, "RSN") != NULL) { |
| 11380 | strcpy(scan_array[index].ap_SecurityModeEnabled, "RSN"); |
| 11381 | } else if (strstr(line, "Group cipher") != NULL) { |
| 11382 | sscanf(line, " * Group cipher: %s", scan_array[index].ap_EncryptionMode); |
| 11383 | if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) { |
| 11384 | strcpy(scan_array[index].ap_EncryptionMode, "AES"); |
| 11385 | } |
| 11386 | } |
| 11387 | ret = fgets(line, sizeof(line), f); |
| 11388 | } |
| 11389 | |
| 11390 | if (!filter_BSS) { |
| 11391 | *output_array_size = index + 1; |
| 11392 | } else { |
| 11393 | memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t)); |
| 11394 | *output_array_size = index; |
| 11395 | } |
| 11396 | *neighbor_ap_array = scan_array; |
| 11397 | pclose(f); |
| 11398 | free(channels_noise_arr); |
| 11399 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11400 | return RETURN_OK; |
| 11401 | } |
| 11402 | |
| 11403 | INT wifi_getApAssociatedDeviceStats( |
| 11404 | INT apIndex, |
| 11405 | mac_address_t *clientMacAddress, |
| 11406 | wifi_associated_dev_stats_t *associated_dev_stats, |
| 11407 | u64 *handle) |
| 11408 | { |
| 11409 | wifi_associated_dev_stats_t *dev_stats = associated_dev_stats; |
| 11410 | char interface_name[50] = {0}; |
| 11411 | char cmd[1024] = {0}; |
| 11412 | char mac_str[18] = {0}; |
| 11413 | char *key = NULL; |
| 11414 | char *val = NULL; |
| 11415 | FILE *f = NULL; |
| 11416 | char *line = NULL; |
| 11417 | size_t len = 0; |
| 11418 | |
| 11419 | if(wifi_getApName(apIndex, interface_name) != RETURN_OK) { |
| 11420 | wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__); |
| 11421 | return RETURN_ERR; |
| 11422 | } |
| 11423 | |
| 11424 | sprintf(mac_str, "%x:%x:%x:%x:%x:%x", (*clientMacAddress)[0],(*clientMacAddress)[1],(*clientMacAddress)[2],(*clientMacAddress)[3],(*clientMacAddress)[4],(*clientMacAddress)[5]); |
| 11425 | sprintf(cmd,"iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str); |
| 11426 | if((f = popen(cmd, "r")) == NULL) { |
| 11427 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 11428 | return RETURN_ERR; |
| 11429 | } |
| 11430 | |
| 11431 | while ((getline(&line, &len, f)) != -1) { |
| 11432 | key = strtok(line,":"); |
| 11433 | val = strtok(NULL,":"); |
| 11434 | |
| 11435 | if(!strncmp(key,"rx bytes",8)) |
| 11436 | sscanf(val, "%llu", &dev_stats->cli_rx_bytes); |
| 11437 | if(!strncmp(key,"tx bytes",8)) |
| 11438 | sscanf(val, "%llu", &dev_stats->cli_tx_bytes); |
| 11439 | if(!strncmp(key,"rx packets",10)) |
| 11440 | sscanf(val, "%llu", &dev_stats->cli_tx_frames); |
| 11441 | if(!strncmp(key,"tx packets",10)) |
| 11442 | sscanf(val, "%llu", &dev_stats->cli_tx_frames); |
| 11443 | if(!strncmp(key,"tx retries",10)) |
| 11444 | sscanf(val, "%llu", &dev_stats->cli_tx_retries); |
| 11445 | if(!strncmp(key,"tx failed",9)) |
| 11446 | sscanf(val, "%llu", &dev_stats->cli_tx_errors); |
| 11447 | if(!strncmp(key,"rx drop misc",13)) |
| 11448 | sscanf(val, "%llu", &dev_stats->cli_rx_errors); |
| 11449 | if(!strncmp(key,"rx bitrate",10)) { |
| 11450 | val = strtok(val, " "); |
| 11451 | sscanf(val, "%lf", &dev_stats->cli_rx_rate); |
| 11452 | } |
| 11453 | if(!strncmp(key,"tx bitrate",10)) { |
| 11454 | val = strtok(val, " "); |
| 11455 | sscanf(val, "%lf", &dev_stats->cli_tx_rate); |
| 11456 | } |
| 11457 | } |
| 11458 | free(line); |
| 11459 | pclose(f); |
| 11460 | return RETURN_OK; |
| 11461 | } |
| 11462 | |
| 11463 | INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string) |
| 11464 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 11465 | char interface_name[IF_NAME_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11466 | char cmd[MAX_CMD_SIZE] = {0}, buf[MAX_BUF_SIZE] = {0}; |
| 11467 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 11468 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 11469 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11470 | if (NULL == output_string) |
| 11471 | return RETURN_ERR; |
| 11472 | |
| 11473 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 11474 | return RETURN_ERR; |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 11475 | |
| 11476 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11477 | _syscmd(cmd, buf, sizeof(buf)); |
| 11478 | |
| 11479 | //size of SSID name restricted to value less than 32 bytes |
| 11480 | snprintf(output_string, 32, "%s", buf); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 11481 | WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11482 | |
| 11483 | return RETURN_OK; |
| 11484 | } |
| 11485 | |
| 11486 | INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode) |
| 11487 | { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 11488 | char *mac_arry_buf = NULL; |
| 11489 | INT policy = -1; |
| 11490 | INT buf_size = 1024; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11491 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 11492 | mac_arry_buf = malloc(buf_size); |
| 11493 | if (!mac_arry_buf) { |
| 11494 | wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n"); |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 11495 | return RETURN_ERR; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 11496 | } |
| 11497 | memset(mac_arry_buf, 0, buf_size); |
| 11498 | if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) { |
| 11499 | wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n"); |
| 11500 | goto err; |
| 11501 | } |
| 11502 | /* |
| 11503 | mtk format to get policy: |
| 11504 | "policy=1 |
| 11505 | 00:11:22:33:44:55 |
| 11506 | 00:11:22:33:44:66 |
| 11507 | " |
| 11508 | */ |
| 11509 | if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) { |
| 11510 | wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf); |
| 11511 | goto err; |
| 11512 | } |
| 11513 | if (!(policy >=0 && policy <= 2)){ |
| 11514 | wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy); |
| 11515 | goto err; |
| 11516 | } |
| 11517 | *output_filterMode = policy; |
| 11518 | wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode); |
| 11519 | free(mac_arry_buf); |
| 11520 | mac_arry_buf = NULL; |
| 11521 | return RETURN_OK; |
| 11522 | err: |
| 11523 | free(mac_arry_buf); |
| 11524 | mac_arry_buf = NULL; |
| 11525 | wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode); |
| 11526 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11527 | } |
| 11528 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 11529 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11530 | INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size) |
| 11531 | { |
| 11532 | FILE *fp = NULL; |
| 11533 | char str[MAX_BUF_SIZE] = {0}; |
| 11534 | int wificlientindex = 0 ; |
| 11535 | int count = 0; |
| 11536 | int signalstrength = 0; |
| 11537 | int arr[MACADDRESS_SIZE] = {0}; |
| 11538 | unsigned char mac[MACADDRESS_SIZE] = {0}; |
| 11539 | UINT wifi_count = 0; |
| 11540 | char virtual_interface_name[MAX_BUF_SIZE] = {0}; |
| 11541 | char pipeCmd[MAX_CMD_SIZE] = {0}; |
| 11542 | |
| 11543 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11544 | *output_array_size = 0; |
| 11545 | *associated_dev_array = NULL; |
| 11546 | char interface_name[50] = {0}; |
| 11547 | |
| 11548 | if(wifi_getApName(apIndex, interface_name) != RETURN_OK) { |
| 11549 | wifi_dbg_printf("%s: wifi_getApName failed\n", __FUNCTION__); |
| 11550 | return RETURN_ERR; |
| 11551 | } |
| 11552 | |
| 11553 | sprintf(pipeCmd, "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name); |
| 11554 | fp = popen(pipeCmd, "r"); |
| 11555 | if (fp == NULL) |
| 11556 | { |
| 11557 | printf("Failed to run command inside function %s\n",__FUNCTION__ ); |
| 11558 | return RETURN_ERR; |
| 11559 | } |
| 11560 | |
| 11561 | /* Read the output a line at a time - output it. */ |
| 11562 | fgets(str, sizeof(str)-1, fp); |
| 11563 | wifi_count = (unsigned int) atoi ( str ); |
| 11564 | *output_array_size = wifi_count; |
| 11565 | wifi_dbg_printf(" In rdkb hal ,Wifi Client Counts and index %d and %d \n",*output_array_size,apIndex); |
| 11566 | pclose(fp); |
| 11567 | |
| 11568 | if(wifi_count == 0) |
| 11569 | { |
| 11570 | return RETURN_OK; |
| 11571 | } |
| 11572 | else |
| 11573 | { |
| 11574 | wifi_associated_dev2_t* temp = NULL; |
| 11575 | temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t)); |
| 11576 | *associated_dev_array = temp; |
| 11577 | if(temp == NULL) |
| 11578 | { |
| 11579 | printf("Error Statement. Insufficient memory \n"); |
| 11580 | return RETURN_ERR; |
| 11581 | } |
| 11582 | |
| 11583 | snprintf(pipeCmd, sizeof(pipeCmd), "iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name); |
| 11584 | system(pipeCmd); |
| 11585 | |
| 11586 | fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r"); |
| 11587 | if(fp == NULL) |
| 11588 | { |
| 11589 | printf("/tmp/AssociatedDevice_Stats.txt not exists \n"); |
| 11590 | return RETURN_ERR; |
| 11591 | } |
| 11592 | fclose(fp); |
| 11593 | |
| 11594 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2"); |
| 11595 | fp = popen(pipeCmd, "r"); |
| 11596 | if(fp) |
| 11597 | { |
| 11598 | for(count =0 ; count < wifi_count; count++) |
| 11599 | { |
| 11600 | fgets(str, MAX_BUF_SIZE, fp); |
| 11601 | if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) ) |
| 11602 | { |
| 11603 | for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex ) |
| 11604 | { |
| 11605 | mac[wificlientindex] = (unsigned char) arr[wificlientindex]; |
| 11606 | |
| 11607 | } |
| 11608 | memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6); |
| 11609 | wifi_dbg_printf("MAC %d = %X:%X:%X:%X:%X:%X \n", count, temp[count].cli_MACAddress[0],temp[count].cli_MACAddress[1], temp[count].cli_MACAddress[2], temp[count].cli_MACAddress[3], temp[count].cli_MACAddress[4], temp[count].cli_MACAddress[5]); |
| 11610 | } |
| 11611 | temp[count].cli_AuthenticationState = 1; //TODO |
| 11612 | temp[count].cli_Active = 1; //TODO |
| 11613 | } |
| 11614 | pclose(fp); |
| 11615 | } |
| 11616 | |
| 11617 | //Updating RSSI per client |
| 11618 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt"); |
| 11619 | fp = popen(pipeCmd, "r"); |
| 11620 | if(fp) |
| 11621 | { |
| 11622 | pclose(fp); |
| 11623 | } |
| 11624 | fp = popen("cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2","r"); |
| 11625 | if(fp) |
| 11626 | { |
| 11627 | for(count =0 ; count < wifi_count ;count++) |
| 11628 | { |
| 11629 | fgets(str, MAX_BUF_SIZE, fp); |
| 11630 | signalstrength = atoi(str); |
| 11631 | temp[count].cli_RSSI = signalstrength; |
| 11632 | } |
| 11633 | pclose(fp); |
| 11634 | } |
| 11635 | |
| 11636 | |
| 11637 | //LastDataDownlinkRate |
| 11638 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt"); |
| 11639 | fp = popen(pipeCmd, "r"); |
| 11640 | if (fp) |
| 11641 | { |
| 11642 | pclose(fp); |
| 11643 | } |
| 11644 | fp = popen("cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2", "r"); |
| 11645 | if (fp) |
| 11646 | { |
| 11647 | for (count = 0; count < wifi_count; count++) |
| 11648 | { |
| 11649 | fgets(str, MAX_BUF_SIZE, fp); |
| 11650 | temp[count].cli_LastDataDownlinkRate = strtoul(str, NULL, 10); |
| 11651 | temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps |
| 11652 | } |
| 11653 | pclose(fp); |
| 11654 | } |
| 11655 | |
| 11656 | //LastDataUplinkRate |
| 11657 | sprintf(pipeCmd, "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt"); |
| 11658 | fp = popen(pipeCmd, "r"); |
| 11659 | if (fp) |
| 11660 | { |
| 11661 | pclose(fp); |
| 11662 | } |
| 11663 | fp = popen("cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2", "r"); |
| 11664 | if (fp) |
| 11665 | { |
| 11666 | for (count = 0; count < wifi_count; count++) |
| 11667 | { |
| 11668 | fgets(str, MAX_BUF_SIZE, fp); |
| 11669 | temp[count].cli_LastDataUplinkRate = strtoul(str, NULL, 10); |
| 11670 | temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps |
| 11671 | } |
| 11672 | pclose(fp); |
| 11673 | } |
| 11674 | } |
| 11675 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11676 | return RETURN_OK; |
| 11677 | |
| 11678 | } |
| 11679 | |
| 11680 | INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct) |
| 11681 | { |
| 11682 | #if 0 |
| 11683 | /*char buf[1024] = {0}; |
| 11684 | sprintf(cmd, "ifconfig %s ", interface_name); |
| 11685 | _syscmd(cmd, buf, sizeof(buf));*/ |
| 11686 | |
| 11687 | output_struct->ssid_BytesSent = 2048; //The total number of bytes transmitted out of the interface, including framing characters. |
| 11688 | output_struct->ssid_BytesReceived = 4096; //The total number of bytes received on the interface, including framing characters. |
| 11689 | output_struct->ssid_PacketsSent = 128; //The total number of packets transmitted out of the interface. |
| 11690 | output_struct->ssid_PacketsReceived = 128; //The total number of packets received on the interface. |
| 11691 | |
| 11692 | output_struct->ssid_RetransCount = 0; //The total number of transmitted packets which were retransmissions. Two retransmissions of the same packet results in this counter incrementing by two. |
| 11693 | output_struct->ssid_FailedRetransCount = 0; //The number of packets that were not transmitted successfully due to the number of retransmission attempts exceeding an 802.11 retry limit. This parameter is based on dot11FailedCount from [802.11-2012]. |
| 11694 | output_struct->ssid_RetryCount = 0; //The number of packets that were successfully transmitted after one or more retransmissions. This parameter is based on dot11RetryCount from [802.11-2012]. |
| 11695 | output_struct->ssid_MultipleRetryCount = 0; //The number of packets that were successfully transmitted after more than one retransmission. This parameter is based on dot11MultipleRetryCount from [802.11-2012]. |
| 11696 | output_struct->ssid_ACKFailureCount = 0; //The number of expected ACKs that were never received. This parameter is based on dot11ACKFailureCount from [802.11-2012]. |
| 11697 | output_struct->ssid_AggregatedPacketCount = 0; //The number of aggregated packets that were transmitted. This applies only to 802.11n and 802.11ac. |
| 11698 | |
| 11699 | output_struct->ssid_ErrorsSent = 0; //The total number of outbound packets that could not be transmitted because of errors. |
| 11700 | output_struct->ssid_ErrorsReceived = 0; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol. |
| 11701 | output_struct->ssid_UnicastPacketsSent = 2; //The total number of inbound packets that contained errors preventing them from being delivered to a higher-layer protocol. |
| 11702 | output_struct->ssid_UnicastPacketsReceived = 2; //The total number of received packets, delivered by this layer to a higher layer, which were not addressed to a multicast or broadcast address at this layer. |
| 11703 | output_struct->ssid_DiscardedPacketsSent = 1; //The total number of outbound packets which were chosen to be discarded even though no errors had been detected to prevent their being transmitted. One possible reason for discarding such a packet could be to free up buffer space. |
| 11704 | output_struct->ssid_DiscardedPacketsReceived = 1; //The total number of inbound packets which were chosen to be discarded even though no errors had been detected to prevent their being delivered. One possible reason for discarding such a packet could be to free up buffer space. |
| 11705 | output_struct->ssid_MulticastPacketsSent = 10; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a multicast address at this layer, including those that were discarded or not sent. |
| 11706 | output_struct->ssid_MulticastPacketsReceived = 0; //The total number of received packets, delivered by this layer to a higher layer, which were addressed to a multicast address at this layer. |
| 11707 | output_struct->ssid_BroadcastPacketsSent = 0; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a broadcast address at this layer, including those that were discarded or not sent. |
| 11708 | output_struct->ssid_BroadcastPacketsRecevied = 1; //The total number of packets that higher-level protocols requested for transmission and which were addressed to a broadcast address at this layer, including those that were discarded or not sent. |
| 11709 | output_struct->ssid_UnknownPacketsReceived = 0; //The total number of packets received via the interface which were discarded because of an unknown or unsupported protocol. |
| 11710 | #endif |
| 11711 | |
| 11712 | FILE *fp = NULL; |
| 11713 | char interface_name[50] = {0}; |
| 11714 | char pipeCmd[128] = {0}; |
| 11715 | char str[256] = {0}; |
| 11716 | wifi_ssidTrafficStats2_t *out = output_struct; |
| 11717 | |
| 11718 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 11719 | if (!output_struct) |
| 11720 | return RETURN_ERR; |
| 11721 | |
| 11722 | memset(out, 0, sizeof(wifi_ssidTrafficStats2_t)); |
| 11723 | if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK) |
| 11724 | return RETURN_ERR; |
| 11725 | sprintf(pipeCmd, "cat /proc/net/dev | grep %s", interface_name); |
| 11726 | |
| 11727 | fp = popen(pipeCmd, "r"); |
| 11728 | if (fp == NULL) { |
| 11729 | fprintf(stderr, "%s: popen failed\n", __func__); |
| 11730 | return RETURN_ERR; |
| 11731 | } |
| 11732 | fgets(str, sizeof(str), fp); |
| 11733 | pclose(fp); |
| 11734 | |
| 11735 | if (strlen(str) == 0) // interface not exist |
| 11736 | return RETURN_OK; |
| 11737 | |
| 11738 | sscanf(str, "%*[^:]: %lu %lu %lu %lu %* %* %* %* %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \ |
| 11739 | &out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent); |
| 11740 | |
| 11741 | memset(str, 0, sizeof(str)); |
| 11742 | sprintf(pipeCmd, "tail -n1 /proc/net/netstat"); |
| 11743 | fp = popen(pipeCmd, "r"); |
| 11744 | if (fp == NULL) { |
| 11745 | fprintf(stderr, "%s: popen failed\n", __func__); |
| 11746 | return RETURN_ERR; |
| 11747 | } |
| 11748 | fgets(str, sizeof(str), fp); |
| 11749 | |
| 11750 | sscanf(str, "%*[^:]: %* %* %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \ |
| 11751 | &out->ssid_BroadcastPacketsSent); |
| 11752 | pclose(fp); |
| 11753 | |
| 11754 | out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent; |
| 11755 | out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived; |
| 11756 | |
| 11757 | // Not supported |
| 11758 | output_struct->ssid_RetransCount = 0; |
| 11759 | output_struct->ssid_FailedRetransCount = 0; |
| 11760 | output_struct->ssid_RetryCount = 0; |
| 11761 | output_struct->ssid_MultipleRetryCount = 0; |
| 11762 | output_struct->ssid_ACKFailureCount = 0; |
| 11763 | output_struct->ssid_AggregatedPacketCount = 0; |
| 11764 | |
| 11765 | return RETURN_OK; |
| 11766 | } |
| 11767 | |
| 11768 | //Enables or disables device isolation. A value of true means that the devices connected to the Access Point are isolated from all other devices within the home network (as is typically the case for a Wireless Hotspot). |
| 11769 | INT wifi_getApIsolationEnable(INT apIndex, BOOL *output) |
| 11770 | { |
| 11771 | char output_val[16]={'\0'}; |
| 11772 | char config_file[MAX_BUF_SIZE] = {0}; |
| 11773 | |
| 11774 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11775 | if (!output) |
| 11776 | return RETURN_ERR; |
| 11777 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 11778 | wifi_hostapdRead(config_file, "ap_isolate", output_val, sizeof(output_val)); |
| 11779 | |
| 11780 | if( strcmp(output_val,"1") == 0 ) |
| 11781 | *output = TRUE; |
| 11782 | else |
| 11783 | *output = FALSE; |
| 11784 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11785 | |
| 11786 | return RETURN_OK; |
| 11787 | } |
| 11788 | |
| 11789 | INT wifi_setApIsolationEnable(INT apIndex, BOOL enable) |
| 11790 | { |
| 11791 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11792 | char str[MAX_BUF_SIZE]={'\0'}; |
| 11793 | char string[MAX_BUF_SIZE]={'\0'}; |
| 11794 | char cmd[MAX_CMD_SIZE]={'\0'}; |
| 11795 | char *ch; |
| 11796 | char config_file[MAX_BUF_SIZE] = {0}; |
| 11797 | struct params params; |
| 11798 | |
| 11799 | if(enable == TRUE) |
| 11800 | strcpy(string,"1"); |
| 11801 | else |
| 11802 | strcpy(string,"0"); |
| 11803 | |
| 11804 | params.name = "ap_isolate"; |
| 11805 | params.value = string; |
| 11806 | |
| 11807 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 11808 | wifi_hostapdWrite(config_file,¶ms,1); |
| 11809 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11810 | |
| 11811 | return RETURN_OK; |
| 11812 | } |
| 11813 | |
| 11814 | INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm) |
| 11815 | { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 11816 | char mgmtpwr_file[32] = {0}; |
| 11817 | char cmd[64] = {0}; |
| 11818 | char buf[32]={0}; |
| 11819 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11820 | if (NULL == output_dBm) |
| 11821 | return RETURN_ERR; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 11822 | snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex); |
| 11823 | snprintf(cmd, sizeof(cmd), "cat %s 2> /dev/null", mgmtpwr_file); |
| 11824 | _syscmd(cmd, buf, sizeof(buf)); |
| 11825 | if (strlen(buf) > 0) |
| 11826 | *output_dBm = strtol(buf, NULL, 10); |
| 11827 | else |
| 11828 | *output_dBm = 23; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11829 | return RETURN_OK; |
| 11830 | } |
| 11831 | |
| 11832 | INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm) |
| 11833 | { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 11834 | char interface_name[16] = {0}; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 11835 | char mgmt_pwr_file[128]={0}; |
| 11836 | FILE *f = NULL; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 11837 | int if_idx, ret = 0; |
| 11838 | struct nl_msg *msg = NULL; |
| 11839 | struct nlattr * msg_data = NULL; |
| 11840 | struct mtk_nl80211_param param; |
| 11841 | struct unl unl_ins; |
| 11842 | char power[16] = {0}; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 11843 | |
| 11844 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11845 | |
| 11846 | if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK) |
| 11847 | return RETURN_ERR; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 11848 | |
| 11849 | if_idx = if_nametoindex(interface_name); |
| 11850 | /*init mtk nl80211 vendor cmd*/ |
| 11851 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER; |
| 11852 | param.if_type = NL80211_ATTR_IFINDEX; |
| 11853 | param.if_idx = if_idx; |
| 11854 | |
| 11855 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 11856 | if (ret) { |
| 11857 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 11858 | return RETURN_ERR; |
| 11859 | } |
| 11860 | |
| 11861 | /*add mtk vendor cmd data*/ |
| 11862 | snprintf(power, sizeof(power), "%d", dBm); |
| 11863 | if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) { |
| 11864 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 11865 | nlmsg_free(msg); |
| 11866 | goto err; |
| 11867 | } |
| 11868 | |
| 11869 | /*send mtk nl80211 vendor msg*/ |
| 11870 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 11871 | if (ret) { |
| 11872 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 11873 | goto err; |
| 11874 | } |
| 11875 | |
| 11876 | /*deinit mtk nl80211 vendor msg*/ |
| 11877 | mtk_nl80211_deint(&unl_ins); |
| 11878 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
| 11879 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 11880 | snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex); |
| 11881 | f = fopen(mgmt_pwr_file, "w"); |
| 11882 | if (f == NULL) { |
| 11883 | fprintf(stderr, "%s: fopen failed\n", __func__); |
| 11884 | return RETURN_ERR; |
| 11885 | } |
| 11886 | fprintf(f, "%d", dBm); |
| 11887 | fclose(f); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11888 | return RETURN_OK; |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 11889 | err: |
| 11890 | mtk_nl80211_deint(&unl_ins); |
| 11891 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 11892 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 11893 | } |
| 11894 | INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size) |
| 11895 | { |
| 11896 | return RETURN_OK; |
| 11897 | } |
| 11898 | INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms) |
| 11899 | { |
| 11900 | return RETURN_OK; |
| 11901 | } |
| 11902 | INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms) |
| 11903 | { |
| 11904 | return RETURN_OK; |
| 11905 | } |
| 11906 | INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable) |
| 11907 | { |
| 11908 | return RETURN_OK; |
| 11909 | } |
| 11910 | INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate) |
| 11911 | { |
| 11912 | char config_file[MAX_BUF_SIZE] = {0}; |
| 11913 | struct params list; |
| 11914 | |
| 11915 | list.name = "bss_transition"; |
| 11916 | list.value = activate?"1":"0"; |
| 11917 | snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex); |
| 11918 | wifi_hostapdWrite(config_file, &list, 1); |
| 11919 | |
| 11920 | return RETURN_OK; |
| 11921 | } |
| 11922 | wifi_apAuthEvent_callback apAuthEvent_cb = NULL; |
| 11923 | |
| 11924 | void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc) |
| 11925 | { |
| 11926 | return; |
| 11927 | } |
| 11928 | |
| 11929 | INT wifi_setApCsaDeauth(INT apIndex, INT mode) |
| 11930 | { |
| 11931 | // TODO Implement me! |
| 11932 | return RETURN_OK; |
| 11933 | } |
| 11934 | |
| 11935 | INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid) |
| 11936 | { |
| 11937 | char file_name[128] = {0}; |
| 11938 | char buf[128] = {0}; |
| 11939 | FILE *f = NULL; |
| 11940 | int max_num_radios = 0; |
| 11941 | |
| 11942 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 11943 | |
| 11944 | wifi_getMaxRadioNumber(&max_num_radios); |
| 11945 | if (essid == NULL || strlen(essid) == 0 || apIndex == -1) { |
| 11946 | for (int index = 0; index < max_num_radios; index++) { |
| 11947 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index); |
| 11948 | f = fopen(file_name, "w"); |
| 11949 | if (f == NULL) |
| 11950 | return RETURN_ERR; |
| 11951 | // For mode == 0 is to disable filter, just don't write to the file. |
| 11952 | if (mode) |
| 11953 | fprintf(f, "%s", essid); |
| 11954 | |
| 11955 | fclose(f); |
| 11956 | } |
| 11957 | } else { // special case, need to set AP's SSID as filter for each radio. |
| 11958 | snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex); |
| 11959 | f = fopen(file_name, "w"); |
| 11960 | if (f == NULL) |
| 11961 | return RETURN_ERR; |
| 11962 | |
| 11963 | // For mode == 0 is to disable filter, just don't write to the file. |
| 11964 | if (mode) |
| 11965 | fprintf(f, "%s", essid); |
| 11966 | |
| 11967 | fclose(f); |
| 11968 | } |
| 11969 | |
| 11970 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 11971 | return RETURN_OK; |
| 11972 | } |
| 11973 | |
| 11974 | INT wifi_pushRadioChannel(INT radioIndex, UINT channel) |
| 11975 | { |
| 11976 | // TODO Implement me! |
| 11977 | //Apply wifi_pushRadioChannel() instantly |
| 11978 | return RETURN_ERR; |
| 11979 | } |
| 11980 | |
| 11981 | INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable) |
| 11982 | { |
| 11983 | // TODO Implement me! |
| 11984 | return RETURN_OK; |
| 11985 | } |
| 11986 | |
| 11987 | #ifdef HAL_NETLINK_IMPL |
| 11988 | static int tidStats_callback(struct nl_msg *msg, void *arg) { |
| 11989 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 11990 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 11991 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 11992 | struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr; |
| 11993 | int rem , tid_index = 0; |
| 11994 | |
| 11995 | wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg; |
| 11996 | wifi_associated_dev_tid_entry_t *stats_entry; |
| 11997 | |
| 11998 | static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = { |
| 11999 | [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }, |
| 12000 | }; |
| 12001 | static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = { |
| 12002 | [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 }, |
| 12003 | }; |
| 12004 | |
| 12005 | nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0), |
| 12006 | genlmsg_attrlen(gnlh, 0), NULL); |
| 12007 | |
| 12008 | |
| 12009 | if (!tb[NL80211_ATTR_STA_INFO]) { |
| 12010 | fprintf(stderr, "station stats missing!\n"); |
| 12011 | return NL_SKIP; |
| 12012 | } |
| 12013 | |
| 12014 | if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX, |
| 12015 | tb[NL80211_ATTR_STA_INFO], |
| 12016 | stats_policy)) { |
| 12017 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 12018 | return NL_SKIP; |
| 12019 | } |
| 12020 | |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12021 | if (sinfo[NL80211_STA_INFO_TID_STATS]) { |
| 12022 | nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem) |
| 12023 | { |
| 12024 | stats_entry = &out->tid_array[tid_index]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12025 | |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12026 | stats_entry->tid = tid_index; |
| 12027 | stats_entry->ac = _tid_ac_index_get[tid_index]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12028 | |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12029 | if(sinfo[NL80211_STA_INFO_TID_STATS]) |
| 12030 | { |
| 12031 | if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) { |
| 12032 | printf("failed to parse nested stats attributes!"); |
| 12033 | return NL_SKIP; |
| 12034 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12035 | } |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12036 | if(stats_info[NL80211_TID_STATS_TX_MSDU]) |
| 12037 | stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12038 | |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12039 | if(tid_index < (PS_MAX_TID - 1)) |
| 12040 | tid_index++; |
| 12041 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12042 | } |
| 12043 | //ToDo: sum_time_ms, ewma_time_ms |
| 12044 | return NL_SKIP; |
| 12045 | } |
| 12046 | #endif |
| 12047 | |
| 12048 | INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex, mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats, ULLONG *handle) |
| 12049 | { |
| 12050 | #ifdef HAL_NETLINK_IMPL |
| 12051 | Netlink nl; |
| 12052 | char if_name[10]; |
| 12053 | char interface_name[16] = {0}; |
| 12054 | |
| 12055 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 12056 | return RETURN_ERR; |
| 12057 | |
| 12058 | snprintf(if_name, sizeof(if_name), "%s", interface_name); |
| 12059 | |
| 12060 | nl.id = initSock80211(&nl); |
| 12061 | |
| 12062 | if (nl.id < 0) { |
| 12063 | fprintf(stderr, "Error initializing netlink \n"); |
| 12064 | return -1; |
| 12065 | } |
| 12066 | |
| 12067 | struct nl_msg* msg = nlmsg_alloc(); |
| 12068 | |
| 12069 | if (!msg) { |
| 12070 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 12071 | nlfree(&nl); |
| 12072 | return -2; |
| 12073 | } |
| 12074 | |
| 12075 | genlmsg_put(msg, |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12076 | NL_AUTO_PID, |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12077 | NL_AUTO_SEQ, |
| 12078 | nl.id, |
| 12079 | 0, |
| 12080 | 0, |
| 12081 | NL80211_CMD_GET_STATION, |
| 12082 | 0); |
| 12083 | |
| 12084 | nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress); |
| 12085 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 12086 | nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12087 | nl_send_auto_complete(nl.socket, msg); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12088 | nl_recvmsgs(nl.socket, nl.cb); |
| 12089 | nlmsg_free(msg); |
| 12090 | nlfree(&nl); |
| 12091 | return RETURN_OK; |
| 12092 | #else |
| 12093 | //iw implementation |
| 12094 | #define TID_STATS_FILE "/tmp/tid_stats_file.txt" |
| 12095 | #define TOTAL_MAX_LINES 50 |
| 12096 | |
| 12097 | char buf[256] = {'\0'}; /* or other suitable maximum line size */ |
| 12098 | char if_name[32] = {0}; |
| 12099 | FILE *fp=NULL; |
| 12100 | char pipeCmd[1024]= {'\0'}; |
| 12101 | int lines,tid_index=0; |
| 12102 | char mac_addr[20] = {'\0'}; |
| 12103 | |
| 12104 | if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK) |
| 12105 | return RETURN_ERR; |
| 12106 | |
| 12107 | wifi_associated_dev_tid_entry_t *stats_entry; |
| 12108 | |
| 12109 | strcpy(mac_addr,clientMacAddress); |
| 12110 | |
| 12111 | snprintf(pipeCmd,sizeof(pipeCmd),"iw dev %s station dump -v > "TID_STATS_FILE,if_name); |
| 12112 | fp= popen(pipeCmd,"r"); |
| 12113 | if(fp == NULL) |
| 12114 | { |
| 12115 | perror("popen for station dump failed\n"); |
| 12116 | return RETURN_ERR; |
| 12117 | } |
| 12118 | pclose(fp); |
| 12119 | |
| 12120 | snprintf(pipeCmd,sizeof(pipeCmd),"grep -n 'Station' "TID_STATS_FILE " | cut -d ':' -f1 | head -2 | tail -1"); |
| 12121 | fp=popen(pipeCmd,"r"); |
| 12122 | if(fp == NULL) |
| 12123 | { |
| 12124 | perror("popen for grep station failed\n"); |
| 12125 | return RETURN_ERR; |
| 12126 | } |
| 12127 | else if(fgets(buf,sizeof(buf),fp) != NULL) |
| 12128 | lines=atoi(buf); |
| 12129 | else |
| 12130 | { |
| 12131 | pclose(fp); |
| 12132 | fprintf(stderr,"No devices are connected \n"); |
| 12133 | return RETURN_ERR; |
| 12134 | } |
| 12135 | pclose(fp); |
| 12136 | |
| 12137 | if(lines == 1) |
| 12138 | lines = TOTAL_MAX_LINES; //only one client is connected , considering next MAX lines of iw output |
| 12139 | |
| 12140 | for(tid_index=0; tid_index<PS_MAX_TID; tid_index++) |
| 12141 | { |
| 12142 | stats_entry = &tid_stats->tid_array[tid_index]; |
| 12143 | stats_entry->tid = tid_index; |
| 12144 | |
| 12145 | snprintf(pipeCmd, sizeof(pipeCmd),"cat "TID_STATS_FILE" | awk '/%s/ {for(i=0; i<=%d; i++) {getline; print}}' | grep -F -A%d 'MSDU' | awk '{print $3}' | tail -1",mac_addr,lines,tid_index+2); |
| 12146 | |
| 12147 | fp=popen(pipeCmd,"r"); |
| 12148 | if(fp ==NULL) |
| 12149 | { |
| 12150 | perror("Failed to read from tid file \n"); |
| 12151 | return RETURN_ERR; |
| 12152 | } |
| 12153 | else if(fgets(buf,sizeof(buf),fp) != NULL) |
| 12154 | stats_entry->num_msdus = atol(buf); |
| 12155 | |
| 12156 | pclose(fp); |
| 12157 | stats_entry->ac = _tid_ac_index_get[tid_index]; |
| 12158 | // TODO: |
| 12159 | // ULLONG ewma_time_ms; <! Moving average value based on last couple of transmitted msdus |
| 12160 | // ULLONG sum_time_ms; <! Delta of cumulative msdus times over interval |
| 12161 | } |
| 12162 | return RETURN_OK; |
| 12163 | #endif |
| 12164 | } |
| 12165 | |
| 12166 | |
| 12167 | INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list) |
| 12168 | { |
| 12169 | char interface_name[16] = {0}; |
| 12170 | char cmd[128]={0}; |
| 12171 | char buf[128]={0}; |
| 12172 | int freq = 0; |
| 12173 | |
| 12174 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12175 | |
| 12176 | // full mode is used to scan all channels. |
| 12177 | // multiple channels is ambiguous, iw can not set multiple frequencies in one time. |
| 12178 | if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL) |
| 12179 | ieee80211_channel_to_frequency(chan_list[0], &freq); |
| 12180 | |
| 12181 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 12182 | return RETURN_ERR; |
| 12183 | |
| 12184 | if (freq) |
| 12185 | snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq); |
| 12186 | else |
| 12187 | snprintf(cmd, sizeof(cmd), "iw dev %s scan trigger duration %d", interface_name, dwell_time); |
| 12188 | |
| 12189 | _syscmd(cmd, buf, sizeof(buf)); |
| 12190 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12191 | |
| 12192 | return RETURN_OK; |
| 12193 | } |
| 12194 | |
| 12195 | |
| 12196 | INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5) |
| 12197 | { |
| 12198 | // TODO Implement me! |
| 12199 | return RETURN_ERR; |
| 12200 | } |
| 12201 | |
| 12202 | INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config) |
| 12203 | { |
| 12204 | // TODO Implement me! |
| 12205 | return RETURN_ERR; |
| 12206 | } |
| 12207 | |
| 12208 | INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac) |
| 12209 | { |
| 12210 | // TODO Implement me! |
| 12211 | return RETURN_ERR; |
| 12212 | } |
| 12213 | |
| 12214 | INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac) |
| 12215 | { |
| 12216 | // TODO Implement me! |
| 12217 | return RETURN_ERR; |
| 12218 | } |
| 12219 | |
| 12220 | INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason) |
| 12221 | { |
| 12222 | // TODO Implement me! |
| 12223 | return RETURN_ERR; |
| 12224 | } |
| 12225 | |
| 12226 | INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb) |
| 12227 | { |
| 12228 | // TODO Implement me! |
| 12229 | return RETURN_ERR; |
| 12230 | } |
| 12231 | |
| 12232 | INT wifi_steering_eventUnregister(void) |
| 12233 | { |
| 12234 | // TODO Implement me! |
| 12235 | return RETURN_ERR; |
| 12236 | } |
| 12237 | |
| 12238 | INT wifi_delApAclDevices(INT apIndex) |
| 12239 | { |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 12240 | char inf_name[IF_NAME_SIZE] = {0}; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 12241 | struct unl unl_ins; |
| 12242 | int if_idx = 0, ret = 0; |
| 12243 | struct nl_msg *msg = NULL; |
| 12244 | struct nlattr * msg_data = NULL; |
| 12245 | struct mtk_nl80211_param param; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12246 | |
developer | 7e4a2a6 | 2023-04-06 19:56:03 +0800 | [diff] [blame] | 12247 | if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK) |
| 12248 | return RETURN_ERR; |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 12249 | if_idx = if_nametoindex(inf_name); |
| 12250 | if (!if_idx) { |
| 12251 | wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name); |
| 12252 | return RETURN_ERR; |
| 12253 | } |
| 12254 | /*init mtk nl80211 vendor cmd*/ |
| 12255 | param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL; |
| 12256 | param.if_type = NL80211_ATTR_IFINDEX; |
| 12257 | param.if_idx = if_idx; |
| 12258 | ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, ¶m); |
| 12259 | if (ret) { |
| 12260 | wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n"); |
| 12261 | return RETURN_ERR; |
| 12262 | } |
| 12263 | /*add mtk vendor cmd data*/ |
| 12264 | if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) { |
| 12265 | wifi_debug(DEBUG_ERROR, "Nla put attribute error\n"); |
| 12266 | nlmsg_free(msg); |
| 12267 | goto err; |
| 12268 | } |
| 12269 | /*send mtk nl80211 vendor msg*/ |
| 12270 | ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL); |
| 12271 | if (ret) { |
| 12272 | wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n"); |
| 12273 | goto err; |
| 12274 | } |
| 12275 | /*deinit mtk nl80211 vendor msg*/ |
| 12276 | mtk_nl80211_deint(&unl_ins); |
| 12277 | wifi_debug(DEBUG_NOTICE, "set cmd success.\n"); |
| 12278 | return RETURN_OK; |
| 12279 | err: |
| 12280 | mtk_nl80211_deint(&unl_ins); |
| 12281 | wifi_debug(DEBUG_ERROR, "set cmd fails.\n"); |
| 12282 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12283 | |
| 12284 | return RETURN_OK; |
| 12285 | } |
| 12286 | |
| 12287 | #ifdef HAL_NETLINK_IMPL |
| 12288 | static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) { |
| 12289 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 12290 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 12291 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 12292 | struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 12293 | struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1]; |
| 12294 | char mac_addr[20],dev[20]; |
| 12295 | |
| 12296 | nla_parse(tb, |
| 12297 | NL80211_ATTR_MAX, |
| 12298 | genlmsg_attrdata(gnlh, 0), |
| 12299 | genlmsg_attrlen(gnlh, 0), |
| 12300 | NULL); |
| 12301 | |
| 12302 | if(!tb[NL80211_ATTR_STA_INFO]) { |
| 12303 | fprintf(stderr, "sta stats missing!\n"); |
| 12304 | return NL_SKIP; |
| 12305 | } |
| 12306 | |
| 12307 | if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) { |
| 12308 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 12309 | return NL_SKIP; |
| 12310 | } |
| 12311 | mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); |
| 12312 | |
| 12313 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); |
| 12314 | |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12315 | if (sinfo[NL80211_STA_INFO_RX_BITRATE]) { |
| 12316 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) { |
| 12317 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 12318 | return NL_SKIP; |
| 12319 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12320 | } |
| 12321 | |
| 12322 | if(sinfo[NL80211_STA_INFO_TID_STATS]) |
| 12323 | { |
| 12324 | if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) { |
| 12325 | printf("failed to parse nested stats attributes!"); |
| 12326 | return NL_SKIP; |
| 12327 | } |
| 12328 | } |
developer | 5a1194f | 2023-05-24 16:00:03 +0800 | [diff] [blame] | 12329 | if (tb[NL80211_ATTR_VHT_CAPABILITY]) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12330 | |
developer | eb1ea83 | 2023-05-24 14:46:27 +0800 | [diff] [blame] | 12331 | if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) ) |
| 12332 | { |
| 12333 | printf("Type is VHT\n"); |
| 12334 | if(rinfo[NL80211_RATE_INFO_VHT_NSS]) |
| 12335 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12336 | |
developer | eb1ea83 | 2023-05-24 14:46:27 +0800 | [diff] [blame] | 12337 | if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) |
| 12338 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1; |
| 12339 | if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH]) |
| 12340 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2; |
| 12341 | if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) |
| 12342 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2; |
| 12343 | if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH]) |
| 12344 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2; |
| 12345 | if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) ) |
| 12346 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0; |
| 12347 | } |
| 12348 | else |
| 12349 | { |
| 12350 | printf(" OFDM or CCK \n"); |
| 12351 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0; |
| 12352 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0; |
| 12353 | } |
| 12354 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12355 | |
developer | eff896f | 2023-05-29 14:52:55 +0800 | [diff] [blame] | 12356 | if(sinfo[NL80211_STA_INFO_RX_BITRATE]) { |
| 12357 | if(rinfo[NL80211_RATE_INFO_MCS]) |
| 12358 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]); |
| 12359 | } |
| 12360 | if(sinfo[NL80211_STA_INFO_RX_BYTES64]) |
| 12361 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]); |
| 12362 | else if (sinfo[NL80211_STA_INFO_RX_BYTES]) |
| 12363 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12364 | |
developer | eff896f | 2023-05-29 14:52:55 +0800 | [diff] [blame] | 12365 | if(sinfo[NL80211_STA_INFO_TID_STATS]) { |
| 12366 | if(stats_info[NL80211_TID_STATS_RX_MSDU]) |
| 12367 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]); |
| 12368 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12369 | |
developer | eff896f | 2023-05-29 14:52:55 +0800 | [diff] [blame] | 12370 | if (sinfo[NL80211_STA_INFO_SIGNAL]) |
| 12371 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]); |
| 12372 | //Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0 |
| 12373 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0; |
| 12374 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0; |
| 12375 | ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0; |
| 12376 | //rssi_array need to be filled |
| 12377 | return NL_SKIP; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12378 | } |
| 12379 | #endif |
| 12380 | |
| 12381 | 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) |
| 12382 | { |
| 12383 | #ifdef HAL_NETLINK_IMPL |
| 12384 | Netlink nl; |
| 12385 | char if_name[32]; |
| 12386 | if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK) |
| 12387 | return RETURN_ERR; |
| 12388 | |
| 12389 | *output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t); |
| 12390 | |
| 12391 | if (*output_array_size <= 0) |
| 12392 | return RETURN_OK; |
| 12393 | |
| 12394 | nl.id = initSock80211(&nl); |
| 12395 | |
| 12396 | if (nl.id < 0) { |
| 12397 | fprintf(stderr, "Error initializing netlink \n"); |
| 12398 | return 0; |
| 12399 | } |
| 12400 | |
| 12401 | struct nl_msg* msg = nlmsg_alloc(); |
| 12402 | |
| 12403 | if (!msg) { |
| 12404 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 12405 | nlfree(&nl); |
| 12406 | return 0; |
| 12407 | } |
| 12408 | |
| 12409 | genlmsg_put(msg, |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12410 | NL_AUTO_PID, |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12411 | NL_AUTO_SEQ, |
| 12412 | nl.id, |
| 12413 | 0, |
| 12414 | 0, |
| 12415 | NL80211_CMD_GET_STATION, |
| 12416 | 0); |
| 12417 | |
| 12418 | nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress); |
| 12419 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 12420 | nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12421 | nl_send_auto_complete(nl.socket, msg); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12422 | nl_recvmsgs(nl.socket, nl.cb); |
| 12423 | nlmsg_free(msg); |
| 12424 | nlfree(&nl); |
| 12425 | return RETURN_OK; |
| 12426 | #else |
| 12427 | //TODO Implement me |
| 12428 | return RETURN_OK; |
| 12429 | #endif |
| 12430 | } |
| 12431 | |
| 12432 | #ifdef HAL_NETLINK_IMPL |
| 12433 | static int txStatsInfo_callback(struct nl_msg *msg, void *arg) { |
| 12434 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 12435 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 12436 | struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1]; |
| 12437 | struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1]; |
| 12438 | struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1]; |
| 12439 | char mac_addr[20],dev[20]; |
| 12440 | |
| 12441 | nla_parse(tb, |
| 12442 | NL80211_ATTR_MAX, |
| 12443 | genlmsg_attrdata(gnlh, 0), |
| 12444 | genlmsg_attrlen(gnlh, 0), |
| 12445 | NULL); |
| 12446 | |
| 12447 | if(!tb[NL80211_ATTR_STA_INFO]) { |
| 12448 | fprintf(stderr, "sta stats missing!\n"); |
| 12449 | return NL_SKIP; |
| 12450 | } |
| 12451 | |
| 12452 | if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) { |
| 12453 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 12454 | return NL_SKIP; |
| 12455 | } |
| 12456 | |
| 12457 | mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC])); |
| 12458 | |
| 12459 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); |
| 12460 | |
developer | 386281b | 2023-05-20 15:43:13 +0800 | [diff] [blame] | 12461 | if (sinfo[NL80211_STA_INFO_TX_BITRATE]) { |
| 12462 | if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) { |
| 12463 | fprintf(stderr, "failed to parse nested rate attributes!"); |
| 12464 | return NL_SKIP; |
| 12465 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12466 | } |
| 12467 | |
| 12468 | if(sinfo[NL80211_STA_INFO_TID_STATS]) |
| 12469 | { |
| 12470 | if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) { |
| 12471 | printf("failed to parse nested stats attributes!"); |
| 12472 | return NL_SKIP; |
| 12473 | } |
| 12474 | } |
developer | a6beea4 | 2023-05-24 16:44:05 +0800 | [diff] [blame] | 12475 | if (tb[NL80211_ATTR_VHT_CAPABILITY]) { |
developer | eb1ea83 | 2023-05-24 14:46:27 +0800 | [diff] [blame] | 12476 | if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY])) |
| 12477 | { |
| 12478 | printf("Type is VHT\n"); |
| 12479 | if(rinfo[NL80211_RATE_INFO_VHT_NSS]) |
| 12480 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12481 | |
developer | eb1ea83 | 2023-05-24 14:46:27 +0800 | [diff] [blame] | 12482 | if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH]) |
| 12483 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1; |
| 12484 | if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH]) |
| 12485 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2; |
| 12486 | if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH]) |
| 12487 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2; |
| 12488 | if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH]) |
| 12489 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2; |
| 12490 | if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH])) |
| 12491 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0; |
| 12492 | } |
| 12493 | else |
| 12494 | { |
| 12495 | printf(" OFDM or CCK \n"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12496 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0; |
developer | eb1ea83 | 2023-05-24 14:46:27 +0800 | [diff] [blame] | 12497 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0; |
| 12498 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12499 | } |
| 12500 | |
| 12501 | if(sinfo[NL80211_STA_INFO_TX_BITRATE]) { |
| 12502 | if(rinfo[NL80211_RATE_INFO_MCS]) |
| 12503 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]); |
| 12504 | } |
| 12505 | |
| 12506 | if(sinfo[NL80211_STA_INFO_TX_BYTES64]) |
| 12507 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]); |
| 12508 | else if (sinfo[NL80211_STA_INFO_TX_BYTES]) |
| 12509 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]); |
| 12510 | |
| 12511 | //Assigning 0 for mpdus and ppdus , as we do not have attributes in netlink |
developer | eff896f | 2023-05-29 14:52:55 +0800 | [diff] [blame] | 12512 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0; |
| 12513 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12514 | |
developer | eff896f | 2023-05-29 14:52:55 +0800 | [diff] [blame] | 12515 | if(sinfo[NL80211_STA_INFO_TID_STATS]) { |
| 12516 | if(stats_info[NL80211_TID_STATS_TX_MSDU]) |
| 12517 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]); |
| 12518 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12519 | |
| 12520 | if(sinfo[NL80211_STA_INFO_TX_RETRIES]) |
| 12521 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]); |
| 12522 | |
developer | eff896f | 2023-05-29 14:52:55 +0800 | [diff] [blame] | 12523 | if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS]) |
| 12524 | ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->attempts = nla_get_u32(sinfo[NL80211_STA_INFO_TX_PACKETS]) + nla_get_u32(sinfo[NL80211_STA_INFO_TX_FAILED]); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12525 | |
| 12526 | return NL_SKIP; |
| 12527 | } |
| 12528 | #endif |
| 12529 | |
| 12530 | 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) |
| 12531 | { |
| 12532 | #ifdef HAL_NETLINK_IMPL |
| 12533 | Netlink nl; |
| 12534 | char if_name[10]; |
| 12535 | char interface_name[16] = {0}; |
| 12536 | if (wifi_GetInterfaceName(radioIndex, interface_name) != RETURN_OK) |
| 12537 | return RETURN_ERR; |
| 12538 | |
| 12539 | *output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t); |
| 12540 | |
| 12541 | if (*output_array_size <= 0) |
| 12542 | return RETURN_OK; |
| 12543 | |
| 12544 | snprintf(if_name, sizeof(if_name), "%s", interface_name); |
| 12545 | |
| 12546 | nl.id = initSock80211(&nl); |
| 12547 | |
| 12548 | if(nl.id < 0) { |
| 12549 | fprintf(stderr, "Error initializing netlink \n"); |
| 12550 | return 0; |
| 12551 | } |
| 12552 | |
| 12553 | struct nl_msg* msg = nlmsg_alloc(); |
| 12554 | |
| 12555 | if(!msg) { |
| 12556 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 12557 | nlfree(&nl); |
| 12558 | return 0; |
| 12559 | } |
| 12560 | |
| 12561 | genlmsg_put(msg, |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12562 | NL_AUTO_PID, |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12563 | NL_AUTO_SEQ, |
| 12564 | nl.id, |
| 12565 | 0, |
| 12566 | 0, |
| 12567 | NL80211_CMD_GET_STATION, |
| 12568 | 0); |
| 12569 | |
| 12570 | nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress); |
| 12571 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
| 12572 | nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12573 | nl_send_auto_complete(nl.socket, msg); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12574 | nl_recvmsgs(nl.socket, nl.cb); |
| 12575 | nlmsg_free(msg); |
| 12576 | nlfree(&nl); |
| 12577 | return RETURN_OK; |
| 12578 | #else |
| 12579 | //TODO Implement me |
| 12580 | return RETURN_OK; |
| 12581 | #endif |
| 12582 | } |
| 12583 | |
| 12584 | INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate) |
| 12585 | { |
| 12586 | // TODO Implement me! |
| 12587 | char buf[MAX_BUF_SIZE] = {0}; |
| 12588 | char config_file[MAX_BUF_SIZE] = {0}; |
| 12589 | |
| 12590 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 12591 | wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf)); |
| 12592 | *activate = (strncmp("1",buf,1) == 0); |
| 12593 | |
| 12594 | return RETURN_OK; |
| 12595 | } |
| 12596 | |
| 12597 | INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate) |
| 12598 | { |
| 12599 | char config_file[MAX_BUF_SIZE] = {0}; |
| 12600 | struct params list; |
| 12601 | |
| 12602 | list.name = "rrm_neighbor_report"; |
| 12603 | list.value = activate?"1":"0"; |
| 12604 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 12605 | wifi_hostapdWrite(config_file, &list, 1); |
| 12606 | |
| 12607 | return RETURN_OK; |
| 12608 | } |
| 12609 | |
| 12610 | INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate) |
| 12611 | { |
| 12612 | char buf[32] = {0}; |
| 12613 | char config_file[MAX_BUF_SIZE] = {0}; |
| 12614 | |
| 12615 | sprintf(config_file,"%s%d.conf",CONFIG_PREFIX,apIndex); |
| 12616 | wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf)); |
| 12617 | *activate = (strncmp("1",buf,1) == 0); |
| 12618 | |
| 12619 | return RETURN_OK; |
| 12620 | } |
| 12621 | #undef HAL_NETLINK_IMPL |
| 12622 | #ifdef HAL_NETLINK_IMPL |
| 12623 | static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) { |
| 12624 | struct nlattr *tb[NL80211_ATTR_MAX + 1]; |
| 12625 | struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg)); |
| 12626 | struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1]; |
| 12627 | char dev[20]; |
| 12628 | int freq =0 ; |
| 12629 | static int i=0; |
| 12630 | |
| 12631 | wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg; |
| 12632 | |
| 12633 | static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = { |
| 12634 | }; |
| 12635 | |
| 12636 | nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL); |
| 12637 | |
| 12638 | if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev); |
| 12639 | |
| 12640 | if (!tb[NL80211_ATTR_SURVEY_INFO]) { |
| 12641 | fprintf(stderr, "survey data missing!\n"); |
| 12642 | return NL_SKIP; |
| 12643 | } |
| 12644 | |
| 12645 | if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy)) |
| 12646 | { |
| 12647 | fprintf(stderr, "failed to parse nested attributes!\n"); |
| 12648 | return NL_SKIP; |
| 12649 | } |
| 12650 | |
| 12651 | |
| 12652 | if(out[0].array_size == 1 ) |
| 12653 | { |
| 12654 | if(sinfo[NL80211_SURVEY_INFO_IN_USE]) |
| 12655 | { |
| 12656 | if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) |
| 12657 | freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]); |
| 12658 | out[0].ch_number = ieee80211_frequency_to_channel(freq); |
| 12659 | |
| 12660 | if (sinfo[NL80211_SURVEY_INFO_NOISE]) |
| 12661 | out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]); |
| 12662 | if (sinfo[NL80211_SURVEY_INFO_TIME_RX]) |
| 12663 | out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]); |
| 12664 | if (sinfo[NL80211_SURVEY_INFO_TIME_TX]) |
| 12665 | out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]); |
| 12666 | if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY]) |
| 12667 | out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]); |
| 12668 | if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]) |
| 12669 | out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]); |
| 12670 | if (sinfo[NL80211_SURVEY_INFO_TIME]) |
| 12671 | out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]); |
| 12672 | return NL_STOP; |
| 12673 | } |
| 12674 | } |
| 12675 | else |
| 12676 | { |
| 12677 | if ( i <= out[0].array_size ) |
| 12678 | { |
| 12679 | if (sinfo[NL80211_SURVEY_INFO_FREQUENCY]) |
| 12680 | freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]); |
| 12681 | out[i].ch_number = ieee80211_frequency_to_channel(freq); |
| 12682 | |
| 12683 | if (sinfo[NL80211_SURVEY_INFO_NOISE]) |
| 12684 | out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]); |
| 12685 | if (sinfo[NL80211_SURVEY_INFO_TIME_RX]) |
| 12686 | out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]); |
| 12687 | if (sinfo[NL80211_SURVEY_INFO_TIME_TX]) |
| 12688 | out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]); |
| 12689 | if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY]) |
| 12690 | out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]); |
| 12691 | if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]) |
| 12692 | out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]); |
| 12693 | if (sinfo[NL80211_SURVEY_INFO_TIME]) |
| 12694 | out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]); |
| 12695 | } |
| 12696 | } |
| 12697 | |
| 12698 | i++; |
| 12699 | return NL_SKIP; |
| 12700 | } |
| 12701 | #endif |
| 12702 | |
| 12703 | static int ieee80211_channel_to_frequency(int channel, int *freqMHz) |
| 12704 | { |
| 12705 | char command[MAX_CMD_SIZE], output[MAX_BUF_SIZE]; |
| 12706 | FILE *fp; |
| 12707 | |
| 12708 | if(access("/tmp/freq-channel-map.txt", F_OK)==-1) |
| 12709 | { |
| 12710 | printf("Creating Frequency-Channel Map\n"); |
| 12711 | system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt"); |
| 12712 | } |
| 12713 | snprintf(command, sizeof(command), "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel); |
| 12714 | if((fp = popen(command, "r"))) |
| 12715 | { |
| 12716 | fgets(output, sizeof(output), fp); |
| 12717 | *freqMHz = atoi(output); |
| 12718 | pclose(fp); |
| 12719 | } |
| 12720 | |
| 12721 | return 0; |
| 12722 | } |
| 12723 | |
| 12724 | static int get_survey_dump_buf(INT radioIndex, int channel, const char *buf, size_t bufsz) |
| 12725 | { |
| 12726 | int freqMHz = -1; |
| 12727 | char cmd[MAX_CMD_SIZE] = {'\0'}; |
| 12728 | char interface_name[16] = {0}; |
| 12729 | |
| 12730 | ieee80211_channel_to_frequency(channel, &freqMHz); |
| 12731 | if (freqMHz == -1) { |
| 12732 | wifi_dbg_printf("%s: failed to get channel frequency for channel: %d\n", __func__, channel); |
| 12733 | return -1; |
| 12734 | } |
| 12735 | |
| 12736 | wifi_GetInterfaceName(radioIndex, interface_name); |
| 12737 | if (sprintf(cmd,"iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) < 0) { |
| 12738 | wifi_dbg_printf("%s: failed to build iw dev command for radioIndex=%d freq=%d\n", __FUNCTION__, |
| 12739 | radioIndex, freqMHz); |
| 12740 | return -1; |
| 12741 | } |
| 12742 | |
| 12743 | if (_syscmd(cmd, buf, bufsz) == RETURN_ERR) { |
| 12744 | wifi_dbg_printf("%s: failed to execute '%s' for radioIndex=%d\n", __FUNCTION__, cmd, radioIndex); |
| 12745 | return -1; |
| 12746 | } |
| 12747 | |
| 12748 | return 0; |
| 12749 | } |
| 12750 | |
| 12751 | static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats) |
| 12752 | { |
| 12753 | const char *ptr = buf; |
| 12754 | char *key = NULL; |
| 12755 | char *val = NULL; |
| 12756 | char line[256] = { '\0' }; |
| 12757 | |
| 12758 | while (ptr = get_line_from_str_buf(ptr, line)) { |
| 12759 | if (strstr(line, "Frequency")) continue; |
| 12760 | |
| 12761 | key = strtok(line, ":"); |
| 12762 | val = strtok(NULL, " "); |
| 12763 | wifi_dbg_printf("%s: key='%s' val='%s'\n", __func__, key, val); |
| 12764 | |
| 12765 | if (!strcmp(key, "noise")) { |
| 12766 | sscanf(val, "%d", &stats->ch_noise); |
| 12767 | if (stats->ch_noise == 0) { |
| 12768 | // Workaround for missing noise information. |
| 12769 | // Assume -95 for 2.4G and -103 for 5G |
| 12770 | if (radioIndex == 0) stats->ch_noise = -95; |
| 12771 | if (radioIndex == 1) stats->ch_noise = -103; |
| 12772 | } |
| 12773 | } |
| 12774 | else if (!strcmp(key, "channel active time")) { |
| 12775 | sscanf(val, "%llu", &stats->ch_utilization_total); |
| 12776 | } |
| 12777 | else if (!strcmp(key, "channel busy time")) { |
| 12778 | sscanf(val, "%llu", &stats->ch_utilization_busy); |
| 12779 | } |
| 12780 | else if (!strcmp(key, "channel receive time")) { |
| 12781 | sscanf(val, "%llu", &stats->ch_utilization_busy_rx); |
| 12782 | } |
| 12783 | else if (!strcmp(key, "channel transmit time")) { |
| 12784 | sscanf(val, "%llu", &stats->ch_utilization_busy_tx); |
| 12785 | } |
| 12786 | }; |
| 12787 | |
| 12788 | return 0; |
| 12789 | } |
| 12790 | |
| 12791 | INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size) |
| 12792 | { |
| 12793 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 12794 | #ifdef HAL_NETLINK_IMPL |
| 12795 | Netlink nl; |
| 12796 | wifi_channelStats_t_loc local[array_size]; |
| 12797 | char if_name[32]; |
| 12798 | |
| 12799 | local[0].array_size = array_size; |
| 12800 | |
| 12801 | if (wifi_GetInterfaceName(radioIndex, if_name) != RETURN_OK) |
| 12802 | return RETURN_ERR; |
| 12803 | |
| 12804 | nl.id = initSock80211(&nl); |
| 12805 | |
| 12806 | if (nl.id < 0) { |
| 12807 | fprintf(stderr, "Error initializing netlink \n"); |
| 12808 | return -1; |
| 12809 | } |
| 12810 | |
| 12811 | struct nl_msg* msg = nlmsg_alloc(); |
| 12812 | |
| 12813 | if (!msg) { |
| 12814 | fprintf(stderr, "Failed to allocate netlink message.\n"); |
| 12815 | nlfree(&nl); |
| 12816 | return -2; |
| 12817 | } |
| 12818 | |
| 12819 | genlmsg_put(msg, |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12820 | NL_AUTO_PID, |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12821 | NL_AUTO_SEQ, |
| 12822 | nl.id, |
| 12823 | 0, |
| 12824 | NLM_F_DUMP, |
| 12825 | NL80211_CMD_GET_SURVEY, |
| 12826 | 0); |
| 12827 | |
| 12828 | nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name)); |
developer | 8dd7253 | 2023-05-17 19:58:35 +0800 | [diff] [blame] | 12829 | nl_send_auto_complete(nl.socket, msg); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 12830 | nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local); |
| 12831 | nl_recvmsgs(nl.socket, nl.cb); |
| 12832 | nlmsg_free(msg); |
| 12833 | nlfree(&nl); |
| 12834 | //Copying the Values |
| 12835 | for(int i=0;i<array_size;i++) |
| 12836 | { |
| 12837 | input_output_channelStats_array[i].ch_number = local[i].ch_number; |
| 12838 | input_output_channelStats_array[i].ch_noise = local[i].ch_noise; |
| 12839 | input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx; |
| 12840 | input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx; |
| 12841 | input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy; |
| 12842 | input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext; |
| 12843 | input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total; |
| 12844 | //TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self |
| 12845 | } |
| 12846 | #else |
| 12847 | ULONG channel = 0; |
| 12848 | int i; |
| 12849 | int number_of_channels = array_size; |
| 12850 | char buf[512]; |
| 12851 | INT ret; |
| 12852 | wifi_channelStats_t tmp_stats; |
| 12853 | |
| 12854 | if (number_of_channels == 0) { |
| 12855 | if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) { |
| 12856 | wifi_dbg_printf("%s: cannot get current channel for radioIndex=%d\n", __func__, radioIndex); |
| 12857 | return RETURN_ERR; |
| 12858 | } |
| 12859 | number_of_channels = 1; |
| 12860 | input_output_channelStats_array[0].ch_number = channel; |
| 12861 | } |
| 12862 | |
| 12863 | for (i = 0; i < number_of_channels; i++) { |
| 12864 | |
| 12865 | input_output_channelStats_array[i].ch_noise = 0; |
| 12866 | input_output_channelStats_array[i].ch_utilization_busy_rx = 0; |
| 12867 | input_output_channelStats_array[i].ch_utilization_busy_tx = 0; |
| 12868 | input_output_channelStats_array[i].ch_utilization_busy = 0; |
| 12869 | input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable |
| 12870 | input_output_channelStats_array[i].ch_utilization_total = 0; |
| 12871 | |
| 12872 | memset(buf, 0, sizeof(buf)); |
| 12873 | if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) { |
| 12874 | return RETURN_ERR; |
| 12875 | } |
| 12876 | if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) { |
| 12877 | wifi_dbg_printf("%s: cannot fetch survey from buf for radioIndex=%d\n", __func__, radioIndex); |
| 12878 | return RETURN_ERR; |
| 12879 | } |
| 12880 | |
| 12881 | // XXX: fake missing 'self' counter which is not available in iw survey output |
| 12882 | // the 'self' counter (a.k.a 'bss') requires Linux Kernel update |
| 12883 | input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8; |
| 12884 | |
| 12885 | input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000; |
| 12886 | input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000; |
| 12887 | input_output_channelStats_array[i].ch_utilization_busy_self *= 1000; |
| 12888 | input_output_channelStats_array[i].ch_utilization_busy *= 1000; |
| 12889 | input_output_channelStats_array[i].ch_utilization_total *= 1000; |
| 12890 | |
| 12891 | wifi_dbg_printf("%s: ch_number=%d ch_noise=%d total=%llu busy=%llu busy_rx=%llu busy_tx=%llu busy_self=%llu busy_ext=%llu\n", |
| 12892 | __func__, |
| 12893 | input_output_channelStats_array[i].ch_number, |
| 12894 | input_output_channelStats_array[i].ch_noise, |
| 12895 | input_output_channelStats_array[i].ch_utilization_total, |
| 12896 | input_output_channelStats_array[i].ch_utilization_busy, |
| 12897 | input_output_channelStats_array[i].ch_utilization_busy_rx, |
| 12898 | input_output_channelStats_array[i].ch_utilization_busy_tx, |
| 12899 | input_output_channelStats_array[i].ch_utilization_busy_self, |
| 12900 | input_output_channelStats_array[i].ch_utilization_busy_ext); |
| 12901 | } |
| 12902 | #endif |
| 12903 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 12904 | return RETURN_OK; |
| 12905 | } |
| 12906 | #define HAL_NETLINK_IMPL |
| 12907 | |
| 12908 | /* Hostapd events */ |
| 12909 | |
| 12910 | #ifndef container_of |
| 12911 | #define offset_of(st, m) ((size_t)&(((st *)0)->m)) |
| 12912 | #define container_of(ptr, type, member) \ |
| 12913 | ((type *)((char *)ptr - offset_of(type, member))) |
| 12914 | #endif /* container_of */ |
| 12915 | |
| 12916 | struct ctrl { |
| 12917 | char sockpath[128]; |
| 12918 | char sockdir[128]; |
| 12919 | char bss[IFNAMSIZ]; |
| 12920 | char reply[4096]; |
| 12921 | int ssid_index; |
| 12922 | void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len); |
| 12923 | void (*overrun)(struct ctrl *ctrl); |
| 12924 | struct wpa_ctrl *wpa; |
| 12925 | unsigned int ovfl; |
| 12926 | size_t reply_len; |
| 12927 | int initialized; |
| 12928 | ev_timer retry; |
| 12929 | ev_timer watchdog; |
| 12930 | ev_stat stat; |
| 12931 | ev_io io; |
| 12932 | }; |
| 12933 | static wifi_newApAssociatedDevice_callback clients_connect_cb; |
| 12934 | static wifi_apDisassociatedDevice_callback clients_disconnect_cb; |
| 12935 | static struct ctrl wpa_ctrl[MAX_APS]; |
| 12936 | static int initialized; |
| 12937 | |
| 12938 | static unsigned int ctrl_get_drops(struct ctrl *ctrl) |
| 12939 | { |
| 12940 | char cbuf[256] = {}; |
| 12941 | struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) }; |
| 12942 | struct cmsghdr *cmsg; |
| 12943 | unsigned int ovfl = ctrl->ovfl; |
| 12944 | unsigned int drop; |
| 12945 | |
| 12946 | recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT); |
| 12947 | for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) |
| 12948 | if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL) |
| 12949 | ovfl = *(unsigned int *)CMSG_DATA(cmsg); |
| 12950 | |
| 12951 | drop = ovfl - ctrl->ovfl; |
| 12952 | ctrl->ovfl = ovfl; |
| 12953 | |
| 12954 | return drop; |
| 12955 | } |
| 12956 | |
| 12957 | static void ctrl_close(struct ctrl *ctrl) |
| 12958 | { |
| 12959 | if (ctrl->io.cb) |
| 12960 | ev_io_stop(EV_DEFAULT_ &ctrl->io); |
| 12961 | if (ctrl->retry.cb) |
| 12962 | ev_timer_stop(EV_DEFAULT_ &ctrl->retry); |
| 12963 | if (!ctrl->wpa) |
| 12964 | return; |
| 12965 | |
| 12966 | wpa_ctrl_detach(ctrl->wpa); |
| 12967 | wpa_ctrl_close(ctrl->wpa); |
| 12968 | ctrl->wpa = NULL; |
| 12969 | printf("WPA_CTRL: closed index=%d\n", ctrl->ssid_index); |
| 12970 | } |
| 12971 | |
| 12972 | static void ctrl_process(struct ctrl *ctrl) |
| 12973 | { |
| 12974 | const char *str; |
| 12975 | int drops; |
| 12976 | int level; |
| 12977 | int err; |
| 12978 | |
| 12979 | /* Example events: |
| 12980 | * |
| 12981 | * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 |
| 12982 | * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid |
| 12983 | * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19 |
| 12984 | * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=] |
| 12985 | * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1 |
| 12986 | */ |
| 12987 | if (!(str = index(ctrl->reply, '>'))) |
| 12988 | return; |
| 12989 | if (sscanf(ctrl->reply, "<%d>", &level) != 1) |
| 12990 | return; |
| 12991 | |
| 12992 | str++; |
| 12993 | |
| 12994 | if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) { |
| 12995 | if (!(str = index(ctrl->reply, ' '))) |
| 12996 | return; |
| 12997 | wifi_associated_dev_t sta; |
| 12998 | memset(&sta, 0, sizeof(sta)); |
| 12999 | |
| 13000 | sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx", |
| 13001 | &sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2], |
| 13002 | &sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]); |
| 13003 | |
| 13004 | sta.cli_Active=true; |
| 13005 | |
| 13006 | (clients_connect_cb)(ctrl->ssid_index, &sta); |
| 13007 | goto handled; |
| 13008 | } |
| 13009 | |
| 13010 | if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) { |
| 13011 | if (!(str = index(ctrl->reply, ' '))) |
| 13012 | return; |
| 13013 | |
| 13014 | (clients_disconnect_cb)(ctrl->ssid_index, (char*)str, 0); |
| 13015 | goto handled; |
| 13016 | } |
| 13017 | |
| 13018 | if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) { |
| 13019 | printf("CTRL_WPA: handle TERMINATING event\n"); |
| 13020 | goto retry; |
| 13021 | } |
| 13022 | |
| 13023 | if (strncmp("AP-DISABLED", str, 11) == 0) { |
| 13024 | printf("CTRL_WPA: handle AP-DISABLED\n"); |
| 13025 | goto retry; |
| 13026 | } |
| 13027 | |
| 13028 | printf("Event not supported!!\n"); |
| 13029 | |
| 13030 | handled: |
| 13031 | |
| 13032 | if ((drops = ctrl_get_drops(ctrl))) { |
| 13033 | printf("WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index); |
| 13034 | if (ctrl->overrun) |
| 13035 | ctrl->overrun(ctrl); |
| 13036 | } |
| 13037 | |
| 13038 | return; |
| 13039 | |
| 13040 | retry: |
| 13041 | printf("WPA_CTRL: closing\n"); |
| 13042 | ctrl_close(ctrl); |
| 13043 | printf("WPA_CTRL: retrying from ctrl prcoess\n"); |
| 13044 | ev_timer_again(EV_DEFAULT_ &ctrl->retry); |
| 13045 | } |
| 13046 | |
| 13047 | static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events) |
| 13048 | { |
| 13049 | struct ctrl *ctrl = container_of(io, struct ctrl, io); |
| 13050 | int err; |
| 13051 | |
| 13052 | memset(ctrl->reply, 0, sizeof(ctrl->reply)); |
| 13053 | ctrl->reply_len = sizeof(ctrl->reply) - 1; |
| 13054 | err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len); |
| 13055 | ctrl->reply[ctrl->reply_len] = 0; |
| 13056 | if (err < 0) { |
| 13057 | if (errno == EAGAIN || errno == EWOULDBLOCK) |
| 13058 | return; |
| 13059 | ctrl_close(ctrl); |
| 13060 | ev_timer_again(EV_A_ &ctrl->retry); |
| 13061 | return; |
| 13062 | } |
| 13063 | |
| 13064 | ctrl_process(ctrl); |
| 13065 | } |
| 13066 | |
| 13067 | static int ctrl_open(struct ctrl *ctrl) |
| 13068 | { |
| 13069 | int fd; |
| 13070 | |
| 13071 | if (ctrl->wpa) |
| 13072 | return 0; |
| 13073 | |
| 13074 | ctrl->wpa = wpa_ctrl_open(ctrl->sockpath); |
| 13075 | if (!ctrl->wpa) |
| 13076 | goto err; |
| 13077 | |
| 13078 | if (wpa_ctrl_attach(ctrl->wpa) < 0) |
| 13079 | goto err_close; |
| 13080 | |
| 13081 | fd = wpa_ctrl_get_fd(ctrl->wpa); |
| 13082 | if (fd < 0) |
| 13083 | goto err_detach; |
| 13084 | |
| 13085 | if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0) |
| 13086 | goto err_detach; |
| 13087 | |
| 13088 | ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ); |
| 13089 | ev_io_start(EV_DEFAULT_ &ctrl->io); |
| 13090 | |
| 13091 | return 0; |
| 13092 | |
| 13093 | err_detach: |
| 13094 | wpa_ctrl_detach(ctrl->wpa); |
| 13095 | err_close: |
| 13096 | wpa_ctrl_close(ctrl->wpa); |
| 13097 | err: |
| 13098 | ctrl->wpa = NULL; |
| 13099 | return -1; |
| 13100 | } |
| 13101 | |
| 13102 | static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events) |
| 13103 | { |
| 13104 | struct ctrl *ctrl = container_of(stat, struct ctrl, stat); |
| 13105 | |
| 13106 | printf("WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index); |
| 13107 | ctrl_open(ctrl); |
| 13108 | } |
| 13109 | |
| 13110 | static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events) |
| 13111 | { |
| 13112 | struct ctrl *ctrl = container_of(timer, struct ctrl, retry); |
| 13113 | |
| 13114 | printf("WPA_CTRL: index=%d retrying\n", ctrl->ssid_index); |
| 13115 | if (ctrl_open(ctrl) == 0) { |
| 13116 | printf("WPA_CTRL: retry successful\n"); |
| 13117 | ev_timer_stop(EV_DEFAULT_ &ctrl->retry); |
| 13118 | } |
| 13119 | } |
| 13120 | |
| 13121 | int ctrl_enable(struct ctrl *ctrl) |
| 13122 | { |
| 13123 | if (ctrl->wpa) |
| 13124 | return 0; |
| 13125 | |
| 13126 | if (!ctrl->stat.cb) { |
| 13127 | ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.); |
| 13128 | ev_stat_start(EV_DEFAULT_ &ctrl->stat); |
| 13129 | } |
| 13130 | |
| 13131 | if (!ctrl->retry.cb) { |
| 13132 | ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.); |
| 13133 | } |
| 13134 | |
| 13135 | return ctrl_open(ctrl); |
| 13136 | } |
| 13137 | |
| 13138 | static void |
| 13139 | ctrl_msg_cb(char *buf, size_t len) |
| 13140 | { |
| 13141 | struct ctrl *ctrl = container_of(buf, struct ctrl, reply); |
| 13142 | |
| 13143 | printf("WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s", ctrl->ssid_index, len, buf); |
| 13144 | ctrl_process(ctrl); |
| 13145 | } |
| 13146 | |
| 13147 | static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len) |
| 13148 | { |
| 13149 | int err; |
| 13150 | |
| 13151 | if (!ctrl->wpa) |
| 13152 | return -1; |
| 13153 | if (*reply_len < 2) |
| 13154 | return -1; |
| 13155 | |
| 13156 | (*reply_len)--; |
| 13157 | ctrl->reply_len = sizeof(ctrl->reply); |
| 13158 | err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb); |
| 13159 | printf("WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err); |
| 13160 | if (err < 0) |
| 13161 | return err; |
| 13162 | |
| 13163 | if (ctrl->reply_len > *reply_len) |
| 13164 | ctrl->reply_len = *reply_len; |
| 13165 | |
| 13166 | *reply_len = ctrl->reply_len; |
| 13167 | memcpy(reply, ctrl->reply, *reply_len); |
| 13168 | reply[*reply_len - 1] = 0; |
| 13169 | printf("WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply); |
| 13170 | return 0; |
| 13171 | } |
| 13172 | |
| 13173 | static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events) |
| 13174 | { |
| 13175 | const char *pong = "PONG"; |
| 13176 | const char *ping = "PING"; |
| 13177 | char reply[1024]; |
| 13178 | size_t len = sizeof(reply); |
| 13179 | int err; |
| 13180 | ULONG s, snum; |
| 13181 | INT ret; |
| 13182 | BOOL status; |
| 13183 | |
| 13184 | printf("WPA_CTRL: watchdog cb\n"); |
| 13185 | |
| 13186 | ret = wifi_getSSIDNumberOfEntries(&snum); |
| 13187 | if (ret != RETURN_OK) { |
| 13188 | printf("%s: failed to get SSID count", __func__); |
| 13189 | return; |
| 13190 | } |
| 13191 | |
| 13192 | if (snum > MAX_APS) { |
| 13193 | printf("more ssid than supported! %lu\n", snum); |
| 13194 | return; |
| 13195 | } |
| 13196 | |
| 13197 | for (s = 0; s < snum; s++) { |
| 13198 | if (wifi_getApEnable(s, &status) != RETURN_OK) { |
| 13199 | printf("%s: failed to get AP Enable for index: %lu\n", __func__, s); |
| 13200 | continue; |
| 13201 | } |
| 13202 | if (status == false) continue; |
| 13203 | |
| 13204 | memset(reply, 0, sizeof(reply)); |
| 13205 | len = sizeof(reply); |
| 13206 | printf("WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index); |
| 13207 | err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len); |
| 13208 | if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong))) |
| 13209 | continue; |
| 13210 | |
| 13211 | printf("WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index); |
| 13212 | ctrl_close(&wpa_ctrl[s]); |
| 13213 | printf("WPA_CTRL: ev_timer_again %lu\n", s); |
| 13214 | ev_timer_again(EV_DEFAULT_ &wpa_ctrl[s].retry); |
| 13215 | } |
| 13216 | } |
| 13217 | |
| 13218 | static int init_wpa() |
| 13219 | { |
| 13220 | int ret = 0, i = 0; |
| 13221 | ULONG s, snum; |
| 13222 | |
| 13223 | ret = wifi_getSSIDNumberOfEntries(&snum); |
| 13224 | if (ret != RETURN_OK) { |
| 13225 | printf("%s: failed to get SSID count", __func__); |
| 13226 | return RETURN_ERR; |
| 13227 | } |
| 13228 | |
| 13229 | if (snum > MAX_APS) { |
| 13230 | printf("more ssid than supported! %lu\n", snum); |
| 13231 | return RETURN_ERR; |
| 13232 | } |
| 13233 | |
| 13234 | for (s = 0; s < snum; s++) { |
| 13235 | memset(&wpa_ctrl[s], 0, sizeof(struct ctrl)); |
| 13236 | sprintf(wpa_ctrl[s].sockpath, "%s%lu", SOCK_PREFIX, s); |
| 13237 | wpa_ctrl[s].ssid_index = s; |
| 13238 | ctrl_enable(&wpa_ctrl[s]); |
| 13239 | } |
| 13240 | |
| 13241 | ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.); |
| 13242 | ev_timer_again(EV_DEFAULT_ &wpa_ctrl->watchdog); |
| 13243 | |
| 13244 | initialized = 1; |
| 13245 | printf("WPA_CTRL: initialized\n"); |
| 13246 | |
| 13247 | return RETURN_OK; |
| 13248 | } |
| 13249 | |
| 13250 | void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc) |
| 13251 | { |
| 13252 | clients_connect_cb = callback_proc; |
| 13253 | if (!initialized) |
| 13254 | init_wpa(); |
| 13255 | } |
| 13256 | |
| 13257 | void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc) |
| 13258 | { |
| 13259 | clients_disconnect_cb = callback_proc; |
| 13260 | if (!initialized) |
| 13261 | init_wpa(); |
| 13262 | } |
| 13263 | |
| 13264 | INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request) |
| 13265 | { |
| 13266 | // TODO Implement me! |
| 13267 | return RETURN_ERR; |
| 13268 | } |
| 13269 | |
| 13270 | INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken) |
| 13271 | { |
| 13272 | // TODO Implement me! |
| 13273 | return RETURN_ERR; |
| 13274 | } |
| 13275 | |
| 13276 | INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize) |
| 13277 | { |
| 13278 | int i; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13279 | int phyId = -1; |
| 13280 | char cmd[256] = {0}; |
| 13281 | char channel_numbers_buf[256] = {0}; |
| 13282 | char dfs_state_buf[256] = {0}; |
| 13283 | char line[256] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13284 | const char *ptr; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13285 | BOOL dfs_enable = false; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13286 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13287 | memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13288 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13289 | wifi_getRadioDfsEnable(radioIndex, &dfs_enable); |
| 13290 | phyId = radio_index_to_phy(radioIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13291 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13292 | snprintf(cmd, sizeof (cmd), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v '%sno IR\\|5340\\|5480' | awk '{print $4}' | tr -d '[]'", phyId, dfs_enable?"":"radar\\|"); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13293 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13294 | if (_syscmd(cmd, channel_numbers_buf, sizeof(channel_numbers_buf)) == RETURN_ERR) { |
| 13295 | wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd); |
| 13296 | return RETURN_ERR; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13297 | } |
| 13298 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13299 | ptr = channel_numbers_buf; |
| 13300 | i = 0; |
| 13301 | while (ptr = get_line_from_str_buf(ptr, line)) { |
| 13302 | if (i >= outputMapSize) { |
| 13303 | wifi_dbg_printf("%s: DFS map size too small\n", __FUNCTION__); |
| 13304 | return RETURN_ERR; |
| 13305 | } |
| 13306 | sscanf(line, "%d", &outputMap[i].ch_number); |
| 13307 | |
| 13308 | memset(cmd, 0, sizeof(cmd)); |
| 13309 | // Below command should fetch string for DFS state (usable, available or unavailable) |
| 13310 | // Example line: "DFS state: usable (for 78930 sec)" |
| 13311 | if (sprintf(cmd,"iw list | grep -A 2 '\\[%d\\]' | tr -d '\\t' | grep 'DFS state' | awk '{print $3}' | tr -d '\\n'", outputMap[i].ch_number) < 0) { |
| 13312 | wifi_dbg_printf("%s: failed to build dfs state command\n", __FUNCTION__); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13313 | return RETURN_ERR; |
| 13314 | } |
| 13315 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13316 | memset(dfs_state_buf, 0, sizeof(dfs_state_buf)); |
| 13317 | if (_syscmd(cmd, dfs_state_buf, sizeof(dfs_state_buf)) == RETURN_ERR) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13318 | wifi_dbg_printf("%s: failed to execute '%s'\n", __FUNCTION__, cmd); |
| 13319 | return RETURN_ERR; |
| 13320 | } |
| 13321 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13322 | wifi_dbg_printf("DFS state = '%s'\n", dfs_state_buf); |
developer | 59fda4f | 2023-05-16 15:47:38 +0800 | [diff] [blame] | 13323 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13324 | if (!strcmp(dfs_state_buf, "usable")) { |
| 13325 | outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED; |
| 13326 | } else if (!strcmp(dfs_state_buf, "available")) { |
| 13327 | outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED; |
| 13328 | } else if (!strcmp(dfs_state_buf, "unavailable")) { |
| 13329 | outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START; |
| 13330 | } else { |
| 13331 | outputMap[i].ch_state = CHAN_STATE_AVAILABLE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13332 | } |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13333 | i++; |
developer | 59fda4f | 2023-05-16 15:47:38 +0800 | [diff] [blame] | 13334 | } |
developer | 40ba176 | 2023-05-13 11:03:49 +0800 | [diff] [blame] | 13335 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13336 | return RETURN_OK; |
| 13337 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13338 | wifi_dbg_printf("%s: wrong radio index (%d)\n", __FUNCTION__, radioIndex); |
| 13339 | return RETURN_ERR; |
| 13340 | } |
| 13341 | |
| 13342 | INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb) |
| 13343 | { |
| 13344 | // TODO Implement me! |
| 13345 | return RETURN_ERR; |
| 13346 | } |
| 13347 | |
| 13348 | INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage) |
| 13349 | { |
| 13350 | return RETURN_OK; |
| 13351 | } |
| 13352 | |
| 13353 | INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn) |
| 13354 | { |
| 13355 | // TODO Implement me! |
| 13356 | return RETURN_ERR; |
| 13357 | } |
| 13358 | |
| 13359 | INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand) |
| 13360 | { |
| 13361 | // TODO API refrence Implementaion is present on RPI hal |
| 13362 | return RETURN_ERR; |
| 13363 | } |
| 13364 | |
| 13365 | INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg) |
| 13366 | { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13367 | /* |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13368 | char interface_name[16] = {0}; |
| 13369 | char cmd[128]={'\0'}; |
| 13370 | char buf[128]={'\0'}; |
| 13371 | char *support; |
| 13372 | int maximum_tx = 0, current_tx = 0; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13373 | */ ULONG pwr_percentage = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13374 | |
| 13375 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13376 | if(txpwr_pcntg == NULL) |
| 13377 | return RETURN_ERR; |
| 13378 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13379 | wifi_getRadioTransmitPower(apIndex, &pwr_percentage); |
| 13380 | *txpwr_pcntg = pwr_percentage; |
| 13381 | /* if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13382 | return RETURN_ERR; |
| 13383 | |
| 13384 | // Get the maximum tx power of the device |
| 13385 | snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s status | grep max_txpower | cut -d '=' -f2 | tr -d '\n'", interface_name); |
| 13386 | _syscmd(cmd, buf, sizeof(buf)); |
| 13387 | maximum_tx = strtol(buf, NULL, 10); |
| 13388 | |
| 13389 | // Get the current tx power |
| 13390 | memset(cmd, 0, sizeof(cmd)); |
| 13391 | memset(buf, 0, sizeof(buf)); |
| 13392 | snprintf(cmd, sizeof(cmd), "iw %s info | grep txpower | awk '{print $2}' | cut -d '.' -f1 | tr -d '\\n'", interface_name); |
| 13393 | _syscmd(cmd, buf, sizeof(buf)); |
| 13394 | current_tx = strtol(buf, NULL, 10); |
| 13395 | |
| 13396 | // Get the power supported list and find the current power percentage in supported list |
| 13397 | memset(buf, 0, sizeof(buf)); |
| 13398 | wifi_getRadioTransmitPowerSupported(apIndex, buf); |
| 13399 | support = strtok(buf, ","); |
| 13400 | while(true) |
| 13401 | { |
| 13402 | if(support == NULL) { // current power is not in supported list, this should not happen if the power is set by hal. |
| 13403 | *txpwr_pcntg = 100; |
| 13404 | wifi_dbg_printf("current power is not in supported list\n"); |
| 13405 | return RETURN_OK; |
| 13406 | } |
| 13407 | int tmp = maximum_tx*strtol(support, NULL, 10)/100; |
| 13408 | if (tmp == current_tx) { |
| 13409 | *txpwr_pcntg = strtol(support, NULL, 10); |
| 13410 | break; |
| 13411 | } |
| 13412 | support = strtok(NULL, ","); |
| 13413 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13414 | */ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13415 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13416 | return RETURN_OK; |
| 13417 | } |
| 13418 | |
| 13419 | INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac) |
| 13420 | { |
| 13421 | // TODO precac feature. |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13422 | struct params params[2] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13423 | char config_file[128] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13424 | BOOL dfs_enable = false; |
| 13425 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13426 | |
| 13427 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13428 | band = wifi_index_to_band(radioIndex); |
| 13429 | wifi_getRadioDfsEnable(radioIndex, &dfs_enable); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13430 | |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13431 | if (dfs_enable == false) { |
| 13432 | WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__); |
| 13433 | return RETURN_ERR; |
| 13434 | } |
| 13435 | params[0].name = "DfsZeroWaitDefault"; |
| 13436 | params[0].value = enable?"1":"0"; |
| 13437 | params[1].name = "DfsDedicatedZeroWait"; |
| 13438 | params[1].value = enable?"1":"0"; |
| 13439 | snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13440 | wifi_datfileWrite(config_file, params, 2); |
developer | c0772e6 | 2023-05-18 15:10:48 +0800 | [diff] [blame] | 13441 | wifi_reloadAp(radioIndex); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13442 | /* TODO precac feature */ |
| 13443 | |
| 13444 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13445 | return RETURN_OK; |
| 13446 | } |
| 13447 | |
| 13448 | INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac) |
| 13449 | { |
| 13450 | char config_file[128] = {0}; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13451 | char buf1[32] = {0}; |
| 13452 | char buf2[32] = {0}; |
| 13453 | wifi_band band = band_invalid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13454 | |
| 13455 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13456 | if (NULL == enable || NULL == precac) |
| 13457 | return RETURN_ERR; |
developer | d182445 | 2023-05-18 12:30:04 +0800 | [diff] [blame] | 13458 | band = wifi_index_to_band(radioIndex); |
| 13459 | snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13460 | wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1)); |
| 13461 | wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2)); |
| 13462 | if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0)) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13463 | *enable = true; |
| 13464 | else |
| 13465 | *enable = false; |
| 13466 | |
| 13467 | /* TODO precac feature */ |
| 13468 | |
| 13469 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13470 | return RETURN_OK; |
| 13471 | } |
| 13472 | |
| 13473 | INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported) |
| 13474 | { |
| 13475 | *supported = TRUE; |
| 13476 | return RETURN_OK; |
| 13477 | } |
| 13478 | |
| 13479 | INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type) |
| 13480 | { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13481 | UCHAR dat_file[64] = {0}; |
| 13482 | wifi_band band = band_invalid; |
| 13483 | char cmd[128] = {0}; |
| 13484 | char buf[256] = {0}; |
| 13485 | char ofdmabuf[32] = {'\0'}; |
| 13486 | char mimobuf[32] = {'\0'}; |
| 13487 | char new_ofdmabuf[32] = {'\0'}; |
| 13488 | char new_mimobuf[32] = {'\0'}; |
| 13489 | struct params params[2]; |
| 13490 | char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/ |
| 13491 | char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1"; |
| 13492 | UCHAR bss_cnt = 0; |
| 13493 | UCHAR val_cnt = 0; |
| 13494 | char *token = NULL; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13495 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13496 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13497 | if ((mu_type < WIFI_DL_MU_TYPE_NONE) |
| 13498 | || (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) { |
| 13499 | printf("%s:mu_type input Error", __func__); |
| 13500 | return RETURN_ERR; |
| 13501 | } |
| 13502 | band = wifi_index_to_band(radio_index); |
| 13503 | if (band == band_invalid) { |
| 13504 | printf("%s:Band Error\n", __func__); |
| 13505 | return RETURN_ERR; |
| 13506 | } |
| 13507 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13508 | /*get current value in dat file*/ |
| 13509 | wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf)); |
| 13510 | wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf)); |
| 13511 | WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf); |
| 13512 | get_bssnum_byindex(radio_index, &bss_cnt); |
| 13513 | val_cnt = 2*bss_cnt - 1; |
| 13514 | WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt); |
| 13515 | if ((val_cnt >= sizeof(new_ofdmabuf)) |
| 13516 | || (val_cnt >= sizeof(new_mimobuf))) { |
| 13517 | printf("%s:bss cnt Error", __func__, bss_cnt); |
| 13518 | return RETURN_ERR; |
| 13519 | } |
| 13520 | /*translate set value*/ |
| 13521 | if (mu_type == WIFI_DL_MU_TYPE_NONE) { |
| 13522 | strncpy(new_ofdmabuf, str_zero, val_cnt); |
| 13523 | strncpy(new_mimobuf, str_zero, val_cnt); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13524 | } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13525 | strncpy(new_ofdmabuf, str_one, val_cnt); |
| 13526 | strncpy(new_mimobuf, str_zero, val_cnt); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13527 | } else if (mu_type == WIFI_DL_MU_TYPE_MIMO) { |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13528 | strncpy(new_ofdmabuf, str_zero, val_cnt); |
| 13529 | strncpy(new_mimobuf, str_one, val_cnt); |
| 13530 | } else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) { |
| 13531 | strncpy(new_ofdmabuf, str_one, val_cnt); |
| 13532 | strncpy(new_mimobuf, str_one, val_cnt); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13533 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13534 | WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf); |
| 13535 | /*same value, not operation*/ |
| 13536 | if ((strncmp(new_mimobuf, mimobuf, 1) ==0) |
| 13537 | && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) { |
| 13538 | printf("%s:Reduntant value\n", __func__); |
| 13539 | return RETURN_OK; |
| 13540 | } |
| 13541 | /*modify dat file to new file*/ |
| 13542 | params[0].name="MuOfdmaDlEnable"; |
| 13543 | params[0].value=new_ofdmabuf; |
| 13544 | params[1].name="MuMimoDlEnable"; |
| 13545 | params[1].value=new_mimobuf; |
| 13546 | wifi_datfileWrite(dat_file, params, 2); |
| 13547 | /*hostapd control restarp ap to take effect on these new value*/ |
| 13548 | wifi_reloadAp(radio_index); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13549 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13550 | return RETURN_OK; |
| 13551 | } |
| 13552 | |
| 13553 | INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type) |
| 13554 | { |
| 13555 | struct params params={0}; |
| 13556 | char config_file[64] = {0}; |
| 13557 | char buf[64] = {0}; |
| 13558 | unsigned int get_mu_type = 0; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13559 | UCHAR dat_file[64] = {0}; |
| 13560 | wifi_band band = band_invalid; |
| 13561 | char ofdmabuf[32] = {'\0'}; |
| 13562 | char mimobuf[32] = {'\0'}; |
| 13563 | char *token = NULL; |
| 13564 | UCHAR ofdma = 0; |
| 13565 | UCHAR mimo = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13566 | |
| 13567 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13568 | |
| 13569 | if (mu_type == NULL) |
| 13570 | return RETURN_ERR; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13571 | band = wifi_index_to_band(radio_index); |
| 13572 | if (band == band_invalid) { |
| 13573 | printf("%s:Band Error\n", __func__); |
| 13574 | return RETURN_ERR; |
| 13575 | } |
| 13576 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13577 | /*get current value in dat file*/ |
| 13578 | wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf)); |
| 13579 | wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13580 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13581 | token = strtok(ofdmabuf, ";"); |
| 13582 | ofdma = strtol(token, NULL, 10); |
| 13583 | token = strtok(mimobuf, ";"); |
| 13584 | mimo = strtol(token, NULL, 10); |
| 13585 | WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d,mimo=%d\n", __func__, ofdma, mimo); |
| 13586 | if ((ofdma == 1) && (mimo == 1)) |
| 13587 | *mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO; |
| 13588 | else if ((ofdma == 0) && (mimo == 1)) |
| 13589 | *mu_type = WIFI_DL_MU_TYPE_MIMO; |
| 13590 | else if ((ofdma == 1) && (mimo == 0)) |
| 13591 | *mu_type = WIFI_DL_MU_TYPE_OFDMA; |
| 13592 | else |
| 13593 | *mu_type = WIFI_DL_MU_TYPE_NONE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13594 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13595 | return RETURN_OK; |
| 13596 | } |
| 13597 | |
| 13598 | INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type) |
| 13599 | { |
| 13600 | // hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0)) |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13601 | UCHAR dat_file[64] = {0}; |
| 13602 | wifi_band band = band_invalid; |
| 13603 | char cmd[128] = {0}; |
| 13604 | char buf[256] = {0}; |
| 13605 | char ofdmabuf[32] = {'\0'}; |
| 13606 | char mimobuf[32] = {'\0'}; |
| 13607 | char new_ofdmabuf[32] = {'\0'}; |
| 13608 | char new_mimobuf[32] = {'\0'}; |
| 13609 | struct params params[2]; |
| 13610 | char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/ |
| 13611 | char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1"; |
| 13612 | UCHAR bss_cnt = 0; |
| 13613 | UCHAR val_cnt = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13614 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13615 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13616 | band = wifi_index_to_band(radio_index); |
| 13617 | if (band == band_invalid) { |
| 13618 | printf("%s:Band Error\n", __func__); |
| 13619 | return RETURN_ERR; |
| 13620 | } |
| 13621 | if ((mu_type < WIFI_UL_MU_TYPE_NONE) |
| 13622 | || (mu_type > WIFI_UL_MU_TYPE_OFDMA)) { |
| 13623 | printf("%s:mu_type input Error\n", __func__); |
| 13624 | return RETURN_ERR; |
| 13625 | } |
| 13626 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13627 | /*get current value in dat file*/ |
| 13628 | wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf)); |
| 13629 | wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf)); |
| 13630 | WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf); |
| 13631 | get_bssnum_byindex(radio_index, &bss_cnt); |
| 13632 | val_cnt = 2*bss_cnt - 1; |
| 13633 | printf("bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt); |
| 13634 | if ((val_cnt >= sizeof(new_ofdmabuf)) |
| 13635 | || (val_cnt >= sizeof(new_mimobuf))) { |
| 13636 | printf("%s:bss cnt Error\n", __func__, val_cnt); |
| 13637 | return RETURN_ERR; |
| 13638 | } |
| 13639 | /*translate set value*/ |
| 13640 | if (mu_type == WIFI_UL_MU_TYPE_NONE) { |
| 13641 | strncpy(new_ofdmabuf, str_zero, val_cnt); |
| 13642 | strncpy(new_mimobuf, str_zero, val_cnt); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13643 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13644 | if (mu_type == WIFI_UL_MU_TYPE_OFDMA) { |
| 13645 | strncpy(new_ofdmabuf, str_one, val_cnt); |
| 13646 | strncpy(new_mimobuf, str_zero, val_cnt); |
| 13647 | } |
| 13648 | printf("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf); |
| 13649 | /*same value, not operation*/ |
| 13650 | if ((strncmp(new_mimobuf, mimobuf, 1) ==0) |
| 13651 | && (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) { |
| 13652 | printf("%s:Reduntant value\n", __func__); |
| 13653 | return RETURN_OK; |
| 13654 | } |
| 13655 | /*modify dat file to new file*/ |
| 13656 | params[0].name="MuOfdmaUlEnable"; |
| 13657 | params[0].value=new_ofdmabuf; |
| 13658 | params[1].name="MuMimoUlEnable"; |
| 13659 | params[1].value=new_mimobuf; |
| 13660 | wifi_datfileWrite(dat_file, params, 2); |
| 13661 | wifi_reloadAp(radio_index); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13662 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13663 | return RETURN_OK; |
| 13664 | } |
| 13665 | |
| 13666 | INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type) |
| 13667 | { |
| 13668 | struct params params={0}; |
| 13669 | char config_file[64] = {0}; |
| 13670 | char buf[64] = {0}; |
| 13671 | unsigned int get_mu_type = 0; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13672 | UCHAR dat_file[64] = {0}; |
| 13673 | wifi_band band = band_invalid; |
| 13674 | char ofdmabuf[32] = {'\0'}; |
| 13675 | char mimobuf[32] = {'\0'}; |
| 13676 | char *token = NULL; |
| 13677 | UCHAR ofdma = 0; |
| 13678 | UCHAR mimo = 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13679 | |
| 13680 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13681 | |
| 13682 | if (mu_type == NULL) |
| 13683 | return RETURN_ERR; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13684 | band = wifi_index_to_band(radio_index); |
| 13685 | if (band == band_invalid) { |
| 13686 | printf("%s:Band Error", __func__); |
| 13687 | return RETURN_ERR; |
| 13688 | } |
| 13689 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13690 | /*get current value in dat file*/ |
| 13691 | wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf)); |
| 13692 | wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13693 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13694 | token = strtok(ofdmabuf, ";"); |
| 13695 | ofdma = strtol(token, NULL, 10); |
| 13696 | token = strtok(mimobuf, ";"); |
| 13697 | mimo = strtol(token, NULL, 10); |
| 13698 | WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo); |
| 13699 | if ((ofdma == 1) && (mimo == 0)) |
| 13700 | *mu_type = WIFI_UL_MU_TYPE_OFDMA; |
| 13701 | else |
| 13702 | *mu_type = WIFI_UL_MU_TYPE_NONE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13703 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13704 | return RETURN_OK; |
| 13705 | } |
| 13706 | |
| 13707 | |
| 13708 | INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval) |
| 13709 | { |
| 13710 | char cmd[128] = {0}; |
| 13711 | char buf[256] = {0}; |
| 13712 | char config_file[64] = {0}; |
| 13713 | char GI[8] = {0}; |
| 13714 | int mode_map = 0; |
| 13715 | FILE *f = NULL; |
| 13716 | wifi_band band = band_invalid; |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13717 | char dat_file[64] = {'\0'}; |
| 13718 | struct params params[3]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13719 | |
| 13720 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13721 | |
| 13722 | if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) { |
| 13723 | wifi_dbg_printf("%s: wifi_getRadioMode return error\n", __func__); |
| 13724 | return RETURN_ERR; |
| 13725 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13726 | /*sanity check*/ |
| 13727 | if (((guard_interval == wifi_guard_interval_1600) |
| 13728 | || (guard_interval == wifi_guard_interval_3200)) |
| 13729 | && (mode_map & (WIFI_MODE_BE | WIFI_MODE_AX) == 0)) { |
| 13730 | wifi_dbg_printf("%s: N/AC Mode not support 1600/3200ns GI\n", __func__); |
| 13731 | return RETURN_ERR; |
| 13732 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13733 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 13734 | band = wifi_index_to_band(radio_index); |
| 13735 | |
| 13736 | // Hostapd are not supported HE mode GI 1600, 3200 ns. |
| 13737 | if (guard_interval == wifi_guard_interval_800) { // remove all capab about short GI |
| 13738 | snprintf(cmd, sizeof(cmd), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file); |
| 13739 | _syscmd(cmd, buf, sizeof(buf)); |
| 13740 | } else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){ |
| 13741 | wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf)); |
| 13742 | if (strstr(buf, "[SHORT-GI-") == NULL) { |
| 13743 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file); |
| 13744 | _syscmd(cmd, buf, sizeof(buf)); |
| 13745 | } |
| 13746 | if (band == band_5) { |
| 13747 | wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf)); |
| 13748 | if (strstr(buf, "[SHORT-GI-") == NULL) { |
| 13749 | snprintf(cmd, sizeof(cmd), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file); |
| 13750 | _syscmd(cmd, buf, sizeof(buf)); |
| 13751 | } |
| 13752 | } |
| 13753 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13754 | /*wifi_reloadAp(radio_index); |
| 13755 | caller "wifi_setRadioOperatingParameters" have done this step. |
| 13756 | */ |
| 13757 | snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band); |
| 13758 | if (guard_interval == wifi_guard_interval_400) { |
| 13759 | params[0].name = "HT_GI"; |
| 13760 | params[0].value = "1"; |
| 13761 | params[1].name = "VHT_SGI"; |
| 13762 | params[1].value = "1"; |
| 13763 | wifi_datfileWrite(dat_file, params, 2); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13764 | strcpy(GI, "0.4"); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13765 | } else { |
| 13766 | params[0].name = "HT_GI"; |
| 13767 | params[0].value = "0"; |
| 13768 | params[1].name = "VHT_SGI"; |
| 13769 | params[1].value = "0"; |
| 13770 | /*should enable FIXED_HE_GI_SUPPORT in driver*/ |
| 13771 | params[2].name = "FgiFltf"; |
| 13772 | if (guard_interval == wifi_guard_interval_800) { |
| 13773 | params[2].value = "800"; |
| 13774 | strcpy(GI, "0.8"); |
| 13775 | } else if (guard_interval == wifi_guard_interval_1600) { |
| 13776 | params[2].value = "1600"; |
| 13777 | strcpy(GI, "1.6"); |
| 13778 | } else if (guard_interval == wifi_guard_interval_3200) { |
| 13779 | params[2].value = "3200"; |
| 13780 | strcpy(GI, "3.2"); |
| 13781 | } else if (guard_interval == wifi_guard_interval_auto) { |
| 13782 | params[2].value = "0"; |
| 13783 | strcpy(GI, "auto"); |
| 13784 | } |
| 13785 | wifi_datfileWrite(dat_file, params, 3); |
| 13786 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13787 | // Record GI for get GI function |
| 13788 | snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index); |
| 13789 | f = fopen(buf, "w"); |
| 13790 | if (f == NULL) |
| 13791 | return RETURN_ERR; |
| 13792 | fprintf(f, "%s", GI); |
| 13793 | fclose(f); |
| 13794 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13795 | return RETURN_OK; |
| 13796 | } |
| 13797 | |
| 13798 | INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval) |
| 13799 | { |
| 13800 | char buf[32] = {0}; |
| 13801 | char cmd[64] = {0}; |
| 13802 | |
| 13803 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13804 | |
| 13805 | if (guard_interval == NULL) |
| 13806 | return RETURN_ERR; |
| 13807 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13808 | snprintf(cmd, sizeof(cmd), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13809 | _syscmd(cmd, buf, sizeof(buf)); |
| 13810 | |
| 13811 | if (strncmp(buf, "0.4", 3) == 0) |
| 13812 | *guard_interval = wifi_guard_interval_400; |
| 13813 | else if (strncmp(buf, "0.8", 3) == 0) |
| 13814 | *guard_interval = wifi_guard_interval_800; |
| 13815 | else if (strncmp(buf, "1.6", 3) == 0) |
| 13816 | *guard_interval = wifi_guard_interval_1600; |
| 13817 | else if (strncmp(buf, "3.2", 3) == 0) |
| 13818 | *guard_interval = wifi_guard_interval_3200; |
| 13819 | else |
| 13820 | *guard_interval = wifi_guard_interval_auto; |
| 13821 | |
| 13822 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13823 | return RETURN_OK; |
| 13824 | } |
| 13825 | |
| 13826 | INT wifi_setBSSColor(INT radio_index, UCHAR color) |
| 13827 | { |
| 13828 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 13829 | struct params params = {0}; |
| 13830 | char config_file[128] = {0}; |
| 13831 | char bss_color[4] ={0}; |
| 13832 | |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13833 | if (color < 1 || color > 63) { |
| 13834 | wifi_dbg_printf("color value is err:%d.\n", color); |
| 13835 | return RETURN_ERR; |
| 13836 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13837 | params.name = "he_bss_color"; |
| 13838 | snprintf(bss_color, sizeof(bss_color), "%hhu", color); |
| 13839 | params.value = bss_color; |
| 13840 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 13841 | wifi_hostapdWrite(config_file, ¶ms, 1); |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 13842 | //wifi_hostapdProcessUpdate(radio_index, ¶ms, 1); |
| 13843 | wifi_reloadAp(radio_index); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 13844 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 13845 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 13846 | return RETURN_OK; |
| 13847 | } |
| 13848 | |
| 13849 | INT wifi_getBSSColor(INT radio_index, UCHAR *color) |
| 13850 | { |
| 13851 | char config_file[128] = {0}; |
| 13852 | char buf[64] = {0}; |
| 13853 | char temp_output[128] = {'\0'}; |
| 13854 | |
| 13855 | wifi_dbg_printf("\nFunc=%s\n", __func__); |
| 13856 | if (NULL == color) |
| 13857 | return RETURN_ERR; |
| 13858 | |
| 13859 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radio_index); |
| 13860 | wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf)); |
| 13861 | |
| 13862 | if(strlen(buf) > 0) { |
| 13863 | snprintf(temp_output, sizeof(temp_output), "%s", buf); |
| 13864 | } else { |
| 13865 | snprintf(temp_output, sizeof(temp_output), "1"); // default value |
| 13866 | } |
| 13867 | |
| 13868 | *color = (UCHAR)strtoul(temp_output, NULL, 10); |
| 13869 | wifi_dbg_printf("\noutput_string=%s\n", color); |
| 13870 | |
| 13871 | return RETURN_OK; |
| 13872 | } |
| 13873 | |
| 13874 | /* multi-psk support */ |
| 13875 | INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key) |
| 13876 | { |
| 13877 | char cmd[256]; |
| 13878 | char interface_name[16] = {0}; |
| 13879 | |
| 13880 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 13881 | return RETURN_ERR; |
| 13882 | |
| 13883 | sprintf(cmd, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'", |
| 13884 | interface_name, |
| 13885 | mac[0], |
| 13886 | mac[1], |
| 13887 | mac[2], |
| 13888 | mac[3], |
| 13889 | mac[4], |
| 13890 | mac[5] |
| 13891 | ); |
| 13892 | printf("DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd); |
| 13893 | _syscmd(cmd, key->wifi_keyId, 64); |
| 13894 | |
| 13895 | |
| 13896 | return RETURN_OK; |
| 13897 | } |
| 13898 | |
| 13899 | INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber) |
| 13900 | { |
| 13901 | char interface_name[16] = {0}; |
| 13902 | FILE *fd = NULL; |
| 13903 | char fname[100]; |
| 13904 | char cmd[128] = {0}; |
| 13905 | char out[64] = {0}; |
| 13906 | wifi_key_multi_psk_t * key = NULL; |
| 13907 | if(keysNumber < 0) |
| 13908 | return RETURN_ERR; |
| 13909 | |
| 13910 | snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex); |
| 13911 | fd = fopen(fname, "w"); |
| 13912 | if (!fd) { |
| 13913 | return RETURN_ERR; |
| 13914 | } |
| 13915 | key= (wifi_key_multi_psk_t *) keys; |
| 13916 | for(int i=0; i<keysNumber; ++i, key++) { |
| 13917 | fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk); |
| 13918 | } |
| 13919 | fclose(fd); |
| 13920 | |
| 13921 | //reload file |
| 13922 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 13923 | return RETURN_ERR; |
| 13924 | sprintf(cmd, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name); |
| 13925 | _syscmd(cmd, out, 64); |
| 13926 | return RETURN_OK; |
| 13927 | } |
| 13928 | |
| 13929 | INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber) |
| 13930 | { |
| 13931 | FILE *fd = NULL; |
| 13932 | char fname[100]; |
| 13933 | char * line = NULL; |
| 13934 | char * pos = NULL; |
| 13935 | size_t len = 0; |
| 13936 | ssize_t read = 0; |
| 13937 | INT ret = RETURN_OK; |
| 13938 | wifi_key_multi_psk_t *keys_it = NULL; |
| 13939 | |
| 13940 | if (keysNumber < 1) { |
| 13941 | return RETURN_ERR; |
| 13942 | } |
| 13943 | |
| 13944 | snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex); |
| 13945 | fd = fopen(fname, "r"); |
| 13946 | if (!fd) { |
| 13947 | return RETURN_ERR; |
| 13948 | } |
| 13949 | |
| 13950 | if (keys == NULL) { |
| 13951 | ret = RETURN_ERR; |
| 13952 | goto close; |
| 13953 | } |
| 13954 | |
| 13955 | keys_it = keys; |
| 13956 | while ((read = getline(&line, &len, fd)) != -1) { |
| 13957 | //Strip trailing new line if present |
| 13958 | if (read > 0 && line[read-1] == '\n') { |
| 13959 | line[read-1] = '\0'; |
| 13960 | } |
| 13961 | |
| 13962 | if(strcmp(line,"keyid=")) { |
| 13963 | sscanf(line, "keyid=%s", &(keys_it->wifi_keyId)); |
| 13964 | if (!(pos = index(line, ' '))) { |
| 13965 | ret = RETURN_ERR; |
| 13966 | goto close; |
| 13967 | } |
| 13968 | pos++; |
| 13969 | //Here should be 00:00:00:00:00:00 |
| 13970 | if (!(strcmp(pos,"00:00:00:00:00:00"))) { |
| 13971 | printf("Not supported MAC: %s\n", pos); |
| 13972 | } |
| 13973 | if (!(pos = index(pos, ' '))) { |
| 13974 | ret = RETURN_ERR; |
| 13975 | goto close; |
| 13976 | } |
| 13977 | pos++; |
| 13978 | |
| 13979 | //The rest is PSK |
| 13980 | snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos); |
| 13981 | keys_it++; |
| 13982 | |
| 13983 | if(--keysNumber <= 0) |
| 13984 | break; |
| 13985 | } |
| 13986 | } |
| 13987 | |
| 13988 | close: |
| 13989 | free(line); |
| 13990 | fclose(fd); |
| 13991 | return ret; |
| 13992 | } |
| 13993 | /* end of multi-psk support */ |
| 13994 | |
| 13995 | INT wifi_setNeighborReports(UINT apIndex, |
| 13996 | UINT numNeighborReports, |
| 13997 | wifi_NeighborReport_t *neighborReports) |
| 13998 | { |
| 13999 | char cmd[256] = { 0 }; |
| 14000 | char hex_bssid[13] = { 0 }; |
| 14001 | char bssid[18] = { 0 }; |
| 14002 | char nr[256] = { 0 }; |
| 14003 | char ssid[256]; |
| 14004 | char hex_ssid[256]; |
| 14005 | char interface_name[16] = {0}; |
| 14006 | INT ret; |
| 14007 | |
| 14008 | /*rmeove all neighbors*/ |
| 14009 | wifi_dbg_printf("\n[%s]: removing all neighbors from %s\n", __func__, interface_name); |
| 14010 | if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) |
| 14011 | return RETURN_ERR; |
| 14012 | sprintf(cmd, "hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",interface_name,interface_name); |
| 14013 | system(cmd); |
| 14014 | |
| 14015 | for(unsigned int i = 0; i < numNeighborReports; i++) |
| 14016 | { |
| 14017 | memset(ssid, 0, sizeof(ssid)); |
| 14018 | ret = wifi_getSSIDName(apIndex, ssid); |
| 14019 | if (ret != RETURN_OK) |
| 14020 | return RETURN_ERR; |
| 14021 | |
| 14022 | memset(hex_ssid, 0, sizeof(hex_ssid)); |
| 14023 | for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 ) |
| 14024 | sprintf(hex_ssid + k,"%02x", ssid[j]); |
| 14025 | |
| 14026 | snprintf(hex_bssid, sizeof(hex_bssid), |
| 14027 | "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx", |
| 14028 | neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]); |
| 14029 | snprintf(bssid, sizeof(bssid), |
| 14030 | "%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx", |
| 14031 | neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]); |
| 14032 | |
| 14033 | snprintf(nr, sizeof(nr), |
| 14034 | "%s" // bssid |
| 14035 | "%02hhx%02hhx%02hhx%02hhx" // bssid_info |
| 14036 | "%02hhx" // operclass |
| 14037 | "%02hhx" // channel |
| 14038 | "%02hhx", // phy_mode |
| 14039 | hex_bssid, |
| 14040 | neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff, |
| 14041 | (neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff, |
| 14042 | neighborReports[i].opClass, |
| 14043 | neighborReports[i].channel, |
| 14044 | neighborReports[i].phyTable); |
| 14045 | |
| 14046 | snprintf(cmd, sizeof(cmd), |
| 14047 | "hostapd_cli set_neighbor " |
| 14048 | "%s " // bssid |
| 14049 | "ssid=%s " // ssid |
| 14050 | "nr=%s " // nr |
| 14051 | "-i %s", |
| 14052 | bssid,hex_ssid,nr, interface_name); |
| 14053 | |
| 14054 | if (WEXITSTATUS(system(cmd)) != 0) |
| 14055 | { |
| 14056 | wifi_dbg_printf("\n[%s]: %s failed",__func__,cmd); |
| 14057 | } |
| 14058 | } |
| 14059 | |
| 14060 | return RETURN_OK; |
| 14061 | } |
| 14062 | |
| 14063 | INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct) |
| 14064 | { |
| 14065 | return RETURN_OK; |
| 14066 | } |
| 14067 | |
| 14068 | #ifdef _WIFI_HAL_TEST_ |
| 14069 | int main(int argc,char **argv) |
| 14070 | { |
| 14071 | int index; |
| 14072 | INT ret=0; |
| 14073 | char buf[1024]=""; |
| 14074 | |
| 14075 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 14076 | if(argc<3) |
| 14077 | { |
| 14078 | if(argc==2) |
| 14079 | { |
| 14080 | if(!strcmp(argv[1], "init")) |
| 14081 | return wifi_init(); |
| 14082 | if(!strcmp(argv[1], "reset")) |
| 14083 | return wifi_reset(); |
| 14084 | if(!strcmp(argv[1], "wifi_getHalVersion")) |
| 14085 | { |
| 14086 | char buffer[64]; |
| 14087 | if(wifi_getHalVersion(buffer)==RETURN_OK) |
| 14088 | printf("Version: %s\n", buffer); |
| 14089 | else |
| 14090 | printf("Error in wifi_getHalVersion\n"); |
| 14091 | return RETURN_OK; |
| 14092 | } |
| 14093 | } |
| 14094 | printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n"); |
| 14095 | exit(-1); |
| 14096 | } |
| 14097 | |
| 14098 | index = atoi(argv[2]); |
| 14099 | if(strstr(argv[1], "wifi_getApName")!=NULL) |
| 14100 | { |
| 14101 | wifi_getApName(index,buf); |
| 14102 | printf("Ap name is %s \n",buf); |
| 14103 | return 0; |
| 14104 | } |
developer | fead397 | 2023-05-25 20:15:02 +0800 | [diff] [blame] | 14105 | if(strstr(argv[1], "wifi_setRadioMode")!=NULL) |
| 14106 | { |
| 14107 | UINT pureMode = atoi(argv[3]); |
| 14108 | |
| 14109 | wifi_setRadioMode(index, NULL, pureMode); |
| 14110 | printf("Ap SET Radio mode 0x%x\n", pureMode); |
| 14111 | return 0; |
| 14112 | } |
| 14113 | if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL) |
| 14114 | { |
| 14115 | ULONG TransmitPower = atoi(argv[3]); |
| 14116 | |
| 14117 | wifi_setRadioTransmitPower(index, TransmitPower); |
| 14118 | printf("Ap SET TransmitPower %lu\n", TransmitPower); |
| 14119 | return 0; |
| 14120 | } |
| 14121 | if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL) |
| 14122 | { |
| 14123 | INT TransmitPower = atoi(argv[3]); |
| 14124 | |
| 14125 | wifi_setApManagementFramePowerControl(index, TransmitPower); |
| 14126 | printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower); |
| 14127 | return 0; |
| 14128 | } |
| 14129 | if(strstr(argv[1], "wifi_setRadioBW")!=NULL) |
| 14130 | { |
| 14131 | CHAR *bandwith = argv[3]; |
| 14132 | |
| 14133 | wifi_setRadioOperatingChannelBandwidth(index, bandwith); |
| 14134 | printf("Ap SET bw %s\n", bandwith); |
| 14135 | return 0; |
| 14136 | } |
| 14137 | if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL) |
| 14138 | { |
| 14139 | wifi_factoryResetRadio(index); |
| 14140 | printf("wifi_factoryResetRadio ok!\n"); |
| 14141 | return 0; |
| 14142 | } |
| 14143 | if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL) |
| 14144 | { |
| 14145 | ULONG rst_cnt; |
| 14146 | wifi_getRadioResetCount(index, &rst_cnt); |
| 14147 | printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt); |
| 14148 | return 0; |
| 14149 | } |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 14150 | if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) { |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 14151 | if(argc <= 3 ) |
| 14152 | { |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 14153 | wifi_debug(DEBUG_ERROR, "Insufficient arguments \n"); |
developer | 49b1723 | 2023-05-19 16:35:19 +0800 | [diff] [blame] | 14154 | exit(-1); |
| 14155 | } |
| 14156 | wifi_addApAclDevice(index, argv[3]); |
| 14157 | return 0; |
| 14158 | } |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 14159 | if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) { |
| 14160 | wifi_getApAclDevices(index, buf, 1024); |
| 14161 | wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf); |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 14162 | return 0; |
| 14163 | } |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 14164 | if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) { |
| 14165 | if(argc <= 3 ) |
| 14166 | { |
| 14167 | wifi_debug(DEBUG_ERROR, "Insufficient arguments \n"); |
| 14168 | exit(-1); |
| 14169 | } |
| 14170 | wifi_delApAclDevice(index, argv[3]); |
| 14171 | return 0; |
| 14172 | } |
| 14173 | if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) { |
| 14174 | wifi_delApAclDevices(index); |
| 14175 | return 0; |
| 14176 | } |
| 14177 | if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) { |
| 14178 | int acl_num = 0; |
| 14179 | wifi_getApAclDeviceNum(index, &acl_num); |
| 14180 | wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num); |
| 14181 | return 0; |
| 14182 | } |
| 14183 | if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) { |
| 14184 | wifi_getApDenyAclDevices(index, buf, 1024); |
| 14185 | wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf); |
| 14186 | return 0; |
| 14187 | } |
| 14188 | if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) { |
| 14189 | int filter_mode = 0; |
| 14190 | if(argc <= 3 ) |
| 14191 | { |
| 14192 | wifi_debug(DEBUG_ERROR, "Insufficient arguments \n"); |
| 14193 | exit(-1); |
| 14194 | } |
| 14195 | filter_mode = atoi(argv[3]); |
| 14196 | wifi_setApMacAddressControlMode(index,filter_mode); |
| 14197 | return 0; |
| 14198 | } |
developer | 5cd4c86 | 2023-05-26 09:34:42 +0800 | [diff] [blame] | 14199 | if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) { |
| 14200 | BOOL output_bool = 0; |
| 14201 | wifi_getRadioDeclineBARequestEnable(index, &output_bool); |
| 14202 | wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool); |
| 14203 | return 0; |
| 14204 | } |
| 14205 | if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) { |
| 14206 | BOOL output_bool = 0; |
| 14207 | wifi_getRadioAutoBlockAckEnable(index, &output_bool); |
| 14208 | wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool); |
| 14209 | return 0; |
| 14210 | } |
| 14211 | |
| 14212 | if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) { |
| 14213 | int filter_mode = 0; |
| 14214 | wifi_getApMacAddressControlMode(index, &filter_mode); |
| 14215 | wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode); |
| 14216 | return 0; |
| 14217 | } |
| 14218 | if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) { |
| 14219 | int enable = 0; |
| 14220 | if(argc <= 3 ) |
| 14221 | { |
| 14222 | wifi_debug(DEBUG_ERROR, "Insufficient arguments \n"); |
| 14223 | exit(-1); |
| 14224 | } |
| 14225 | enable = (BOOL)atoi(argv[3]); |
| 14226 | wifi_setRadioIGMPSnoopingEnable(index, enable); |
| 14227 | wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable); |
| 14228 | return 0; |
| 14229 | } |
| 14230 | |
| 14231 | if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) { |
| 14232 | BOOL out_status = 0; |
| 14233 | wifi_getRadioIGMPSnoopingEnable(index, &out_status); |
| 14234 | wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status); |
| 14235 | return 0; |
| 14236 | } |
developer | 121a8e7 | 2023-05-22 09:19:39 +0800 | [diff] [blame] | 14237 | |
developer | 95c045d | 2023-05-24 19:26:28 +0800 | [diff] [blame] | 14238 | if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) { |
| 14239 | int enable = 0; |
| 14240 | if(argc <= 3) |
| 14241 | { |
| 14242 | wifi_debug(DEBUG_ERROR, "Insufficient arguments \n"); |
| 14243 | exit(-1); |
| 14244 | } |
| 14245 | enable = atoi(argv[3]); |
| 14246 | wifi_setApWmmEnable(index,enable); |
| 14247 | return 0; |
| 14248 | } |
| 14249 | |
| 14250 | if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) { |
| 14251 | BOOL enable = 0; |
| 14252 | |
| 14253 | wifi_getApWMMCapability(index, &enable); |
| 14254 | wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable); |
| 14255 | return 0; |
| 14256 | } |
| 14257 | |
| 14258 | if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) { |
| 14259 | BOOL enable = 0; |
| 14260 | |
| 14261 | wifi_getApWmmEnable(index, &enable); |
| 14262 | wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable); |
| 14263 | return 0; |
| 14264 | } |
| 14265 | |
developer | 2edaf01 | 2023-05-24 14:24:53 +0800 | [diff] [blame] | 14266 | if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) { |
| 14267 | int filter_mode = 0; |
| 14268 | wifi_getApMacAddressControlMode(index, &filter_mode); |
| 14269 | wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode); |
| 14270 | return 0; |
| 14271 | } |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 14272 | if(strstr(argv[1], "wifi_getRadioMode")!=NULL) |
| 14273 | { |
| 14274 | int mode = 0; |
| 14275 | |
| 14276 | wifi_getRadioMode(index, buf, &mode); |
| 14277 | printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode); |
| 14278 | return 0; |
| 14279 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14280 | if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL) |
| 14281 | { |
| 14282 | BOOL b = FALSE; |
| 14283 | BOOL *output_bool = &b; |
| 14284 | wifi_getRadioAutoChannelEnable(index,output_bool); |
| 14285 | printf("Channel enabled = %d \n",b); |
| 14286 | return 0; |
| 14287 | } |
| 14288 | if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL) |
| 14289 | { |
| 14290 | wifi_getApWpaEncryptionMode(index,buf); |
| 14291 | printf("encryption enabled = %s\n",buf); |
| 14292 | return 0; |
| 14293 | } |
| 14294 | if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL) |
| 14295 | { |
| 14296 | BOOL b = FALSE; |
| 14297 | BOOL *output_bool = &b; |
| 14298 | wifi_getApSsidAdvertisementEnable(index,output_bool); |
| 14299 | printf("advertisment enabled = %d\n",b); |
| 14300 | return 0; |
| 14301 | } |
| 14302 | if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL) |
| 14303 | { |
| 14304 | if(argc <= 3 ) |
| 14305 | { |
| 14306 | printf("Insufficient arguments \n"); |
| 14307 | exit(-1); |
| 14308 | } |
| 14309 | |
| 14310 | char sta[20] = {'\0'}; |
| 14311 | ULLONG handle= 0; |
| 14312 | strcpy(sta,argv[3]); |
| 14313 | mac_address_t st; |
| 14314 | mac_addr_aton(st,sta); |
| 14315 | |
| 14316 | wifi_associated_dev_tid_stats_t tid_stats; |
| 14317 | wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle); |
| 14318 | for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats |
| 14319 | printf(" tid=%d \t ac=%d \t num_msdus=%lld \n" ,tid_stats.tid_array[tid_index].tid,tid_stats.tid_array[tid_index].ac,tid_stats.tid_array[tid_index].num_msdus); |
| 14320 | } |
| 14321 | |
| 14322 | if(strstr(argv[1], "getApEnable")!=NULL) { |
| 14323 | BOOL enable; |
| 14324 | ret=wifi_getApEnable(index, &enable); |
| 14325 | printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret); |
| 14326 | } |
| 14327 | else if(strstr(argv[1], "setApEnable")!=NULL) { |
| 14328 | BOOL enable = atoi(argv[3]); |
| 14329 | ret=wifi_setApEnable(index, enable); |
| 14330 | printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret); |
| 14331 | } |
| 14332 | else if(strstr(argv[1], "getApStatus")!=NULL) { |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 14333 | char status[64]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14334 | ret=wifi_getApStatus(index, status); |
| 14335 | printf("%s %d: %s, returns %d\n", argv[1], index, status, ret); |
| 14336 | } |
| 14337 | else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL) |
| 14338 | { |
| 14339 | wifi_getSSIDNameStatus(index,buf); |
| 14340 | printf("%s %d: active ssid : %s\n",argv[1], index,buf); |
| 14341 | return 0; |
developer | 2202b33 | 2023-05-24 16:23:22 +0800 | [diff] [blame] | 14342 | } else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) { |
| 14343 | wifi_resetApVlanCfg(index); |
| 14344 | printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf); |
| 14345 | return 0; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14346 | } |
| 14347 | else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) { |
| 14348 | wifi_ssidTrafficStats2_t stats={0}; |
| 14349 | ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181 |
| 14350 | printf("%s %d: returns %d\n", argv[1], index, ret); |
| 14351 | printf(" ssid_BytesSent =%lu\n", stats.ssid_BytesSent); |
| 14352 | printf(" ssid_BytesReceived =%lu\n", stats.ssid_BytesReceived); |
| 14353 | printf(" ssid_PacketsSent =%lu\n", stats.ssid_PacketsSent); |
| 14354 | printf(" ssid_PacketsReceived =%lu\n", stats.ssid_PacketsReceived); |
| 14355 | printf(" ssid_RetransCount =%lu\n", stats.ssid_RetransCount); |
| 14356 | printf(" ssid_FailedRetransCount =%lu\n", stats.ssid_FailedRetransCount); |
| 14357 | printf(" ssid_RetryCount =%lu\n", stats.ssid_RetryCount); |
| 14358 | printf(" ssid_MultipleRetryCount =%lu\n", stats.ssid_MultipleRetryCount); |
| 14359 | printf(" ssid_ACKFailureCount =%lu\n", stats.ssid_ACKFailureCount); |
| 14360 | printf(" ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount); |
| 14361 | printf(" ssid_ErrorsSent =%lu\n", stats.ssid_ErrorsSent); |
| 14362 | printf(" ssid_ErrorsReceived =%lu\n", stats.ssid_ErrorsReceived); |
| 14363 | printf(" ssid_UnicastPacketsSent =%lu\n", stats.ssid_UnicastPacketsSent); |
| 14364 | printf(" ssid_UnicastPacketsReceived =%lu\n", stats.ssid_UnicastPacketsReceived); |
| 14365 | printf(" ssid_DiscardedPacketsSent =%lu\n", stats.ssid_DiscardedPacketsSent); |
| 14366 | printf(" ssid_DiscardedPacketsReceived =%lu\n", stats.ssid_DiscardedPacketsReceived); |
| 14367 | printf(" ssid_MulticastPacketsSent =%lu\n", stats.ssid_MulticastPacketsSent); |
| 14368 | printf(" ssid_MulticastPacketsReceived =%lu\n", stats.ssid_MulticastPacketsReceived); |
| 14369 | printf(" ssid_BroadcastPacketsSent =%lu\n", stats.ssid_BroadcastPacketsSent); |
| 14370 | printf(" ssid_BroadcastPacketsRecevied =%lu\n", stats.ssid_BroadcastPacketsRecevied); |
| 14371 | printf(" ssid_UnknownPacketsReceived =%lu\n", stats.ssid_UnknownPacketsReceived); |
| 14372 | } |
| 14373 | else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) { |
| 14374 | wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL; |
| 14375 | UINT array_size=0; |
| 14376 | UINT i=0; |
| 14377 | ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size); |
| 14378 | printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 14379 | for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14380 | printf(" neighbor %d:\n", i); |
| 14381 | printf(" ap_SSID =%s\n", pt->ap_SSID); |
| 14382 | printf(" ap_BSSID =%s\n", pt->ap_BSSID); |
| 14383 | printf(" ap_Mode =%s\n", pt->ap_Mode); |
| 14384 | printf(" ap_Channel =%d\n", pt->ap_Channel); |
| 14385 | printf(" ap_SignalStrength =%d\n", pt->ap_SignalStrength); |
| 14386 | printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled); |
| 14387 | printf(" ap_EncryptionMode =%s\n", pt->ap_EncryptionMode); |
| 14388 | printf(" ap_SupportedStandards =%s\n", pt->ap_SupportedStandards); |
| 14389 | printf(" ap_OperatingStandards =%s\n", pt->ap_OperatingStandards); |
| 14390 | printf(" ap_OperatingChannelBandwidth =%s\n", pt->ap_OperatingChannelBandwidth); |
| 14391 | printf(" ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled); |
| 14392 | printf(" ap_BeaconPeriod =%d\n", pt->ap_BeaconPeriod); |
| 14393 | printf(" ap_Noise =%d\n", pt->ap_Noise); |
| 14394 | printf(" ap_BasicDataTransferRates =%s\n", pt->ap_BasicDataTransferRates); |
| 14395 | printf(" ap_SupportedDataTransferRates =%s\n", pt->ap_SupportedDataTransferRates); |
| 14396 | printf(" ap_DTIMPeriod =%d\n", pt->ap_DTIMPeriod); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 14397 | printf(" ap_ChannelUtilization =%d\n", pt->ap_ChannelUtilization); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14398 | } |
| 14399 | if(neighbor_ap_array) |
| 14400 | free(neighbor_ap_array); //make sure to free the list |
| 14401 | } |
| 14402 | else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) { |
| 14403 | wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL; |
| 14404 | UINT array_size=0; |
| 14405 | UINT i=0; |
| 14406 | ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size); |
| 14407 | printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 14408 | for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14409 | printf(" associated_dev %d:\n", i); |
| 14410 | printf(" cli_OperatingStandard =%s\n", pt->cli_OperatingStandard); |
| 14411 | printf(" cli_OperatingChannelBandwidth =%s\n", pt->cli_OperatingChannelBandwidth); |
| 14412 | printf(" cli_SNR =%d\n", pt->cli_SNR); |
| 14413 | printf(" cli_InterferenceSources =%s\n", pt->cli_InterferenceSources); |
| 14414 | printf(" cli_DataFramesSentAck =%lu\n", pt->cli_DataFramesSentAck); |
| 14415 | printf(" cli_DataFramesSentNoAck =%lu\n", pt->cli_DataFramesSentNoAck); |
| 14416 | printf(" cli_BytesSent =%lu\n", pt->cli_BytesSent); |
| 14417 | printf(" cli_BytesReceived =%lu\n", pt->cli_BytesReceived); |
| 14418 | printf(" cli_RSSI =%d\n", pt->cli_RSSI); |
| 14419 | printf(" cli_MinRSSI =%d\n", pt->cli_MinRSSI); |
| 14420 | printf(" cli_MaxRSSI =%d\n", pt->cli_MaxRSSI); |
| 14421 | printf(" cli_Disassociations =%d\n", pt->cli_Disassociations); |
| 14422 | printf(" cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures); |
| 14423 | } |
| 14424 | if(associated_dev_array) |
| 14425 | free(associated_dev_array); //make sure to free the list |
| 14426 | } |
| 14427 | |
| 14428 | if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL) |
| 14429 | { |
| 14430 | #define MAX_ARRAY_SIZE 64 |
| 14431 | int i, array_size; |
| 14432 | char *p, *ch_str; |
| 14433 | wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE]; |
| 14434 | |
| 14435 | if(argc != 5) |
| 14436 | { |
| 14437 | printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n"); |
| 14438 | exit(-1); |
| 14439 | } |
| 14440 | memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array)); |
| 14441 | |
| 14442 | for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p) |
| 14443 | { |
| 14444 | strtok_r(ch_str, ",", &p); |
| 14445 | input_output_channelStats_array[i].ch_number = atoi(ch_str); |
| 14446 | } |
| 14447 | wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size); |
| 14448 | if(!array_size) |
| 14449 | array_size=1;//Need to print current channel statistics |
| 14450 | for(i=0; i<array_size; i++) |
| 14451 | printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\ |
| 14452 | ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\ |
| 14453 | ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\ |
| 14454 | input_output_channelStats_array[i].ch_number,\ |
| 14455 | input_output_channelStats_array[i].ch_noise,\ |
| 14456 | input_output_channelStats_array[i].ch_utilization_busy_rx,\ |
| 14457 | input_output_channelStats_array[i].ch_utilization_busy_tx,\ |
| 14458 | input_output_channelStats_array[i].ch_utilization_busy,\ |
| 14459 | input_output_channelStats_array[i].ch_utilization_busy_ext,\ |
| 14460 | input_output_channelStats_array[i].ch_utilization_total); |
| 14461 | } |
| 14462 | |
| 14463 | if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL) |
| 14464 | { |
| 14465 | if(argc <= 3 ) |
| 14466 | { |
| 14467 | printf("Insufficient arguments \n"); |
| 14468 | exit(-1); |
| 14469 | } |
| 14470 | char mac_addr[20] = {'\0'}; |
| 14471 | wifi_device_t output_struct; |
| 14472 | int dev_index = atoi(argv[3]); |
| 14473 | |
| 14474 | wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct); |
| 14475 | mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress); |
| 14476 | printf("wifi_devMacAddress=%s \t wifi_devAssociatedDeviceAuthentiationState=%d \t, wifi_devSignalStrength=%d \t,wifi_devTxRate=%d \t, wifi_devRxRate =%d \t\n ", mac_addr,output_struct.wifi_devAssociatedDeviceAuthentiationState,output_struct.wifi_devSignalStrength,output_struct.wifi_devTxRate,output_struct.wifi_devRxRate); |
| 14477 | } |
| 14478 | |
| 14479 | if(strstr(argv[1],"wifi_setNeighborReports")!=NULL) |
| 14480 | { |
| 14481 | if (argc <= 3) |
| 14482 | { |
| 14483 | printf("Insufficient arguments\n"); |
| 14484 | exit(-1); |
| 14485 | } |
| 14486 | char args[256]; |
| 14487 | wifi_NeighborReport_t *neighborReports; |
| 14488 | |
| 14489 | neighborReports = calloc(argc - 2, sizeof(neighborReports)); |
| 14490 | if (!neighborReports) |
| 14491 | { |
| 14492 | printf("Failed to allocate memory"); |
| 14493 | exit(-1); |
| 14494 | } |
| 14495 | |
| 14496 | for (int i = 3; i < argc; ++i) |
| 14497 | { |
| 14498 | char *val; |
| 14499 | int j = 0; |
| 14500 | memset(args, 0, sizeof(args)); |
| 14501 | strncpy(args, argv[i], sizeof(args)); |
| 14502 | val = strtok(args, ";"); |
| 14503 | while (val != NULL) |
| 14504 | { |
| 14505 | if (j == 0) |
| 14506 | { |
| 14507 | mac_addr_aton(neighborReports[i - 3].bssid, val); |
| 14508 | } else if (j == 1) |
| 14509 | { |
| 14510 | neighborReports[i - 3].info = strtol(val, NULL, 16); |
| 14511 | } else if (j == 2) |
| 14512 | { |
| 14513 | neighborReports[i - 3].opClass = strtol(val, NULL, 16); |
| 14514 | } else if (j == 3) |
| 14515 | { |
| 14516 | neighborReports[i - 3].channel = strtol(val, NULL, 16); |
| 14517 | } else if (j == 4) |
| 14518 | { |
| 14519 | neighborReports[i - 3].phyTable = strtol(val, NULL, 16); |
| 14520 | } else { |
| 14521 | printf("Insufficient arguments]n\n"); |
| 14522 | exit(-1); |
| 14523 | } |
| 14524 | val = strtok(NULL, ";"); |
| 14525 | j++; |
| 14526 | } |
| 14527 | } |
| 14528 | |
| 14529 | INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports); |
| 14530 | if (ret != RETURN_OK) |
| 14531 | { |
| 14532 | printf("wifi_setNeighborReports ret = %d", ret); |
| 14533 | exit(-1); |
| 14534 | } |
| 14535 | } |
| 14536 | if(strstr(argv[1],"wifi_getRadioIfName")!=NULL) |
| 14537 | { |
| 14538 | if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK) |
| 14539 | printf("%s.\n", buf); |
| 14540 | else |
| 14541 | printf("Error returned\n"); |
| 14542 | } |
| 14543 | if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL) |
| 14544 | { |
| 14545 | if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK) |
| 14546 | printf("%s.\n", buf); |
| 14547 | else |
| 14548 | printf("Error returned\n"); |
| 14549 | } |
| 14550 | if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL) |
| 14551 | { |
| 14552 | if (argc <= 2) |
| 14553 | { |
| 14554 | printf("Insufficient arguments\n"); |
| 14555 | exit(-1); |
| 14556 | } |
| 14557 | char buf[64]= {'\0'}; |
| 14558 | wifi_getRadioOperatingChannelBandwidth(index,buf); |
| 14559 | printf("Current bandwidth is %s \n",buf); |
| 14560 | return 0; |
| 14561 | } |
| 14562 | if(strstr(argv[1],"pushRadioChannel2")!=NULL) |
| 14563 | { |
| 14564 | if (argc <= 5) |
| 14565 | { |
| 14566 | printf("Insufficient arguments\n"); |
| 14567 | exit(-1); |
| 14568 | } |
| 14569 | UINT channel = atoi(argv[3]); |
| 14570 | UINT width = atoi(argv[4]); |
| 14571 | UINT beacon = atoi(argv[5]); |
| 14572 | INT ret = wifi_pushRadioChannel2(index,channel,width,beacon); |
| 14573 | printf("Result = %d", ret); |
| 14574 | } |
| 14575 | |
| 14576 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 14577 | return 0; |
| 14578 | } |
| 14579 | |
| 14580 | #endif |
| 14581 | |
| 14582 | #ifdef WIFI_HAL_VERSION_3 |
| 14583 | |
| 14584 | INT BitMapToTransmitRates(UINT bitMap, char *BasicRate) |
| 14585 | { |
| 14586 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 14587 | if (bitMap & WIFI_BITRATE_1MBPS) |
| 14588 | strcat(BasicRate, "1,"); |
| 14589 | if (bitMap & WIFI_BITRATE_2MBPS) |
| 14590 | strcat(BasicRate, "2,"); |
| 14591 | if (bitMap & WIFI_BITRATE_5_5MBPS) |
| 14592 | strcat(BasicRate, "5.5,"); |
| 14593 | if (bitMap & WIFI_BITRATE_6MBPS) |
| 14594 | strcat(BasicRate, "6,"); |
| 14595 | if (bitMap & WIFI_BITRATE_9MBPS) |
| 14596 | strcat(BasicRate, "9,"); |
| 14597 | if (bitMap & WIFI_BITRATE_11MBPS) |
| 14598 | strcat(BasicRate, "11,"); |
| 14599 | if (bitMap & WIFI_BITRATE_12MBPS) |
| 14600 | strcat(BasicRate, "12,"); |
| 14601 | if (bitMap & WIFI_BITRATE_18MBPS) |
| 14602 | strcat(BasicRate, "18,"); |
| 14603 | if (bitMap & WIFI_BITRATE_24MBPS) |
| 14604 | strcat(BasicRate, "24,"); |
| 14605 | if (bitMap & WIFI_BITRATE_36MBPS) |
| 14606 | strcat(BasicRate, "36,"); |
| 14607 | if (bitMap & WIFI_BITRATE_48MBPS) |
| 14608 | strcat(BasicRate, "48,"); |
| 14609 | if (bitMap & WIFI_BITRATE_54MBPS) |
| 14610 | strcat(BasicRate, "54,"); |
| 14611 | if (strlen(BasicRate) != 0) // remove last comma |
| 14612 | BasicRate[strlen(BasicRate) - 1] = '\0'; |
| 14613 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 14614 | return RETURN_OK; |
| 14615 | } |
| 14616 | |
| 14617 | INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap) |
| 14618 | { |
| 14619 | UINT BitMap = 0; |
| 14620 | char *rate; |
| 14621 | |
| 14622 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 14623 | rate = strtok(BasicRatesList, ","); |
| 14624 | while(rate != NULL) |
| 14625 | { |
| 14626 | if (strcmp(rate, "1") == 0) |
| 14627 | BitMap |= WIFI_BITRATE_1MBPS; |
| 14628 | else if (strcmp(rate, "2") == 0) |
| 14629 | BitMap |= WIFI_BITRATE_2MBPS; |
| 14630 | else if (strcmp(rate, "5.5") == 0) |
| 14631 | BitMap |= WIFI_BITRATE_5_5MBPS; |
| 14632 | else if (strcmp(rate, "6") == 0) |
| 14633 | BitMap |= WIFI_BITRATE_6MBPS; |
| 14634 | else if (strcmp(rate, "9") == 0) |
| 14635 | BitMap |= WIFI_BITRATE_9MBPS; |
| 14636 | else if (strcmp(rate, "11") == 0) |
| 14637 | BitMap |= WIFI_BITRATE_11MBPS; |
| 14638 | else if (strcmp(rate, "12") == 0) |
| 14639 | BitMap |= WIFI_BITRATE_12MBPS; |
| 14640 | else if (strcmp(rate, "18") == 0) |
| 14641 | BitMap |= WIFI_BITRATE_18MBPS; |
| 14642 | else if (strcmp(rate, "24") == 0) |
| 14643 | BitMap |= WIFI_BITRATE_24MBPS; |
| 14644 | else if (strcmp(rate, "36") == 0) |
| 14645 | BitMap |= WIFI_BITRATE_36MBPS; |
| 14646 | else if (strcmp(rate, "48") == 0) |
| 14647 | BitMap |= WIFI_BITRATE_48MBPS; |
| 14648 | else if (strcmp(rate, "54") == 0) |
| 14649 | BitMap |= WIFI_BITRATE_54MBPS; |
| 14650 | rate = strtok(NULL, ","); |
| 14651 | } |
| 14652 | *basicRateBitMap = BitMap; |
| 14653 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 14654 | return RETURN_OK; |
| 14655 | } |
| 14656 | |
| 14657 | // This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration. |
| 14658 | INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam) |
| 14659 | { |
| 14660 | char buf[128] = {0}; |
| 14661 | char cmd[128] = {0}; |
| 14662 | char config_file[64] = {0}; |
| 14663 | int bandwidth; |
| 14664 | int set_mode = 0; |
| 14665 | wifi_radio_operationParam_t current_param; |
| 14666 | |
| 14667 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 14668 | |
| 14669 | multiple_set = TRUE; |
| 14670 | if (wifi_getRadioOperatingParameters(index, ¤t_param) != RETURN_OK) { |
| 14671 | fprintf(stderr, "%s: wifi_getRadioOperatingParameters return error.\n", __func__); |
| 14672 | return RETURN_ERR; |
| 14673 | } |
| 14674 | if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) { |
| 14675 | if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) { |
| 14676 | fprintf(stderr, "%s: wifi_setRadioAutoChannelEnable return error.\n", __func__); |
| 14677 | return RETURN_ERR; |
| 14678 | } |
| 14679 | } |
| 14680 | |
| 14681 | if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ) |
| 14682 | bandwidth = 20; |
| 14683 | else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ) |
| 14684 | bandwidth = 40; |
| 14685 | else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ) |
| 14686 | bandwidth = 80; |
| 14687 | else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ) |
| 14688 | bandwidth = 160; |
| 14689 | if (operationParam->autoChannelEnabled){ |
| 14690 | if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) { |
| 14691 | fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__); |
| 14692 | return RETURN_ERR; |
| 14693 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 14694 | }else{ |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14695 | if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) { |
| 14696 | fprintf(stderr, "%s: wifi_pushRadioChannel2 return error.\n", __func__); |
| 14697 | return RETURN_ERR; |
| 14698 | } |
| 14699 | } |
| 14700 | |
| 14701 | if (current_param.variant != operationParam->variant) { |
| 14702 | // Two different definition bit map, so need to check every bit. |
| 14703 | if (operationParam->variant & WIFI_80211_VARIANT_A) |
| 14704 | set_mode |= WIFI_MODE_A; |
| 14705 | if (operationParam->variant & WIFI_80211_VARIANT_B) |
| 14706 | set_mode |= WIFI_MODE_B; |
| 14707 | if (operationParam->variant & WIFI_80211_VARIANT_G) |
| 14708 | set_mode |= WIFI_MODE_G; |
| 14709 | if (operationParam->variant & WIFI_80211_VARIANT_N) |
| 14710 | set_mode |= WIFI_MODE_N; |
| 14711 | if (operationParam->variant & WIFI_80211_VARIANT_AC) |
| 14712 | set_mode |= WIFI_MODE_AC; |
| 14713 | if (operationParam->variant & WIFI_80211_VARIANT_AX) |
| 14714 | set_mode |= WIFI_MODE_AX; |
| 14715 | // Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed. |
| 14716 | memset(buf, 0, sizeof(buf)); |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 14717 | if (wifi_setRadioMode_by_dat(index, set_mode) != RETURN_OK) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14718 | fprintf(stderr, "%s: wifi_setRadioMode return error.\n", __func__); |
| 14719 | return RETURN_ERR; |
| 14720 | } |
| 14721 | } |
| 14722 | if (current_param.dtimPeriod != operationParam->dtimPeriod) { |
| 14723 | if (wifi_setApDTIMInterval(index, operationParam->dtimPeriod) != RETURN_OK) { |
| 14724 | fprintf(stderr, "%s: wifi_setApDTIMInterval return error.\n", __func__); |
| 14725 | return RETURN_ERR; |
| 14726 | } |
| 14727 | } |
| 14728 | if (current_param.beaconInterval != operationParam->beaconInterval) { |
| 14729 | if (wifi_setRadioBeaconPeriod(index, operationParam->beaconInterval) != RETURN_OK) { |
| 14730 | fprintf(stderr, "%s: wifi_setRadioBeaconPeriod return error.\n", __func__); |
| 14731 | return RETURN_ERR; |
| 14732 | } |
| 14733 | } |
| 14734 | if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) { |
| 14735 | BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf); |
| 14736 | if (wifi_setRadioBasicDataTransmitRates(index, buf) != RETURN_OK) { |
| 14737 | fprintf(stderr, "%s: wifi_setRadioBasicDataTransmitRates return error.\n", __func__); |
| 14738 | return RETURN_ERR; |
| 14739 | } |
| 14740 | } |
| 14741 | if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) { |
| 14742 | if (wifi_setRadioFragmentationThreshold(index, operationParam->fragmentationThreshold) != RETURN_OK) { |
| 14743 | fprintf(stderr, "%s: wifi_setRadioFragmentationThreshold return error.\n", __func__); |
| 14744 | return RETURN_ERR; |
| 14745 | } |
| 14746 | } |
| 14747 | if (current_param.guardInterval != operationParam->guardInterval) { |
| 14748 | if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) { |
| 14749 | fprintf(stderr, "%s: wifi_setGuardInterval return error.\n", __func__); |
| 14750 | return RETURN_ERR; |
| 14751 | } |
| 14752 | } |
| 14753 | if (current_param.transmitPower != operationParam->transmitPower) { |
| 14754 | if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) { |
| 14755 | fprintf(stderr, "%s: wifi_setRadioTransmitPower return error.\n", __func__); |
| 14756 | return RETURN_ERR; |
| 14757 | } |
| 14758 | } |
| 14759 | if (current_param.rtsThreshold != operationParam->rtsThreshold) { |
| 14760 | if (wifi_setApRtsThreshold(index, operationParam->rtsThreshold) != RETURN_OK) { |
| 14761 | fprintf(stderr, "%s: wifi_setApRtsThreshold return error.\n", __func__); |
| 14762 | return RETURN_ERR; |
| 14763 | } |
| 14764 | } |
| 14765 | if (current_param.obssCoex != operationParam->obssCoex) { |
| 14766 | if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) { |
| 14767 | fprintf(stderr, "%s: wifi_setRadioObssCoexistenceEnable return error.\n", __func__); |
| 14768 | return RETURN_ERR; |
| 14769 | } |
| 14770 | } |
| 14771 | if (current_param.stbcEnable != operationParam->stbcEnable) { |
| 14772 | if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) { |
| 14773 | fprintf(stderr, "%s: wifi_setRadioSTBCEnable return error.\n", __func__); |
| 14774 | return RETURN_ERR; |
| 14775 | } |
| 14776 | } |
| 14777 | if (current_param.greenFieldEnable != operationParam->greenFieldEnable) { |
| 14778 | if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) { |
| 14779 | fprintf(stderr, "%s: wifi_setRadio11nGreenfieldEnable return error.\n", __func__); |
| 14780 | return RETURN_ERR; |
| 14781 | } |
| 14782 | } |
| 14783 | |
| 14784 | // if enable is true, then restart the radio |
| 14785 | wifi_setRadioEnable(index, FALSE); |
| 14786 | if (operationParam->enable == TRUE) |
| 14787 | wifi_setRadioEnable(index, TRUE); |
| 14788 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 14789 | |
| 14790 | return RETURN_OK; |
| 14791 | } |
| 14792 | |
| 14793 | INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam) |
| 14794 | { |
| 14795 | char band[64] = {0}; |
| 14796 | char buf[256] = {0}; |
| 14797 | char config_file[64] = {0}; |
| 14798 | char cmd[128] = {0}; |
| 14799 | int ret = RETURN_ERR; |
| 14800 | int mode = 0; |
| 14801 | ULONG channel = 0; |
| 14802 | BOOL enabled = FALSE; |
| 14803 | |
| 14804 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 14805 | printf("Entering %s index = %d\n", __func__, (int)index); |
| 14806 | |
| 14807 | memset(operationParam, 0, sizeof(wifi_radio_operationParam_t)); |
| 14808 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, index); |
| 14809 | if (wifi_getRadioEnable(index, &enabled) != RETURN_OK) |
| 14810 | { |
| 14811 | fprintf(stderr, "%s: wifi_getRadioEnable return error.\n", __func__); |
| 14812 | return RETURN_ERR; |
| 14813 | } |
| 14814 | operationParam->enable = enabled; |
| 14815 | |
| 14816 | memset(band, 0, sizeof(band)); |
| 14817 | if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK) |
| 14818 | { |
| 14819 | fprintf(stderr, "%s: wifi_getRadioOperatingFrequencyBand return error.\n", __func__); |
| 14820 | return RETURN_ERR; |
| 14821 | } |
| 14822 | |
| 14823 | if (!strcmp(band, "2.4GHz")) |
| 14824 | operationParam->band = WIFI_FREQUENCY_2_4_BAND; |
| 14825 | else if (!strcmp(band, "5GHz")) |
| 14826 | operationParam->band = WIFI_FREQUENCY_5_BAND; |
| 14827 | else if (!strcmp(band, "6GHz")) |
| 14828 | operationParam->band = WIFI_FREQUENCY_6_BAND; |
| 14829 | else |
| 14830 | { |
| 14831 | fprintf(stderr, "%s: cannot decode band for radio index %d ('%s')\n", __func__, index, |
| 14832 | band); |
| 14833 | } |
| 14834 | |
| 14835 | wifi_hostapdRead(config_file, "channel", buf, sizeof(buf)); |
| 14836 | if (strcmp(buf, "0") == 0 || strcmp(buf, "acs_survey") == 0) { |
| 14837 | operationParam->channel = 0; |
| 14838 | operationParam->autoChannelEnabled = TRUE; |
| 14839 | } else { |
| 14840 | operationParam->channel = strtol(buf, NULL, 10); |
| 14841 | operationParam->autoChannelEnabled = FALSE; |
| 14842 | } |
| 14843 | |
| 14844 | memset(buf, 0, sizeof(buf)); |
| 14845 | if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) { |
| 14846 | fprintf(stderr, "%s: wifi_getRadioOperatingChannelBandwidth return error.\n", __func__); |
| 14847 | return RETURN_ERR; |
| 14848 | } |
| 14849 | if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ; |
| 14850 | else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ; |
| 14851 | else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ; |
| 14852 | else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ; |
| 14853 | else |
| 14854 | { |
| 14855 | fprintf(stderr, "Unknown channel bandwidth: %s\n", buf); |
| 14856 | return false; |
| 14857 | } |
| 14858 | |
| 14859 | if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) { |
| 14860 | fprintf(stderr, "%s: wifi_getRadioMode return error.\n", __func__); |
| 14861 | return RETURN_ERR; |
| 14862 | } |
| 14863 | // Two different definition bit map, so need to check every bit. |
| 14864 | if (mode & WIFI_MODE_A) |
| 14865 | operationParam->variant |= WIFI_80211_VARIANT_A; |
| 14866 | if (mode & WIFI_MODE_B) |
| 14867 | operationParam->variant |= WIFI_80211_VARIANT_B; |
| 14868 | if (mode & WIFI_MODE_G) |
| 14869 | operationParam->variant |= WIFI_80211_VARIANT_G; |
| 14870 | if (mode & WIFI_MODE_N) |
| 14871 | operationParam->variant |= WIFI_80211_VARIANT_N; |
| 14872 | if (mode & WIFI_MODE_AC) |
| 14873 | operationParam->variant |= WIFI_80211_VARIANT_AC; |
| 14874 | if (mode & WIFI_MODE_AX) |
| 14875 | operationParam->variant |= WIFI_80211_VARIANT_AX; |
| 14876 | if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) { |
| 14877 | fprintf(stderr, "%s: wifi_getRadioDCSEnable return error.\n", __func__); |
| 14878 | return RETURN_ERR; |
| 14879 | } |
| 14880 | if (wifi_getApDTIMInterval(index, &operationParam->dtimPeriod) != RETURN_OK) { |
| 14881 | fprintf(stderr, "%s: wifi_getApDTIMInterval return error.\n", __func__); |
| 14882 | return RETURN_ERR; |
| 14883 | } |
| 14884 | if (wifi_getRadioBeaconPeriod(index, &operationParam->dtimPeriod) != RETURN_OK) { |
| 14885 | fprintf(stderr, "%s: wifi_getRadioBeaconPeriod return error.\n", __func__); |
| 14886 | return RETURN_ERR; |
| 14887 | } |
| 14888 | |
| 14889 | memset(buf, 0, sizeof(buf)); |
| 14890 | if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) { |
| 14891 | fprintf(stderr, "%s: wifi_getRadioSupportedDataTransmitRates return error.\n", __func__); |
| 14892 | return RETURN_ERR; |
| 14893 | } |
| 14894 | TransmitRatesToBitMap(buf, &operationParam->basicDataTransmitRates); |
| 14895 | |
| 14896 | memset(buf, 0, sizeof(buf)); |
| 14897 | if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) { |
| 14898 | fprintf(stderr, "%s: wifi_getRadioBasicDataTransmitRates return error.\n", __func__); |
| 14899 | return RETURN_ERR; |
| 14900 | } |
| 14901 | TransmitRatesToBitMap(buf, &operationParam->operationalDataTransmitRates); |
| 14902 | |
| 14903 | memset(buf, 0, sizeof(buf)); |
| 14904 | wifi_hostapdRead(config_file, "fragm_threshold", buf, sizeof(buf)); |
| 14905 | operationParam->fragmentationThreshold = strtoul(buf, NULL, 10); |
| 14906 | |
| 14907 | if (wifi_getGuardInterval(index, &operationParam->guardInterval) != RETURN_OK) { |
| 14908 | fprintf(stderr, "%s: wifi_getGuardInterval return error.\n", __func__); |
| 14909 | return RETURN_ERR; |
| 14910 | } |
developer | a1255e4 | 2023-05-13 17:45:02 +0800 | [diff] [blame] | 14911 | if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&operationParam->transmitPower) != RETURN_OK) { |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14912 | fprintf(stderr, "%s: wifi_getRadioPercentageTransmitPower return error.\n", __func__); |
| 14913 | return RETURN_ERR; |
| 14914 | } |
| 14915 | |
| 14916 | memset(buf, 0, sizeof(buf)); |
| 14917 | wifi_hostapdRead(config_file, "rts_threshold", buf, sizeof(buf)); |
| 14918 | if (strcmp(buf, "-1") == 0) { |
| 14919 | operationParam->rtsThreshold = (UINT)-1; // maxuimum unsigned integer value |
| 14920 | operationParam->ctsProtection = FALSE; |
| 14921 | } else { |
| 14922 | operationParam->rtsThreshold = strtoul(buf, NULL, 10); |
| 14923 | operationParam->ctsProtection = TRUE; |
| 14924 | } |
| 14925 | |
| 14926 | memset(buf, 0, sizeof(buf)); |
| 14927 | wifi_hostapdRead(config_file, "ht_coex", buf, sizeof(buf)); |
| 14928 | if (strcmp(buf, "0") == 0) |
| 14929 | operationParam->obssCoex = FALSE; |
| 14930 | else |
| 14931 | operationParam->obssCoex = TRUE; |
| 14932 | |
| 14933 | snprintf(cmd, sizeof(cmd), "cat %s | grep STBC", config_file); |
| 14934 | _syscmd(cmd, buf, sizeof(buf)); |
| 14935 | if (strlen(buf) != 0) |
| 14936 | operationParam->stbcEnable = TRUE; |
| 14937 | else |
| 14938 | operationParam->stbcEnable = FALSE; |
| 14939 | |
| 14940 | if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) { |
| 14941 | fprintf(stderr, "%s: wifi_getRadio11nGreenfieldEnable return error.\n", __func__); |
| 14942 | return RETURN_ERR; |
| 14943 | } |
| 14944 | |
| 14945 | // Below value is hardcoded |
| 14946 | |
| 14947 | operationParam->numSecondaryChannels = 0; |
| 14948 | for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) { |
| 14949 | operationParam->channelSecondary[i] = 0; |
| 14950 | } |
| 14951 | operationParam->csa_beacon_count = 15; |
| 14952 | operationParam->countryCode = wifi_countrycode_US; // hard to convert string to corresponding enum |
| 14953 | |
| 14954 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 14955 | return RETURN_OK; |
| 14956 | } |
| 14957 | |
| 14958 | static int array_index_to_vap_index(UINT radioIndex, int arrayIndex) |
| 14959 | { |
| 14960 | int max_radio_num = 0; |
| 14961 | |
| 14962 | wifi_getMaxRadioNumber(&max_radio_num); |
| 14963 | if (radioIndex >= max_radio_num) { |
| 14964 | fprintf(stderr, "%s: Wrong radio index (%d)\n", __func__, radioIndex); |
| 14965 | return RETURN_ERR; |
| 14966 | } |
| 14967 | |
| 14968 | return (arrayIndex * max_radio_num) + radioIndex; |
| 14969 | } |
| 14970 | |
developer | 96b3851 | 2023-02-22 11:17:45 +0800 | [diff] [blame] | 14971 | static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex) |
| 14972 | { |
| 14973 | int max_radio_num = 0; |
| 14974 | |
| 14975 | if ((vapIndex < 0) || (vapIndex > MAX_NUM_VAP_PER_RADIO*MAX_NUM_RADIOS)) |
| 14976 | return -1; |
| 14977 | |
| 14978 | wifi_getMaxRadioNumber(&max_radio_num); |
| 14979 | |
| 14980 | (*radioIndex) = vapIndex % max_radio_num; |
| 14981 | (*arrayIndex) = vapIndex / max_radio_num; |
| 14982 | |
| 14983 | return 0; |
| 14984 | } |
| 14985 | |
| 14986 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 14987 | wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) { |
| 14988 | if (strncmp(beaconRate, "1Mbps", 5) == 0) |
| 14989 | return WIFI_BITRATE_1MBPS; |
| 14990 | else if (strncmp(beaconRate, "2Mbps", 5) == 0) |
| 14991 | return WIFI_BITRATE_2MBPS; |
| 14992 | else if (strncmp(beaconRate, "5.5Mbps", 7) == 0) |
| 14993 | return WIFI_BITRATE_5_5MBPS; |
| 14994 | else if (strncmp(beaconRate, "6Mbps", 5) == 0) |
| 14995 | return WIFI_BITRATE_6MBPS; |
| 14996 | else if (strncmp(beaconRate, "9Mbps", 5) == 0) |
| 14997 | return WIFI_BITRATE_9MBPS; |
| 14998 | else if (strncmp(beaconRate, "11Mbps", 6) == 0) |
| 14999 | return WIFI_BITRATE_11MBPS; |
| 15000 | else if (strncmp(beaconRate, "12Mbps", 6) == 0) |
| 15001 | return WIFI_BITRATE_12MBPS; |
| 15002 | else if (strncmp(beaconRate, "18Mbps", 6) == 0) |
| 15003 | return WIFI_BITRATE_18MBPS; |
| 15004 | else if (strncmp(beaconRate, "24Mbps", 6) == 0) |
| 15005 | return WIFI_BITRATE_24MBPS; |
| 15006 | else if (strncmp(beaconRate, "36Mbps", 6) == 0) |
| 15007 | return WIFI_BITRATE_36MBPS; |
| 15008 | else if (strncmp(beaconRate, "48Mbps", 6) == 0) |
| 15009 | return WIFI_BITRATE_48MBPS; |
| 15010 | else if (strncmp(beaconRate, "54Mbps", 6) == 0) |
| 15011 | return WIFI_BITRATE_54MBPS; |
| 15012 | return WIFI_BITRATE_DEFAULT; |
| 15013 | } |
| 15014 | |
| 15015 | INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str) |
| 15016 | { |
| 15017 | if (beacon == WIFI_BITRATE_1MBPS) |
| 15018 | strcpy(beacon_str, "1Mbps"); |
| 15019 | else if (beacon == WIFI_BITRATE_2MBPS) |
| 15020 | strcpy(beacon_str, "2Mbps"); |
| 15021 | else if (beacon == WIFI_BITRATE_5_5MBPS) |
| 15022 | strcpy(beacon_str, "5.5Mbps"); |
| 15023 | else if (beacon == WIFI_BITRATE_6MBPS) |
| 15024 | strcpy(beacon_str, "6Mbps"); |
| 15025 | else if (beacon == WIFI_BITRATE_9MBPS) |
| 15026 | strcpy(beacon_str, "9Mbps"); |
| 15027 | else if (beacon == WIFI_BITRATE_11MBPS) |
| 15028 | strcpy(beacon_str, "11Mbps"); |
| 15029 | else if (beacon == WIFI_BITRATE_12MBPS) |
| 15030 | strcpy(beacon_str, "12Mbps"); |
| 15031 | else if (beacon == WIFI_BITRATE_18MBPS) |
| 15032 | strcpy(beacon_str, "18Mbps"); |
| 15033 | else if (beacon == WIFI_BITRATE_24MBPS) |
| 15034 | strcpy(beacon_str, "24Mbps"); |
| 15035 | else if (beacon == WIFI_BITRATE_36MBPS) |
| 15036 | strcpy(beacon_str, "36Mbps"); |
| 15037 | else if (beacon == WIFI_BITRATE_48MBPS) |
| 15038 | strcpy(beacon_str, "48Mbps"); |
| 15039 | else if (beacon == WIFI_BITRATE_54MBPS) |
| 15040 | strcpy(beacon_str, "54Mbps"); |
| 15041 | return RETURN_OK; |
| 15042 | } |
| 15043 | |
| 15044 | INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map) |
| 15045 | { |
| 15046 | INT mode = 0; |
| 15047 | INT ret = -1; |
| 15048 | INT output = 0; |
| 15049 | int i = 0; |
| 15050 | int vap_index = 0; |
| 15051 | BOOL enabled = FALSE; |
| 15052 | char buf[256] = {0}; |
| 15053 | wifi_vap_security_t security = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15054 | |
| 15055 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 15056 | printf("Entering %s index = %d\n", __func__, (int)index); |
| 15057 | |
developer | fde0126 | 2023-05-22 15:15:24 +0800 | [diff] [blame] | 15058 | ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0"); |
| 15059 | if (ret != 0) { |
| 15060 | fprintf(stderr, "%s: wifi_BandProfileRead BssidNum failed\n", __func__); |
| 15061 | return RETURN_ERR; |
| 15062 | } |
| 15063 | |
| 15064 | map->num_vaps = atoi(buf); |
| 15065 | if (map->num_vaps <= 0) { |
| 15066 | fprintf(stderr, "%s: invalid BssidNum %s\n", __func__, buf); |
| 15067 | return RETURN_ERR; |
| 15068 | } |
| 15069 | |
| 15070 | for (i = 0; i < map->num_vaps; i++) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15071 | { |
| 15072 | map->vap_array[i].radio_index = index; |
| 15073 | |
| 15074 | vap_index = array_index_to_vap_index(index, i); |
| 15075 | if (vap_index < 0) |
| 15076 | return RETURN_ERR; |
| 15077 | |
| 15078 | strcpy(map->vap_array[i].bridge_name, BRIDGE_NAME); |
| 15079 | |
| 15080 | map->vap_array[i].vap_index = vap_index; |
| 15081 | |
| 15082 | memset(buf, 0, sizeof(buf)); |
| 15083 | ret = wifi_getApName(vap_index, buf); |
| 15084 | if (ret != RETURN_OK) { |
| 15085 | printf("%s: wifi_getApName return error\n", __func__); |
| 15086 | return RETURN_ERR; |
| 15087 | } |
| 15088 | snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf); |
| 15089 | |
| 15090 | memset(buf, 0, sizeof(buf)); |
| 15091 | ret = wifi_getSSIDName(vap_index, buf); |
| 15092 | if (ret != RETURN_OK) { |
| 15093 | printf("%s: wifi_getSSIDName return error\n", __func__); |
| 15094 | return RETURN_ERR; |
| 15095 | } |
| 15096 | snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf); |
| 15097 | |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15098 | #if 0 |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15099 | ret = wifi_getSSIDEnable(vap_index, &enabled); |
| 15100 | if (ret != RETURN_OK) { |
| 15101 | printf("%s: wifi_getSSIDEnable return error\n", __func__); |
| 15102 | return RETURN_ERR; |
| 15103 | } |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15104 | #endif |
| 15105 | map->vap_array[i].u.bss_info.enabled = true; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15106 | |
| 15107 | ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled); |
| 15108 | if (ret != RETURN_OK) { |
| 15109 | printf("%s: wifi_getApSsidAdvertisementEnable return error\n", __func__); |
| 15110 | return RETURN_ERR; |
| 15111 | } |
| 15112 | map->vap_array[i].u.bss_info.showSsid = enabled; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 15113 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15114 | ret = wifi_getApIsolationEnable(vap_index, &enabled); |
| 15115 | if (ret != RETURN_OK) { |
| 15116 | printf("%s: wifi_getApIsolationEnable return error\n", __func__); |
| 15117 | return RETURN_ERR; |
| 15118 | } |
| 15119 | map->vap_array[i].u.bss_info.isolation = enabled; |
| 15120 | |
| 15121 | ret = wifi_getApMaxAssociatedDevices(vap_index, &output); |
| 15122 | if (ret != RETURN_OK) { |
| 15123 | printf("%s: wifi_getApMaxAssociatedDevices return error\n", __func__); |
| 15124 | return RETURN_ERR; |
| 15125 | } |
| 15126 | map->vap_array[i].u.bss_info.bssMaxSta = output; |
| 15127 | |
| 15128 | ret = wifi_getBSSTransitionActivation(vap_index, &enabled); |
| 15129 | if (ret != RETURN_OK) { |
| 15130 | printf("%s: wifi_getBSSTransitionActivation return error\n", __func__); |
| 15131 | return RETURN_ERR; |
| 15132 | } |
| 15133 | map->vap_array[i].u.bss_info.bssTransitionActivated = enabled; |
| 15134 | |
| 15135 | ret = wifi_getNeighborReportActivation(vap_index, &enabled); |
| 15136 | if (ret != RETURN_OK) { |
| 15137 | printf("%s: wifi_getNeighborReportActivation return error\n", __func__); |
| 15138 | return RETURN_ERR; |
| 15139 | } |
| 15140 | map->vap_array[i].u.bss_info.nbrReportActivated = enabled; |
| 15141 | |
| 15142 | ret = wifi_getApSecurity(vap_index, &security); |
| 15143 | if (ret != RETURN_OK) { |
| 15144 | printf("%s: wifi_getApSecurity return error\n", __func__); |
| 15145 | return RETURN_ERR; |
| 15146 | } |
| 15147 | map->vap_array[i].u.bss_info.security = security; |
| 15148 | |
| 15149 | ret = wifi_getApMacAddressControlMode(vap_index, &mode); |
| 15150 | if (ret != RETURN_OK) { |
| 15151 | printf("%s: wifi_getApMacAddressControlMode return error\n", __func__); |
| 15152 | return RETURN_ERR; |
| 15153 | } |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 15154 | if (mode == 0) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15155 | map->vap_array[i].u.bss_info.mac_filter_enable = FALSE; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 15156 | else |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15157 | map->vap_array[i].u.bss_info.mac_filter_enable = TRUE; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 15158 | if (mode == 1) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15159 | map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list; |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 15160 | else if (mode == 2) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15161 | map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list; |
| 15162 | |
| 15163 | ret = wifi_getApWmmEnable(vap_index, &enabled); |
| 15164 | if (ret != RETURN_OK) { |
| 15165 | printf("%s: wifi_getApWmmEnable return error\n", __func__); |
| 15166 | return RETURN_ERR; |
| 15167 | } |
| 15168 | map->vap_array[i].u.bss_info.wmm_enabled = enabled; |
| 15169 | |
| 15170 | ret = wifi_getApUAPSDCapability(vap_index, &enabled); |
| 15171 | if (ret != RETURN_OK) { |
| 15172 | printf("%s: wifi_getApUAPSDCapability return error\n", __func__); |
| 15173 | return RETURN_ERR; |
| 15174 | } |
| 15175 | map->vap_array[i].u.bss_info.UAPSDEnabled = enabled; |
| 15176 | |
| 15177 | memset(buf, 0, sizeof(buf)); |
| 15178 | ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf); |
| 15179 | if (ret != RETURN_OK) { |
| 15180 | printf("%s: wifi_getApBeaconRate return error\n", __func__); |
| 15181 | return RETURN_ERR; |
| 15182 | } |
| 15183 | map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf); |
| 15184 | |
| 15185 | memset(buf, 0, sizeof(buf)); |
| 15186 | ret = wifi_getBaseBSSID(vap_index, buf); |
| 15187 | if (ret != RETURN_OK) { |
| 15188 | printf("%s: wifi_getBaseBSSID return error\n", __func__); |
| 15189 | return RETURN_ERR; |
| 15190 | } |
developer | 5b2f10c | 2023-05-25 17:02:21 +0800 | [diff] [blame] | 15191 | if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) { |
| 15192 | printf("%s: hwaddr_aton2 fail\n", __func__); |
| 15193 | return RETURN_ERR; |
| 15194 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15195 | |
| 15196 | ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled); |
| 15197 | if (ret != RETURN_OK) { |
| 15198 | fprintf(stderr, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__); |
| 15199 | return RETURN_ERR; |
| 15200 | } |
| 15201 | map->vap_array[i].u.bss_info.mcast2ucast = enabled; |
| 15202 | |
| 15203 | // TODO: wps, noack |
| 15204 | } |
| 15205 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 15206 | return RETURN_OK; |
| 15207 | } |
| 15208 | |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 15209 | void checkVapStatus(int apIndex, BOOL *enable) |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15210 | { |
| 15211 | char if_name[16] = {0}; |
| 15212 | char cmd[128] = {0}; |
| 15213 | char buf[128] = {0}; |
| 15214 | |
| 15215 | *enable = FALSE; |
| 15216 | if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK) |
| 15217 | return; |
| 15218 | |
| 15219 | snprintf(cmd, sizeof(cmd), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name); |
| 15220 | _syscmd(cmd, buf, sizeof(buf)); |
| 15221 | if (strlen(buf) > 0) |
| 15222 | *enable = TRUE; |
| 15223 | return; |
| 15224 | } |
| 15225 | |
| 15226 | static int prepareInterface(UINT apIndex, char *new_interface) |
| 15227 | { |
| 15228 | char cur_interface[16] = {0}; |
| 15229 | char config_file[128] = {0}; |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 15230 | char cmd[MAX_CMD_SIZE] = {0}; |
| 15231 | char buf[MAX_BUF_SIZE] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15232 | int max_radio_num = 0; |
| 15233 | int radioIndex = -1; |
| 15234 | int phyIndex = -1; |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 15235 | struct params params; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15236 | |
| 15237 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 15238 | wifi_hostapdRead(config_file, "interface", cur_interface, sizeof(cur_interface)); |
| 15239 | |
| 15240 | if (strncmp(cur_interface, new_interface, sizeof(cur_interface)) != 0) { |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 15241 | wifi_getMaxRadioNumber(&max_radio_num); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15242 | radioIndex = apIndex % max_radio_num; |
| 15243 | phyIndex = radio_index_to_phy(radioIndex); |
| 15244 | // disable and del old interface, then add new interface |
| 15245 | wifi_setApEnable(apIndex, FALSE); |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 15246 | |
| 15247 | params.name = "interface"; |
| 15248 | params.value = new_interface; |
| 15249 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15250 | |
| 15251 | snprintf(cmd, MAX_CMD_SIZE, "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyIndex, config_file); |
| 15252 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15253 | } |
developer | 8a3bbbf | 2023-03-15 17:47:23 +0800 | [diff] [blame] | 15254 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15255 | // update the vap status file |
| 15256 | snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^%s=/!p' -e '$a%s=1' %s", cur_interface, new_interface, VAP_STATUS_FILE); |
| 15257 | _syscmd(cmd, buf, sizeof(buf)); |
| 15258 | return RETURN_OK; |
| 15259 | } |
| 15260 | |
| 15261 | INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map) |
| 15262 | { |
| 15263 | char interface_name[16] = {0}; |
| 15264 | unsigned int i; |
| 15265 | wifi_vap_info_t *vap_info = NULL; |
| 15266 | int acl_mode; |
| 15267 | int ret = 0; |
| 15268 | char *sec_str = NULL; |
| 15269 | char buf[256] = {0}; |
| 15270 | char cmd[128] = {0}; |
| 15271 | char config_file[64] = {0}; |
| 15272 | char bssid[32] = {0}; |
| 15273 | char psk_file[64] = {0}; |
developer | 47cc27a | 2023-05-17 23:09:58 +0800 | [diff] [blame] | 15274 | BOOL enable = FALSE; |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15275 | int band_idx; |
| 15276 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15277 | |
| 15278 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 15279 | printf("Entering %s index = %d\n", __func__, (int)index); |
| 15280 | for (i = 0; i < map->num_vaps; i++) |
| 15281 | { |
| 15282 | multiple_set = TRUE; |
| 15283 | vap_info = &map->vap_array[i]; |
| 15284 | |
| 15285 | // Check vap status file to enable multiple ap if the system boot. |
| 15286 | checkVapStatus(vap_info->vap_index, &enable); |
| 15287 | if (vap_info->u.bss_info.enabled == FALSE && enable == FALSE) |
| 15288 | continue; |
| 15289 | |
| 15290 | fprintf(stderr, "\nCreate VAP for ssid_index=%d (vap_num=%d)\n", vap_info->vap_index, i); |
| 15291 | |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15292 | band_idx = radio_index_to_band(index); |
| 15293 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index); |
| 15294 | snprintf(cmd, sizeof(cmd), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file); |
| 15295 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15296 | |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15297 | struct params params[4]; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15298 | params[0].name = "interface"; |
| 15299 | params[0].value = vap_info->vap_name; |
| 15300 | mac_addr_ntoa(bssid, vap_info->u.bss_info.bssid); |
| 15301 | params[1].name = "bssid"; |
| 15302 | params[1].value = bssid; |
| 15303 | snprintf(psk_file, sizeof(psk_file), "\\/nvram\\/hostapd%d.psk", vap_info->vap_index); |
| 15304 | params[2].name = "wpa_psk_file"; |
| 15305 | params[2].value = psk_file; |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15306 | params[3].name = "ssid"; |
| 15307 | params[3].value = vap_info->u.bss_info.ssid; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15308 | |
| 15309 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index); |
developer | e740c2a | 2023-05-23 18:34:32 +0800 | [diff] [blame] | 15310 | wifi_hostapdWrite(config_file, params, 4); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15311 | |
| 15312 | snprintf(cmd, sizeof(cmd), "touch %s", psk_file); |
| 15313 | _syscmd(cmd, buf, sizeof(buf)); |
| 15314 | |
| 15315 | ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid); |
| 15316 | if (ret != RETURN_OK) { |
| 15317 | fprintf(stderr, "%s: wifi_setSSIDName return error\n", __func__); |
| 15318 | return RETURN_ERR; |
| 15319 | } |
| 15320 | |
| 15321 | ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid); |
| 15322 | if (ret != RETURN_OK) { |
| 15323 | fprintf(stderr, "%s: wifi_setApSsidAdvertisementEnable return error\n", __func__); |
| 15324 | return RETURN_ERR; |
| 15325 | } |
| 15326 | |
| 15327 | ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation); |
| 15328 | if (ret != RETURN_OK) { |
| 15329 | fprintf(stderr, "%s: wifi_setApIsolationEnable return error\n", __func__); |
| 15330 | return RETURN_ERR; |
| 15331 | } |
| 15332 | |
| 15333 | ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta); |
| 15334 | if (ret != RETURN_OK) { |
| 15335 | fprintf(stderr, "%s: wifi_setApMaxAssociatedDevices return error\n", __func__); |
| 15336 | return RETURN_ERR; |
| 15337 | } |
| 15338 | |
| 15339 | ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated); |
| 15340 | if (ret != RETURN_OK) { |
| 15341 | fprintf(stderr, "%s: wifi_setBSSTransitionActivation return error\n", __func__); |
| 15342 | return RETURN_ERR; |
| 15343 | } |
| 15344 | |
| 15345 | ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated); |
| 15346 | if (ret != RETURN_OK) { |
| 15347 | fprintf(stderr, "%s: wifi_setNeighborReportActivation return error\n", __func__); |
| 15348 | return RETURN_ERR; |
| 15349 | } |
| 15350 | |
| 15351 | if (vap_info->u.bss_info.mac_filter_enable == false){ |
| 15352 | acl_mode = 0; |
| 15353 | }else { |
| 15354 | if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){ |
| 15355 | acl_mode = 2; |
| 15356 | snprintf(cmd, sizeof(cmd), "touch %s%d", DENY_PREFIX, vap_info->vap_index); |
| 15357 | _syscmd(cmd, buf, sizeof(buf)); |
| 15358 | }else{ |
| 15359 | acl_mode = 1; |
| 15360 | } |
| 15361 | } |
| 15362 | |
| 15363 | ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled); |
| 15364 | if (ret != RETURN_OK) { |
| 15365 | fprintf(stderr, "%s: wifi_setApWmmEnable return error\n", __func__); |
| 15366 | return RETURN_ERR; |
| 15367 | } |
| 15368 | |
| 15369 | ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled); |
| 15370 | if (ret != RETURN_OK) { |
| 15371 | fprintf(stderr, "%s: wifi_setApWmmUapsdEnable return error\n", __func__); |
| 15372 | return RETURN_ERR; |
| 15373 | } |
| 15374 | |
developer | 0f10c77 | 2023-05-16 21:43:39 +0800 | [diff] [blame] | 15375 | memset(buf, 0, sizeof(buf)); |
| 15376 | beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf); |
| 15377 | ret = wifi_setApBeaconRate(vap_info->radio_index, buf); |
| 15378 | if (ret != RETURN_OK) { |
| 15379 | fprintf(stderr, "%s: wifi_setApBeaconRate return error\n", __func__); |
| 15380 | return RETURN_ERR; |
| 15381 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15382 | |
| 15383 | ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast); |
| 15384 | if (ret != RETURN_OK) { |
| 15385 | fprintf(stderr, "%s: wifi_setRadioIGMPSnoopingEnable\n", __func__); |
| 15386 | return RETURN_ERR; |
| 15387 | } |
| 15388 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15389 | ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security); |
| 15390 | if (ret != RETURN_OK) { |
| 15391 | fprintf(stderr, "%s: wifi_setApSecurity return error\n", __func__); |
| 15392 | return RETURN_ERR; |
| 15393 | } |
| 15394 | |
developer | 23e7128 | 2023-01-18 10:25:19 +0800 | [diff] [blame] | 15395 | wifi_setApEnable(vap_info->vap_index, FALSE); |
| 15396 | wifi_setApEnable(vap_info->vap_index, TRUE); |
| 15397 | multiple_set = FALSE; |
| 15398 | |
| 15399 | // If config use hostapd_cli to set, we calling these type of functions after enable the ap. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15400 | ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode); |
| 15401 | if (ret != RETURN_OK) { |
| 15402 | fprintf(stderr, "%s: wifi_setApMacAddressControlMode return error\n", __func__); |
| 15403 | return RETURN_ERR; |
| 15404 | } |
| 15405 | |
| 15406 | // TODO mgmtPowerControl, interworking, wps |
| 15407 | } |
| 15408 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 15409 | return RETURN_OK; |
| 15410 | } |
| 15411 | |
| 15412 | int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr) |
| 15413 | { |
| 15414 | char *token, *next; |
| 15415 | const char s[2] = ","; |
| 15416 | int count =0; |
| 15417 | |
| 15418 | /* get the first token */ |
| 15419 | token = strtok_r(pchannels, s, &next); |
| 15420 | |
| 15421 | /* walk through other tokens */ |
| 15422 | while( token != NULL && count < MAX_CHANNELS) { |
| 15423 | chlistptr->channels_list[count++] = atoi(token); |
| 15424 | token = strtok_r(NULL, s, &next); |
| 15425 | } |
| 15426 | |
| 15427 | return count; |
| 15428 | } |
| 15429 | |
| 15430 | static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap) |
| 15431 | { |
| 15432 | INT status; |
| 15433 | wifi_channels_list_t *chlistp; |
| 15434 | CHAR output_string[64]; |
| 15435 | CHAR pchannels[128]; |
| 15436 | CHAR interface_name[16] = {0}; |
| 15437 | wifi_band band; |
| 15438 | |
| 15439 | if(rcap == NULL) |
| 15440 | { |
| 15441 | return RETURN_ERR; |
| 15442 | } |
| 15443 | |
| 15444 | rcap->numSupportedFreqBand = 1; |
| 15445 | band = wifi_index_to_band(radioIndex); |
| 15446 | |
| 15447 | if (band == band_2_4) |
| 15448 | rcap->band[0] = WIFI_FREQUENCY_2_4_BAND; |
| 15449 | else if (band == band_5) |
| 15450 | rcap->band[0] = WIFI_FREQUENCY_5_BAND; |
| 15451 | else if (band == band_6) |
| 15452 | rcap->band[0] = WIFI_FREQUENCY_6_BAND; |
| 15453 | |
| 15454 | chlistp = &(rcap->channel_list[0]); |
| 15455 | memset(pchannels, 0, sizeof(pchannels)); |
| 15456 | |
| 15457 | /* possible number of radio channels */ |
| 15458 | status = wifi_getRadioPossibleChannels(radioIndex, pchannels); |
| 15459 | { |
| 15460 | printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, pchannels); |
| 15461 | } |
| 15462 | /* Number of channels and list*/ |
| 15463 | chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp); |
| 15464 | |
| 15465 | /* autoChannelSupported */ |
| 15466 | /* always ON with wifi_getRadioAutoChannelSupported */ |
| 15467 | rcap->autoChannelSupported = TRUE; |
| 15468 | |
| 15469 | /* DCSSupported */ |
| 15470 | /* always ON with wifi_getRadioDCSSupported */ |
| 15471 | rcap->DCSSupported = TRUE; |
| 15472 | |
| 15473 | /* zeroDFSSupported - TBD */ |
| 15474 | rcap->zeroDFSSupported = FALSE; |
| 15475 | |
| 15476 | /* Supported Country List*/ |
| 15477 | memset(output_string, 0, sizeof(output_string)); |
| 15478 | status = wifi_getRadioCountryCode(radioIndex, output_string); |
| 15479 | if( status != 0 ) { |
| 15480 | printf("[wifi_hal dbg] : func[%s] line[%d] error_ret[%d] radio_index[%d] output[%s]\n", __FUNCTION__, __LINE__, status, radioIndex, output_string); |
| 15481 | return RETURN_ERR; |
| 15482 | } else { |
| 15483 | printf("[wifi_hal dbg] : func[%s] line[%d], output [%s]\n", __FUNCTION__, __LINE__, output_string); |
| 15484 | } |
| 15485 | if(!strcmp(output_string,"US")){ |
| 15486 | rcap->countrySupported[0] = wifi_countrycode_US; |
| 15487 | rcap->countrySupported[1] = wifi_countrycode_CA; |
| 15488 | } else if (!strcmp(output_string,"CA")) { |
| 15489 | rcap->countrySupported[0] = wifi_countrycode_CA; |
| 15490 | rcap->countrySupported[1] = wifi_countrycode_US; |
| 15491 | } else { |
| 15492 | printf("[wifi_hal dbg] : func[%s] line[%d] radio_index[%d] Invalid Country [%s]\n", __FUNCTION__, __LINE__, radioIndex, output_string); |
| 15493 | } |
| 15494 | |
| 15495 | rcap->numcountrySupported = 2; |
| 15496 | |
| 15497 | /* csi */ |
| 15498 | rcap->csi.maxDevices = 8; |
| 15499 | rcap->csi.soudingFrameSupported = TRUE; |
| 15500 | |
| 15501 | wifi_GetInterfaceName(radioIndex, interface_name); |
| 15502 | snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name); |
| 15503 | |
| 15504 | /* channelWidth - all supported bandwidths */ |
| 15505 | int i=0; |
| 15506 | rcap->channelWidth[i] = 0; |
| 15507 | if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) { |
| 15508 | rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ | |
| 15509 | WIFI_CHANNELBANDWIDTH_40MHZ); |
| 15510 | |
| 15511 | } |
| 15512 | else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) || rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) { |
| 15513 | rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ | |
| 15514 | WIFI_CHANNELBANDWIDTH_40MHZ | |
| 15515 | WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ); |
| 15516 | } |
| 15517 | |
| 15518 | |
| 15519 | /* mode - all supported variants */ |
| 15520 | // rcap->mode[i] = WIFI_80211_VARIANT_H; |
| 15521 | if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) { |
| 15522 | rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX ); |
| 15523 | } |
| 15524 | else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) { |
| 15525 | rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX ); |
| 15526 | } |
| 15527 | else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) { |
| 15528 | rcap->mode[i] = ( WIFI_80211_VARIANT_AX ); |
| 15529 | } |
| 15530 | rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 : |
| 15531 | ((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0); |
| 15532 | |
| 15533 | /* supportedBitRate - all supported bitrates */ |
| 15534 | rcap->supportedBitRate[i] = 0; |
| 15535 | if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) { |
| 15536 | rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS | |
| 15537 | WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS); |
| 15538 | } |
| 15539 | else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND ) | rcap->band[i] & (WIFI_FREQUENCY_6_BAND )) { |
| 15540 | rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS | |
| 15541 | WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS | |
| 15542 | WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS); |
| 15543 | } |
| 15544 | |
| 15545 | |
| 15546 | rcap->transmitPowerSupported_list[i].numberOfElements = 5; |
| 15547 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12; |
| 15548 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25; |
| 15549 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50; |
| 15550 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75; |
| 15551 | rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100; |
| 15552 | rcap->cipherSupported = 0; |
| 15553 | rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP; |
| 15554 | rcap->maxNumberVAPs = MAX_NUM_VAP_PER_RADIO; |
| 15555 | |
| 15556 | return RETURN_OK; |
| 15557 | } |
| 15558 | |
| 15559 | INT wifi_getHalCapability(wifi_hal_capability_t *cap) |
| 15560 | { |
| 15561 | INT status = 0, radioIndex = 0; |
| 15562 | char cmd[MAX_BUF_SIZE] = {0}, output[MAX_BUF_SIZE] = {0}; |
| 15563 | int iter = 0; |
| 15564 | unsigned int j = 0; |
| 15565 | int max_num_radios; |
| 15566 | wifi_interface_name_idex_map_t *iface_info = NULL; |
| 15567 | |
| 15568 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 15569 | |
| 15570 | memset(cap, 0, sizeof(wifi_hal_capability_t)); |
| 15571 | |
| 15572 | /* version */ |
| 15573 | cap->version.major = WIFI_HAL_MAJOR_VERSION; |
| 15574 | cap->version.minor = WIFI_HAL_MINOR_VERSION; |
| 15575 | |
| 15576 | /* number of radios platform property */ |
| 15577 | wifi_getMaxRadioNumber(&max_num_radios); |
| 15578 | cap->wifi_prop.numRadios = max_num_radios; |
| 15579 | |
| 15580 | for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++) |
| 15581 | { |
| 15582 | status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex])); |
| 15583 | if (status != 0) { |
| 15584 | printf("%s: getRadioCapabilities idx = %d\n", __FUNCTION__, radioIndex); |
| 15585 | return RETURN_ERR; |
| 15586 | } |
| 15587 | |
| 15588 | for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++) |
| 15589 | { |
| 15590 | if (iter >= MAX_NUM_RADIOS * MAX_NUM_VAP_PER_RADIO) |
| 15591 | { |
| 15592 | printf("%s: to many vaps for index map (%d)\n", __func__, iter); |
| 15593 | return RETURN_ERR; |
| 15594 | } |
| 15595 | iface_info = &cap->wifi_prop.interface_map[iter]; |
| 15596 | iface_info->phy_index = radioIndex; // XXX: parse phyX index instead |
| 15597 | iface_info->rdk_radio_index = radioIndex; |
| 15598 | memset(output, 0, sizeof(output)); |
| 15599 | if (wifi_getRadioIfName(radioIndex, output) == RETURN_OK) |
| 15600 | { |
| 15601 | strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1); |
| 15602 | } |
| 15603 | // TODO: bridge name |
| 15604 | // TODO: vlan id |
| 15605 | // TODO: primary |
| 15606 | iface_info->index = array_index_to_vap_index(radioIndex, j); |
| 15607 | memset(output, 0, sizeof(output)); |
| 15608 | if (wifi_getApName(iface_info->index, output) == RETURN_OK) |
| 15609 | { |
| 15610 | strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1); |
| 15611 | } |
| 15612 | iter++; |
| 15613 | } |
| 15614 | } |
| 15615 | |
| 15616 | cap->BandSteeringSupported = FALSE; |
| 15617 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 15618 | return RETURN_OK; |
| 15619 | } |
| 15620 | |
| 15621 | INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable) |
| 15622 | { |
| 15623 | struct params h_config={0}; |
| 15624 | char config_file[64] = {0}; |
| 15625 | |
| 15626 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 15627 | |
| 15628 | h_config.name = "okc"; |
| 15629 | h_config.value = okc_enable?"1":"0"; |
| 15630 | |
| 15631 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 15632 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 15633 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 15634 | |
| 15635 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 15636 | return RETURN_OK; |
| 15637 | } |
| 15638 | |
| 15639 | INT wifi_setSAEMFP(int ap_index, BOOL enable) |
| 15640 | { |
| 15641 | struct params h_config={0}; |
| 15642 | char config_file[64] = {0}; |
| 15643 | char buf[128] = {0}; |
| 15644 | |
| 15645 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 15646 | |
| 15647 | h_config.name = "sae_require_mfp"; |
| 15648 | h_config.value = enable?"1":"0"; |
| 15649 | |
| 15650 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 15651 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 15652 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 15653 | |
| 15654 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 15655 | return RETURN_OK; |
| 15656 | } |
| 15657 | |
| 15658 | INT wifi_setSAEpwe(int ap_index, int sae_pwe) |
| 15659 | { |
| 15660 | struct params h_config={0}; |
| 15661 | char config_file[64] = {0}; |
| 15662 | char buf[128] = {0}; |
| 15663 | |
| 15664 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 15665 | |
| 15666 | h_config.name = "sae_pwe"; |
| 15667 | snprintf(buf, sizeof(buf), "%d", sae_pwe); |
| 15668 | h_config.value = buf; |
| 15669 | |
| 15670 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 15671 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 15672 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 15673 | |
| 15674 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 15675 | return RETURN_OK; |
| 15676 | } |
| 15677 | |
| 15678 | INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries) |
| 15679 | { |
| 15680 | // wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3. |
| 15681 | struct params h_config={0}; |
| 15682 | char config_file[64] = {0}; |
| 15683 | |
| 15684 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__); |
| 15685 | |
| 15686 | h_config.name = "wpa_disable_eapol_key_retries"; |
| 15687 | h_config.value = disable_EAPOL_retries?"1":"0"; |
| 15688 | |
| 15689 | snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 15690 | wifi_hostapdWrite(config_file, &h_config, 1); |
| 15691 | wifi_hostapdProcessUpdate(ap_index, &h_config, 1); |
| 15692 | |
| 15693 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__); |
| 15694 | return RETURN_OK; |
| 15695 | } |
| 15696 | |
| 15697 | INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security) |
| 15698 | { |
| 15699 | char buf[128] = {0}; |
| 15700 | char config_file[128] = {0}; |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 15701 | char cmd[128] = {0}; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15702 | char password[64] = {0}; |
| 15703 | char mfp[32] = {0}; |
| 15704 | char wpa_mode[32] = {0}; |
| 15705 | BOOL okc_enable = FALSE; |
| 15706 | BOOL sae_MFP = FALSE; |
| 15707 | BOOL disable_EAPOL_retries = TRUE; |
| 15708 | int sae_pwe = 0; |
| 15709 | struct params params = {0}; |
| 15710 | wifi_band band = band_invalid; |
| 15711 | |
| 15712 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 15713 | |
| 15714 | multiple_set = TRUE; |
| 15715 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 15716 | if (security->mode == wifi_security_mode_none) { |
| 15717 | strcpy(wpa_mode, "None"); |
| 15718 | } else if (security->mode == wifi_security_mode_wpa_personal) |
| 15719 | strcpy(wpa_mode, "WPA-Personal"); |
| 15720 | else if (security->mode == wifi_security_mode_wpa2_personal) |
| 15721 | strcpy(wpa_mode, "WPA2-Personal"); |
| 15722 | else if (security->mode == wifi_security_mode_wpa_wpa2_personal) |
| 15723 | strcpy(wpa_mode, "WPA-WPA2-Personal"); |
| 15724 | else if (security->mode == wifi_security_mode_wpa_enterprise) |
| 15725 | strcpy(wpa_mode, "WPA-Enterprise"); |
| 15726 | else if (security->mode == wifi_security_mode_wpa2_enterprise) |
| 15727 | strcpy(wpa_mode, "WPA2-Enterprise"); |
| 15728 | else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise) |
| 15729 | strcpy(wpa_mode, "WPA-WPA2-Enterprise"); |
| 15730 | else if (security->mode == wifi_security_mode_wpa3_personal) { |
| 15731 | strcpy(wpa_mode, "WPA3-Personal"); |
| 15732 | okc_enable = TRUE; |
| 15733 | sae_MFP = TRUE; |
| 15734 | sae_pwe = 2; |
| 15735 | disable_EAPOL_retries = FALSE; |
| 15736 | } else if (security->mode == wifi_security_mode_wpa3_transition) { |
| 15737 | strcpy(wpa_mode, "WPA3-Personal-Transition"); |
| 15738 | okc_enable = TRUE; |
| 15739 | sae_MFP = TRUE; |
| 15740 | sae_pwe = 2; |
| 15741 | disable_EAPOL_retries = FALSE; |
| 15742 | } else if (security->mode == wifi_security_mode_wpa3_enterprise) { |
| 15743 | strcpy(wpa_mode, "WPA3-Enterprise"); |
| 15744 | sae_MFP = TRUE; |
| 15745 | sae_pwe = 2; |
| 15746 | disable_EAPOL_retries = FALSE; |
developer | d01e3e8 | 2023-04-26 19:10:38 +0800 | [diff] [blame] | 15747 | } else if (security->mode == wifi_security_mode_enhanced_open) { |
developer | 3086e2f | 2023-01-17 09:40:01 +0800 | [diff] [blame] | 15748 | strcpy(wpa_mode, "OWE"); |
| 15749 | sae_MFP = TRUE; |
| 15750 | sae_pwe = 2; |
| 15751 | disable_EAPOL_retries = FALSE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15752 | } |
| 15753 | |
| 15754 | band = wifi_index_to_band(ap_index); |
| 15755 | if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) { |
| 15756 | fprintf(stderr, "%s: 6G band must set with wpa3.\n", __func__); |
| 15757 | return RETURN_ERR; |
| 15758 | } |
| 15759 | |
| 15760 | wifi_setApSecurityModeEnabled(ap_index, wpa_mode); |
| 15761 | wifi_setOpportunisticKeyCaching(ap_index, okc_enable); |
| 15762 | wifi_setSAEMFP(ap_index, sae_MFP); |
| 15763 | wifi_setSAEpwe(ap_index, sae_pwe); |
| 15764 | wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries); |
| 15765 | |
developer | d01e3e8 | 2023-04-26 19:10:38 +0800 | [diff] [blame] | 15766 | if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) { |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 15767 | if (security->u.key.type == wifi_security_key_type_psk || security->u.key.type == wifi_security_key_type_pass || security->u.key.type == wifi_security_key_type_psk_sae) { |
| 15768 | int key_len = strlen(security->u.key.key); |
| 15769 | // wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other. |
| 15770 | if (key_len == 64) { // set wpa_psk |
| 15771 | strncpy(password, security->u.key.key, 64); // 64 characters |
| 15772 | password[64] = '\0'; |
| 15773 | wifi_setApSecurityPreSharedKey(ap_index, password); |
| 15774 | snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file); |
| 15775 | } else if (key_len >= 8 && key_len < 64) { // set wpa_passphrase |
| 15776 | strncpy(password, security->u.key.key, 63); |
| 15777 | password[63] = '\0'; |
| 15778 | wifi_setApSecurityKeyPassphrase(ap_index, password); |
| 15779 | snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file); |
| 15780 | } else |
| 15781 | return RETURN_ERR; |
| 15782 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15783 | } |
| 15784 | if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) { |
| 15785 | params.name = "sae_password"; |
| 15786 | params.value = security->u.key.key; |
| 15787 | wifi_hostapdWrite(config_file, ¶ms, 1); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 15788 | } else { // remove sae_password |
| 15789 | snprintf(cmd, sizeof(cmd), "sed -i -n -e '/^sae_password=/!p' %s", config_file); |
| 15790 | _syscmd(cmd, buf, sizeof(buf)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15791 | } |
| 15792 | } |
| 15793 | |
| 15794 | if (security->mode != wifi_security_mode_none) { |
| 15795 | memset(¶ms, 0, sizeof(params)); |
| 15796 | params.name = "wpa_pairwise"; |
| 15797 | if (security->encr == wifi_encryption_tkip) |
| 15798 | params.value = "TKIP"; |
| 15799 | else if (security->encr == wifi_encryption_aes) |
| 15800 | params.value = "CCMP"; |
| 15801 | else if (security->encr == wifi_encryption_aes_tkip) |
| 15802 | params.value = "TKIP CCMP"; |
| 15803 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15804 | } |
| 15805 | |
| 15806 | if (security->mfp == wifi_mfp_cfg_disabled) |
| 15807 | strcpy(mfp, "Disabled"); |
| 15808 | else if (security->mfp == wifi_mfp_cfg_optional) |
| 15809 | strcpy(mfp, "Optional"); |
| 15810 | else if (security->mfp == wifi_mfp_cfg_required) |
| 15811 | strcpy(mfp, "Required"); |
| 15812 | wifi_setApSecurityMFPConfig(ap_index, mfp); |
| 15813 | |
| 15814 | memset(¶ms, 0, sizeof(params)); |
| 15815 | params.name = "transition_disable"; |
| 15816 | if (security->wpa3_transition_disable == TRUE) |
| 15817 | params.value = "0x01"; |
| 15818 | else |
| 15819 | params.value = "0x00"; |
| 15820 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15821 | |
| 15822 | memset(¶ms, 0, sizeof(params)); |
| 15823 | params.name = "wpa_group_rekey"; |
| 15824 | snprintf(buf, sizeof(buf), "%d", security->rekey_interval); |
| 15825 | params.value = buf; |
| 15826 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15827 | |
| 15828 | memset(¶ms, 0, sizeof(params)); |
| 15829 | params.name = "wpa_strict_rekey"; |
| 15830 | params.value = security->strict_rekey?"1":"0"; |
| 15831 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15832 | |
| 15833 | memset(¶ms, 0, sizeof(params)); |
| 15834 | params.name = "wpa_pairwise_update_count"; |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 15835 | if (security->eapol_key_retries == 0) |
| 15836 | security->eapol_key_retries = 4; // 0 is invalid, set to default value. |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15837 | snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries); |
| 15838 | params.value = buf; |
| 15839 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15840 | |
| 15841 | memset(¶ms, 0, sizeof(params)); |
| 15842 | params.name = "disable_pmksa_caching"; |
| 15843 | params.value = security->disable_pmksa_caching?"1":"0"; |
| 15844 | wifi_hostapdWrite(config_file, ¶ms, 1); |
| 15845 | |
developer | 23e7128 | 2023-01-18 10:25:19 +0800 | [diff] [blame] | 15846 | if (multiple_set == FALSE) { |
| 15847 | wifi_setApEnable(ap_index, FALSE); |
| 15848 | wifi_setApEnable(ap_index, TRUE); |
| 15849 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15850 | |
| 15851 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 15852 | |
| 15853 | return RETURN_OK; |
| 15854 | } |
| 15855 | |
| 15856 | INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security) |
| 15857 | { |
| 15858 | char buf[256] = {0}; |
| 15859 | char config_file[128] = {0}; |
| 15860 | int disable = 0; |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 15861 | bool set_sae = FALSE; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15862 | |
| 15863 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 15864 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, ap_index); |
| 15865 | wifi_getApSecurityModeEnabled(ap_index, buf); // Get wpa config |
| 15866 | security->mode = wifi_security_mode_none; |
| 15867 | if (strlen(buf) != 0) { |
| 15868 | if (!strcmp(buf, "WPA-Personal")) |
| 15869 | security->mode = wifi_security_mode_wpa_personal; |
| 15870 | else if (!strcmp(buf, "WPA2-Personal")) |
| 15871 | security->mode = wifi_security_mode_wpa2_personal; |
| 15872 | else if (!strcmp(buf, "WPA-WPA2-Personal")) |
| 15873 | security->mode = wifi_security_mode_wpa_wpa2_personal; |
| 15874 | else if (!strcmp(buf, "WPA-Enterprise")) |
| 15875 | security->mode = wifi_security_mode_wpa_enterprise; |
| 15876 | else if (!strcmp(buf, "WPA2-Enterprise")) |
| 15877 | security->mode = wifi_security_mode_wpa2_enterprise; |
| 15878 | else if (!strcmp(buf, "WPA-WPA2-Enterprise")) |
| 15879 | security->mode = wifi_security_mode_wpa_wpa2_enterprise; |
| 15880 | else if (!strcmp(buf, "WPA3-Personal")) |
| 15881 | security->mode = wifi_security_mode_wpa3_personal; |
| 15882 | else if (!strcmp(buf, "WPA3-Personal-Transition")) |
| 15883 | security->mode = wifi_security_mode_wpa3_transition; |
| 15884 | else if (!strcmp(buf, "WPA3-Enterprise")) |
| 15885 | security->mode = wifi_security_mode_wpa3_enterprise; |
developer | 3086e2f | 2023-01-17 09:40:01 +0800 | [diff] [blame] | 15886 | else if (!strcmp(buf, "OWE")) |
developer | d01e3e8 | 2023-04-26 19:10:38 +0800 | [diff] [blame] | 15887 | security->mode = wifi_security_mode_enhanced_open; |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15888 | } |
| 15889 | |
| 15890 | wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf)); |
| 15891 | if (security->mode == wifi_security_mode_none) |
| 15892 | security->encr = wifi_encryption_none; |
| 15893 | else { |
| 15894 | if (strcmp(buf, "TKIP") == 0) |
| 15895 | security->encr = wifi_encryption_tkip; |
| 15896 | else if (strcmp(buf, "CCMP") == 0) |
| 15897 | security->encr = wifi_encryption_aes; |
| 15898 | else |
| 15899 | security->encr = wifi_encryption_aes_tkip; |
| 15900 | } |
| 15901 | |
| 15902 | if (security->mode != wifi_encryption_none) { |
| 15903 | memset(buf, 0, sizeof(buf)); |
| 15904 | // wpa3 can use one or both configs as password, so we check sae_password first. |
| 15905 | wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf)); |
developer | e575045 | 2023-05-15 16:46:42 +0800 | [diff] [blame] | 15906 | if (strlen(buf) != 0) { |
| 15907 | if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition) |
| 15908 | security->u.key.type = wifi_security_key_type_sae; |
| 15909 | set_sae = TRUE; |
| 15910 | strncpy(security->u.key.key, buf, sizeof(buf)); |
| 15911 | } |
| 15912 | wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf)); |
| 15913 | if (strlen(buf) != 0){ |
| 15914 | if (set_sae == TRUE) |
| 15915 | security->u.key.type = wifi_security_key_type_psk_sae; |
| 15916 | else if (strlen(buf) == 64) |
| 15917 | security->u.key.type = wifi_security_key_type_psk; |
| 15918 | else |
| 15919 | security->u.key.type = wifi_security_key_type_pass; |
| 15920 | strncpy(security->u.key.key, buf, sizeof(security->u.key.key)); |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15921 | } |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 15922 | security->u.key.key[255] = '\0'; |
| 15923 | } |
| 15924 | |
| 15925 | memset(buf, 0, sizeof(buf)); |
| 15926 | wifi_getApSecurityMFPConfig(ap_index, buf); |
| 15927 | if (strcmp(buf, "Disabled") == 0) |
| 15928 | security->mfp = wifi_mfp_cfg_disabled; |
| 15929 | else if (strcmp(buf, "Optional") == 0) |
| 15930 | security->mfp = wifi_mfp_cfg_optional; |
| 15931 | else if (strcmp(buf, "Required") == 0) |
| 15932 | security->mfp = wifi_mfp_cfg_required; |
| 15933 | |
| 15934 | memset(buf, 0, sizeof(buf)); |
| 15935 | security->wpa3_transition_disable = FALSE; |
| 15936 | wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf)); |
| 15937 | disable = strtol(buf, NULL, 16); |
| 15938 | if (disable != 0) |
| 15939 | security->wpa3_transition_disable = TRUE; |
| 15940 | |
| 15941 | memset(buf, 0, sizeof(buf)); |
| 15942 | wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf)); |
| 15943 | if (strlen(buf) == 0) |
| 15944 | security->rekey_interval = 86400; |
| 15945 | else |
| 15946 | security->rekey_interval = strtol(buf, NULL, 10); |
| 15947 | |
| 15948 | memset(buf, 0, sizeof(buf)); |
| 15949 | wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf)); |
| 15950 | if (strlen(buf) == 0) |
| 15951 | security->strict_rekey = 1; |
| 15952 | else |
| 15953 | security->strict_rekey = strtol(buf, NULL, 10); |
| 15954 | |
| 15955 | memset(buf, 0, sizeof(buf)); |
| 15956 | wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf)); |
| 15957 | if (strlen(buf) == 0) |
| 15958 | security->eapol_key_retries = 4; |
| 15959 | else |
| 15960 | security->eapol_key_retries = strtol(buf, NULL, 10); |
| 15961 | |
| 15962 | memset(buf, 0, sizeof(buf)); |
| 15963 | wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf)); |
| 15964 | if (strlen(buf) == 0) |
| 15965 | security->disable_pmksa_caching = FALSE; |
| 15966 | else |
| 15967 | security->disable_pmksa_caching = strtol(buf, NULL, 10)?TRUE:FALSE; |
| 15968 | |
| 15969 | /* TODO |
| 15970 | eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries |
| 15971 | */ |
| 15972 | security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol. |
| 15973 | security->eap_identity_req_timeout = 0; |
| 15974 | security->eap_identity_req_retries = 0; |
| 15975 | security->eap_req_timeout = 0; |
| 15976 | security->eap_req_retries = 0; |
| 15977 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 15978 | return RETURN_OK; |
| 15979 | } |
| 15980 | |
| 15981 | #endif /* WIFI_HAL_VERSION_3 */ |
| 15982 | |
| 15983 | #ifdef WIFI_HAL_VERSION_3_PHASE2 |
| 15984 | INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices) |
| 15985 | { |
| 15986 | char interface_name[16] = {0}; |
| 15987 | char cmd[128] = {0}; |
| 15988 | char buf[128] = {0}; |
| 15989 | char *mac_addr = NULL; |
| 15990 | BOOL status = FALSE; |
| 15991 | size_t len = 0; |
| 15992 | |
| 15993 | if(ap_index > MAX_APS) |
| 15994 | return RETURN_ERR; |
| 15995 | |
| 15996 | *output_numDevices = 0; |
| 15997 | wifi_getApEnable(ap_index, &status); |
| 15998 | if (status == FALSE) |
| 15999 | return RETURN_OK; |
| 16000 | |
| 16001 | if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) |
| 16002 | return RETURN_ERR; |
| 16003 | sprintf(cmd, "hostapd_cli -i %s list_sta", interface_name); |
| 16004 | _syscmd(cmd, buf, sizeof(buf)); |
| 16005 | |
| 16006 | mac_addr = strtok(buf, "\n"); |
| 16007 | for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) { |
| 16008 | *output_numDevices = i + 1; |
| 16009 | fprintf(stderr, "mac_addr: %s\n", mac_addr); |
| 16010 | addr_ptr = output_deviceMacAddressArray[i]; |
| 16011 | mac_addr_aton(addr_ptr, mac_addr); |
| 16012 | mac_addr = strtok(NULL, "\n"); |
| 16013 | } |
| 16014 | |
| 16015 | return RETURN_OK; |
| 16016 | } |
| 16017 | #else |
| 16018 | INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size) |
| 16019 | { |
| 16020 | char interface_name[16] = {0}; |
| 16021 | char cmd[128]; |
| 16022 | BOOL status = false; |
| 16023 | |
| 16024 | if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0) |
| 16025 | return RETURN_ERR; |
| 16026 | |
| 16027 | output_buf[0] = '\0'; |
| 16028 | |
| 16029 | wifi_getApEnable(ap_index,&status); |
| 16030 | if (!status) |
| 16031 | return RETURN_OK; |
| 16032 | |
| 16033 | if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) |
| 16034 | return RETURN_ERR; |
| 16035 | sprintf(cmd, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name); |
| 16036 | _syscmd(cmd, output_buf, output_buf_size); |
developer | 69b61b0 | 2023-03-07 17:17:44 +0800 | [diff] [blame] | 16037 | |
developer | 72fb0bb | 2023-01-11 09:46:29 +0800 | [diff] [blame] | 16038 | return RETURN_OK; |
| 16039 | } |
| 16040 | #endif |
| 16041 | |
| 16042 | INT wifi_getProxyArp(INT apIndex, BOOL *enable) |
| 16043 | { |
| 16044 | char output[16]={'\0'}; |
| 16045 | char config_file[MAX_BUF_SIZE] = {0}; |
| 16046 | |
| 16047 | if (!enable) |
| 16048 | return RETURN_ERR; |
| 16049 | |
| 16050 | sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, apIndex); |
| 16051 | wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output)); |
| 16052 | |
| 16053 | if (strlen(output) == 0) |
| 16054 | *enable = FALSE; |
| 16055 | else if (strncmp(output, "1", 1) == 0) |
| 16056 | *enable = TRUE; |
| 16057 | else |
| 16058 | *enable = FALSE; |
| 16059 | |
| 16060 | wifi_dbg_printf("\n[%s]: proxy_arp is : %s", __func__, output); |
| 16061 | return RETURN_OK; |
| 16062 | } |
| 16063 | |
| 16064 | INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable) |
| 16065 | { |
| 16066 | if (NULL == output_enable || radioIndex >=MAX_NUM_RADIOS) |
| 16067 | return RETURN_ERR; |
| 16068 | *output_enable=TRUE; |
| 16069 | return RETURN_OK; |
| 16070 | } |
| 16071 | |
| 16072 | INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned) |
| 16073 | { |
| 16074 | char cmd[128] = {0}; |
| 16075 | char buf[128] = {0}; |
| 16076 | char line[128] = {0}; |
| 16077 | size_t len = 0; |
| 16078 | FILE *f = NULL; |
| 16079 | int index = 0; |
| 16080 | int exp = 0; |
| 16081 | int mantissa = 0; |
| 16082 | int duration = 0; |
| 16083 | int radio_index = 0; |
| 16084 | int max_radio_num = 0; |
| 16085 | uint twt_wake_interval = 0; |
| 16086 | int phyId = 0; |
| 16087 | WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__); |
| 16088 | |
| 16089 | wifi_getMaxRadioNumber(&max_radio_num); |
| 16090 | |
| 16091 | radio_index = ap_index % max_radio_num; |
| 16092 | |
| 16093 | phyId = radio_index_to_phy(radio_index); |
| 16094 | sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId); |
| 16095 | _syscmd(cmd, buf, sizeof(buf)); |
| 16096 | *numSessionReturned = strtol(buf, NULL, 10) - 1; |
| 16097 | if (*numSessionReturned > maxNumberSessions) |
| 16098 | *numSessionReturned = maxNumberSessions; |
| 16099 | else if (*numSessionReturned < 1) { |
| 16100 | *numSessionReturned = 0; |
| 16101 | return RETURN_OK; |
| 16102 | } |
| 16103 | |
| 16104 | sprintf(cmd, "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned); |
| 16105 | if ((f = popen(cmd, "r")) == NULL) { |
| 16106 | wifi_dbg_printf("%s: popen %s error\n", __func__, cmd); |
| 16107 | return RETURN_ERR; |
| 16108 | } |
| 16109 | |
| 16110 | // the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]" |
| 16111 | while((fgets(line, sizeof(line), f)) != NULL) { |
| 16112 | char *tmp = NULL; |
| 16113 | strcpy(buf, line); |
| 16114 | tmp = strtok(buf, " "); |
| 16115 | twtSessions[index].numDevicesInSession = strtol(tmp, NULL, 10); |
| 16116 | tmp = strtok(NULL, " "); |
| 16117 | twtSessions[index].twtParameters.operation.flowID = strtol(tmp, NULL, 10); |
| 16118 | tmp = strtok(NULL, " "); |
| 16119 | if (strstr(tmp, "t")) { |
| 16120 | twtSessions[index].twtParameters.operation.trigger_enabled = TRUE; |
| 16121 | } |
| 16122 | if (strstr(tmp, "a")) { |
| 16123 | twtSessions[index].twtParameters.operation.announced = TRUE; |
| 16124 | } |
| 16125 | tmp = strtok(NULL, " "); |
| 16126 | exp = strtol(tmp, NULL, 10); |
| 16127 | tmp = strtok(NULL, " "); |
| 16128 | mantissa = strtol(tmp, NULL, 10); |
| 16129 | tmp = strtok(NULL, " "); |
| 16130 | duration = strtol(tmp, NULL, 10); |
| 16131 | |
| 16132 | // only implicit supported |
| 16133 | twtSessions[index].twtParameters.operation.implicit = TRUE; |
| 16134 | // only individual agreement supported |
| 16135 | twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual; |
| 16136 | |
| 16137 | // wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47. |
| 16138 | twt_wake_interval = mantissa * (1 << exp); |
| 16139 | if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) { |
| 16140 | // Overflow handling |
| 16141 | twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1; // max unsigned int |
| 16142 | } else { |
| 16143 | twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval; |
| 16144 | } |
| 16145 | twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256; |
| 16146 | index++; |
| 16147 | } |
| 16148 | |
| 16149 | pclose(f); |
| 16150 | WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__); |
| 16151 | return RETURN_OK; |
| 16152 | } |