[[AN7581][Eagle][RDK-B] the wifi-hal of CcspWifissp cause 6G and TBTC performance downgrade]
[Description]
replace syscmd with stardard c code.
[Release-log]
diff --git a/src/logan_wifi/wifi_hal.c b/src/logan_wifi/wifi_hal.c
index e1fd24c..23c7866 100644
--- a/src/logan_wifi/wifi_hal.c
+++ b/src/logan_wifi/wifi_hal.c
@@ -46,6 +46,8 @@
#include <stdbool.h>
#include <pthread.h>
#include "wifi_hal.h"
+#include <libkvcutil.h>
+#include <dirent.h>
#ifdef HAL_NETLINK_IMPL
#include <errno.h>
@@ -353,6 +355,24 @@
INT Noise;
}wifi_radio_stats_t;
+struct ctrl {
+ char sockpath[128];
+ char sockdir[128];
+ char bss[IFNAMSIZ];
+ char reply[4096];
+ int ssid_index;
+ void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
+ void (*overrun)(struct ctrl *ctrl);
+ struct wpa_ctrl *wpa;
+ unsigned int ovfl;
+ size_t reply_len;
+ int initialized;
+ ev_timer retry;
+ ev_timer watchdog;
+ ev_stat stat;
+ ev_io io;
+};
+
#ifdef WIFI_HAL_VERSION_3
// Return number of elements in array
@@ -442,6 +462,8 @@
int hostapd_raw_add_bss(int apIndex);
int hostapd_raw_remove_bss(int apIndex);
INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size);
+static int wifi_GetInterfaceName(int apIndex, char *interface_name);
+bool wifi_get_ap_status_ioctl(char *interface_name);
static inline int hal_strtol(char *src, int base, long int *out)
{
@@ -1874,22 +1896,24 @@
static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
{
-
- char buf[MAX_BUF_SIZE] = {0};
+ struct kvc_context *ctx;
+ const char *value;
int res = 0;
-
- res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^%s=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",conf_file, param);
- if (res) {
- wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
- }
-
-
- res = snprintf(output, output_size, "%s", buf);
- if (os_snprintf_error(output_size, res)) {
- wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
+ ctx = kvc_load(conf_file, LF_KEY_CASE_SENSITIVE);
+ if (!ctx) {
+ wifi_debug(DEBUG_ERROR, "load conf fail\n");
return RETURN_ERR;
}
+ value = kvc_get(ctx, param);
+ if (value) {
+ res = snprintf(output, output_size, "%s", value);
+ if (os_snprintf_error(output_size, res)) {
+ wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail, conf_file[%s] param[%s] %s\n", conf_file, param, value);
+ return RETURN_ERR;
+ }
+ }
+ kvc_unload(ctx);
return 0;
}
@@ -3637,7 +3661,6 @@
INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool) //RDKB
{
char interface_name[16] = {0};
- char buf[128] = {0};
int apIndex, bss_idx;
if (NULL == output_bool)
@@ -3655,7 +3678,7 @@
if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
continue;
- *output_bool = _syscmd_secure(buf, sizeof(buf), "ifconfig %s 2> /dev/null | grep UP", interface_name) ? FALSE : TRUE;
+ *output_bool = wifi_get_ap_status_ioctl(interface_name);
if (*output_bool == TRUE)
break;
@@ -6821,10 +6844,9 @@
INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
{
char buf[32] = {0};
- int ret = 0, res, len = 0;
+ int ret = 0, res;
BOOL radio_enable = FALSE;
- //unsigned char bw;
- char interface_name[64] = {0};
+ unsigned char bw;
int main_vap_idx;
WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
@@ -6847,17 +6869,13 @@
return RETURN_ERR;
}
- if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
- return RETURN_ERR;
-
- ret = _syscmd_secure(buf, sizeof(buf), "iw dev %s info | grep 'width' | cut -d ' ' -f6 | tr -d '\\n'", interface_name);
- if(ret) {
- wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
+ if (mtk_wifi_get_radio_info(radioIndex, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_BANDWIDTH,
+ get_bandwidth_handler, &bw) != RETURN_OK) {
+ wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_BANDWIDTH cmd fails\n");
}
-
- len = strlen(buf);
- if ((ret != 0) || (len == 0)) {
- wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
+ ret = bwidx_to_string(bw, buf);
+ if (ret) {
+ wifi_debug(DEBUG_ERROR, "bwidx_to_string fails\n");
return RETURN_ERR;
}
@@ -12057,12 +12075,154 @@
return RETURN_OK;
}
+bool get_ctrl_interface(char *ctrl_interface, char *interface_name)
+{
+ DIR *dir;
+ struct dirent *entry;
+ bool found = FALSE;
+
+ if (strlen(ctrl_interface) == 0)
+ dir = opendir("/var/run/hostapd/");
+ else
+ dir = opendir(ctrl_interface);
+
+ if (dir == NULL) {
+ wifi_debug(DEBUG_ERROR, "opendir fail\n");
+ return FALSE;
+ }
+
+ while ((entry = readdir(dir)) != NULL) {
+ if (strcmp(entry->d_name, interface_name) == 0) {
+ found = TRUE;
+ break;
+ }
+ }
+
+ closedir(dir);
+ return found;
+}
+
+int hostapd_connect(struct ctrl *wpa_ctrl, char *interface_name)
+{
+ int ret = 0;
+
+ ret = snprintf(wpa_ctrl->sockpath, sizeof(wpa_ctrl->sockpath), "%s%s", SOCK_PREFIX, interface_name);
+ if (os_snprintf_error(sizeof(wpa_ctrl->sockpath), ret)) {
+ wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
+ return RETURN_ERR;
+ }
+
+ wpa_ctrl->wpa = wpa_ctrl_open(wpa_ctrl->sockpath);
+ if (!wpa_ctrl->wpa)
+ return RETURN_ERR;
+
+ if (wpa_ctrl_attach(wpa_ctrl->wpa) < 0) {
+ wpa_ctrl_close(wpa_ctrl->wpa);
+ return RETURN_ERR;
+ }
+
+ return RETURN_OK;
+}
+
+void hostapd_disconnect(struct ctrl *wpa_ctrl)
+{
+ wpa_ctrl_detach(wpa_ctrl->wpa);
+ wpa_ctrl_close(wpa_ctrl->wpa);
+ wpa_ctrl->wpa = NULL;
+
+ return;
+}
+
+static int hostapd_command(struct ctrl *ctrl, const char *cmd, char *reply, size_t *reply_len)
+{
+ char buf[4096];
+ size_t len;
+ int ret;
+
+ len = sizeof(buf) - 1;
+ ret = wpa_ctrl_request(ctrl->wpa, cmd, strlen(cmd), buf, &len, NULL);
+
+ if (ret < 0) {
+ wifi_debug(DEBUG_ERROR, "wpa_ctrl_request fail, ret = %d\n", ret);
+ return ret;
+ }
+
+ if (len > *reply_len)
+ len = *reply_len;
+
+ memcpy(reply, buf, len);
+ reply[*reply_len - 1] = '\0';
+
+ return 0;
+}
+
+int wifi_get_ap_status_hostapd(char *interface_name, BOOL *output_bool)
+{
+ struct ctrl wpa_ctrl = {0};
+ const char *status = "STATUS";
+ char reply[1024];
+ size_t len = sizeof(reply);
+ char *pos;
+
+ if(hostapd_connect(&wpa_ctrl, interface_name) == RETURN_ERR) {
+ wifi_debug(DEBUG_ERROR, "hostapd_connect fail\n");
+ return RETURN_ERR;
+ }
+
+ if (hostapd_command(&wpa_ctrl, status, reply, &len)) {
+ hostapd_disconnect(&wpa_ctrl);
+ return RETURN_ERR;
+ }
+
+ pos = strstr(reply, "state=");
+ if (pos != NULL) {
+ pos += 6;
+ if (strncmp(pos, "ENABLED", 7) == 0 || strncmp(pos, "ACS", 3) == 0 ||
+ strncmp(pos, "HT_SCAN", 7) == 0 || strncmp(pos, "DFS", 3) == 0) {
+ *output_bool = TRUE;
+ } else
+ *output_bool = FALSE;
+ } else {
+ *output_bool = FALSE;
+ }
+
+ hostapd_disconnect(&wpa_ctrl);
+ return RETURN_OK;
+}
+
+
+bool wifi_get_ap_status_ioctl(char *interface_name)
+{
+ struct ifreq ifr;
+ int sock = socket(AF_INET, SOCK_DGRAM, 0);
+
+ if(sock < 0) {
+ wifi_debug(DEBUG_ERROR, "sock init fail\n");
+ return FALSE;
+ }
+
+ if (strlen(interface_name) >= IFNAMSIZ) {
+ wifi_debug(DEBUG_ERROR, "invalide interface_name length=%ld\n", strlen(interface_name));
+ close(sock);
+ return FALSE;
+ }
+
+ memset(&ifr, 0, sizeof(ifr));
+ strncpy(ifr.ifr_name, interface_name, strlen(interface_name));
+ if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
+ wifi_debug(DEBUG_INFO, "ioctl(SIOCGIFFLAGS) failed, %s\n", strerror(errno));
+ close(sock);
+ return FALSE;
+ }
+
+ close(sock);
+ return !!(ifr.ifr_flags & IFF_UP);
+}
// Outputs the setting of the internal variable that is set by wifi_setApEnable().
INT wifi_getApEnable(INT apIndex, BOOL *output_bool)
{
char interface_name[IF_NAME_SIZE] = {0};
- char buf[MAX_BUF_SIZE] = {0};
- int res, len;
+ int res;
char ctrl_interface[64] = {0};
char config_file[128] = {0};
BOOL is_ap_enable, hostapd_state;
@@ -12089,26 +12249,13 @@
wifi_debug(DEBUG_ERROR, "ctrl_interface for %s not exist\n", interface_name);
}
- _syscmd_secure(buf, sizeof(buf), "ls %s | grep %s",
- strlen(ctrl_interface) == 0 ? "/var/run/hostapd/" : ctrl_interface, interface_name);
- len = strlen(buf) >= strlen(interface_name) ? strlen(interface_name) : strlen(buf);
-
- if (len == 0 || strncmp(buf, interface_name, len)) {
+ if (get_ctrl_interface(ctrl_interface, interface_name) == FALSE)
return RETURN_OK;
- }
- memset(buf, 0, sizeof(buf));
-
- res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s status | grep state | cut -d '=' -f2", interface_name);
- if (res) {
- wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
- }
- if (strncmp(buf, "ENABLED", 7) == 0 || strncmp(buf, "ACS", 3) == 0 ||
- strncmp(buf, "HT_SCAN", 7) == 0 || strncmp(buf, "DFS", 3) == 0) {
- hostapd_state = TRUE;
- }
+ if (wifi_get_ap_status_hostapd(interface_name, &hostapd_state) == RETURN_ERR)
+ wifi_debug(DEBUG_ERROR, "wifi_get_ap_status_hostapd RETURN_ERR\n");
- is_ap_enable = _syscmd_secure(buf, sizeof(buf), "ifconfig %s | grep UP", interface_name) ? FALSE : TRUE;
+ is_ap_enable = wifi_get_ap_status_ioctl(interface_name);
if (hostapd_state && is_ap_enable)
*output_bool = TRUE;
@@ -18043,23 +18190,6 @@
((type *)((char *)ptr - offset_of(type, member)))
#endif /* container_of */
-struct ctrl {
- char sockpath[128];
- char sockdir[128];
- char bss[IFNAMSIZ];
- char reply[4096];
- int ssid_index;
- void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
- void (*overrun)(struct ctrl *ctrl);
- struct wpa_ctrl *wpa;
- unsigned int ovfl;
- size_t reply_len;
- int initialized;
- ev_timer retry;
- ev_timer watchdog;
- ev_stat stat;
- ev_io io;
-};
struct ev_loop *evloop = NULL;
static wifi_newApAssociatedDevice_callback clients_connect_cb[MAX_CB_SIZE] = {0};
static wifi_apDisassociatedDevice_callback clients_disconnect_cb[MAX_CB_SIZE] = {0};
@@ -22828,6 +22958,77 @@
#endif /* WIFI_HAL_VERSION_3 */
+static int hostapd_get_sta(struct ctrl *ctrl, const char *cmd,
+ char *addr, size_t addr_len)
+{
+ char buf[4096], *pos;
+ size_t len;
+ int ret;
+
+ len = sizeof(buf) - 1;
+ ret = wpa_ctrl_request(ctrl->wpa, cmd, strlen(cmd), buf, &len, NULL);
+ if (ret < 0) {
+ wifi_debug(DEBUG_ERROR, "wpa_ctrl_request fail, ret = %d\n", ret);
+ return ret;
+ }
+
+ buf[len] = '\0';
+ if (memcmp(buf, "FAIL", 4) == 0 || memcmp(buf, "UNKNOWN COMMAND", 15) == 0)
+ return -1;
+
+ pos = buf;
+ while (*pos != '\0' && *pos != '\n')
+ pos++;
+ *pos = '\0';
+ memcpy(addr, buf, addr_len);
+ return 0;
+}
+
+int wifi_get_associated_sta(char *interface_name, CHAR *output_buf, INT output_buf_size)
+{
+ struct ctrl wpa_ctrl = {0};
+ char addr[32], cmd[64];
+ int tem_len;
+ int res;
+
+ memset(output_buf, 0, output_buf_size);
+ tem_len = output_buf_size - strlen(output_buf);
+
+ if(hostapd_connect(&wpa_ctrl, interface_name) == RETURN_ERR) {
+ wifi_debug(DEBUG_ERROR, "hostapd_connect fail\n");
+ return RETURN_ERR;
+ }
+
+ if (hostapd_get_sta(&wpa_ctrl, "STA-FIRST", addr, sizeof(addr))) {
+ hostapd_disconnect(&wpa_ctrl);
+ return RETURN_OK;
+ }
+
+ do {
+ if (strlen(addr) == 17) {
+ res = snprintf(output_buf + strlen(output_buf), tem_len, "%s,", addr);
+ if (os_snprintf_error(tem_len, res)) {
+ wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
+ break;
+ }
+ tem_len = output_buf_size - strlen(output_buf);
+ }
+
+ res = snprintf(cmd, sizeof(cmd), "STA-NEXT %s", addr);
+ if (os_snprintf_error(sizeof(cmd), res)) {
+ wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
+ break;
+ }
+ } while (hostapd_get_sta(&wpa_ctrl, cmd, addr, sizeof(addr)) == 0);
+
+ /* Remove the last comma */
+ if (strlen(output_buf) != 0)
+ output_buf[strlen(output_buf) - 1] = '\0';
+
+ hostapd_disconnect(&wpa_ctrl);
+ return RETURN_OK;
+}
+
#ifdef WIFI_HAL_VERSION_3_PHASE2
INT wifi_getApAssociatedDevice(INT ap_index, mac_address_t *output_deviceMacAddressArray, UINT maxNumDevices, UINT *output_numDevices)
{
@@ -22872,7 +23073,7 @@
char interface_name[16] = {0};
BOOL status = false;
- int res;
+ //int res;
if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
return RETURN_ERR;
@@ -22885,14 +23086,12 @@
if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
return RETURN_ERR;
- res = _syscmd_secure(output_buf, output_buf_size, "hostapd_cli -i %s list_sta | tr '\\n' ',' | sed 's/.$//'", interface_name);
- if (res) {
- wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
+ if (wifi_get_associated_sta(interface_name, output_buf, output_buf_size) != RETURN_OK) {
+ wifi_debug(DEBUG_ERROR, "wifi_get_associated_sta fail\n");
+ return RETURN_ERR;
}
-
-
return RETURN_OK;
}
#endif