diff --git a/src/logan_wifi/Makefile.am b/src/logan_wifi/Makefile.am
deleted file mode 100644
index 2202692..0000000
--- a/src/logan_wifi/Makefile.am
+++ /dev/null
@@ -1,35 +0,0 @@
-##########################################################################
-# If not stated otherwise in this file or this component's LICENSE
-# file the following copyright and licenses apply:
-#
-# Copyright 2019 RDK Management
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##########################################################################
-AM_CFLAGS = -D_ANSC_LINUX
-AM_CFLAGS += -D_ANSC_USER
-AM_CFLAGS += -D_ANSC_LITTLE_ENDIAN_
-
-AM_CPPFLAGS = -Wall -Werror
-ACLOCAL_AMFLAGS = -I m4
-hardware_platform = armv7ahf-neon-rdk-linux-musleabi
-
-lib_LTLIBRARIES = libhal_wifi.la
-libhal_wifi_la_CPPFLAGS = -I$(top_srcdir)/include $(CPPFLAGS)
-libhal_wifi_la_SOURCES = wifi_hal.c
-libhal_wifi_la_LDFLAGS = -lev -lwpa_client
-
-#wifihal test binary
-bin_PROGRAMS = wifihal
-wifihal_CPPFLAGS = -I$(top_srcdir)/include $(CPPFLAGS) -D_WIFI_HAL_TEST_
-wifihal_SOURCES = wifi_hal.c
diff --git a/src/logan_wifi/client_wifi_hal.c b/src/logan_wifi/client_wifi_hal.c
deleted file mode 100644
index 8207ed2..0000000
--- a/src/logan_wifi/client_wifi_hal.c
+++ /dev/null
@@ -1,721 +0,0 @@
-/*
- * If not stated otherwise in this file or this component's LICENSE file the
- * following copyright and licenses apply:
- *
- * Copyright 2019 RDK Management
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include "wifi_hal.h"
-#include "client_wifi_hal.h"
-
-#include <ev.h>
-#include <wpa_ctrl.h>
-#include <errno.h>
-#include <net/if.h>
-#define CTRL_INTERFACE "/var/run/wpa_supplicant"
-
-/* Helper wpa_supplicant events */
-#ifndef container_of
-#define offsetof(st, m) ((size_t)&(((st *)0)->m))
-#define container_of(ptr, type, member) \
-                   ((type *)((char *)ptr - offsetof(type, member)))
-#endif /* container_of */
-static int _syscmd(char *cmd, char *retBuf, int retBufSize)
-{
-    FILE *f;
-    char *ptr = retBuf;
-    int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
-
-    if((f = popen(cmd, "r")) == NULL) {
-        fprintf(stderr,"\npopen %s error\n", cmd);
-        return RETURN_ERR;
-    }
-
-    while(!feof(f))
-    {   
-        *ptr = 0;
-        if(bufSize>=128) {
-            bufbytes=128;
-        } else {
-            bufbytes=bufSize-1;
-        }
-
-        fgets(ptr,bufbytes,f);
-        readbytes=strlen(ptr);
-
-        if(!readbytes)
-            break;
-
-        bufSize-=readbytes;
-        ptr += readbytes;
-    }
-    cmd_ret = pclose(f);
-    retBuf[retBufSize-1]=0;
-
-    return cmd_ret >> 8;
-}
-
-struct ctrl {
-    char sockpath[128];
-    char sockdir[128];
-    char bss[IFNAMSIZ];
-    int ssid_index;
-    void (*cb)(struct ctrl *ctrl, int level, const char *buf, size_t len);
-    void (*overrun)(struct ctrl *ctrl);
-    void (*closed)(struct ctrl *ctrl);
-    struct wpa_ctrl *wpa;
-    unsigned int ovfl;
-    int initialized;
-    ev_timer retry;
-    ev_stat stat;
-    ev_io io;
-    char reply[4096];
-    size_t reply_len;
-    ev_timer watchdog;
-};
-static wifi_client_event_callback clients_connect_cb;
-static struct ctrl wpa_ctrl[2];
-static int client_initialized;
-
-static void ctrl_close(struct ctrl *ctrl)
-{
-    if (ctrl->io.cb)
-        ev_io_stop(EV_DEFAULT_ &ctrl->io);
-    if (ctrl->retry.cb)
-        ev_timer_stop(EV_DEFAULT_ &ctrl->retry);
-    if (ctrl->watchdog.cb)
-        ev_timer_stop(EV_DEFAULT_ &ctrl->watchdog);
-    if (!ctrl->wpa)
-        return;
-
-    wpa_ctrl_detach(ctrl->wpa);
-    wpa_ctrl_close(ctrl->wpa);
-    ctrl->wpa = NULL;
-    
-    if (ctrl->closed)
-        ctrl->closed(ctrl);
-}
-
-static void ctrl_process(struct ctrl *ctrl)
-{
-    char *str;
-    size_t len;
-    char buf[1024];
-    int drops;
-    int level;
-    int err;
-    char * k;
-    char * v;
-    char *kv;
-    wifi_client_associated_dev_t ap;
-    memset(&ap, 0, sizeof(ap));
-
-    /* Example events:
-     *
-     * CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
-     * CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
-    */
-    if (!(str = index(ctrl->reply, '>')))
-        return;
-    if (sscanf(ctrl->reply, "<%d>", &level) != 1)
-        return;
-
-    str++;
- 
-    if (strncmp("CTRL-EVENT-CONNECTED ", str, 21) == 0) {
-        strsep(&str, " "); /* "-" */
-        strsep(&str, " "); /* "Connection" */
-        strsep(&str, " "); /* "to" */
-
-        sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-                &ap.MACAddress[0], &ap.MACAddress[1], &ap.MACAddress[2],
-                &ap.MACAddress[3], &ap.MACAddress[4], &ap.MACAddress[5]);
-        strsep(&str, " [id="); // completed
-        ap.NetworkID = atoi(str);
-       
-        ap.connected = true;       
-       
-        (clients_connect_cb)(ctrl->ssid_index, &ap);
-        goto handled;
-    }
-    if (strncmp("CTRL-EVENT-DISCONNECTED ", str, 24) == 0) {
-        while ((kv = strsep(&str, " "))) {
-            if ((k = strsep(&kv, "=")) &&
-                (v = strsep(&kv, ""))) {
-                if (!strcmp(k, "bssid"))
-                    sscanf(v, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-                        &ap.MACAddress[0], &ap.MACAddress[1], &ap.MACAddress[2],
-                        &ap.MACAddress[3], &ap.MACAddress[4], &ap.MACAddress[5]);
-
-                else if (!strcmp(k, "reason"))
-                    ap.reason = atoi(v);
-                else if (!strcmp(k, "locally_generated"))
-                    ap.locally_generated = atoi(v);
-            }
-        }
-        ap.connected = false;
-        (clients_connect_cb)(ctrl->ssid_index, &ap);
-        goto handled;
-    }
-
-handled:
-
-    return;
-
-}
-
-static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events) {
-    struct ctrl *ctrl = container_of(io, struct ctrl, io);
-    int err;
-
-    ctrl->reply_len = sizeof(ctrl->reply) - 1;
-    err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
-    ctrl->reply[ctrl->reply_len] = 0;
-    if (err < 0) {
-        if (errno == EAGAIN || errno == EWOULDBLOCK)
-            return;
-        ctrl_close(ctrl);
-        ev_timer_again(EV_A_ &ctrl->retry);
-        return;
-    }
-
-    ctrl_process(ctrl);
-}
-
-static int ctrl_open(struct ctrl *ctrl)
-{
-    int fd;
-
-    if (ctrl->wpa)
-        return 0;
-
-    ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
-    if (!ctrl->wpa)
-        goto err;
-
-    if (wpa_ctrl_attach(ctrl->wpa) < 0)
-        goto err_close;
-
-    fd = wpa_ctrl_get_fd(ctrl->wpa);
-    if (fd < 0)
-        goto err_detach;
-    ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
-    ev_io_start(EV_DEFAULT_ &ctrl->io);
-
-    ev_timer_again(EV_DEFAULT_ &ctrl->watchdog);
-
-    return 0;
-
-err_detach:
-    wpa_ctrl_detach(ctrl->wpa);
-err_close:
-    wpa_ctrl_close(ctrl->wpa);
-err:
-    ctrl->wpa = NULL;
-    return -1;
-}
-
-static void ctrl_msg_cb(char *buf, size_t len)
-{
-    struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
-    ctrl_process(ctrl);
-}
-
-static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
-{
-    int err;
-
-    if (!ctrl->wpa)
-        return -1;
-    if (*reply_len < 2)
-        return -1;
-
-    (*reply_len)--;
-    ctrl->reply_len = sizeof(ctrl->reply);
-    err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
-    if (err < 0)
-        return err;
-
-    if (ctrl->reply_len > *reply_len)
-        ctrl->reply_len = *reply_len;
-
-    *reply_len = ctrl->reply_len;
-    memcpy(reply, ctrl->reply, *reply_len);
-    reply[*reply_len] = 0;
-    return 0;
-}
-
-static void
-ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
-{
-    struct ctrl *ctrl = container_of(timer, struct ctrl, watchdog);
-    const char *pong = "PONG";
-    const char *ping = "PING";
-    char reply[1024];
-    size_t len = sizeof(reply);
-    int err;
-    err = ctrl_request(ctrl, ping, strlen(ping), reply, &len);
-    if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong))) {
-        return;
-    }
-    ctrl_close(ctrl);
-    ev_timer_again(EV_A_ &ctrl->retry);
-}
-
-
-static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
-{
-    struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
-
-    printf("%s: file state changed", ctrl->bss);
-    ctrl_open(ctrl);
-}
-
-static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
-{
-    struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
-
-    printf("CTRL %s: retrying", ctrl->bss);
-    if (ctrl_open(ctrl) < 0)
-        ev_timer_again(EV_DEFAULT_ &ctrl->retry);
-}
-
-static int ctrl_enable(struct ctrl *ctrl)
-{
-    if (ctrl->wpa)
-        return 0;
-
-    if (!ctrl->stat.cb) {
-        ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
-        ev_stat_start(EV_DEFAULT_ &ctrl->stat);
-    }
-
-    if (!ctrl->retry.cb)
-        ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
-
-    if (!ctrl->watchdog.cb)
-        ev_timer_init(&ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
-
-
-    return ctrl_open(ctrl);
-}
-
-/* client API */
-INT wifi_getSTANumberOfEntries(ULONG *output) //Tr181
-{
-    char cmd[128] = {0};
-    char buf[16] = {0};
-
-    if (NULL == output)
-        return RETURN_ERR;
-
-    snprintf(cmd, sizeof(cmd), "wpa_cli -g%s-global status | grep ^ifname | wc -l", CTRL_INTERFACE);
-    _syscmd(cmd, buf, sizeof(buf));
-    // *output = 2;
-    *output = strtoll(buf, NULL, 10);
-    return RETURN_OK;
-}
-
-INT wifi_getSTAName(INT apIndex, CHAR *output_string)
-{
-    int radioIndex = 0;
-    int staIndex = 0;
-
-    if (NULL == output_string || apIndex < 0)
-        return RETURN_ERR;
-
-    wifi_getSTARadioIndex(apIndex, &radioIndex);
-    staIndex = apIndex % radioIndex;
-    snprintf(output_string, 33, "radio%d-sta%d", radioIndex, staIndex);
-
-    return RETURN_OK;
-}
-
-INT wifi_getSTARadioIndex(INT ssidIndex, INT *radioIndex)
-{
-    if (NULL == radioIndex)
-        return RETURN_ERR;
-    *radioIndex = ssidIndex%MAX_NUM_RADIOS;
-    return RETURN_OK;
-}
-
-INT wifi_getSTAMAC(INT ssidIndex, CHAR *output_string)
-{
-    char cmd[128] = {0};
-    int ret = 0;
-    char ssid_ifname[128];
-
-    if (NULL == output_string)
-        return RETURN_ERR;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-    {   
-        return RETURN_ERR;
-    }
-
-    sprintf(cmd, "wpa_cli -i%s status |grep '^address' | cut -f 2 -d =", ssid_ifname);
-    _syscmd(cmd, output_string, 64);
-
-    return RETURN_OK;
-}
-
-INT wifi_getSTABSSID(INT ssidIndex, CHAR *output_string)
-{
-    char cmd[128] = {0};
-    int ret = 0;
-    char ssid_ifname[128];
-
-    if (NULL == output_string)
-        return RETURN_ERR;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-    {
-        return RETURN_ERR;
-    }
-
-    sprintf(cmd, "wpa_cli -i%s status |grep bssid | cut -f 2 -d =", ssid_ifname);
-    _syscmd(cmd, output_string, 64);
-
-    return RETURN_OK;
-}
-
-INT wifi_setSTABSSID(INT ssidIndex, CHAR *input_string)
-{
-    char cmd[128] = {0};
-    int ret = 0;
-    char ssid_ifname[128];
-    char buf[128] = {0};
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-        return RETURN_ERR;
-
-    snprintf(cmd, sizeof(cmd), "ip link set dev %s address %s", ssid_ifname, input_string);
-    _syscmd(cmd, buf, sizeof(buf));
-
-    return RETURN_OK;
-}
-
-INT wifi_getSTASSID(INT ssidIndex, CHAR *output_string)
-{
-    char cmd[128] = {0};
-    int ret = 0;
-    char ssid_ifname[128];
-
-    if (NULL == output_string)
-        return RETURN_ERR;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-    {
-        return RETURN_ERR;
-    }
-
-    sprintf(cmd, "wpa_cli -i%s status |grep ^ssid | cut -f 2 -d = | tr -d '\n'", ssid_ifname);
-    _syscmd(cmd, output_string, 64);
-
-    return RETURN_OK;
-}
-
-INT wifi_getSTACredentials(INT ssidIndex, CHAR *output_string)
-{
-    char cmd[128] = {0};
-    int ret = 0;
-    char ssid_ifname[128];
-
-    if (NULL == output_string)
-        return RETURN_ERR;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-    {   
-        return RETURN_ERR;
-    }
-
-    sprintf(cmd, "wpa_cli -i%s status |grep ssid | cut -f 2 -d =", ssid_ifname);
-    _syscmd(cmd, output_string, 64);
-
-    return RETURN_OK;
-}
-
-static int init_client_wpa()
-{
-    int ret = 0, i = 0;
-    ULONG s, snum;
-    char * sock_path;
-    char ssid_ifname[128];
-
-    ret = wifi_getSTANumberOfEntries(&snum);
-    if (ret != RETURN_OK) {
-        printf("%s: failed to get SSID count", __func__);
-        return RETURN_ERR;
-    }
-
-    for (s = 0; s < snum; s++) {
-        ret = wifi_getSTAName(s, ssid_ifname);
-        if (ret != RETURN_OK)
-        {   
-            return RETURN_ERR;
-        }
-        sprintf(wpa_ctrl[s].sockpath, "%s/%s", CTRL_INTERFACE, ssid_ifname);
-        wpa_ctrl[s].ssid_index = s;
-        printf("Opening ctrl for %s\n", ssid_ifname);
-        if (ctrl_enable(&wpa_ctrl[s]))
-        {
-             return RETURN_ERR;
-        }
-    }
-
-    client_initialized = 1;
-
-    return RETURN_OK;
-}
-
-void wifi_client_event_callback_register(wifi_client_event_callback callback_proc)
-{
-    clients_connect_cb = callback_proc;
-    printf("Registering callback STA\n");
-    if (!client_initialized)
-        init_client_wpa();
-}
-
-INT wifi_getSTANetworks(INT apIndex, wifi_sta_network_t **out_staNetworks_array, INT out_array_size, BOOL *out_scan_cur_freq)
-{
-    FILE *fd      = NULL;
-    char fname[100];
-    char * line = NULL;
-    char * pos = NULL;
-    size_t len = 0;
-    ssize_t read = 0;
-    int id = 0;
-    int ret = 0;
-    char * k;
-    char * v;
-    char *kv;
-    wifi_sta_network_t * staNetwork;
-
-    if(out_array_size <= 0 )
-        return RETURN_ERR;
-
-    char ssid_ifname[128];
-
-    ret = wifi_getSTAName(apIndex, ssid_ifname);
-    if (ret != RETURN_OK)   
-        return RETURN_ERR;
-    
-    snprintf(fname, sizeof(fname), "/nvram/%s.conf", ssid_ifname);
-    fd = fopen(fname, "r");
-    if (!fd)
-        return RETURN_ERR;
-
-    staNetwork= *out_staNetworks_array;
-    while ((read = getline(&line, &len, fd)) != -1) {
-        if(!strncmp(line, "network={",strlen("network={"))) {
-            read = getline(&line, &len, fd) ;
-            staNetwork->id = id;
-            while (strncmp(line,"}",1)) {
-                if ((k = strsep(&line, "=")) &&
-                    (v = strsep(&line, ""))) {
-                    if (!strcmp(k, "\tssid"))
-                    {
-                        v++; //skip quote
-                        v = strsep(&v, "\"");
-                        strncpy(staNetwork->ssid, v,32);
-                    }
-                    else if (!strcmp(k, "\tpsk"))
-                    {
-                        v++; //skip quote
-                        v = strsep(&v, "\"");
-                        strncpy(staNetwork->psk, v,128);
-                    }
-                    else if (!strcmp(k, "\tpairwise"))
-                        strncpy(staNetwork->pairwise, v,64);
-                    else if (!strcmp(k, "\tkey_mgmt"))
-                        strncpy(staNetwork->key_mgmt, v,64);
-                    else if (!strcmp(k, "\tproto"))
-                    {
-                        v = strsep(&v, "\n");
-                        strncpy(staNetwork->proto, v,64);
-                    }
-                    else if (!strcmp(k, "\tbssid"))
-                        sscanf(v, "%02x:%02x:%02x:%02x:%02x:%02x",
-                               (unsigned int *)&staNetwork->bssid[0],
-                               (unsigned int *)&staNetwork->bssid[1],
-                               (unsigned int *)&staNetwork->bssid[2],
-                               (unsigned int *)&staNetwork->bssid[3],
-                               (unsigned int *)&staNetwork->bssid[4],
-                               (unsigned int *)&staNetwork->bssid[5]);
-                    else if (!strcmp(k, "multi_ap_backhaul_sta"))
-                         staNetwork->multi_ap = atoi(v);
-                } 
-                if((read = getline(&line, &len, fd)) == -1)
-                    break;
-            }           
-            id++;
-            if(id >= out_array_size)
-                goto close;
-            staNetwork++;
-        }
-    }
-close:
-    fclose(fd);
-    return RETURN_OK;
-    
- 
-}
-
-INT wifi_setSTANetworks(INT apIndex, wifi_sta_network_t **staNetworks_array, INT array_size, BOOL scan_cur_freq)
-{
-    FILE *fd = NULL;
-    char fname[100] = {0};
-    char cmd[128] = {0};
-    char out[64] = {0};
-    int ret = 0;
-    char zero[8] = {0};
-    bool enable_current = FALSE;
-
-    wifi_sta_network_t *sta = NULL;
-    if(array_size < 0)
-            return RETURN_ERR;
-    char ssid_ifname[128];
-
-    ret = wifi_getSTAName(apIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-        return RETURN_ERR;
-    snprintf(fname, sizeof(fname), "/nvram/%s.conf", ssid_ifname);
-    sprintf(cmd, "touch %s && cp %s /nvram/%s.old", fname, fname, ssid_ifname);
-    _syscmd(cmd, out, 64);
-
-    fd = fopen(fname, "w");
-    if (!fd) {
-            return RETURN_ERR;
-    }
-    fprintf(fd, "ctrl_interface=%s\n", CTRL_INTERFACE);
-    fprintf(fd, "scan_cur_freq=%d\n", scan_cur_freq ? 1 : 0);
-
-    sta = *staNetworks_array;
-    for(int i=0; i<array_size; ++i, sta++) {
-        fprintf(fd, "network={\n");
-        fprintf(fd, "\tscan_ssid=1\n");
-        fprintf(fd, "\tbgscan=\"\"\n");
-        fprintf(fd, "\tssid=\"%s\"\n", sta->ssid);
-        if (sta->psk_len > 7 && sta->psk_len < 128)
-            fprintf(fd, "\tpsk=\"%s\"\n", sta->psk);
-        fprintf(fd, "\tkey_mgmt=%s\n", sta->key_mgmt);
-        if (!strncmp(sta->key_mgmt, "SAE", 3) || !strncmp(sta->key_mgmt, "OWE", 3)) {                    // wpa3-personal must use with ieee80211w
-            fprintf(fd, "\tieee80211w=2\n");
-        }
-        fprintf(fd, "\tpairwise=%s\n", sta->pairwise);
-        if (memcmp(sta->bssid, zero, sizeof(sta->bssid)) != 0)      // Not 00:00:00:00:00:00 means need to specify ap mac address.
-            fprintf(fd, "bssid=%02x:%02x:%02x:%02x:%02x:%02x\n", sta->bssid[0],sta->bssid[1],sta->bssid[2],sta->bssid[3],sta->bssid[4],sta->bssid[5]);
-        fprintf(fd, "}\n");
-    }
-    fclose(fd);
-
-    wifi_getSTAEnabled(apIndex, &enable_current);
-    sprintf(cmd, "diff -q /nvram/%s.conf /nvram/%s.old", ssid_ifname, ssid_ifname);
-    if (enable_current && _syscmd(cmd, out, 64))
-    {
-        sprintf(cmd, "wpa_cli -B -i%s reconfigure", ssid_ifname);
-        _syscmd(cmd, out, 64);
-    }
-    sprintf(cmd, "rm /nvram/%s.old", ssid_ifname);
-    _syscmd(cmd, out, 64);
-
-    return RETURN_OK;
-
-}
-
-INT wifi_getSTAEnabled(INT ssidIndex, BOOL *enabled)
-{
-    char ssid_ifname[128];
-    char cmd[128] = {0};
-    char out[64] = {0};
-    int ret = 0;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-    {
-        return RETURN_ERR;
-    }
-
-    sprintf(cmd, "wpa_cli -g/var/run/wpa_supplicant-global -i global status | grep %s", ssid_ifname);
-    ret = _syscmd(cmd, out, 64);
-    *enabled = ret == 0 ? true : false;
-
-    return RETURN_OK;
-}
-
-INT wifi_setSTAEnabled(INT ssidIndex, BOOL enable)
-{
-    char ssid_ifname[128];
-    char cmd[256] = {0};
-    char out[64] = {0};
-    int ret = 0;
-    int radioIndex = 0;
-
-    BOOL en;
-    wifi_getSTAEnabled(ssidIndex,&en);
-    if (enable == en)
-        return RETURN_OK;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)   
-        return RETURN_ERR;
-
-    if (enable) {
-        snprintf(cmd, sizeof(cmd), "wpa_cli -g/var/run/wpa_supplicant-global interface_add %s /nvram/%s.conf nl80211 /var/run/wpa_supplicant", ssid_ifname, ssid_ifname);
-        ret = _syscmd(cmd, out, 64);
-    } else {
-        snprintf(cmd, sizeof(cmd), "wpa_cli -g/var/run/wpa_supplicant-global -i global interface_remove  %s", ssid_ifname);
-        ret = _syscmd(cmd, out, 64);
-    }
-
-    return ret == 0 ? RETURN_OK : RETURN_ERR;
-}
-
-INT wifi_createSTAInterface(INT ssidIndex, char *bssid, BOOL wds_flag)
-{
-    char cmd[128] = {0};
-    char buf[128] = {0};
-    char ssid_ifname[128] = {0};
-    int radioIndex = 0;
-    int phyIndex = 0;
-    int ret = 0;
-
-    ret = wifi_getSTAName(ssidIndex, ssid_ifname);
-    if (ret != RETURN_OK)
-        return RETURN_ERR;
-
-    wifi_getSTARadioIndex(ssidIndex, &radioIndex);
-    phyIndex = radio_index_to_phy(radioIndex);
-    if (phyIndex == -1) {
-        fprintf(stderr, "%s: Invalid radio index %d.\n", __func__, radioIndex);
-        return RETURN_ERR;
-    }
-    snprintf(cmd, sizeof(cmd), "iw phy phy%d interface add %s type managed %s", phyIndex, ssid_ifname, wds_flag?"4addr on":"");
-    _syscmd(cmd, buf, sizeof(buf));
-    snprintf(cmd, sizeof(cmd), "ip link set dev %s address %s && ip link set dev %s up", ssid_ifname, bssid, ssid_ifname);
-    _syscmd(cmd, buf, sizeof(buf));
-
-    return RETURN_OK;
-}
\ No newline at end of file
diff --git a/src/logan_wifi/client_wifi_hal.h b/src/logan_wifi/client_wifi_hal.h
deleted file mode 100644
index 0424670..0000000
--- a/src/logan_wifi/client_wifi_hal.h
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * If not stated otherwise in this file or this component's LICENSE file the
- * following copyright and licenses apply:
- *
- * Copyright 2019 RDK Management
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-#ifndef __CLIENT_WIFI_HAL_H__
-#define __CLIENT_WIFI_HAL_H__
-INT wifi_getSTANumberOfEntries(ULONG *output);
-INT wifi_getSTAName(INT apIndex, CHAR *output_string);
-INT wifi_getSTARadioIndex(INT ssidIndex, INT *radioIndex);
-INT wifi_getSTAMAC(INT ssidIndex, CHAR *output_string);
-INT wifi_getSTABSSID(INT ssidIndex, CHAR *output_string);
-INT wifi_getSTASSID(INT ssidIndex, CHAR *output_string);
-INT wifi_getSTACredentials(INT ssidIndex, CHAR *output_string);
-INT wifi_getSTANetworks(INT apIndex, wifi_sta_network_t **out_staNetworks_array, INT out_array_size, BOOL *out_scan_cur_freq);
-INT wifi_setSTANetworks(INT apIndex, wifi_sta_network_t **staNetworks_array, INT array_size, BOOL scan_cur_freq);
-INT wifi_getSTAEnabled(INT ssidIndex, BOOL *enabled);
-INT wifi_setSTAEnabled(INT ssidIndex, BOOL enable);
-#endif
diff --git a/src/logan_wifi/configure.ac b/src/logan_wifi/configure.ac
deleted file mode 100644
index 7dd85ca..0000000
--- a/src/logan_wifi/configure.ac
+++ /dev/null
@@ -1,55 +0,0 @@
-##########################################################################
-# If not stated otherwise in this file or this component's Licenses.txt
-# file the following copyright and licenses apply:
-#
-# Copyright 2019 RDK Management
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-##########################################################################
-#                                              -*- Autoconf -*-
-# Process this file with autoconf to produce configure script.
-#
-
-AC_PREREQ([2.65])
-AC_INIT([hal], [1.0], [BUG-REPORT-ADDRESS])
-AM_INIT_AUTOMAKE([foreign])
-LT_INIT
-
-AC_PREFIX_DEFAULT(`pwd`)
-AC_ENABLE_SHARED
-AC_DISABLE_STATIC
-
-AC_CONFIG_HEADERS([config.h])
-AC_CONFIG_MACRO_DIR([m4])
-
-# Checks for programs.
-AC_PROG_CC
-AC_PROG_INSTALL
-AM_PROG_CC_C_O
-AM_PROG_LIBTOOL(libtool)
-
-# Checks for header files.
-AC_CHECK_HEADERS([stdlib.h string.h unistd.h])
-
-# Checks for typedefs, structures, and compiler characteristics.
-AC_HEADER_STDBOOL
-AC_C_INLINE
-
-# Checks for library functions.
-AC_FUNC_MALLOC
-
-AC_CONFIG_FILES(Makefile)
-
-
-AC_OUTPUT
-
diff --git a/src/logan_wifi/wifi_hal.c b/src/logan_wifi/wifi_hal.c
deleted file mode 100644
index 04ae444..0000000
--- a/src/logan_wifi/wifi_hal.c
+++ /dev/null
@@ -1,24046 +0,0 @@
-/*
- * If not stated otherwise in this file or this component's LICENSE file the
- * following copyright and licenses apply:
- *
- * Copyright 2019 RDK Management
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
-*/
-
-/*
-* Material from the TR181 data model is Copyright (c) 2010-2017, Broadband Forum
-* Licensed under the BSD-3 license
-*/
-
-/*
-* This file includes material that is Copyright (c) 2020, Plume Design Inc.
-* Licensed under the BSD-3 license
-*/
-
-/* Code in rxStatsInfo_callback and other callbacks is credited as follows:
-Copyright (c) 2007, 2008	Johannes Berg
-Copyright (c) 2007		Andy Lutomirski
-Copyright (c) 2007		Mike Kershaw
-Copyright (c) 2008-2009		Luis R. Rodriguez
-Licensed under the ISC license
-*/
-#define MTK_IMPL
-#define HAL_NETLINK_IMPL
-#define _GNU_SOURCE /* needed for strcasestr */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-#include <string.h>
-#include <fcntl.h>
-#include <stdbool.h>
-#include <pthread.h>
-#include "wifi_hal.h"
-#include <libkvcutil.h>
-#include <dirent.h>
-#include <stdarg.h>
-
-#ifdef HAL_NETLINK_IMPL
-#include <errno.h>
-#include <netlink/attr.h>
-#include <netlink/netlink.h>
-#include <netlink/genl/genl.h>
-#include <netlink/genl/family.h>
-#include <netlink/genl/ctrl.h>
-#include <linux/nl80211.h>
-#include <net/if.h>
-#include <unl.h>
-#include "mtk_vendor_nl80211.h"
-#endif
-
-#include <ev.h>
-#include <wpa_ctrl.h>
-#include <errno.h>
-#include <time.h>
-
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <arpa/inet.h>
-#include <linux/if.h>
-#include <linux/if_bridge.h>
-#include <linux/sockios.h>
-#include <errno.h>
-#include <limits.h>
-#include "secure_wrapper.h"
-
-#define MAC_ALEN 6
-
-#define MAX_BUF_SIZE 256
-#define MAX_CMD_SIZE 256
-#define MAX_SUB_CMD_SIZE 200
-#define MAX_CB_SIZE 5
-#define IF_NAME_SIZE 16
-#define MAX_SSID_NAME_LEN 33
-#define CONFIG_PREFIX "/nvram/hostapd"
-#define ACL_PREFIX "/nvram/hostapd-acl"
-#define DENY_PREFIX "/nvram/hostapd-deny"
-//#define ACL_PREFIX "/tmp/wifi_acl_list" //RDKB convention
-#define SOCK_PREFIX "/var/run/hostapd/"
-#define VAP_STATUS_FILE "/nvram/vap-status"
-#define ESSID_FILE "/tmp/essid"
-#define GUARD_INTERVAL_FILE "/nvram/guard-interval"
-#define CHANNEL_STATS_FILE "/tmp/channel_stats"
-#define DFS_ENABLE_FILE "/nvram/dfs_enable.txt"
-#define VLAN_FILE "/nvram/hostapd.vlan"
-#define PSK_FILE "/nvram/hostapd"
-#define MCS_FILE "/tmp/MCS"
-#define MGMT_POWER_CTRL "/tmp/mgmt_power_ctrl"
-/*LOGAN_DAT_FILE: may be different on customer's platform.*/
-#ifdef WIFI_7992
-#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7992.b"
-#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7992.b"
-#else
-#define LOGAN_DAT_FILE "/etc/wireless/mediatek/mt7990.b"
-#define ROM_LOGAN_DAT_FILE "/rom/etc/wireless/mediatek/mt7990.b"
-#endif
-
-#ifdef ARHT_SOC
-#define ROM_SSID_ENABLE_CONFIG "/usr/wireless/hal/wifi_config"
-#define ROM_WIFI_BRLAN_CONFIG "/usr/wireless/hal/wifi_config"
-#else
-#define ROM_SSID_ENABLE_CONFIG "/rom/etc/wireless/hal/wifi_config"
-#define ROM_WIFI_BRLAN_CONFIG "/rom/etc/wireless/hal/wifi_config"
-#endif
-
-#define SSID_ENABLE_CONFIG "/etc/wireless/hal/wifi_config"
-#define WIFI_BRLAN_CONFIG "/etc/wireless/hal/wifi_config"
-
-#define NOACK_MAP_FILE "/tmp/NoAckMap"
-#define RADIO_RESET_FILE "/nvram/radio_reset"
-
-#define DEFAULT_BRIDGE_NAME "brlan0"
-#define BASE_PHY_INDEX 1
-#define BASE_RADIO_INDEX 0
-
-/*
-   MAX_APS - Number of all AP available in system
-   2x Home AP
-   2x Backhaul AP
-   2x Guest AP
-   2x Secure Onboard AP
-   2x Service AP
-
-*/
-#ifndef MIN
-#define MIN(a,b) \
-		({ __typeof__ (a) _a = (a); \
-		__typeof__ (b) _b = (b); \
-		_a < _b ? _a : _b; })
-#endif
-
-#ifndef MAX
-#define MAX(a,b) \
-		({ __typeof__ (a) _a = (a); \
-		__typeof__ (b) _b = (b); \
-		_a > _b ? _a : _b; })
-#endif
-
-#define LOGAN_MAX_NUM_VAP_PER_RADIO (MAX_NUM_VAP_PER_RADIO > 16 ? 16 : MAX_NUM_VAP_PER_RADIO)
-#define MAX_APS MAX_NUM_RADIOS * LOGAN_MAX_NUM_VAP_PER_RADIO
-
-#define PREFIX_WIFI2G	"ra"
-#define PREFIX_WIFI5G	"rai"
-#define PREFIX_WIFI6G	"rax"
-
-#define PREFIX_SSID_2G	"RDKB_2G"
-#define PREFIX_SSID_5G	"RDKB_5G"
-#define PREFIX_SSID_6G	"RDKB_6G"
-#define PREFIX_SSID_MLD	"MLD_GROUP"
-
-
-#ifndef RADIO_PREFIX
-#define RADIO_PREFIX	"wlan"
-#endif
-
-#define MAX_ASSOCIATED_STA_NUM 2007
-
-//Uncomment to enable debug logs
-//#define WIFI_DEBUG
-enum {
-	DEBUG_OFF = 0,
-	DEBUG_ERROR = 1,
-	DEBUG_WARN = 2,
-	DEBUG_NOTICE = 3,
-	DEBUG_INFO = 4,
-	DEBUG_MAX
-};
-int wifi_debug_level = DEBUG_WARN;
-
-#ifdef WIFI_DEBUG_FILE
-char *get_time(char *time)
-{
-	struct tm *tm_info;
-	struct timeval tv_now;
-	char tmp[64];
-
-	gettimeofday(&tv_now, NULL);
-	tm_info = localtime(&tv_now.tv_sec);
-
-	strftime(tmp, 64, "%y%m%d-%T", tm_info);
-	snprintf(time, 128, "%s.%06d", tmp, (int)tv_now.tv_usec);
-	return time;
-}
-
-void _wifi_debug(int level, const char *function, int line, const char *format, ...)
-{
-	char buff[256] = {0};
-	va_list list;
-	FILE *fpg = NULL;
-	get_time(buff);
-
-	if ((access("/nvram/wifiVendorHalDbg", R_OK)) == 0) {
-		fpg = fopen("/tmp/wifiVendorHal", "a+");
-		if (fpg == NULL) {
-			return;
-		}
-	} else {
-		switch (level) {
-			case DEBUG_OFF:
-			case DEBUG_ERROR:
-			case DEBUG_WARN:
-				fpg = fopen("/rdklogs/logs/wifi_vendor_hal.log", "a+");
-				if (fpg == NULL) {
-					return;
-				}
-			break;
-			case DEBUG_NOTICE:
-			case DEBUG_INFO:
-			default:
-				return;
-		}
-	}
-	static const char *level_marker[DEBUG_MAX] =
-	{
-		[DEBUG_OFF] = "<OFF>",
-		[DEBUG_ERROR] = "<ERR>",
-		[DEBUG_WARN] = "<WARN>",
-		[DEBUG_NOTICE] = "<NOTICE>",
-		[DEBUG_INFO] = "<INFO>",
-	};
-	if (level < DEBUG_MAX)
-		snprintf(&buff[strlen(buff)], 256 - strlen(buff), " %s ", level_marker[level]);
-	fprintf(fpg, "%s[%s:%d]", buff, function, line);
-	va_start(list, format);
-	vfprintf(fpg, format, list);
-	va_end(list);
-	fflush(fpg);
-	fclose(fpg);
-
-	return;
-}
-
-#define wifi_debug(level, format, ...) _wifi_debug(level, __func__, __LINE__, format, ##__VA_ARGS__)
-#else
-#define wifi_debug(level, fmt, args...) \
-{	\
-	if (level <= wifi_debug_level)	\
-	{ \
-		printf("[%s][%d]"fmt"", __func__, __LINE__, ##args);	\
-	} \
-}
-#endif
-#define wifi_assert(cond) \
-{\
-	if (!(cond)) {\
-		wifi_debug(DEBUG_ERROR, "!!!wifi hal assert!!!\n");\
-	}\
-}
-
-#ifdef WIFI_DEBUG
-#define WIFI_ENTRY_EXIT_DEBUG(format, ...) _wifi_debug(DEBUG_OFF, __func__, __LINE__, format, ##__VA_ARGS__)
-#else
-#define WIFI_ENTRY_EXIT_DEBUG(format, args...)
-#endif
-
-#define HOSTAPD_CONF_0 "/nvram/hostapd0.conf"   //private-wifi-2g
-#define HOSTAPD_CONF_1 "/nvram/hostapd1.conf"   //private-wifi-5g
-#define HOSTAPD_CONF_4 "/nvram/hostapd4.conf"   //public-wifi-2g
-#define HOSTAPD_CONF_5 "/nvram/hostapd5.conf"   //public-wifi-5g
-#define DEF_HOSTAPD_CONF_0 "/usr/ccsp/wifi/hostapd0.conf"
-#define DEF_HOSTAPD_CONF_1 "/usr/ccsp/wifi/hostapd1.conf"
-#define DEF_HOSTAPD_CONF_4 "/usr/ccsp/wifi/hostapd4.conf"
-#define DEF_HOSTAPD_CONF_5 "/usr/ccsp/wifi/hostapd5.conf"
-#define DEF_RADIO_PARAM_CONF "/usr/ccsp/wifi/radio_param_def.cfg"
-#define LM_DHCP_CLIENT_FORMAT   "%63d %17s %63s %63s"
-
-#define HOSTAPD_HT_CAPAB "[LDPC][SHORT-GI-20][SHORT-GI-40][MAX-AMSDU-7935]"
-
-#define BW_FNAME "/nvram/bw_file.txt"
-
-#define PS_MAX_TID 16
-
-#define MAX_CARD_INDEX 3
-
-static wifi_radioQueueType_t _tid_ac_index_get[PS_MAX_TID] = {
-	WIFI_RADIO_QUEUE_TYPE_BE,	  /* 0 */
-	WIFI_RADIO_QUEUE_TYPE_BK,	  /* 1 */
-	WIFI_RADIO_QUEUE_TYPE_BK,	  /* 2 */
-	WIFI_RADIO_QUEUE_TYPE_BE,	  /* 3 */
-	WIFI_RADIO_QUEUE_TYPE_VI,	  /* 4 */
-	WIFI_RADIO_QUEUE_TYPE_VI,	  /* 5 */
-	WIFI_RADIO_QUEUE_TYPE_VO,	  /* 6 */
-	WIFI_RADIO_QUEUE_TYPE_VO,	  /* 7 */
-	WIFI_RADIO_QUEUE_TYPE_BE,	  /* 8 */
-	WIFI_RADIO_QUEUE_TYPE_BK,	  /* 9 */
-	WIFI_RADIO_QUEUE_TYPE_BK,	  /* 10 */
-	WIFI_RADIO_QUEUE_TYPE_BE,	  /* 11 */
-	WIFI_RADIO_QUEUE_TYPE_VI,	  /* 12 */
-	WIFI_RADIO_QUEUE_TYPE_VI,	  /* 13 */
-	WIFI_RADIO_QUEUE_TYPE_VO,	  /* 14 */
-	WIFI_RADIO_QUEUE_TYPE_VO,	  /* 15 */
-};
-
-typedef unsigned long long  u64;
-
-/* Enum to define WiFi Bands */
-typedef enum
-{
-	band_invalid = -1,
-	band_2_4 = 0,
-	band_5 = 1,
-	band_6 = 2,
-} wifi_band;
-
-char* wifi_band_str[] = {
-	"2G",
-	"5G",
-	"6G",
-};
-
-typedef enum {
-	WIFI_MODE_A = 0x01,
-	WIFI_MODE_B = 0x02,
-	WIFI_MODE_G = 0x04,
-	WIFI_MODE_N = 0x08,
-	WIFI_MODE_AC = 0x10,
-	WIFI_MODE_AX = 0x20,
-	WIFI_MODE_BE = 0x40,
-} wifi_ieee80211_Mode;
-
-typedef enum {
-	HT_BW_20,
-	HT_BW_40,
-} ht_config_bw;
-
-typedef enum {
-	VHT_BW_2040,
-	VHT_BW_80,
-	VHT_BW_160,
-	VHT_BW_8080,
-} vht_config_bw;
-
-typedef enum {
-	EHT_BW_20,
-	EHT_BW_40,
-	EHT_BW_80,
-	EHT_BW_160,
-	EHT_BW_320,
-} eht_config_bw;
-
-static char *phy_bw_str_txrx_stainfo[] = {"20M", "40M", "80M", "160M", "320M"};
-static char *phy_mode_str[] = {"g", "b", "n", "n", "ac", "ax",
-				"be", "ax", "ax", "ax", "ax", "ax", "NA",
-				"be", "be", "be"};
-
-/* Device.WiFi.SSID.{i}.Stats. */
-typedef struct _wifi_bss_stats {
-	ULONG BytesSent;
-	ULONG BytesReceived;
-	ULONG PacketsSent;
-	ULONG PacketsReceived;
-	UINT ErrorsSent;
-	UINT RetransCount; /* MT7915 Not Support, default: 0 */
-	UINT FailedRetransCount; /* MT7915 Not Support, default: 0 */
-	UINT RetryCount; /* MT7915 Not Support, default: 0 */
-	UINT MultipleRetryCount; /* MT7915 Not Support, default: 0 */
-	UINT ACKFailureCount; /* MT7915 Not Support, default: 0 */
-	UINT AggregatedPacketCount; /* MT7915 Not Support, default: 0 */
-	UINT ErrorsReceived;
-	ULONG UnicastPacketsSent;
-	ULONG UnicastPacketsReceived;
-	UINT DiscardPacketsSent;
-	UINT DiscardPacketsReceived;
-	ULONG MulticastPacketsSent;
-	ULONG MulticastPacketsReceived;
-	ULONG BroadcastPacketsSent;
-	ULONG BroadcastPacketsReceived;
-	UINT UnknownProtoPacketsReceived; /* MT7915 Not Support, default: 0 */
-	ULONG DiscardPacketsSentBufOverflow; /* MT7915 Not Support, default: 0 */
-	ULONG DiscardPacketsSentNoAssoc; /* MT7915 Not Support, default: 0 */
-	ULONG FragSent; /* MT7915 Not Support, default: 0 */
-	ULONG SentNoAck; /* MT7915 Not Support, default: 0 */
-	ULONG DupReceived; /* MT7915 Not Support, default: 0 */
-	ULONG TooLongReceived; /* MT7915 Not Support, default: 0 */
-	ULONG TooShortReceived; /* MT7915 Not Support, default: 0 */
-	ULONG AckUcastReceived; /* MT7915 Not Support, default: 0 */
-}wifi_bss_stats_t;
-/* Device.WiFi.Radio.{i} */
-typedef struct _wifi_radio_stats {
-	ULONG BytesSent;
-	ULONG BytesReceived;
-	ULONG PacketsSent;
-	ULONG PacketsReceived;
-	ULONG ErrorsSent;
-	ULONG ErrorsReceived;
-	ULONG DiscardPacketsSent;
-	ULONG DiscardPacketsReceived;
-	UINT PLCPErrorCount; /* MT7915 Not Support, default: 0 */
-	UINT FCSErrorCount; /* MT7915 Not Support, default: 0 */
-	UINT InvalidMACCount; /* MT7915 Not Support, default: 0 */
-	UINT PacketsOtherReceived; /* MT7915 Not Support, default: 0 */
-	ULONG CtsReceived; /* MT7915 Not Support, default: 0 */
-	ULONG NoCtsReceived; /* MT7915 Not Support, default: 0 */
-	ULONG FrameHeaderError; /* MT7915 Not Support, default: 0 */
-	ULONG GoodPLCPReceived; /* MT7915 Not Support, default: 0 */
-	ULONG DPacketOtherMACReceived; /* MT7915 Not Support, default: 0 */
-	ULONG MPacketOtherMACReceived; /* MT7915 Not Support, default: 0 */
-	ULONG CPacketOtherMACReceived; /* MT7915 Not Support, default: 0 */
-	ULONG CtsOtherMACReceived; /* MT7915 Not Support, default: 0 */
-	ULONG RtsOtherMACReceived; /* MT7915 Not Support, default: 0 */
-	UINT TotalChannelChangeCount;
-	UINT ManualChannelChangeCount;
-	UINT AutoStartupChannelChangeCount;
-	UINT AutoUserChannelChangeCount;
-	UINT AutoRefreshChannelChangeCount;
-	UINT AutoDynamicChannelChangeCount;
-	UINT AutoDFSChannelChangeCount;
-	ULONG UnicastPacketsSent;
-	ULONG UnicastPacketsReceived;
-	ULONG MulticastPacketsSent;
-	ULONG MulticastPacketsReceived;
-	ULONG BroadcastPacketsSent;
-	ULONG BroadcastPacketsReceived;
-	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
-#ifndef ARRAY_SIZE
-#define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
-#endif /* ARRAY_SIZE */
-
-#ifndef ARRAY_AND_SIZE
-#define ARRAY_AND_SIZE(x) (x),ARRAY_SIZE(x)
-#endif /* ARRAY_AND_SIZE */
-
-#define WIFI_ITEM_STR(key, str) {0, sizeof(str)-1, (int)key, (intptr_t)str}
-
-typedef struct {
-	int32_t value;
-	int32_t param;
-	intptr_t key;
-	intptr_t data;
-} wifi_secur_list;
-
-typedef struct GNU_PACKED _wdev_extended_ap_metrics {
-	unsigned int uc_tx;
-	unsigned int uc_rx;
-	unsigned int mc_tx;
-	unsigned int mc_rx;
-	unsigned int bc_tx;
-	unsigned int bc_rx;
-} wdev_extended_ap_metric;
-
-typedef struct GNU_PACKED _wdev_ap_metric {
-	unsigned char	bssid[6];
-	unsigned char	cu;
-	unsigned char 	ESPI_AC[4][3];
-	wdev_extended_ap_metric ext_ap_metric;
-} wdev_ap_metric;
-
-enum mld_type {
-	AP_MLD_SINGLE_LINK,
-	AP_MLD_MULTI_LINK,
-};
-
-struct multi_link_device {
-	unsigned char mld_mac[6];
-	unsigned char mld_index;
-//	enum mld_type type;
-	unsigned char affiliated_ap_bitmap[6];
-};
-
-struct mld_configuration {
-	unsigned char valid_mld_bitmap[9];
-	struct multi_link_device mld[66]; /*0,65 - invalid, 1~16 multi-link mld, 17-64 single link mld*/
-};
-struct mld_configuration mld_config;
-
-wifi_hal_capability_t g_hal_cap;
-
-static char l1profile[32] = "/etc/wireless/l1profile.dat";
-char main_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
-char ext_prefix[MAX_NUM_RADIOS][IFNAMSIZ];
-int g_phy_count = 0;
-#define MAX_SSID_LEN  64
-char default_ssid[MAX_NUM_RADIOS][MAX_SSID_LEN];;
-int radio_band[MAX_NUM_RADIOS];
-BOOL bs_curr_status = TRUE;
-
-static void wifi_ParseProfile(void);
-
-static inline int get_runtime_max_radio(void)
-{
-	/*if rumtime maximun radio number is 0, reinit it.*/
-	wifi_assert(g_phy_count);
-	if(g_phy_count== 0)
-		wifi_ParseProfile();
-
-	return g_phy_count;
-}
-static int util_unii_5g_centerfreq(const char *ht_mode, int channel);
-static int util_unii_6g_centerfreq(const char *ht_mode, int channel);
-wifi_secur_list *	   wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key);
-wifi_secur_list *	   wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str);
-char *				  wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key);
-static int ieee80211_channel_to_frequency(int channel, int *freqMHz);
-static void wifi_PrepareDefaultHostapdConfigs(bool reset);
-static void wifi_psk_file_reset();
-static void wifi_vap_status_reset();
-static void wifi_radio_reset_count_reset();
-static void wifi_guard_interval_file_check();
-static void wifi_dat_file_reset_by_radio(char radio_idx);
-static int util_get_sec_chan_offset(int channel, const char* ht_mode);
-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);
-int wifi_get_ap_status_hostapd(char *interface_name, BOOL *output_bool);
-
-static inline int hal_strtol(char *src, int base, long int *out)
-{
-	long int res = 0;
-	char *end_ptr = NULL;
-
-	errno = 0;
-	res  = strtol(src, &end_ptr, base);
-
-	if ((errno == ERANGE && (res == LONG_MIN || res == LONG_MAX))
-		|| (errno != 0 && res == 0) || /*ignore end_ptr!=0 error*/ /**end_ptr != '\0' ||*/src == end_ptr ) {
-		*out = res;
-		return -1;
- 	} else
-		*out = res;
-
-	return 0;
-}
-
-static inline int hal_strtoul(char *src, int base, unsigned long *out)
-{
-	unsigned long res = 0;
-	char *end_ptr = NULL;
-
-	errno = 0;
-	res  = strtoul(src, &end_ptr, base);
-
-	if ((errno == ERANGE && res == ULONG_MAX)
-		|| (errno != 0 && res == 0) || /*ignore end_ptr!=0 error*/ /**end_ptr != '\0' ||*/src == end_ptr ) {
-		*out = res;
-		return -1;
-	} else
-		*out = res;
-
-	return 0;
-}
-
-static inline int os_snprintf_error(size_t size, int res)
-{
-	return res < 0 || (unsigned int) res >= size;
-}
-
-/*type define the nl80211 call back func*/
-typedef int (*mtk_nl80211_cb) (struct nl_msg *, void *);
-
-/**
-*struct mtk_nl80211_param
-* init mtk nl80211 using parameters
-* @sub_cmd: the cmd define in the mtk_vendor_nl80211.h.
-* @if_type: now only support the NL80211_ATTR_IFINDEX/NL80211_ATTR_WIPHY.
-* @if_idx: the index should match the interface or wiphy.
-* Note: NA
-**/
-struct mtk_nl80211_param {
-	unsigned int sub_cmd;
-	int if_type;
-	int if_idx;
-};
-
-/**
-*struct mtk_nl80211_cb_data
-* init mtk nl80211 call back parameters
-* @out_buf: store the mtk vendor output msg for wifi hal buffer.
-* @out_len: the output buffer length.
-* Note: NA
-**/
-struct mtk_nl80211_cb_data {
-	char * out_buf;
-	unsigned int out_len;
-};
-
-/**
-*mtk_nl80211_init
-* init mtk nl80211 netlink and init the vendor msg common part.
-* @nl: netlink, just init it.
-* @msg: netlink message will alloc it.
-*		the msg send success/fails is not free by app
-*		only the nla_put etc api fails should use nlmsg_free.
-* @msg_data: vendor data msg attr pointer.
-* @param: init using interface and sub_cmd parameter.
-*
-*init the netlink context and mtk netlink vendor msg.
-*
-*return:
-*	0: success
-*	other: fail
-**/
-
-int mtk_nl80211_init(struct unl *nl, struct nl_msg **msg,
-	struct nlattr **msg_data, struct mtk_nl80211_param *param) {
-	int retry_count = 0;
-
-	/*sanity check here*/
-	if (!nl || !param) {
-		(void)fprintf(stderr,
-		"[%s][%d]:nl(%p) or param(%p) is null, error!\n",
-		__func__, __LINE__, nl, param);
-		return -1;
-	}
-	/*if_type check*/
-	if ( param->if_type != NL80211_ATTR_IFINDEX && param->if_type != NL80211_ATTR_WIPHY) {
-		(void)fprintf(stderr,
-			"[%s][%d]:if_type(0x%x) is not supported, only 0x%x and 0x%x supported.\n",
-			__func__, __LINE__, param->if_type, NL80211_ATTR_IFINDEX, NL80211_ATTR_WIPHY);
-		return -1;
-	}
-retry:
-	/*init the nl*/
-	if (unl_genl_init(nl, "nl80211") < 0) {
-		if (retry_count++ < 3) {
-			(void)fprintf(stderr, "[%s][%d]::Failed to connect to nl80211, retry %d\n",
-				__func__, __LINE__, retry_count);
-			usleep(200000);
-			goto retry;
-		}
-		return -1;
-	}
-	/*init the msg*/
-	*msg = unl_genl_msg(nl, NL80211_CMD_VENDOR, false);
-
-	if (nla_put_u32(*msg, param->if_type, param->if_idx) ||
-		nla_put_u32(*msg, NL80211_ATTR_VENDOR_ID, MTK_NL80211_VENDOR_ID) ||
-		nla_put_u32(*msg, NL80211_ATTR_VENDOR_SUBCMD, param->sub_cmd)) {
-		(void)fprintf(stderr,
-		"[%s][%d]:Nla put error: if_type: 0x%x, if_idx: 0x%x, sub_cmd: 0x%x\n",
-		__func__, __LINE__, param->if_type, param->if_idx, param->sub_cmd);
-		goto err;
-	}
-
-	*msg_data = nla_nest_start(*msg, NL80211_ATTR_VENDOR_DATA);
-	if (!*msg_data) {
-		(void)fprintf(stderr, "[%s][%d]:Nla put NL80211_ATTR_VENDOR_DATA start error\n",
-			__func__, __LINE__);
-		goto err;
-	}
-
-	return 0;
-err:
-	nlmsg_free(*msg);
-	unl_free(nl);
-	return -1;
-}
-
-/**
-*mtk_nl80211_send
-* set the vendor cmd call back and sent the vendor msg.
-* @nl: netlink.
-* @msg: netlink message.
-* @msg_data: vendor data msg attr pointer.
-* @handler: if the msg have call back shoud add the call back func
-*			the event msg will handle by the call back func(exp:get cmd)
-*			other set it as NULL(exp:set cmd).
-* @arg:call back func arg parameter.
-*add end of the netlink msg, set the call back and send msg
-*
-*return:
-*	0: success
-*	other: fail
-**/
-int mtk_nl80211_send(struct unl *nl, struct nl_msg *msg,
-	struct nlattr *msg_data, mtk_nl80211_cb handler, void *arg) {
-	int ret = 0;
-	/*sanity check*/
-	if (!nl || !msg || !msg_data) {
-		(void)fprintf(stderr,
-		"[%s][%d]:nl(%p),msg(%p) or msg_data(%p) is null, error!\n",
-		__func__, __LINE__, nl, msg, msg_data);
-		return -1;
-	}
-	/*end the msg attr of vendor data*/
-	nla_nest_end(msg, msg_data);
-	/*send the msg and set call back */
-	ret = unl_genl_request(nl, msg, handler, arg);
-	if (ret)
-		(void)fprintf(stderr, "send nl80211 cmd fails\n");
-	return ret;
-}
-
-/**
-*mtk_nl80211_deint
-* deinit the netlink.
-* @nl: netlink.
-*
-*free deinit the netlink.
-*
-*return:
-*	0: success
-**/
-
-int mtk_nl80211_deint(struct unl *nl) {
-	unl_free(nl);
-	return 0;
-}
-
-wifi_secur_list * wifi_get_item_by_key(wifi_secur_list *list, int list_sz, int key)
-{
-	wifi_secur_list	*item;
-	int	i;
-
-	for (item = list,i = 0;i < list_sz; item++, i++) {
-		if ((int)(item->key) == key) {
-			return item;
-		}
-	}
-
-	return NULL;
-}
-
-char * wifi_get_str_by_key(wifi_secur_list *list, int list_sz, int key)
-{
-	wifi_secur_list	*item = wifi_get_item_by_key(list, list_sz, key);
-
-	if (!item) {
-		return "";
-	}
-
-	return (char *)(item->data);
-}
-
-wifi_secur_list * wifi_get_item_by_str(wifi_secur_list *list, int list_sz, const char *str)
-{
-	wifi_secur_list	*item;
-	int	i;
-
-	for (item = list,i = 0;i < list_sz; item++, i++) {
-		if (strcmp((char *)(item->data), str) == 0) {
-			return item;
-		}
-	}
-
-	return NULL;
-}
-#endif /* WIFI_HAL_VERSION_3 */
-
-#define _syscmd_secure(retBuf, retBufSize, fmt, args...) \
-	({ \
-		FILE *f;	\
-		char *ptr = retBuf; \
-		int bufSize = retBufSize, bufbytes = 0, readbytes = 0, cmd_ret = -1;	\
-		WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);	\
-		f = v_secure_popen("r", fmt, ##args);	\
-		if(f) {	\
-			while(!feof(f))	\
-			{	\
-				*ptr = 0;	\
-				if(bufSize>=128) {	\
-					bufbytes=128;	\
-				} else {	\
-					bufbytes=bufSize-1;	\
-				}	\
-				if (fgets(ptr,bufbytes,f) == NULL)	\
-					break;	\
-				readbytes=strlen(ptr);	\
-				if(!readbytes)	\
-					break;	\
-				bufSize-=readbytes;	\
-				ptr += readbytes;	\
-			}	\
-			cmd_ret = v_secure_pclose(f);	\
-			retBuf[retBufSize-1]=0;	\
-		}	\
-		WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);	\
-		cmd_ret;	\
-	})
-
-typedef enum _RT_802_11_PHY_MODE {
-	PHY_11BG_MIXED = 0,
-	PHY_11B = 1,
-	PHY_11A = 2,
-	PHY_11ABG_MIXED = 3,
-	PHY_11G = 4,
-	PHY_11ABGN_MIXED = 5,	/* both band   5 */
-	PHY_11N_2_4G = 6,		/* 11n-only with 2.4G band	  6 */
-	PHY_11GN_MIXED = 7,		/* 2.4G band	  7 */
-	PHY_11AN_MIXED = 8,		/* 5G  band	   8 */
-	PHY_11BGN_MIXED = 9,	/* if check 802.11b.	  9 */
-	PHY_11AGN_MIXED = 10,	/* if check 802.11b.	  10 */
-	PHY_11N_5G = 11,		/* 11n-only with 5G band				11 */
-	PHY_11VHT_N_ABG_MIXED = 12, /* 12 -> AC/A/AN/B/G/GN mixed */
-	PHY_11VHT_N_AG_MIXED = 13, /* 13 -> AC/A/AN/G/GN mixed  */
-	PHY_11VHT_N_A_MIXED = 14, /* 14 -> AC/AN/A mixed in 5G band */
-	PHY_11VHT_N_MIXED = 15, /* 15 -> AC/AN mixed in 5G band */
-	PHY_11AX_24G = 16,
-	PHY_11AX_5G = 17,
-	PHY_11AX_6G = 18,
-	PHY_11AX_24G_6G = 19,
-	PHY_11AX_5G_6G = 20,
-	PHY_11AX_24G_5G_6G = 21,
-	PHY_11BE_24G = 22,
-	PHY_11BE_5G = 23,
-	PHY_11BE_6G = 24,
-	PHY_11BE_24G_6G = 25,
-	PHY_11BE_5G_6G = 26,
-	PHY_11BE_24G_5G_6G = 27,
-	PHY_MODE_MAX,
-} RT_802_11_PHY_MODE;
-
-enum WIFI_MODE {
-	WMODE_INVALID = 0,
-	WMODE_A = 1 << 0,
-	WMODE_B = 1 << 1,
-	WMODE_G = 1 << 2,
-	WMODE_GN = 1 << 3,
-	WMODE_AN = 1 << 4,
-	WMODE_AC = 1 << 5,
-	WMODE_AX_24G = 1 << 6,
-	WMODE_AX_5G = 1 << 7,
-	WMODE_AX_6G = 1 << 8,
-	WMODE_BE_24G = 1 << 9,
-	WMODE_BE_5G = 1 << 10,
-	WMODE_BE_6G = 1 << 11,
-	/*
-	 * total types of supported wireless mode,
-	 * add this value once yow add new type
-	 */
-	WMODE_COMP = 12,
-};
-
-static unsigned int CFG_WMODE_MAP[] = {
-	PHY_11BG_MIXED, (WMODE_B | WMODE_G), /* 0 => B/G mixed */
-	PHY_11B, (WMODE_B), /* 1 => B only */
-	PHY_11A, (WMODE_A), /* 2 => A only */
-	PHY_11ABG_MIXED, (WMODE_A | WMODE_B | WMODE_G), /* 3 => A/B/G mixed */
-	PHY_11G, WMODE_G, /* 4 => G only */
-	PHY_11ABGN_MIXED, (WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN), /* 5 => A/B/G/GN/AN mixed */
-	PHY_11N_2_4G, (WMODE_GN), /* 6 => N in 2.4G band only */
-	PHY_11GN_MIXED, (WMODE_G | WMODE_GN), /* 7 => G/GN, i.e., no CCK mode */
-	PHY_11AN_MIXED, (WMODE_A | WMODE_AN), /* 8 => A/N in 5 band */
-	PHY_11BGN_MIXED, (WMODE_B | WMODE_G | WMODE_GN), /* 9 => B/G/GN mode*/
-	PHY_11AGN_MIXED, (WMODE_G | WMODE_GN | WMODE_A | WMODE_AN), /* 10 => A/AN/G/GN mode, not support B mode */
-	PHY_11N_5G, (WMODE_AN), /* 11 => only N in 5G band */
-	PHY_11VHT_N_ABG_MIXED, (WMODE_B | WMODE_G | WMODE_GN | WMODE_A | WMODE_AN | WMODE_AC), /* 12 => B/G/GN/A/AN/AC mixed*/
-	PHY_11VHT_N_AG_MIXED, (WMODE_G | WMODE_GN | WMODE_A | WMODE_AN | WMODE_AC), /* 13 => G/GN/A/AN/AC mixed, no B mode */
-	PHY_11VHT_N_A_MIXED, (WMODE_A | WMODE_AN | WMODE_AC), /* 14 => A/AC/AN mixed */
-	PHY_11VHT_N_MIXED, (WMODE_AN | WMODE_AC), /* 15 => AC/AN mixed, but no A mode */
-	PHY_11AX_24G, (WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G),
-	PHY_11AX_5G, (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G),
-	PHY_11AX_6G, (WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G),
-	PHY_11AX_24G_6G, (WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_AX_6G),
-	PHY_11AX_5G_6G, (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G),
-	PHY_11AX_24G_5G_6G, (WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_A |
-						 WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G),
-	PHY_11BE_24G,
-	(WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_BE_24G),
-	PHY_11BE_5G,
-	(WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_BE_5G),
-	PHY_11BE_6G,
-	(WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G | WMODE_BE_6G),
-	PHY_11BE_24G_6G,
-	(WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_AX_6G
-	| WMODE_BE_24G | WMODE_BE_6G),
-	PHY_11BE_5G_6G,
-	(WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G
-	| WMODE_BE_5G | WMODE_BE_6G),
-	PHY_11BE_24G_5G_6G,
-	(WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_A
-	| WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_AX_6G
-	| WMODE_BE_24G | WMODE_BE_5G | WMODE_BE_6G),
-
-	PHY_MODE_MAX, WMODE_INVALID /* default phy mode if not match */
-};
-
-#define WMODE_CAP_6G(_x) \
-(((_x) & (WMODE_AX_6G | WMODE_BE_6G)) != 0)
-#define WMODE_CAP_5G(_x) \
-(((_x) & (WMODE_A | WMODE_AN | WMODE_AC | WMODE_AX_5G | WMODE_BE_5G)) != 0)
-#define WMODE_CAP_2G(_x) \
-(((_x) & (WMODE_B | WMODE_G | WMODE_GN | WMODE_AX_24G | WMODE_BE_24G)) != 0)
-
-static BOOL is_main_vap_index(int vap_index);
-static int array_index_to_vap_index(UINT radioIndex, int arrayIndex, int *vap_index);
-static int vap_index_to_radio_array_index(int vapIndex, int *radioIndex, int *arrayIndex);
-static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size);
-int hwaddr_aton2(const char *txt, unsigned char *addr);
-static int wifi_GetInterfaceName(int apIndex, char *interface_name);
-INT wifi_getMaxRadioNumber(INT *max_radio_num);
-static int wifi_BandProfileRead(int card_idx,
-								int radio_idx,
-								char *param,
-								char *output,
-								int output_size,
-								char *default_value);
-static int array_index_to_vap_index(UINT radioIndex, int arrayIndex, int *vap_index);
-struct params
-{
-	char * name;
-	char * value;
-};
-static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count);
-
-int get_bandwidth_handler(struct nl_msg *msg, void *data);
-
-INT mtk_wifi_get_radio_info(
-	INT radioIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, void *output);
-
-
-#ifdef WIFI_HAL_VERSION_3
-#define MAX_ML_MLD_CNT	16	/*Max multi-link MLD*/
-//#define MAX_SL_MLD_CNT	48	/*MAX single-link MLD*/
-
-static void mld_set(unsigned char mld_index, unsigned char set)
-{
-	if (set)
-		mld_config.valid_mld_bitmap[mld_index / 8] |= (1 << (mld_index % 8));
-	else
-		mld_config.valid_mld_bitmap[mld_index / 8] &= ~(1 << (mld_index % 8));
-}
-
-static unsigned char mld_test(unsigned char mld_index)
-{
-	return mld_config.valid_mld_bitmap[mld_index / 8] & (1 << (mld_index % 8));
-}
-
-static void mld_ap_set(struct multi_link_device *mld, unsigned char ap_index, unsigned char set)
-{
-	if (set)
-		mld->affiliated_ap_bitmap[ap_index / 8] |= (1 << (ap_index % 8));
-	else
-		mld->affiliated_ap_bitmap[ap_index / 8] &= ~(1 << (ap_index % 8));
-}
-
-static unsigned char mld_ap_test(struct multi_link_device *mld, unsigned char ap_index)
-{
-	return mld->affiliated_ap_bitmap[ap_index / 8] & (1 << (ap_index % 8));
-}
-
-int ml_info_callback(struct nl_msg *msg, void *data) {
-    struct nlattr *tb[NL80211_ATTR_MAX + 1];
-    struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO_ATTR_MAX + 1];
-    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-    int err = 0;
-
-    err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-              genlmsg_attrlen(gnlh, 0), NULL);
-    if (err < 0){
-        wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-        return err;
-    }
-
-    if (tb[NL80211_ATTR_VENDOR_DATA]) {
-        err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO_ATTR_MAX,
-            tb[NL80211_ATTR_VENDOR_DATA], NULL);
-        if (err < 0){
-            wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO fails\n");
-            return err;
-        }
-
-        if (vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO]) {
-			if ((size_t)nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO]) !=
-				sizeof(struct bss_mlo_info)) {
-				wifi_debug(DEBUG_ERROR, "wrong mlo info from driver\n");
-				return -1;
-			}
-			memcpy(data, nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO]), sizeof(struct bss_mlo_info));
-        } else
-        return -1;
-    }
-
-    return 0;
-}
-
-static INT eht_mld_nl80211_get_bss_mlo_info(INT apIndex, struct bss_mlo_info *ml_info)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_BSS_MLO_INFO;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_BSS_MLO_INFO);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, ml_info_callback, (void*)ml_info);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO,"send cmd success\n");
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-static int eht_mld_config_init(void)
-{
-	char config_file[128] = {0}, str_mldgroup[256];
-	int res, band, bss_idx;
-	char *token;
-	long mld_index;
-	unsigned char ap_index;
-	int vap_idx;
-	struct multi_link_device *mld;
-	BOOL ap_enable = 0;
-	struct bss_mlo_info ml_info;
-
-	wifi_debug(DEBUG_INFO, "==========>\n");
-
-	memset(&mld_config, 0, sizeof(mld_config));
-	for (band = 0; band < get_runtime_max_radio(); band++) {
-		res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		wifi_datfileRead(config_file, "MldGroup", str_mldgroup, sizeof(str_mldgroup));
-		token = strtok(str_mldgroup, ";");
-		bss_idx = 0;
-		while(token != NULL && bss_idx < 16) {
-			if (hal_strtol(token, 10, &mld_index) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-				break;
-			}
-
-			if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
-				wifi_debug(DEBUG_ERROR, "invalid mld_index %ld, skip it.\n", mld_index);
-				bss_idx++;
-				token = strtok(NULL, ";");
-				continue;
-			}
-
-			mld_set(mld_index, 1);
-			if (array_index_to_vap_index(band, bss_idx, &vap_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid band %d, bss_idx %d, skip it.\n", band, bss_idx);
-				continue;
-			}
-			ap_index = vap_idx;
-			mld = &(mld_config.mld[mld_index]);
-			mld->mld_index = mld_index;
-//			mld->type = mld_index <= MAX_ML_MLD_CNT ? AP_MLD_MULTI_LINK : AP_MLD_SINGLE_LINK;
-			mld_ap_set(mld, ap_index, 1);
-			bss_idx++;
-			token = strtok(NULL, ";");
-			wifi_debug(DEBUG_INFO, "mld[%ld] affiliated ap[%d].\n", mld_index, ap_index);
-		}
-	}
-
-	for (ap_index = 0; ap_index < MAX_APS; ap_index++) {
-		if (wifi_getApEnable(ap_index, &ap_enable) != RETURN_OK)
-			continue;
-
-		if (!ap_enable)
-			continue;
-
-		memset(&ml_info, 0, sizeof(ml_info));
-		if (eht_mld_nl80211_get_bss_mlo_info(ap_index, &ml_info) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "fail to get bss[%d] ml info\n", ap_index);
-			continue;
-		}
-
-		if (ml_info.mld_grp_idx == 0 || ml_info.mld_grp_idx > MAX_ML_MLD_CNT) {
-			wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", ml_info.mld_grp_idx);
-			continue;
-		}
-
-		if (!mld_test(ml_info.mld_grp_idx)) {
-			wifi_debug(DEBUG_ERROR, "!!mld(%d) is not obvoiusly config in dat file, skip it.",
-				ml_info.mld_grp_idx);
-			continue;
-		}
-		wifi_debug(DEBUG_OFF, "!Successfully get bss[%d] ml info from driver, mld_grp_idx=%d"
-			"mld_addr=%02x:%02x:%02x:%02x:%02x:%02x\n", ap_index, ml_info.mld_grp_idx,
-			ml_info.addr[0], ml_info.addr[1], ml_info.addr[2], ml_info.addr[3], ml_info.addr[4],
-			ml_info.addr[5]);
-		mld = &(mld_config.mld[ml_info.mld_grp_idx]);
-		memcpy(mld->mld_mac, ml_info.addr, sizeof(mld->mld_mac));
-	}
-
-	return RETURN_OK;
-}
-
-static unsigned char mld_ap_test_all_mlds(unsigned char ap_index)
-{
-	unsigned char mld_index;
-	struct multi_link_device *mld;
-
-	for (mld_index = 1; mld_index <= MAX_ML_MLD_CNT; mld_index++) {
-
-		if (!mld_test(mld_index))
-			continue;
-
-		mld = &(mld_config.mld[mld_index]);
-
-		if (mld_ap_test(mld, ap_index))
-			return mld_index;
-	}
-
-	return 0;
-}
-
-static void mld_info_display(void)
-{
-	unsigned char mld_index, ap_index;
-	struct multi_link_device *mld;
-	char interface_name[IF_NAME_SIZE] = {0};
-
-	wifi_debug(DEBUG_INFO, "==========>\n");
-	for (mld_index = 1; mld_index <= MAX_ML_MLD_CNT; mld_index++) {
-		if (!mld_test(mld_index))
-			continue;
-
-		mld = &(mld_config.mld[mld_index]);
-
-		wifi_debug(DEBUG_OFF, "MLD[%02d]: %02x:%02x:%02x:%02x:%02x:%02x\n\tAffiliated AP:\n", (int)(mld->mld_index),
-			mld->mld_mac[0], mld->mld_mac[1], mld->mld_mac[2],
-			mld->mld_mac[3], mld->mld_mac[4], mld->mld_mac[5]);
-
-		for (ap_index = 0; ap_index <= MAX_APS; ap_index++) {
-			if (!mld_ap_test(mld, ap_index))
-				continue;
-			if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-				continue;
-			}
-			wifi_debug(DEBUG_INFO, "\tap[%d] %s\n", (int)ap_index, interface_name);
-		}
-	}
-	wifi_debug(DEBUG_INFO, "<==========\n");
-}
-
-INT wifi_eht_create_ap_mld(unsigned char mld_index, unsigned char *mac)
-{
-	int res;
-//	enum mld_type type;
-	struct multi_link_device *mld;
-
-//	if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
-	if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	if (mld_test(mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld already exist with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-//	type = mld_index <= MAX_ML_MLD_CNT ? AP_MLD_MULTI_LINK : AP_MLD_SINGLE_LINK;
-
-	res = v_secure_system("mwctl ra0 set apmld=create:group=%u,addr=%02x:%02x:%02x:%02x:%02x:%02x",
-		mld_index, mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "fail to create mld with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld_set(mld_index, 1);
-
-	mld = &(mld_config.mld[mld_index]);
-	mld->mld_index = mld_index;
-	memcpy(mld->mld_mac, mac, sizeof(mld->mld_mac));
-//	mld->type = type;
-	memset(mld->affiliated_ap_bitmap, 0, sizeof(mld->affiliated_ap_bitmap));
-
-	return RETURN_OK;
-
-}
-
-INT wifi_eht_destroy_ap_mld(unsigned char mld_index)
-{
-	int res;
-	struct multi_link_device *mld;
-
-//	if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
-	if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	if (!mld_test(mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	res = v_secure_system("mwctl ra0 set apmld=destroy:group=%u", mld_index);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "fail to destroy mld with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld_set(mld_index, 0);
-	mld = &(mld_config.mld[mld_index]);
-	memset(mld, 0, sizeof(*mld));
-
-	return RETURN_OK;
-}
-
-INT wifi_eht_list_ap_mld(unsigned char mld_index[], unsigned char *mld_num)
-{
-	unsigned char i, j = 0;
-
-//	for (i = 1; i <= (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT); i++) {
-	for (i = 1; i <= MAX_ML_MLD_CNT; i++) {
-		if (mld_test(i))
-			mld_index[j++] = i;
-	}
-
-	*mld_num = j;
-
-	return RETURN_OK;
-}
-
-INT wifi_eht_add_to_ap_mld(unsigned char mld_index, INT ap_index)
-{
-	int res, radio1, radio2, bss_idx;
-//	enum mld_type type;
-	struct multi_link_device *mld;
-	char interface_name[IF_NAME_SIZE] = {0};
-	unsigned char i;
-
-	if (ap_index < 0 || ap_index >= MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-		return RETURN_ERR;
-	}
-
-//	if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
-	if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	if (!mld_test(mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld = &(mld_config.mld[mld_index]);
-#if 0
-	if (mld->type == AP_MLD_SINGLE_LINK) {
-		/*check single link mld is not occupied by other ap*/
-		for (i = 0; i < MAX_APS; i++) {
-			if(mld_ap_test(mld, i))
-				break;
-		}
-
-		if (i < MAX_APS) {
-			if (i == ap_index) {
-				wifi_debug(DEBUG_ERROR, "current ap(%d) has already joined single link mld(%d)\n", i, mld_index);
-				return RETURN_OK;
-			}
-			wifi_debug(DEBUG_ERROR,
-				"single link mld(%d) already has an affiliated AP(ap_index %d)\n", mld_index, i);
-			return RETURN_ERR;
-		}
-	} else if (mld->type == AP_MLD_MULTI_LINK) {
-#endif
-		/*check if a same band ap already has been joined before*/
-	for (i = 0; i < MAX_APS; i++) {
-		if(mld_ap_test(mld, i)) {
-			if (i == ap_index) {
-				wifi_debug(DEBUG_ERROR, "current ap(index=%d) has already joined current mld\n", i);
-				return RETURN_OK;
-			}
-
-			if (vap_index_to_radio_array_index(i, &radio1, &bss_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
-				return RETURN_ERR;
-			}
-
-			if (vap_index_to_radio_array_index(ap_index, &radio2, &bss_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
-				return RETURN_ERR;
-			}
-
-			if (radio1 == radio2) {
-				wifi_debug(DEBUG_ERROR, "same band ap(index=%d) has already joined current mld\n", i);
-				return RETURN_ERR;
-			}
-		}
-	}
-
-	res = v_secure_system("mwctl %s set apmld=addlink:group=%u", interface_name, mld_index);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "fail to add ap to ap mld with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld_ap_set(mld, ap_index, 1);
-
-	return RETURN_OK;
-}
-
-INT wifi_eht_remove_from_ap_mld(unsigned char mld_index, INT ap_index)
-{
-	int res;
-//	enum mld_type type;
-	struct multi_link_device *mld;
-	char interface_name[IF_NAME_SIZE] = {0};
-
-	if (ap_index < 0 || ap_index >= MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-		return RETURN_ERR;
-	}
-
-//	if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
-	if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	if (!mld_test(mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld = &(mld_config.mld[mld_index]);
-
-	res = v_secure_system("mwctl %s set apmld=dellink", interface_name);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "fail to del ap from ap mld with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld_ap_set(mld, ap_index, 0);
-
-	return RETURN_OK;
-}
-
-INT wifi_eht_get_ap_from_mld(unsigned char mld_index, unsigned char ap_index[], unsigned char *ap_num)
-{
-	unsigned char i, j = 0;
-	struct multi_link_device *mld;
-
-//	if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
-	if (mld_index == 0 || mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	if (!mld_test(mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", mld_index);
-		return RETURN_ERR;
-	}
-
-	mld = &(mld_config.mld[mld_index]);
-
-	for (i = 0; i < MAX_APS; i++) {
-		if (mld_ap_test(mld, i))
-			ap_index[j++] = i;
-	}
-
-	*ap_num = j;
-
-	return RETURN_OK;
-}
-
-INT wifi_eht_mld_ap_transfer(unsigned char old_mld_index,
-	unsigned char new_mld_index, INT ap_index)
-{
-	int res, radio1, radio2, bss_idx;
-//	enum mld_type type;
-	struct multi_link_device *mld, *old_mld;
-	char interface_name[IF_NAME_SIZE] = {0};
-	unsigned char i;
-
-	if (old_mld_index == new_mld_index) {
-		wifi_debug(DEBUG_ERROR, "same mld index %d\n", new_mld_index);
-		return RETURN_OK;
-	}
-
-	if (ap_index < 0 || ap_index >= MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index %d\n", ap_index);
-		return RETURN_ERR;
-	}
-
-	if (old_mld_index == 0 || old_mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid old_mld_index %d\n", old_mld_index);
-		return RETURN_ERR;
-	}
-	old_mld = &(mld_config.mld[old_mld_index]);
-
-	if (!mld_test(old_mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld does not exist with old_mld_index %d\n", old_mld_index);
-		return RETURN_ERR;
-	}
-
-
-//	if (mld_index == 0 || mld_index > (MAX_ML_MLD_CNT + MAX_SL_MLD_CNT)) {
-	if (new_mld_index == 0 || new_mld_index > MAX_ML_MLD_CNT) {
-		wifi_debug(DEBUG_ERROR, "invalid mld_index %d\n", new_mld_index);
-		return RETURN_ERR;
-	}
-
-	if (!mld_test(new_mld_index)) {
-		wifi_debug(DEBUG_ERROR, "mld does not exist with mld_index %d\n", new_mld_index);
-		return RETURN_ERR;
-	}
-
-	mld = &(mld_config.mld[new_mld_index]);
-
-
-	for (i = 0; i < MAX_APS; i++) {
-		if(mld_ap_test(mld, i)) {
-			if (i == ap_index) {
-				wifi_debug(DEBUG_ERROR, "current ap has already joined current mld\n");
-				return RETURN_OK;
-			}
-
-			if (vap_index_to_radio_array_index(i, &radio1, &bss_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
-				return RETURN_ERR;
-			}
-
-			if (vap_index_to_radio_array_index(ap_index, &radio2, &bss_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", i);
-				return RETURN_ERR;
-			}
-
-			if (radio1 == radio2) {
-				wifi_debug(DEBUG_ERROR, "same band ap(index=%d) has already joined current mld\n", i);
-				return RETURN_ERR;
-			}
-		}
-	}
-
-	res = v_secure_system("mwctl %s set apmld=tsfrlink:group=%u", interface_name, new_mld_index);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "fail to transfer ap to ap mld with mld_index %d\n", new_mld_index);
-		return RETURN_ERR;
-	}
-
-	mld_ap_set(old_mld, ap_index, 0);
-	mld_ap_set(mld, ap_index, 1);
-
-	return RETURN_OK;
-}
-
-INT wifi_eht_config_sync2_dat_by_radio(unsigned char band)
-{
-	unsigned char bss_idx, mld_index;
-	char config_file_dat[128] = {0}, MldGroup_V_Str[128] = {0}, buf[64] = {0};
-	int res, vap_index, len = 0, bssidnum;
-	struct params MldGroup;
-
-	if (band >= get_runtime_max_radio()) {
-		wifi_debug(DEBUG_ERROR, "invalid band %u\n", band);
-		return RETURN_ERR;
-	}
-
-	res = wifi_BandProfileRead(0, band, "BssidNum", buf, sizeof(buf), "0");
-	if (res != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
-		return RETURN_ERR;
-	}
-
-	bssidnum = atoi(buf);
-	if (bssidnum <= 0)  {
-		wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
-		return RETURN_ERR;
-	}
-	if (bssidnum > LOGAN_MAX_NUM_VAP_PER_RADIO) {
-		wifi_debug(DEBUG_ERROR, "bss_num is larger than %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file_dat), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	for (bss_idx = 0; bss_idx < bssidnum; bss_idx++) {
-		if (array_index_to_vap_index(band, bss_idx, &vap_index) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalide vap index, band=%d, bss_idx=%d\n", (int)band, (int)bss_idx);
-			break;
-		}
-		mld_index = mld_ap_test_all_mlds(vap_index);
-		res = snprintf(&(MldGroup_V_Str[len]), sizeof(MldGroup_V_Str) - len, "%u;", mld_index);
-		if (os_snprintf_error(sizeof(MldGroup_V_Str) - len, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			break;
-		}
-		len += res;
-	}
-
-	MldGroup.name = "MldGroup";
-	MldGroup.value = MldGroup_V_Str;
-	wifi_datfileWrite(config_file_dat, &MldGroup, 1);
-	wifi_debug(DEBUG_INFO, "band[%u] MldGroup=%s\n", band, MldGroup_V_Str);
-
-	return RETURN_OK;
-}
-
-void wifi_eht_config_sync2_dat(void)
-{
-	unsigned char band;
-
-	for (band = 0; band < get_runtime_max_radio(); band++) {
-		wifi_eht_config_sync2_dat_by_radio(band);
-	}
-}
-
-#endif
-
-static int
-get_value(const char *conf_file, const char *param, char *value, int len)
-{
-	FILE *fp;
-	int ret = -1;
-	int param_len = strlen(param);
-	int buf_len;
-	char buf[256] = {0};
-
-	fp = fopen(conf_file, "r");
-	if (!fp) {
-		return -1;
-	}
-
-	while (fgets(buf, sizeof(buf), fp)) {
-		buf_len = strlen(buf);
-		if (buf_len == 0) {
-			wifi_debug(DEBUG_ERROR, "buf_len = 0\n");
-			if (fclose(fp) != 0) {
-				wifi_debug(DEBUG_ERROR, "fclose fail\n");
-			}
-			return RETURN_ERR;
-		}
-		if (buf[buf_len - 1] == '\n') {
-			buf_len--;
-			buf[buf_len] = '\0';
-		}
-		if ((buf_len > param_len) &&
-			(strncmp(buf, param, param_len) == 0) &&
-			(buf[param_len] == '=')) {
-
-			if (buf_len == (param_len + 1)) {
-				value[0] = '\0';
-				ret = 0;
-			} else {
-				ret = snprintf(value, len, "%s", buf + (param_len + 1));
-				if (os_snprintf_error(len, ret)) {
-					wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				}
-			}
-			if (fclose(fp) != 0) {
-				ret = -1;
-				wifi_debug(DEBUG_ERROR, "fclose fail\n");
-			}
-			return ret;
-		}
-	}
-	if (fclose(fp) == EOF){
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		return RETURN_ERR;
-	}
-	return -1;
-}
-
-static int
-get_value_by_idx(const char *conf_file, const char *param, int idx, char *value, int len)
-{
-	char buf[256];
-	int ret;
-	char *save_ptr = NULL;
-	char *tok = NULL;
-
-	ret = get_value(conf_file, param, buf, sizeof(buf));
-	if (ret < 0)
-		return ret;
-
-	tok = strtok_r(buf, ";", &save_ptr);
-	do {
-		if (idx == 0 || tok == NULL)
-			break;
-		else
-			idx--;
-
-		tok = strtok_r(NULL, ";", &save_ptr);
-	} while (tok != NULL);
-
-	if (tok) {
-		ret = snprintf(value, len, "%s", tok);
-		if (os_snprintf_error(len, ret)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-	} else {
-		ret = 0;
-		value[0] = '\0';
-	}
-
-	return ret;
-}
-
-
-#ifdef HAL_NETLINK_IMPL
-typedef struct {
-	int id;
-	struct nl_sock* socket;
-	struct nl_cb* cb;
-} Netlink;
-
-static int mac_addr_aton(unsigned char *mac_addr, char *arg)
-{
-	unsigned char mac_addr_int[6]={};
-	unsigned int recv;
-
-	recv = 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);
-
-	if (recv != 6) {
-		wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
-		return -1;
-	}
-	mac_addr[0] = mac_addr_int[0];
-	mac_addr[1] = mac_addr_int[1];
-	mac_addr[2] = mac_addr_int[2];
-	mac_addr[3] = mac_addr_int[3];
-	mac_addr[4] = mac_addr_int[4];
-	mac_addr[5] = mac_addr_int[5];
-	return 0;
-}
-
-static void mac_addr_ntoa(char *mac_addr, unsigned char *arg)
-{
-	unsigned int mac_addr_int[6]={};
-	int res;
-
-	mac_addr_int[0] = arg[0];
-	mac_addr_int[1] = arg[1];
-	mac_addr_int[2] = arg[2];
-	mac_addr_int[3] = arg[3];
-	mac_addr_int[4] = arg[4];
-	mac_addr_int[5] = arg[5];
-	res = 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]);
-	if (os_snprintf_error(20, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-	}
-	return;
-}
-
-static int ieee80211_frequency_to_channel(int freq)
-{
-	/* see 802.11-2007 17.3.8.3.2 and Annex J */
-	if (freq == 2484)
-		return 14;
-	/* see 802.11ax D6.1 27.3.23.2 and Annex E */
-	else if (freq == 5935)
-		return 2;
-	else if (freq < 2484)
-		return (freq - 2407) / 5;
-	else if (freq >= 4910 && freq <= 4980)
-		return (freq - 4000) / 5;
-	else if (freq < 5950)
-		return (freq - 5000) / 5;
-	else if (freq <= 45000) /* DMG band lower limit */
-		/* see 802.11ax D6.1 27.3.23.2 */
-		return (freq - 5950) / 5;
-	else if (freq >= 58320 && freq <= 70200)
-		return (freq - 56160) / 2160;
-	else
-		return 0;
-}
-
-static int initSock80211(Netlink* nl) {
-	nl->socket = nl_socket_alloc();
-	if (!nl->socket) {
-		wifi_debug(DEBUG_ERROR, "Failing to allocate the  sock\n");
-		return -ENOMEM;
-	}
-
-	nl_socket_set_buffer_size(nl->socket, 8192, 8192);
-
-	if (genl_connect(nl->socket)) {
-		wifi_debug(DEBUG_ERROR, "Failed to connect\n");
-		nl_close(nl->socket);
-		nl_socket_free(nl->socket);
-		return -ENOLINK;
-	}
-
-	nl->id = genl_ctrl_resolve(nl->socket, "nl80211");
-	if (nl->id< 0) {
-		wifi_debug(DEBUG_ERROR, "interface not found.\n");
-		nl_close(nl->socket);
-		nl_socket_free(nl->socket);
-		return -ENOENT;
-	}
-
-	nl->cb = nl_cb_alloc(NL_CB_DEFAULT);
-	if ((!nl->cb)) {
-		wifi_debug(DEBUG_ERROR, "Failed to allocate netlink callback.\n");
-		nl_close(nl->socket);
-		nl_socket_free(nl->socket);
-		return ENOMEM;
-	}
-
-	return nl->id;
-}
-
-static int nlfree(Netlink *nl)
-{
-	nl_cb_put(nl->cb);
-	nl_close(nl->socket);
-	nl_socket_free(nl->socket);
-	return 0;
-}
-
-static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
-	[NL80211_STA_INFO_TX_BITRATE] = { .type = NLA_NESTED },
-	[NL80211_STA_INFO_RX_BITRATE] = { .type = NLA_NESTED },
-	[NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED }
-};
-
-static struct nla_policy rate_policy[NL80211_RATE_INFO_MAX + 1] = {
-};
-
-static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
-};
-
-typedef struct _wifi_channelStats_loc {
-	INT array_size;
-	INT  ch_number;
-	BOOL ch_in_pool;
-	INT  ch_noise;
-	BOOL ch_radar_noise;
-	INT  ch_max_80211_rssi;
-	INT  ch_non_80211_noise;
-	INT  ch_utilization;
-	ULLONG ch_utilization_total;
-	ULLONG ch_utilization_busy;
-	ULLONG ch_utilization_busy_tx;
-	ULLONG ch_utilization_busy_rx;
-	ULLONG ch_utilization_busy_self;
-	ULLONG ch_utilization_busy_ext;
-} wifi_channelStats_t_loc;
-
-typedef struct wifi_device_info {
-	INT  wifi_devIndex;
-	UCHAR wifi_devMacAddress[6];
-	CHAR wifi_devIPAddress[64];
-	BOOL wifi_devAssociatedDeviceAuthentiationState;
-	INT  wifi_devSignalStrength;
-	INT  wifi_devTxRate;
-	INT  wifi_devRxRate;
-} wifi_device_info_t;
-
-#endif
-
-//For 5g Alias Interfaces
-static BOOL Radio_flag = TRUE;
-//wifi_setApBeaconRate(1, beaconRate);
-
-BOOL multiple_set = FALSE;
-
-/*static int _syscmd(char *cmd, char *retBuf, int retBufSize)
-{
-	FILE *f;
-	char *ptr = retBuf;
-	int bufSize=retBufSize, bufbytes=0, readbytes=0, cmd_ret=0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if((f = popen(cmd, "r")) == NULL) {
-		wifi_debug(DEBUG_ERROR, "\npopen %s error\n", cmd);
-		return RETURN_ERR;
-	}
-
-	while(!feof(f))
-	{
-		*ptr = 0;
-		if(bufSize>=128) {
-			bufbytes=128;
-		} else {
-			bufbytes=bufSize-1;
-		}
-
-		if (fgets(ptr,bufbytes,f) == NULL)
-			break;
-		readbytes=strlen(ptr);
-
-		if(!readbytes)
-			break;
-
-		bufSize-=readbytes;
-		ptr += readbytes;
-	}
-	cmd_ret = pclose(f);
-	retBuf[retBufSize-1]=0;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return cmd_ret >> 8;
-}
-*/
-
-INT radio_index_to_phy(int radioIndex)
-{
-	/* TODO */
-	return radioIndex;
-}
-
-INT wifi_getMaxRadioNumber(INT *max_radio_num)
-{
-	char buf[4] = {0};
-	int res;
-	unsigned long tmp;
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw list | grep Wiphy | wc -l | tr -d '\\n'");
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	if (hal_strtoul(buf, 10, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	res = tmp;
-
-	*max_radio_num = res > MAX_NUM_RADIOS ? MAX_NUM_RADIOS:res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-wifi_band radio_index_to_band(int radioIndex)
-{
-	char buf[64] = {0};
-	long int nl80211_band = 0;
-	wifi_band band = band_invalid;
-	int res;
-	int phyIndex = 0;
-	int zero_array[MAX_NUM_RADIOS] = {0};
-
-	if (memcmp(radio_band, zero_array, sizeof(radio_band)) == 0) {
-		phyIndex = radio_index_to_phy(radioIndex);
-
-		res = _syscmd_secure(buf, sizeof(buf),
-			"iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
-
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		if (hal_strtol(buf, 16, &nl80211_band) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		if (nl80211_band == 1)
-			band = band_2_4;
-		else if (nl80211_band == 2)
-			band = band_5;
-		else if (nl80211_band == 4)	 // band == 3 is 60GHz
-			band = band_6;
-
-		radio_band[radioIndex] = band;
-	}
-
-	return radio_band[radioIndex];
-}
-
-wifi_band wifi_index_to_band(int apIndex)
-{
-	char buf[64] = {0};
-	long int nl80211_band = 0;
-	int i = 0;
-	int phyIndex = 0;
-	int radioIndex = 0, bss_idx;
-	wifi_band band = band_invalid;
-	int res;
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", apIndex);
-		return RETURN_ERR;
-	}
-
-	phyIndex = radio_index_to_phy(radioIndex);
-	while (i < 10) {
-		res = _syscmd_secure(buf, sizeof(buf),
-			"iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", phyIndex);
-
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		
-		if (hal_strtol(buf, 16, &nl80211_band) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		if (nl80211_band == 1)
-			band = band_2_4;
-		else if (nl80211_band == 2)
-			band = band_5;
-		else if (nl80211_band == 4)	 // band == 3 is 60GHz
-			band = band_6;
-
-		if(band != band_invalid)
-			break;
-
-		i++;
-		sleep(1);
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return band;
-}
-
-static int wifi_hostapdRead(char *conf_file, char *param, char *output, int output_size)
-{
-	struct kvc_context *ctx;
-	const char *value;
-	int res = 0;
-
-	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);
-			kvc_unload(ctx);
-			return RETURN_ERR;
-		}
-	} else {
-		res = snprintf(output, output_size, "%s", "");
-		if (os_snprintf_error(output_size, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			kvc_unload(ctx);
-			return RETURN_ERR;
-		}
-	}
-
-	kvc_unload(ctx);
-
-	return 0;
-}
-
-static int wifi_hostapdWrite(char *conf_file, struct params *list, int item_count)
-{
-	struct kvc_context *ctx;
-
-	ctx = kvc_load(conf_file, LF_KEY_CASE_SENSITIVE);
-	if (!ctx) {
-		wifi_debug(DEBUG_ERROR, "load conf fail\n");
-		return RETURN_ERR;
-	}
-	for (int i = 0; i < item_count; i++) {
-		if (kvc_set(ctx, list[i].name, list[i].value))
-			wifi_debug(DEBUG_ERROR, "kvc_set %s to conf_file[%s] fail\n", list[i].name, conf_file);
-		if (kvc_commit(ctx))
-			wifi_debug(DEBUG_ERROR, "kvc_commit %s to conf_file[%s] fail\n", list[i].name, conf_file);
-	}
-	kvc_unload(ctx);
-
-	return 0;
-}
-
-static int wifi_datfileRead(char *conf_file, char *param, char *output, int output_size)
-{
-	int res = 0;
-	int len;
-
-	res = _syscmd_secure(output, output_size, "datconf -f %s get %s", conf_file, param);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail %s %s\n", conf_file, param);
-	}
-
-
-	len = strlen(output);
-	if ((len > 0) && (output[len - 1] == '\n')) {
-		output[len - 1] = '\0';
-	}
-
-	return 0;
-}
-
-static int wifi_datfileWrite(char *conf_file, struct params *list, int item_count)
-{
-	int res;
-	char buf[MAX_BUF_SIZE] = {0};
-
-	for (int i = 0; i < item_count; i++) {
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set %s \"%s\"", conf_file, list[i].name, list[i].value);
-
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	}
-
-	return 0;
-}
-
-static int wifi_l1ProfileRead(char *param, char *output, int output_size)
-{
-	int ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (!param || !output || (output_size <= 0)) {
-		wifi_debug(DEBUG_ERROR, "invalid parameters");
-		return RETURN_ERR;
-	}
-
-	ret = wifi_datfileRead(l1profile, param, output, output_size);
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, l1profile, ret);
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-static int wifi_CardProfileRead(int card_idx, char *param, char *output, int output_size)
-{
-	char option[64];
-	char card_profile_path[64];
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (!param || !output || (output_size <= 0)) {
-		wifi_debug(DEBUG_ERROR, "invalid parameters");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(option, sizeof(option), "INDEX%d_profile_path", card_idx);
-	if (os_snprintf_error(sizeof(option), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	res = wifi_l1ProfileRead(option, card_profile_path, sizeof(card_profile_path));
-	if (res != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_l1ProfileRead %s failed, ret:%d", option,  res);
-		return RETURN_ERR;
-	}
-
-	res = wifi_datfileRead(card_profile_path, param, output, output_size);
-	if (res != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_datfileRead %s from %s failed, ret:%d", param, card_profile_path, res);
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-static int wifi_BandProfileRead(int card_idx,
-								int radio_idx,
-								char *param,
-								char *output,
-								int output_size,
-								char *default_value)
-{
-	char option[64];
-	char band_profile_path[64];
-	int ret, res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (!param || !output || (output_size <= 0)) {
-		wifi_debug(DEBUG_ERROR, "invalid parameters");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(option, sizeof(option), "BN%d_profile_path", radio_idx);
-	if (os_snprintf_error(sizeof(option), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	ret = wifi_CardProfileRead(card_idx, option, band_profile_path, sizeof(band_profile_path));
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_CardProfileRead %s failed, ret:%d", option, ret);
-		return RETURN_ERR;
-	}
-
-	ret = wifi_datfileRead(band_profile_path, param, output, output_size);
-	if (ret != 0) {
-		if (default_value) {
-			res = snprintf(output, output_size, "%s", default_value);
-			if (os_snprintf_error(output_size, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-		} else {
-			output[0] = '\0';
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//For Getting Current Interface Name from corresponding hostapd configuration
-static int wifi_GetInterfaceName(int apIndex, char *interface_name)
-{
-	char config_file[128] = {0};
-	int res;
-
-	if (interface_name == NULL)
-		return RETURN_ERR;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "interface", interface_name, 16);
-	if (strlen(interface_name) == 0)
-		return RETURN_ERR;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-static UCHAR get_bssnum_byindex(INT radio_index, UCHAR *bss_cnt)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	char buf[MAX_CMD_SIZE]={'\0'};
-	UCHAR channel = 0;
-	int res;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radio_index, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_index);
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	/*interface name to channel number*/
-	res = _syscmd_secure(buf, sizeof(buf), "iw dev %s info | grep -i 'channel' | cut -d ' ' -f2", interface_name);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	channel = atoi(buf);
-	WIFI_ENTRY_EXIT_DEBUG("%s:channel=%d\n", __func__, channel);
-	/*count dev number with the same channel*/
-	res = _syscmd_secure(buf, sizeof(buf), "iw dev | grep -i 'channel %d' | wc -l", channel);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	*bss_cnt = atoi(buf) - 1;/*1 for apcli interface*/
-	WIFI_ENTRY_EXIT_DEBUG("%s:bss_cnt=%d\n", __func__, *bss_cnt);
-	return RETURN_OK;
-}
-
-static int wifi_hostapdProcessUpdate(int apIndex, struct params *list, int item_count)
-{
-	char interface_name[16] = {0};
-	char output[32]="";
-	FILE *fp;
-	int i, res;
-	BOOL hostapd_state = FALSE;
-	char buf[MAX_BUF_SIZE] = {0};
-	//NOTE RELOAD should be done in ApplySSIDSettings
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	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 (hostapd_state == TRUE) {
-		for (i=0; i<item_count; i++, list++) {
-			fp = v_secure_popen("r", "hostapd_cli -i%s SET %s %s", interface_name, list->name, list->value);
-
-			if (fp == NULL) {
-				perror("v_secure_popen failed");
-				return -1;
-			}
-			if (!fgets(output, sizeof(output), fp) || strncmp(output, "OK", 2)) {
-				v_secure_pclose(fp);
-				perror("fgets failed");
-				return -1;
-			}
-			v_secure_pclose(fp);
-		}
-	} else
-		wifi_debug(DEBUG_NOTICE, "hostapd_state = FALSE\n");
-	return 0;
-}
-
-static int wifi_quick_reload_ap(int apIndex)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if (multiple_set == TRUE)
-		return RETURN_OK;
-
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s reload", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
- 	}
-
-	return RETURN_OK;
-}
-
-static int wifi_delete_pmkid_cache(int apIndex)
-{
-	char interface_name[16] = {0};
-	int res;
-
-	char buf[MAX_BUF_SIZE]="";
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s pmksa_flush", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-static int wifi_reloadAp(int apIndex)
-{
-	char interface_name[16] = {0};
-	int res;
-
-	if (multiple_set == TRUE)
-		return RETURN_OK;
-	char buf[MAX_BUF_SIZE]="";
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s reload", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s disable", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s enable", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-void wifi_RestartHostapd_2G()
-{
-	int Public2GApIndex = 4;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_setApEnable(Public2GApIndex, FALSE);
-	wifi_setApEnable(Public2GApIndex, TRUE);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-void wifi_RestartHostapd_5G()
-{
-	int Public5GApIndex = 1;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_setApEnable(Public5GApIndex, FALSE);
-	wifi_setApEnable(Public5GApIndex, TRUE);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-void wifi_RestartPrivateWifi_2G()
-{
-	int PrivateApIndex = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_setApEnable(PrivateApIndex, FALSE);
-	wifi_setApEnable(PrivateApIndex, TRUE);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-void wifi_RestartPrivateWifi_5G()
-{
-	int Private5GApIndex = 1;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_setApEnable(Private5GApIndex, FALSE);
-	wifi_setApEnable(Private5GApIndex, TRUE);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static int writeBandWidth(int radioIndex,char *bw_value)
-{
-	char buf[MAX_BUF_SIZE];
-	int res;
-
-
-	if (_syscmd_secure(buf, sizeof(buf), "grep SET_BW%d %s", radioIndex, BW_FNAME)) {
-		res = _syscmd_secure(buf, sizeof(buf), "echo SET_BW%d=%s >> /nvram/bw_file.txt", radioIndex, bw_value);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		return RETURN_OK;
-	}
-
-
-	res = _syscmd_secure(buf, sizeof(buf), "sed -i 's/^SET_BW%d=.*$/SET_BW%d=%s/' %s",radioIndex,radioIndex,bw_value,BW_FNAME);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	return RETURN_OK;
-}
-
-// Input could be "1Mbps"; "5.5Mbps"; "6Mbps"; "2Mbps"; "11Mbps"; "12Mbps"; "24Mbps"
-INT wifi_setApBeaconRate(INT radioIndex,CHAR *beaconRate)
-{
-	struct params params={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {'\0'};
-	int res;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	// Copy the numeric value
-	if (strlen (beaconRate) >= 5) {
-		strncpy(buf, beaconRate, strlen(beaconRate) - 4);
-		buf[strlen(beaconRate) - 4] = '\0';
-	} else if (strlen(beaconRate) > 0){
-		strncpy(buf, beaconRate,sizeof(buf) - 1);
-		buf[sizeof(buf) - 1] = '\0';
-	} else
-		return RETURN_ERR;
-
-	params.name = "beacon_rate";
-	// hostapd config unit is 100 kbps. To convert Mbps to 100kbps, the value need to multiply 10.
-	if (strncmp(buf, "5.5", 3) == 0) {
-		res = snprintf(buf, sizeof(buf), "55");
-		if (os_snprintf_error(sizeof(buf), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		params.value = buf;
-	} else {
-		if (strlen(buf) >= (MAX_BUF_SIZE - 1)) {
-			wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
-			return RETURN_ERR;
-		}
-		strncat(buf, "0", sizeof(buf) - strlen(buf) - 1);
-		params.value = buf;
-	}
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(radioIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_getApBeaconRate(INT radioIndex, CHAR *beaconRate)
-{
-	char config_file[128] = {'\0'};
-	char temp_output[MAX_BUF_SIZE] = {'\0'};
-	char buf[128] = {'\0'};
-	int main_vap_idx;
-
-	long int rate = 0;
-	int phyId = 0, res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == beaconRate)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "beacon_rate", buf, sizeof(buf));
-	phyId = radio_index_to_phy(radioIndex);
-	// Hostapd unit is 100kbps. To convert to 100kbps to Mbps, the value need to divide 10.
-	if(strlen(buf) > 0) {
-		if (strncmp(buf, "55", 2) == 0)
-			res = snprintf(temp_output, sizeof(temp_output), "5.5Mbps");
-		else {
-			if (hal_strtol(buf, 10, &rate) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			res = snprintf(temp_output, sizeof(temp_output), "%ldMbps", rate/10);
-		}
-		if (os_snprintf_error(sizeof(temp_output), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else {
-		// config not set, so we would use lowest rate as default
-		res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep Bitrates -A1 | tail -n 1 | awk '{print $2}' | tr -d '.0\\n'", phyId);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		res = snprintf(temp_output, sizeof(temp_output), "%sMbps", buf);
-		if (os_snprintf_error(sizeof(temp_output), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	strncpy(beaconRate, temp_output, strlen(temp_output));
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_setLED(INT radioIndex, BOOL enable)
-{
-   return 0;
-}
-
-INT wifi_setACSPeriod_netlink(INT radioIndex, ULONG seconds)
-{
-	int main_vap_idx;
-	char interface_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	struct mtk_nl80211_param param;
-	int ret;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
-		return RETURN_ERR;
-	}
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
-		wifi_debug(DEBUG_ERROR, "Nla put AUTO_CH_CHECK_TIME attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-INT wifi_setRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG seconds)
-{
-	char config_file_dat[128] = {0};
-	struct params dat = {0};
-	char str_acs_period[16] = {0};
-	int res;
-	wifi_band band = band_invalid;
-
-	if (seconds == 0)
-		wifi_debug(DEBUG_WARN, "ACS RefreshPeriod is set to 0!!!\n");
-
-	res = snprintf(str_acs_period, sizeof(str_acs_period), "%lu", seconds);
-	if (os_snprintf_error(sizeof(str_acs_period), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	/*set to dat profile*/
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file_dat), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	dat.name = "ACSCheckTime";
-	dat.value = str_acs_period;
-	wifi_datfileWrite(config_file_dat, &dat, 1);
-
-	/*do quick setting*/
-	return wifi_setACSPeriod_netlink(radioIndex, seconds);
-}
-/**********************************************************************************
- *
- *  Wifi Subsystem level function prototypes
- *
-**********************************************************************************/
-//---------------------------------------------------------------------------------------------------
-//Wifi system api
-//Get the wifi hal version in string, eg "2.0.0".  WIFI_HAL_MAJOR_VERSION.WIFI_HAL_MINOR_VERSION.WIFI_HAL_MAINTENANCE_VERSION
-INT wifi_getHalVersion(CHAR *output_string)   //RDKB
-{
-	int res;
-
-	if(!output_string)
-		return RETURN_ERR;
-	res = snprintf(output_string, 64, "%d.%d.%d", WIFI_HAL_MAJOR_VERSION, WIFI_HAL_MINOR_VERSION, WIFI_HAL_MAINTENANCE_VERSION);
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-static void
-wifi_PrepareEnableSSIDConfig(bool reset)
-{
-	int res;
-	char ret_buf[MAX_BUF_SIZE] = {0};
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (access(SSID_ENABLE_CONFIG, F_OK) == 0 && reset == FALSE)
-		return;
-	res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp %s %s", ROM_SSID_ENABLE_CONFIG, SSID_ENABLE_CONFIG);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static void
-wifi_PrepareWifiBrlanConfig(bool reset)
-{
-	int res;
-	char ret_buf[MAX_BUF_SIZE] = {0};
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (access(WIFI_BRLAN_CONFIG, F_OK) == 0 && reset == FALSE)
-		return;
-	res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp %s %s", ROM_WIFI_BRLAN_CONFIG, WIFI_BRLAN_CONFIG);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static BOOL getVapEnableConfig(int vap_index)
-{
-	int res = 0;
-	int len;
-	char output[8] = {0};
-
-	res = _syscmd_secure(output, sizeof(output), "datconf -f %s get enable_ssid%d",
-		SSID_ENABLE_CONFIG, vap_index);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	len = strlen(output);
-	if ((len > 0) && (output[len - 1] == '\n')) {
-		output[len - 1] = '\0';
-	}
-
-	return output[0] == '1' ? TRUE : FALSE;
-}
-
-static BOOL setVapEnableConfig(int vap_index, BOOL enable)
-{
-	int res;
-	char buf[8] = {0};
-
-	res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set enable_ssid%d \"%s\"",
-		SSID_ENABLE_CONFIG, vap_index, enable ? "1" : "0");
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	wifi_debug(DEBUG_OFF, "vap_index[%d] %s\n", vap_index, enable ? "enabled" : "disabled");
-	return 0;
-}
-
-
-/* wifi_factoryReset() function */
-/**
-* @description Clears internal variables to implement a factory reset of the Wi-Fi
-* subsystem. Resets Implementation specifics may dictate some functionality since different hardware implementations may have different requirements.
-*
-* @param None
-*
-* @return The status of the operation.
-* @retval RETURN_OK if successful.
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous
-* @sideeffect None
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_factoryReset()
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-
-	/*delete running hostapd conf files*/
-	wifi_debug(DEBUG_INFO, "deleting hostapd conf file.\n");
-
-	res = _syscmd_secure(buf, sizeof(buf), "rm -rf /nvram/hostapd*.conf");
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	wifi_psk_file_reset();
-	wifi_vap_status_reset();
-	wifi_radio_reset_count_reset();
-	wifi_guard_interval_file_check();
-
-	wifi_PrepareWifiBrlanConfig(TRUE);
-	wifi_PrepareDefaultHostapdConfigs(TRUE);
-	wifi_PrepareEnableSSIDConfig(TRUE);
-	wifi_psk_file_reset();
-
-	for (UCHAR radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
-		wifi_dat_file_reset_by_radio(radio_idx);
-	}
-
-#if 0
-	memset(buf, 0, MAX_BUF_SIZE);
-
-	res = _syscmd_secure(buf, sizeof(buf), "systemctl restart hostapd.service");
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-#endif
-	return RETURN_OK;
-}
-
-/* wifi_factoryResetRadios() function */
-/**
-* @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.
-*
-* @param None
-* @return The status of the operation
-* @retval RETURN_OK if successful
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous
-*
-* @sideeffect None
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_factoryResetRadios()
-{
-	if((RETURN_OK == wifi_factoryResetRadio(0)) && (RETURN_OK == wifi_factoryResetRadio(1)))
-		return RETURN_OK;
-
-	return RETURN_ERR;
-}
-
-ULONG get_radio_reset_cnt(int radioIndex)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	ULONG reset_count = 0;
-	int res;
-
-	res = _syscmd_secure(buf, sizeof(buf),  "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
-		RADIO_RESET_FILE, radioIndex);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) == 0)
-		return 0;
-	else {
-		reset_count = atol(buf);
-		return reset_count;
-	}
-}
-
-void reset_guard_interval(int radioIndex)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-	FILE *f = NULL;
-
-	res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return;
-	}
-	f = fopen(buf, "w");
-	if (f == NULL)
-		return;
-	fprintf(f, "%s", "auto");
-	if (fclose(f) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-}
-
-void update_radio_reset_cnt(int radioIndex)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	ULONG reset_count = 0;
-	int res;
-
-	res = _syscmd_secure(buf, sizeof(buf),  "cat %s 2> /dev/null | grep \"^reset%d=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"",
-		 RADIO_RESET_FILE, radioIndex );
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) == 0)
-		res =_syscmd_secure(buf, sizeof(buf), "sed -i -e '$a reset%d=1' %s", radioIndex, RADIO_RESET_FILE);
-	else {
-		reset_count = atol(buf);
-		reset_count++;
-		res = _syscmd_secure(buf,sizeof(buf), "sed -i \"s/^reset%d=.*/reset%d=%lu/\" %s", radioIndex, radioIndex, reset_count, RADIO_RESET_FILE);
-	}
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-}
-
-/* wifi_factoryResetRadio() function */
-/**
-* @description Restore selected radio parameters without touching access point parameters
-*
-* @param radioIndex - Index of Wi-Fi Radio channel
-*
-* @return The status of the operation.
-* @retval RETURN_OK if successful.
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous.
-* @sideeffect None.
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_factoryResetRadio(int radioIndex) 	//RDKB
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	wifi_dat_file_reset_by_radio(radioIndex);
-
-	/*reset gi setting*/
-	reset_guard_interval(radioIndex);
-
-	/*TBD: check mbss issue*/
-	wifi_factoryResetAP(radioIndex);
-	update_radio_reset_cnt(radioIndex);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-/* wifi_initRadio() function */
-/**
-* Description: This function call initializes the specified radio.
-*  Implementation specifics may dictate the functionality since
-*  different hardware implementations may have different initilization requirements.
-* Parameters : radioIndex - The index of the radio. First radio is index 0. 2nd radio is index 1   - type INT
-*
-* @return The status of the operation.
-* @retval RETURN_OK if successful.
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous.
-* @sideeffect None.
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_initRadio(INT radioIndex)
-{
-	//TODO: Initializes the wifi subsystem (for specified radio)
-	return RETURN_OK;
-}
-
-USHORT cfgmode_to_wmode(UCHAR cfg_mode)
-{
-	if (cfg_mode >= PHY_MODE_MAX)
-		cfg_mode =  PHY_MODE_MAX;
-
-	return CFG_WMODE_MAP[cfg_mode * 2 + 1];
-}
-
-INT wlan_config_set_ch_band(unsigned int wmode)
-{
-	int band = band_2_4;
-
-	/* do not change sequence due to 6GHz might include AC/GN then confused */
-	if (WMODE_CAP_6G(wmode))
-		band = band_6;
-	else if (WMODE_CAP_5G(wmode))
-		band = band_5;
-
-	return band;
-}
-
-
-static void
-wifi_ParseProfile(void)
-{
-	int i, res;
-	int max_radio_num = 0;
-	int card_idx;
-	int band_idx;
-	int phy_idx = 0;
-	int wireless_mode = 0;
-	char buf[MAX_BUF_SIZE] = {0};
-	char chip_name[12];
-	char card_profile[MAX_BUF_SIZE] = {0};
-	char band_profile[MAX_BUF_SIZE] = {0};
-	unsigned int wmode;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	memset(main_prefix, 0, sizeof(main_prefix));
-	memset(ext_prefix, 0, sizeof(ext_prefix));
-	memset(default_ssid, 0, sizeof(default_ssid));
-	for (i = 0; i < MAX_NUM_RADIOS; i++)
-		radio_band[i] = band_invalid;
-
-	if (wifi_getMaxRadioNumber(&max_radio_num) != RETURN_OK) {
-		/* LOG */
-	return;
-	}
-
-	for (card_idx = 0; card_idx < 3; card_idx++) {
-		res = snprintf(buf, sizeof(buf), "INDEX%d", card_idx);
-		if (os_snprintf_error(sizeof(buf), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return;
-		}
-		if (get_value(l1profile, buf, chip_name, sizeof(chip_name)) < 0) {
-			break;
-		}
-		res = snprintf(buf, sizeof(buf), "INDEX%d_profile_path", card_idx);
-		if (os_snprintf_error(sizeof(buf), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return;
-		}
-		if (get_value(l1profile, buf, card_profile, sizeof(card_profile)) < 0) {
-			break;
-		}
-		for (band_idx = 0; band_idx < 3; band_idx++) {
-			res = snprintf(buf, sizeof(buf), "BN%d_profile_path", band_idx);
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			if (get_value(card_profile, buf, band_profile, sizeof(band_profile)) < 0) {
-				/* LOG */
-				continue;
-			}
-
-			res = snprintf(buf, sizeof(buf), "INDEX%d_main_ifname", card_idx);
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			if (get_value_by_idx(l1profile, buf, band_idx, main_prefix[phy_idx], IFNAMSIZ) < 0) {
-				/* LOG */
-			}
-
-			res = snprintf(buf, sizeof(buf), "INDEX%d_ext_ifname", card_idx);
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			if (get_value_by_idx(l1profile, buf, band_idx, ext_prefix[phy_idx], IFNAMSIZ) < 0) {
-				/* LOG */
-			}
-
-			if (get_value(band_profile, "SSID1", default_ssid[phy_idx], sizeof(default_ssid[phy_idx])) < 0) {
-				/* LOG */
-			}
-			if (get_value(band_profile, "WirelessMode", buf, sizeof(buf)) < 0) {
-				/* LOG */
-			}
-
-			wireless_mode = atoi(buf);
-			wmode = cfgmode_to_wmode(wireless_mode);
-			radio_band[phy_idx] = wlan_config_set_ch_band(wmode);
-			phy_idx++;
-			g_phy_count = phy_idx;
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static int wifi_get_bridge_name(char *vap_name, char *bridge_name, unsigned int bridge_buf_size);
-
-static void
-wifi_PrepareDefaultHostapdConfigs(bool reset)
-{
-	int radio_idx, res;
-	int bss_idx;
-	int ap_idx;
-
-	char config_file[MAX_SUB_CMD_SIZE] = {0};
-	char ssid[MAX_BUF_SIZE] = {0};
-	char interface[32] = {0};
-	char bridge[32] = {0};
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	char psk_file[64] = {0};
-	struct params params[4];
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++) {
-
-		for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
-			if (array_index_to_vap_index(radio_idx, bss_idx, &ap_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radio_idx, bss_idx);
-				continue;
-			}
-
-			res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
-			if (os_snprintf_error(sizeof(config_file), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			if (access(config_file, F_OK) == 0 && reset == FALSE)
-				continue;
-			res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-			res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_MLD, bss_idx);
-			if (os_snprintf_error(sizeof(ssid), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			
-			if (radio_idx == band_2_4) {
-				res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
-				if (os_snprintf_error(sizeof(interface), res)) {
-					wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-					return;
-				}
-			} else if (radio_idx == band_5) {
-				res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
-				if (os_snprintf_error(sizeof(interface), res)) {
-					wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-					return;
-				}
-			} else if (radio_idx == band_6) {
-				res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
-				if (os_snprintf_error(sizeof(interface), res)) {
-					wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-					return;
-				}
-			}
-
-			/* fix wpa_psk_file path */
-			res = snprintf(psk_file, sizeof(psk_file), "/nvram/hostapd%d.psk", ap_idx);
-			if (os_snprintf_error(sizeof(psk_file), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			params[0].name = "ssid";
-			params[0].value = ssid;
-			params[1].name = "interface";
-			params[1].value = interface;
-			params[2].name = "wpa_psk_file";
-			params[2].value = psk_file;
-			params[3].name = "bridge";
-			/*by referring to customer's patch*/
-			params[3].value = DEFAULT_BRIDGE_NAME;
-
-			memset(bridge, 0, sizeof(bridge));
-			/*find bridge for a specific wifi interface in /etc/wireless/hal/wifi_config*/
-			if (wifi_get_bridge_name(interface, bridge, sizeof(bridge)) == RETURN_OK) {
-				if (strlen(bridge) > 0)
-					params[3].value = bridge;
-			}
-
-			wifi_hostapdWrite(config_file, params, sizeof(params) / sizeof(params[0]));
-		}
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static unsigned long radio_start_uptime[MAX_NUM_RADIOS];
-/* Get the system uptime in secs.
- * cat /proc/uptime outputs 17884.70 58636.68
- *   - the uptime of the system (17884.70 seconds), and
- *   - the amount of time spent in idle process (58636.68 seconds)
- * we only use to the granularity of secs (17884) now - ignoring the rest
- */
-static unsigned long wifi_getSystemUpSecs(void)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	unsigned long sysUpSeconds = 0;
-	int ret;
-	// consider upto decimal number of seconds
-	ret = _syscmd_secure(buf, sizeof(buf), "cat /proc/uptime | cut -d '.' -f1");
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	if (hal_strtoul(buf, 10, &sysUpSeconds) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	return sysUpSeconds;
-}
-
-static void
-wifiBringUpInterfacesForRadio(int radio_idx)
-{
-	int bss_idx;
-	int ap_idx;
-	char cmd[MAX_CMD_SIZE] = {0};
-	char config_file[MAX_SUB_CMD_SIZE] = {0};
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	char inf_name[IF_NAME_SIZE] = {0};
-	int res, ret, bss_num;
-	char interface_name[IF_NAME_SIZE] = {0};
-
-    WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	bss_idx = 0;
-
-	ret = wifi_BandProfileRead(0, radio_idx, "BssidNum", ret_buf, sizeof(ret_buf), "1");
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
-		return;
-	}
-
-	bss_num = atoi(ret_buf);
-	if (bss_num <= 0)  {
-		wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", ret_buf);
-		return ;
-	}
-
-	if (bss_num > LOGAN_MAX_NUM_VAP_PER_RADIO) {
-		wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
-		bss_num = LOGAN_MAX_NUM_VAP_PER_RADIO;
-	}
-
-	wifi_debug(DEBUG_OFF, "band %d BssidNum %d\n", radio_idx, bss_num);
-	/*TBD: we need refine setup flow and mbss flow*/
-    for (bss_idx = 0; bss_idx < bss_num; bss_idx++) {
-		if (array_index_to_vap_index(radio_idx, bss_idx, &ap_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radio_idx, bss_idx);
-			continue;
-		}
-
-		/* use iw add interface to create interface by default*/
-		if ((wifi_GetInterfaceName(ap_idx, interface_name) == RETURN_OK) && !is_main_vap_index(ap_idx)) {
-			res = _syscmd_secure(ret_buf, sizeof(ret_buf), "iw phy%d interface add %s type __ap", radio_idx, interface_name);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-
-		/* For main interface, always bring it up firstly.
-		 * The purpose is that the non-main interfaces could be added successfully.
-		 */
-		if (getVapEnableConfig(ap_idx) == FALSE && !is_main_vap_index(ap_idx))
-			continue;
-
-		wifi_debug(DEBUG_NOTICE, "bring up vap[%d]\n", ap_idx);
-
-		res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s%d.psk", PSK_FILE, ap_idx);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		memset(cmd, 0, MAX_CMD_SIZE);
-		memset(ret_buf, 0, MAX_BUF_SIZE);
-
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_idx);
-		if (os_snprintf_error(sizeof(cmd), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return;
-		}
-		
-		res = _syscmd_secure(ret_buf, sizeof(ret_buf), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", radio_idx, config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		/* For main interface, bring it down if it is disabled, by using 'ifconfig rax0 down'.*/
-		if (getVapEnableConfig(ap_idx) == FALSE && is_main_vap_index(ap_idx))
-			wifi_setApEnable(ap_idx, FALSE);
-
-		wifi_GetInterfaceName(ap_idx, inf_name);
-		wifi_debug(DEBUG_OFF, "bring up %s\n", inf_name);
-
-		memset(cmd, 0, MAX_CMD_SIZE);
-		memset(ret_buf, 0, MAX_BUF_SIZE);
-
-		/* fix vap-status file */
-		res = _syscmd_secure(ret_buf, sizeof(ret_buf), "sed -i \"s/^%s=.*/%s=1/\" %s", inf_name, inf_name, VAP_STATUS_FILE);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-    }
-
-    WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static void
-wifi_BringUpInterfaces(void)
-{
-    int radio_idx;
-    int band_idx;
-    WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-    for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
-        band_idx = radio_index_to_band(radio_idx);
-        if (band_idx < 0) {
-            break;
-        }
-        wifiBringUpInterfacesForRadio(radio_idx);
-
-		radio_start_uptime[radio_idx] = wifi_getSystemUpSecs();
-    }
-    WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static void
-wifi_BringDownInterfacesForRadio(int radio_idx)
-{
-
-	char ret_buf[MAX_BUF_SIZE]={'\0'};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	res = _syscmd_secure(ret_buf, sizeof(ret_buf), "hostapd_cli -i global raw REMOVE %s", main_prefix[radio_idx]);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-
-static void
-wifi_BringDownInterfaces(void)
-{
-	int radio_idx;
-	int band_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
-		band_idx = radio_index_to_band(radio_idx);
-		if (band_idx < 0) {
-			break;
-		}
-		wifi_BringDownInterfacesForRadio(radio_idx);
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-}
-
-static void wifi_dat_file_reset_by_radio(char radio_idx)
-{
-
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	char rom_dat_file[MAX_SUB_CMD_SIZE]= {0};
-	char dat_file[MAX_SUB_CMD_SIZE]= {0};
-	int res;
-
-	res = snprintf(rom_dat_file, sizeof(rom_dat_file), "%s%d.dat", ROM_LOGAN_DAT_FILE, radio_idx);
-	if (os_snprintf_error(sizeof(rom_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return;
-	}
-
-	res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp -rf %s %s", rom_dat_file, dat_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-}
-
-static void wifi_psk_file_reset()
-{
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	char psk_file[MAX_SUB_CMD_SIZE]= {0};
-	char vap_idx = 0;
-	int res;
-
-	for (vap_idx = 0; vap_idx < MAX_APS; vap_idx++) {
-		res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, vap_idx);
-		if (os_snprintf_error(sizeof(psk_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return;
-		}
-
-		if (access(psk_file, F_OK) != 0) {
-			res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", psk_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		} else {
-
-			res = _syscmd_secure(ret_buf, sizeof(ret_buf), "echo '' > %s", psk_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-	}
-}
-
-static void wifi_vap_status_reset()
-{
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int radio_idx = 0;
-	char bss_idx = 0;
-	int res;
-
-	if (access(VAP_STATUS_FILE, F_OK) != 0) {
-		res = _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", VAP_STATUS_FILE);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	} else {
-		res = _syscmd_secure(ret_buf, sizeof(ret_buf), "echo '' > %s", VAP_STATUS_FILE);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	}
-
-	memset(ret_buf, 0, MAX_BUF_SIZE);
-
-	for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
-		for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
-			res = _syscmd_secure(ret_buf, sizeof(ret_buf), "echo %s%d=0 >> /nvram/vap-status", ext_prefix[radio_idx], bss_idx);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-
-}
-
-static void wifi_radio_reset_count_reset()
-{
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int res;
-	FILE *f = NULL;
-
-	if (access(RADIO_RESET_FILE, F_OK) != 0) {
-		res =  _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", RADIO_RESET_FILE);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	}
-	f = fopen("/nvram/radio_reset", "w");
-	if (f == NULL)
-		return;
-	fprintf(f, "%s", "reset0=0\n");
-	fprintf(f, "%s", "reset1=0\n");
-	fprintf(f, "%s", "reset2=0\n");
-	if (fclose(f) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-}
-
-static void wifi_guard_interval_file_check()
-{
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int res;
-	unsigned char i = 0;
-	char file[MAX_SUB_CMD_SIZE] = {0};
-	FILE *f = NULL;
-
-	for (i = 0; i < get_runtime_max_radio(); i++) {
-		res = snprintf(file, sizeof(file), "%s%d.txt", GUARD_INTERVAL_FILE, i);
-		if (os_snprintf_error(sizeof(file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		}
-		wifi_debug(DEBUG_INFO, "%s:file %s", __func__, file);
-		if (access(file, F_OK) != 0) {
-			res =  _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-		f = fopen(file, "w");
-		if (f == NULL)
-			return;
-		fprintf(f, "%s", "auto");
-		if (fclose(f) == EOF)
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-	}
-}
-
-static void wifi_mcs_file_check()
-{
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int res;
-	unsigned char i = 0;
-	char file[MAX_SUB_CMD_SIZE] = {0};
-	FILE *f = NULL;
-
-	for (i = 0; i < get_runtime_max_radio(); i++) {
-		res = snprintf(file, sizeof(file), "%s%d.txt", MCS_FILE, i);
-		if (os_snprintf_error(sizeof(file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		}
-		wifi_debug(DEBUG_INFO, "%s:file %s", __func__, file);
-		if (access(file, F_OK) != 0) {
-			res =  _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-		f = fopen(file, "w");
-		if (f == NULL)
-			return;
-		fprintf(f, "%s", "11");
-		if (fclose(f) == EOF)
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-	}
-}
-static void wifi_mgmt_pwr_file_check()
-{
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int res;
-	unsigned char i = 0;
-	char file[MAX_SUB_CMD_SIZE] = {0};
-	FILE *f = NULL;
-
-	for (i = 0; i < get_runtime_max_radio(); i++) {
-		res = snprintf(file, sizeof(file), "%s%d.txt", MGMT_POWER_CTRL, i);
-		if (os_snprintf_error(sizeof(file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		}
-		if (access(file, F_OK) != 0) {
-			res =  _syscmd_secure(ret_buf, sizeof(ret_buf), "touch %s", file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-		f = fopen(file, "w");
-		if (f == NULL)
-			return;
-		fprintf(f, "%s", "0");
-		if (fclose(f) == EOF)
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-	}
-}
-#ifdef WIFI_AGENT_TDK_TEST
-static void wifi_upload_reset()
-{
-	FILE *f = NULL;
-
-	if (access("/tmp/upload", F_OK) != 0) {
-		f = fopen("/tmp/upload", "w+");
-		if (f == NULL)
-			return;
-		fprintf(f, "%s", "5");
-		if (fclose(f) == EOF)
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-	}
-}
-#endif
-#define HOSTAPD_DBG "/nvram/wifiVendorHostapdDbg"
-#define HOSTAPD_OPTIONS_FILE_PATH "/etc/default/hostapd"
-#define HOSTAPD_DEFAULT_OPTIONS "-s -t -f /rdklogs/logs/wifi_vendor_hostapd.log"
-#define HOSTAPD_DEBUG_OPTIONS "-t -f /tmp/wifiVendorHostapd"
-
-void start_hostapd_service()
-{
-	int res;
-	char buf[8] = {0};
-
-	res = access(HOSTAPD_DBG, F_OK);
-	res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set OPTIONS %s",
-			HOSTAPD_OPTIONS_FILE_PATH, res == 0 ? HOSTAPD_DEBUG_OPTIONS : HOSTAPD_DEFAULT_OPTIONS);
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	v_secure_system("systemctl start hostapd.service");
-}
-// Initializes the wifi subsystem (all radios)
-INT wifi_init()							//RDKB
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	static int CallOnce = 1;
-
-	//Not intitializing macfilter for Turris-Omnia Platform for now
-	//macfilter_init();
-	if (CallOnce) {
-		wifi_PrepareWifiBrlanConfig(FALSE);
-		wifi_ParseProfile();
-		wifi_PrepareDefaultHostapdConfigs(FALSE);
-		wifi_PrepareEnableSSIDConfig(FALSE);
-		wifi_psk_file_reset();
-		//v_secure_system("/usr/sbin/iw reg set US");
-		start_hostapd_service();
-		sleep(2);
-		setbuf(stdout, NULL);
-		wifi_vap_status_reset();
-		wifi_radio_reset_count_reset();
-		wifi_BringUpInterfaces();
-		eht_mld_config_init();
-		CallOnce = 0;
-		mld_info_display();
-		wifi_guard_interval_file_check();
-		wifi_mcs_file_check();
-		wifi_mgmt_pwr_file_check();
-#ifdef WIFI_AGENT_TDK_TEST
-		/* for wifiagent TDK test */
-		wifi_upload_reset();
-#endif
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-/* wifi_reset() function */
-/**
-* Description: Resets the Wifi subsystem.  This includes reset of all AP varibles.
-*  Implementation specifics may dictate what is actualy reset since
-*  different hardware implementations may have different requirements.
-* Parameters : None
-*
-* @return The status of the operation.
-* @retval RETURN_OK if successful.
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous.
-* @sideeffect None.
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_reset()
-{
-	int radio_idx;
-	wifi_BringDownInterfaces();
-	sleep(2);
-
-	//TODO: resets the wifi subsystem, deletes all APs
-	v_secure_system("systemctl stop hostapd.service");
-	sleep(2);
-
-	v_secure_system("systemctl start hostapd.service");
-	sleep(5);
-
-	wifi_PrepareDefaultHostapdConfigs(TRUE);
-	wifi_PrepareEnableSSIDConfig(TRUE);
-	wifi_PrepareWifiBrlanConfig(TRUE);
-	wifi_psk_file_reset();
-	wifi_BringUpInterfaces();
-	sleep(2);
-
-	wifi_vap_status_reset();
-	for (radio_idx = 0; radio_idx < MAX_NUM_RADIOS; radio_idx++)
-		update_radio_reset_cnt(radio_idx);
-
-	return RETURN_OK;
-}
-
-/* wifi_down() function */
-/**
-* @description Turns off transmit power for the entire Wifi subsystem, for all radios.
-* Implementation specifics may dictate some functionality since
-* different hardware implementations may have different requirements.
-*
-* @param None
-*
-* @return The status of the operation
-* @retval RETURN_OK if successful
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous
-* @sideeffect None
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_down()
-{
-	//TODO: turns off transmit power for the entire Wifi subsystem, for all radios
-
-	for (int radioIndex = 0; radioIndex < get_runtime_max_radio(); radioIndex++)
-		wifi_setRadioEnable(radioIndex, FALSE);
-
-	return RETURN_OK;
-}
-
-
-/* wifi_createInitialConfigFiles() function */
-/**
-* @description This function creates wifi configuration files. The format
-* and content of these files are implementation dependent.  This function call is
-* used to trigger this task if necessary. Some implementations may not need this
-* function. If an implementation does not need to create config files the function call can
-* do nothing and return RETURN_OK.
-*
-* @param None
-*
-* @return The status of the operation
-* @retval RETURN_OK if successful
-* @retval RETURN_ERR if any error is detected
-*
-* @execution Synchronous
-* @sideeffect None
-*
-* @note This function must not suspend and must not invoke any blocking system
-* calls. It should probably just send a message to a driver event handler task.
-*
-*/
-INT wifi_createInitialConfigFiles()
-{
-	//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)
-	return RETURN_OK;
-}
-
-struct hal_country_code {
-	wifi_countrycode_type_t wifi_countrycode;
-	CHAR CountryName[3];
-};
-
-static struct hal_country_code all_country_code[] = {
-	{wifi_countrycode_AE, "AE"},/**< UNITED ARAB EMIRATES */
-	{wifi_countrycode_AL, "AL"},/**< ALBANIA */
-	{wifi_countrycode_AM, "AM"},/**< ARMENIA */
-	{wifi_countrycode_AR, "AR"},/**< ARGENTINA */
-	{wifi_countrycode_AT, "AT"},/**< AUSTRIA */
-	{wifi_countrycode_AU, "AU"},/**< AUSTRALIA */
-	{wifi_countrycode_AZ, "AZ"},/**< AZERBAIJAN */
-	{wifi_countrycode_BE, "BE"},/**< BELGIUM */
-	{wifi_countrycode_BG, "BG"},/**< BULGARIA */
-	{wifi_countrycode_BH, "BH"},/**< BAHRAIN */
-	{wifi_countrycode_BN, "BN"},/**< BRUNEI DARUSSALAM */
-	{wifi_countrycode_BO, "BO"},/**< BOLIVIA */
-	{wifi_countrycode_BR, "BR"},/**< BRAZIL */
-	{wifi_countrycode_BY, "BY"},/**< BELARUS */
-	{wifi_countrycode_BZ, "BZ"},/**< BELIZE */
-	{wifi_countrycode_CA, "CA"},/**< CANADA */
-	{wifi_countrycode_CH, "CH"},/**< SWITZERLAND */
-	{wifi_countrycode_CL, "CL"},/**< CHILE */
-	{wifi_countrycode_CN, "CN"},/**< CHINA */
-	{wifi_countrycode_CO, "CO"},/**< COLOMBIA */
-	{wifi_countrycode_CR, "CR"},/**< COSTA RICA */
-	{wifi_countrycode_CY, "CY"},/**< CYPRUS */
-	{wifi_countrycode_CZ, "CZ"},/**< CZECH REPUBLIC */
-	{wifi_countrycode_DE, "DE"},/**< GERMANY */
-	{wifi_countrycode_DK, "DK"},/**< DENMARK */
-	{wifi_countrycode_DO, "DO"},/**< DOMINICAN REPUBLIC */
-	{wifi_countrycode_DZ, "DZ"},/**< ALGERIA */
-	{wifi_countrycode_EC, "EC"},/**< ECUADOR */
-	{wifi_countrycode_EE, "EE"},/**< ESTONIA */
-	{wifi_countrycode_EG, "EG"},/**< EGYPT */
-	{wifi_countrycode_ES, "ES"},/**< SPAIN */
-	{wifi_countrycode_FI, "FI"},/**< FINLAND */
-	{wifi_countrycode_FR, "FR"},/**< FRANCE */
-	{wifi_countrycode_GB, "GB"},/**< UNITED KINGDOM */
-	{wifi_countrycode_GE, "GE"},/**< GEORGIA */
-	{wifi_countrycode_GR, "GR"},/**< GREECE */
-	{wifi_countrycode_GT, "GT"},/**< GUATEMALA */
-	{wifi_countrycode_HR, "HR"},/**< CROATIA */
-	{wifi_countrycode_HN, "HN"},/**< HONDURAS */
-	{wifi_countrycode_HK, "HK"},/**< HONG KONG */
-	{wifi_countrycode_HU, "HU"},/**< HUNGARY */
-	{wifi_countrycode_IS, "IS"},/**< ICELAND */
-	{wifi_countrycode_IN, "IN"},/**< INDIA */
-	{wifi_countrycode_ID, "ID"},/**< INDONESIA */
-	{wifi_countrycode_IR, "IR"},/**< IRAN, ISLAMIC REPUBLIC OF */
-	{wifi_countrycode_IE, "IE"},/**< IRELAND */
-	{wifi_countrycode_IL, "IL"},/**< ISRAEL */
-	{wifi_countrycode_IT, "IT"},/**< ITALY */
-	{wifi_countrycode_JP, "JP"},/**< JAPAN */
-	{wifi_countrycode_JO, "JO"},/**< JORDAN */
-	{wifi_countrycode_KP, "KP"},/**< KOREA, DEMOCRATIC PEOPLE'S REPUBLIC OF */
-	{wifi_countrycode_KR, "KR"},/**< KOREA, REPUBLIC OF */
-	{wifi_countrycode_KW, "KW"},/**< KUWAIT */
-	{wifi_countrycode_KZ, "KZ"},/**< KAZAKHSTAN */
-	{wifi_countrycode_LB, "LB"},/**< LEBANON */
-	{wifi_countrycode_LI, "LI"},/**< LIECHTENSTEIN */
-	{wifi_countrycode_LT, "LT"},/**< LITHUANIA */
-	{wifi_countrycode_LU, "LU"},/**< LUXEMBOURG */
-	{wifi_countrycode_LV, "LV"},/**< LATVIA */
-	{wifi_countrycode_MA, "MA"},/**< MOROCCO */
-	{wifi_countrycode_MC, "MC"},/**< MONACO */
-	{wifi_countrycode_MK, "MK"},/**< MACEDONIA, THE FORMER YUGOSLAV REPUBLIC OF */
-	{wifi_countrycode_MO, "MO"},/**< MACAO */
-	{wifi_countrycode_MX, "MX"},/**< MEXICO */
-	{wifi_countrycode_MY, "MY"},/**< MALAYSIA */
-	{wifi_countrycode_NL, "NL"},/**< NETHERLANDS */
-	{wifi_countrycode_NO, "NO"},/**< NORWAY */
-	{wifi_countrycode_NZ, "NZ"},/**< NEW ZEALAND */
-	{wifi_countrycode_OM, "OM"},/**< OMAN */
-	{wifi_countrycode_PA, "PA"},/**< PANAMA */
-	{wifi_countrycode_PE, "PE"},/**< PERU */
-	{wifi_countrycode_PH, "PH"},/**< PHILIPPINES */
-	{wifi_countrycode_PK, "PK"},/**< PAKISTAN */
-	{wifi_countrycode_PL, "PL"},/**< POLAND */
-	{wifi_countrycode_PR, "PR"},/**< PUERTO RICO */
-	{wifi_countrycode_PT, "PT"},/**< PORTUGAL */
-	{wifi_countrycode_QA, "QA"},/**< QATAR */
-	{wifi_countrycode_RO, "RO"},/**< ROMANIA */
-	{wifi_countrycode_RU, "RU"},/**< RUSSIAN FEDERATION */
-	{wifi_countrycode_SA, "SA"},/**< SAUDI ARABIA */
-	{wifi_countrycode_SE, "SE"},/**< SWEDEN */
-	{wifi_countrycode_SG, "SG"},/**< SINGAPORE */
-	{wifi_countrycode_SI, "SI"},/**< SLOVENIA */
-	{wifi_countrycode_SK, "SK"},/**< SLOVAKIA */
-	{wifi_countrycode_SV, "SV"},/**< EL SALVADOR */
-	{wifi_countrycode_SY, "SY"},/**< SYRIAN ARAB REPUBLIC */
-	{wifi_countrycode_TH, "TH"},/**< THAILAND */
-	{wifi_countrycode_TN, "TN"},/**< TUNISIA */
-	{wifi_countrycode_TR, "TR"},/**< TURKEY */
-	{wifi_countrycode_TT, "TT"},/**< TRINIDAD AND TOBAGO */
-	{wifi_countrycode_TW, "TW"},/**< TAIWAN, PROVINCE OF CHINA */
-	{wifi_countrycode_UA, "UA"},/**< UKRAINE */
-	{wifi_countrycode_US, "US"},/**< UNITED STATES */
-	{wifi_countrycode_UY, "UY"},/**< URUGUAY */
-	{wifi_countrycode_UZ, "UZ"},/**< UZBEKISTAN */
-	{wifi_countrycode_VE, "VE"},/**< VENEZUELA */
-	{wifi_countrycode_VN, "VN"},/**< VIET NAM */
-	{wifi_countrycode_YE, "YE"},/**< YEMEN */
-	{wifi_countrycode_ZA, "ZA"},/**< SOUTH AFRICA */
-	{wifi_countrycode_ZW, "ZW"},/**< ZIMBABWE */
-};
-
-/* outputs the country code to a max 64 character string */
-INT wifi_getRadioCountryCode(INT radioIndex, CHAR *output_string)
-{
-	int ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	ret = wifi_BandProfileRead(0, radioIndex, "CountryCode", output_string, 64, NULL);
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead CountryCode failed\n");
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_setCountryCode_netlink(INT radioIndex, CHAR *CountryCode)
-{
-	int ret;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int len;
-
-	len = strlen(CountryCode);
-	if (len != 2) {
-		wifi_debug(DEBUG_ERROR, "invalid CountryCode len!!!\n");
-		return RETURN_ERR;
-	}
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_COUNTRY;
-	param.if_type = NL80211_ATTR_WIPHY;
-	param.if_idx = radio_index_to_phy(radioIndex);
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_COUNTRY_SET_CODE, len, CountryCode)) {
-		wifi_debug(DEBUG_ERROR, "Nla put COUNTRY_SET_CODE attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-INT wifi_setRadioCountryCode(INT radioIndex, CHAR *CountryCode)
-{
-	struct params dat = {0};
-	char config_file_dat[128] = {0};
-	wifi_band band = band_invalid;
-	USHORT country_idx;
-	UCHAR country_find = FALSE;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	if ((CountryCode == NULL) || (strlen(CountryCode) != 2)) {
-		wifi_debug(DEBUG_ERROR, "input para error!!!\n");
-		return RETURN_ERR;
-	}
-
-	/*check country code is valid*/
-	for (country_idx = 0; country_idx < ARRAY_SIZE(all_country_code); country_idx++) {
-		if (!strcmp(CountryCode, all_country_code[country_idx].CountryName)) {
-			country_find = TRUE;
-			break;
-		}
-	}
-
-	if (!country_find) {
-		wifi_debug(DEBUG_ERROR, "CountryCode: %s is not supported!!!\n", CountryCode);
-		return RETURN_ERR;
-	}
-
-	dat.name = "CountryCode";
-	dat.value = CountryCode;
-
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file_dat), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileWrite(config_file_dat, &dat, 1);
-
-	/*do country code quick setting*/
-	wifi_setCountryCode_netlink(radioIndex, CountryCode);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_getRadioChannelStats2(INT radioIndex, wifi_channelStats2_t *outputChannelStats2)
-{
-	char interface_name[16] = {0};
-	char channel_util_file[64] = {0};
-	char cmd[128] =  {0};
-	char buf[128] = {0};
-	char *line = NULL;
-	char *param = NULL, *value = NULL;
-	int read = 0, res;
-	unsigned int ActiveTime = 0, BusyTime = 0, TransmitTime = 0;
-	unsigned long preActiveTime = 0, preBusyTime = 0, preTransmitTime = 0;
-	long int rssi;
-	long int tmp_l;
-	unsigned long tmp_ul;
-	size_t len = 0;
-	FILE *f = NULL;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw %s scan | grep signal | awk '{print $2}' | sort -n | tail -n1", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtol(buf, 10, &rssi) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	outputChannelStats2->ch_Max80211Rssi = rssi;
-
-	memset(cmd, 0, sizeof(cmd));
-	memset(buf, 0, sizeof(buf));
-	res = snprintf(cmd, sizeof(cmd), "iw %s survey dump | grep 'in use' -A6", interface_name);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	f = v_secure_popen("r","iw %s survey dump | grep 'in use' -A6", interface_name);
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR,"v_secure_popen %s error\n", cmd);
-		return RETURN_ERR;
-	}
-
-	read = getline(&line, &len, f);
-	while (read != -1) {
-		param = strtok(line, ":\t");
-		if (!param) {
-			read = getline(&line, &len, f);
-			continue;
-		}
-		value = strtok(NULL, " ");
-		if (!value) {
-			read = getline(&line, &len, f);
-			continue;
-		}
-		if(strstr(param, "frequency") != NULL) {
-			if (hal_strtoul(value, 10, &tmp_ul) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			outputChannelStats2->ch_Frequency = tmp_ul;
-		}
-		if(strstr(param, "noise") != NULL) {
-			if (hal_strtol(value, 10, &tmp_l) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			outputChannelStats2->ch_NoiseFloor = tmp_l;
-
-			if (hal_strtol(value, 10, &tmp_l) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			outputChannelStats2->ch_Non80211Noise = tmp_l;
-		}
-		if(strstr(param, "channel active time") != NULL) {
-			if (hal_strtoul(value, 10, &tmp_ul) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			ActiveTime = tmp_ul;
-		}
-		if(strstr(param, "channel busy time") != NULL) {
-			if (hal_strtoul(value, 10, &tmp_ul) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			BusyTime = tmp_ul;
-		}
-		if(strstr(param, "channel transmit time") != NULL) {
-			if (hal_strtoul(value, 10, &tmp_ul) < 0) {
-				wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			}
-			TransmitTime = tmp_ul;
-		}
-		read = getline(&line, &len, f);
-	}
-	v_secure_pclose(f);
-
-	// The file should store the last active, busy and transmit time
-	res = snprintf(channel_util_file, sizeof(channel_util_file), "%s%d.txt", CHANNEL_STATS_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(channel_util_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	f = fopen(channel_util_file, "r");
-	if (f != NULL) {
-		read = getline(&line, &len, f);
-		if (hal_strtoul(line, 10, &preActiveTime) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		read = getline(&line, &len, f);
-		if (hal_strtoul(line, 10, &preBusyTime) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-
-		}
-		read = getline(&line, &len, f);
-		if (hal_strtoul(line, 10, &preTransmitTime) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-
-		if (fclose(f) == EOF)
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-
-	}
-
-	/*if (ActiveTime == preActiveTime) {
-		wifi_debug(DEBUG_ERROR, "error:ActiveTime[%d] == preActiveTime[%ld]\n",
-			ActiveTime, preActiveTime);
-		return RETURN_ERR;
-	}*/
-
-	outputChannelStats2->ch_ObssUtil = (BusyTime - preBusyTime)*100/(ActiveTime - preActiveTime);
-	outputChannelStats2->ch_SelfBssUtil = (TransmitTime - preTransmitTime)*100/(ActiveTime - preActiveTime);
-
-	f = fopen(channel_util_file, "w");
-	if (f != NULL) {
-		if (fprintf(f, "%u\n%u\n%u\n", ActiveTime, BusyTime, TransmitTime) < 0) {
-			wifi_debug(DEBUG_ERROR, "fprintf fail\n");
-		}
-		if (fclose(f) != 0) {
-			wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		}
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-/**********************************************************************************
- *
- *  Wifi radio level function prototypes
- *
-**********************************************************************************/
-
-//Get the total number of radios in this wifi subsystem
-INT wifi_getRadioNumberOfEntries(ULONG *output) //Tr181
-{
-	if (NULL == output)
-		return RETURN_ERR;
-
-	*output = get_runtime_max_radio();
-
-	return RETURN_OK;
-}
-
-//Get the total number of SSID entries in this wifi subsystem
-INT wifi_getSSIDNumberOfEntries(ULONG *output) //Tr181
-{
-	if (NULL == output)
-		return RETURN_ERR;
-	*output = MAX_APS;
-
-	return RETURN_OK;
-}
-
-//Get the Radio enable config parameter
-INT wifi_getRadioEnable(INT radioIndex, BOOL *output_bool)	  //RDKB
-{
-	char interface_name[16] = {0};
-	int apIndex, bss_idx;
-
-	if (NULL == output_bool)
-		return RETURN_ERR;
-
-	*output_bool = FALSE;
-
-	/* loop all interface in radio, if any is enable, reture true, else return false */
-	for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++)
-	{
-		if (array_index_to_vap_index(radioIndex, bss_idx, &apIndex) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, bss_idx %d\n", radioIndex, bss_idx);
-			continue;
-		}
-		if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-			continue;
-
-		*output_bool = wifi_get_ap_status_ioctl(interface_name);
-		if (*output_bool == TRUE)
-			break;
-
-	}
-
-	return RETURN_OK;
-}
-
-enum mwctl_chan_width {
-	MWCTL_CHAN_WIDTH_20,
-	MWCTL_CHAN_WIDTH_40,
-	MWCTL_CHAN_WIDTH_80,
-	MWCTL_CHAN_WIDTH_160,
-	MWCTL_CHAN_WIDTH_320,
-};
-
-struct bw_option  {
-	unsigned int bandwith;
-	enum mwctl_chan_width mode;
-};
-
-struct bw_option bw_opt[] = {
-	{20, MWCTL_CHAN_WIDTH_20},
-	{40, MWCTL_CHAN_WIDTH_40},
-	{80, MWCTL_CHAN_WIDTH_80},
-	{160, MWCTL_CHAN_WIDTH_160},
-	{320, MWCTL_CHAN_WIDTH_320},
-};
-
-INT wifi_setChannel_netlink(INT radioIndex, ULONG* channel, UINT *bandwidth, UCHAR *ext_ch, UCHAR *ht_coex)
-{
-	int ret;
-	int i;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	bool b_match = FALSE;
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_CHANNEL;
-	param.if_type = NL80211_ATTR_WIPHY;
-	param.if_idx = radio_index_to_phy(radioIndex);
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (channel != NULL)
-		if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_NUM, *channel)) {
-			wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_NUM attribute error\n");
-			nlmsg_free(msg);
-			goto err;
-		}
-
-	if (bandwidth != NULL) {
-		for (i = 0; i < (sizeof(bw_opt)/sizeof(bw_opt[0])); i++) {
-			if (bw_opt[i].bandwith == *bandwidth) {
-				b_match = true;
-				if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_BW, bw_opt[i].mode)) {
-					wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_BW attribute error\n");
-					nlmsg_free(msg);
-					goto err;
-				}
-				break;
-			}
-		}
-
-		if (!b_match) {
-			wifi_debug(DEBUG_ERROR, "Cannot find bandwith error\n");
-			nlmsg_free(msg);
-			goto err;
-		}
-	}
-
-	if (ext_ch != NULL)
-		if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_HT_EXTCHAN, *ext_ch)) {
-			wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_HT_EXTCHAN attribute error\n");
-			nlmsg_free(msg);
-			goto err;
-		}
-
-	if (ht_coex != NULL)
-		if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_CHAN_SET_HT_COEX, *ht_coex)) {
-			wifi_debug(DEBUG_ERROR, "Nla put CHAN_SET_HT_COEX attribute error\n");
-			nlmsg_free(msg);
-			goto err;
-		}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-INT wifi_set80211h_netlink(INT radioIndex, unsigned char enable)
-{
-	int ret;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_RADIO;
-	param.if_type = NL80211_ATTR_WIPHY;
-	param.if_idx = radio_index_to_phy(radioIndex);
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_IEEE80211H_INFO, enable)) {
-		wifi_debug(DEBUG_ERROR, "Nla put IEEE80211H_INFO attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-INT wifi_setRadioEnable(INT radioIndex, BOOL enable)
-{
-	char interface_name[16] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
-	int apIndex, bss_idx;
-	int phyId = 0, res;
-	int main_vap_idx = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	phyId = radio_index_to_phy(radioIndex);
-
-	if(enable == FALSE) {
-
-		if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		}
-
-		if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-			return RETURN_ERR;
-
-
-		res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		memset(buf, 0, MAX_BUF_SIZE);
-
-		res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		if(strncmp(buf, "OK", 2))
-			wifi_debug(DEBUG_ERROR, "Could not detach %s from hostapd daemon", interface_name);
-	} else {
-		for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
-			if (array_index_to_vap_index(radioIndex, bss_idx, &apIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, bss_idx %d\n", radioIndex, bss_idx);
-				continue;
-			}
-			if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "!!!Fail to get name of apIndex[%d]\n", apIndex);
-				return RETURN_ERR;
-			}
-
-			memset(buf, 0, MAX_BUF_SIZE);
-			/* For disabled main interface, always bring it up firstly.
-			 * In order that the non-main interfaces could be added successfully.
-			 */
-			if (getVapEnableConfig(apIndex) == FALSE && !is_main_vap_index(apIndex))
-				continue;
-
-			res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-			res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up", interface_name);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-			memset(buf, 0, MAX_BUF_SIZE);
-
-			res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw ADD bss_config=phy%d:/nvram/hostapd%d.conf",phyId,apIndex);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-			/* For disabled main interface, bring it down if it is disabled by using 'ifconfig rax0 down'.*/
-			if (getVapEnableConfig(apIndex) == FALSE && is_main_vap_index(apIndex))
-				wifi_setApEnable(apIndex, FALSE);
-		}
-		radio_start_uptime[radioIndex] = wifi_getSystemUpSecs();
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get the Radio enable status
-INT wifi_getRadioStatus(INT radioIndex, BOOL *output_bool)	//RDKB
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-
-	return wifi_getRadioEnable(radioIndex, output_bool);
-}
-
-//Get the Radio Interface name from platform, eg "wlan0"
-INT wifi_getRadioIfName(INT radioIndex, CHAR *output_string) //Tr181
-{
-	int main_vap_idx;
-
-	if (NULL == output_string || radioIndex>=get_runtime_max_radio() || radioIndex<0)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-	}
-	return wifi_GetInterfaceName(main_vap_idx, output_string);
-}
-
-int mtk_get_vow_info_callback(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	int err = 0;
-	struct vow_info *vow_info = NULL;
-	struct mtk_nl80211_cb_data *cb_data = data;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-		return err;
-	}
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0){
-			wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_VOW_ATTR_MAX fails\n");
-			return err;
-		}
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]) {
-			vow_info = (struct vow_info *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO]);
-			memmove(cb_data->out_buf, vow_info, sizeof(struct vow_info));
-		}
-	}
-
-	return 0;
-}
-
-INT mtk_wifi_set_air_time_management(
-	INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
-	char* data, INT len, void *output)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_VOW;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put(msg, vendor_data_attr, len, data)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "send cmd success.\n");
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-//Get the ATM(Air Time Management) Capable.
-INT wifi_getATMCapable(BOOL *output_bool)
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-    *output_bool = TRUE;
-
-    return RETURN_OK;
-}
-
-INT wifi_setATMEnable(BOOL enable)
-{
-	int radio_idx = 0;
-	int bss_idx;
-	char dat_file[MAX_BUF_SIZE] = {0};
-	int res;
-	struct params params[3];
-	struct vow_group_en_param atc_en_param;
-	int main_vap_idx;
-
-	for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
-		if (array_index_to_vap_index(radio_idx, 0, &main_vap_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_idx);
-			return RETURN_ERR;
-		}
-
-		if (mtk_wifi_set_air_time_management
-			(main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO,
-			NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
-			return RETURN_ERR;
-		}
-
-		if (mtk_wifi_set_air_time_management
-			(main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_BW_EN_INFO,
-			NULL, (char *)&enable, 1, NULL)!= RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATF_EN_INFO cmd fails\n");
-			return RETURN_ERR;
-		}
-
-		/* atc support 15 group now , per band use 5 group */
-		for (bss_idx = 0; bss_idx < 5; bss_idx++) {
-			atc_en_param.group = bss_idx;
-			atc_en_param.en = enable;
-			if (mtk_wifi_set_air_time_management
-				(main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO,
-				NULL, (char *)&atc_en_param, sizeof(struct vow_group_en_param), NULL)!= RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_ATC_EN_INFO cmd fails\n");
-				return RETURN_ERR;
-			}
-		}
-
-		params[0].name = "VOW_Airtime_Fairness_En";
-		params[0].value = enable ? "1" : "0";
-		params[1].name = "VOW_BW_Ctrl";
-		params[1].value = enable ? "1" : "0";
-		params[2].name = "VOW_Airtime_Ctrl_En";
-		params[2].value = enable ? "1;1;1;1;1;0;0;0;0;0;0;0;0;0;0" : "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";
-
-		res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_idx);
-		if (os_snprintf_error(sizeof(dat_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_datfileWrite(dat_file, params, 3);
-	}
-
-    return RETURN_OK;
-}
-
-INT wifi_getATMEnable(BOOL *output_enable)
-{
-	int radio_idx = 0;
-	struct vow_info vow_info;
-	struct vow_info get_vow_info;
-	struct mtk_nl80211_cb_data cb_data;
-	int main_vap_idx;
-
-	if (output_enable == NULL)
-		return RETURN_ERR;
-
-
-	*output_enable = FALSE;
-
-	memset(&vow_info, 0, sizeof(struct vow_info));
-
-	cb_data.out_buf = (char *)&vow_info;
-	cb_data.out_len = sizeof(struct vow_info);
-
-	for (radio_idx = 0; radio_idx < get_runtime_max_radio(); radio_idx++) {
-		if (array_index_to_vap_index(radio_idx, 0, &main_vap_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_idx);
-			return RETURN_ERR;
-		}
-		if (mtk_wifi_set_air_time_management
-			(main_vap_idx, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
-			mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
-			return RETURN_ERR;
-		}
-
-		if (vow_info.atf_en == TRUE || vow_info.bw_en == TRUE) {
-			*output_enable = TRUE;
-			break;
-		}
-	}
-
-    return RETURN_OK;
-}
-
-INT wifi_setApATMAirTimePercent(INT apIndex, UINT ap_AirTimePercent)
-{
-	struct vow_ratio_param radio_param;
-	int group = 0;
-	int radio_index = 0;
-
-	if (ap_AirTimePercent < 0 || ap_AirTimePercent > 100) {
-		wifi_debug(DEBUG_ERROR, "invalid air time percent!\n");
-		return RETURN_ERR;
-	}
-
-	if (vap_index_to_radio_array_index(apIndex, &radio_index, &group) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", apIndex);
-		return RETURN_ERR;
-	}
-
-	if (group > 5) {
-		wifi_debug(DEBUG_ERROR, "invalid group!\n");
-		return RETURN_ERR;
-	}
-
-	radio_param.group = group;
-	radio_param.ratio = ap_AirTimePercent;
-	if (mtk_wifi_set_air_time_management
-		(apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO,
-		NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MIN_RATIO_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-
-	if (mtk_wifi_set_air_time_management
-		(apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO,
-		NULL, (char *)&radio_param, sizeof(struct vow_ratio_param), NULL)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_MAX_RATIO_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_getApATMAirTimePercent(INT apIndex, UINT *output_ap_AirTimePercent)
-{
-	int group = 0;
-	struct vow_info get_vow_info, vow_info;
-	struct mtk_nl80211_cb_data cb_data;
-	int radio_index = 0;
-
-	if (output_ap_AirTimePercent == NULL)
-		return RETURN_ERR;
-
-	if (vap_index_to_radio_array_index(apIndex, &radio_index, &group) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid vap index %d\n", apIndex);
-		return RETURN_ERR;
-	}
-	if (group > 5) {
-		wifi_debug(DEBUG_ERROR, "invalid group!\n");
-		return RETURN_ERR;
-	}
-
-	memset(&vow_info, 0, sizeof(struct vow_info));
-	memset(&get_vow_info, 0, sizeof(struct vow_info));
-
-	cb_data.out_buf = (char *)&vow_info;
-	cb_data.out_len = sizeof(struct vow_info);
-
-	get_vow_info.group = group;
-
-	if (mtk_wifi_set_air_time_management
-		(apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
-		mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-
-	*output_ap_AirTimePercent = vow_info.ratio;
-
-	return RETURN_ERR;
-}
-
-INT wifi_getApATMSta(INT apIndex, UCHAR *output_sta_MAC_ATM_array, UINT  buf_size)
-{
-	ULONG dev_num = 0;
-	struct vow_info vow_info;
-	struct vow_info get_vow_info;
-	struct mtk_nl80211_cb_data cb_data;
-	unsigned int percent;
-	char assocArray[MAX_BUF_SIZE] = {0};
-	char *mac = NULL;
-	unsigned char output_len = 0;
-	int res;
-	char buf[MAX_BUF_SIZE] = {0};
-
-	memset(&vow_info, 0, sizeof(struct vow_info));
-	memset(&get_vow_info, 0, sizeof(struct vow_info));
-
-	cb_data.out_buf = (char *)&vow_info;
-	cb_data.out_len = sizeof(struct vow_info);
-
-	if (mtk_wifi_set_air_time_management
-		(apIndex, MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO,
-		mtk_get_vow_info_callback, (char *)&get_vow_info, sizeof(struct vow_info), &cb_data)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_VOW_GET_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-
-	if (vow_info.atf_en == FALSE) {
-		wifi_debug(DEBUG_ERROR, "ATF disable!\n");
-		return RETURN_ERR;
-	}
-
-	if (wifi_getApNumDevicesAssociated(apIndex, &dev_num) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "get sta num fail!\n");
-		return RETURN_ERR;;
-	}
-
-	percent = 100 / dev_num;
-
-	if (wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray)) != RETURN_OK){
-		wifi_debug(DEBUG_ERROR, "get sta mac fail!\n");
-		return RETURN_ERR;;
-	}
-
-	memset(output_sta_MAC_ATM_array, 0, MAX_BUF_SIZE);
-
-	mac = strtok(assocArray, "\n");
-	while (mac != NULL) {
-		if (strlen(mac) >= 17) {
-			res = snprintf(buf, sizeof(buf), "%s %d|", mac, percent);
-
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-
-			if (output_len + strlen(buf) > buf_size)
-				break;
-
-			strncat((char *)output_sta_MAC_ATM_array, buf, strlen(buf));
-
-			output_len += strlen(buf);
-		}
-
-		mac = strtok(NULL, "\n");
-	}
-
-	/* Remove the last | */
-	if (strlen((char *)output_sta_MAC_ATM_array) != 0)
-		output_sta_MAC_ATM_array[strlen((char *)output_sta_MAC_ATM_array)-1] = '\0';
-
-	return RETURN_OK;
-}
-
-INT wifi_setApATMSta(INT apIndex, UCHAR *sta_MAC_ATM_array, UINT ap_AirTimePercent)
-{
-	return RETURN_ERR;
-}
-
-//Get the maximum PHY bit rate supported by this interface. eg: "216.7 Mb/s", "1.3 Gb/s"
-//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.
-INT wifi_getRadioMaxBitRate(INT radioIndex, CHAR *output_string) //RDKB
-{
-	// The formula to coculate bit rate is "Subcarriers * Modulation * Coding rate * Spatial stream / (Data interval + Guard interval)"
-	// For max bit rate, we should always choose the best MCS
-	char mode[64] = {0};
-	char channel_bandwidth_str[64] = {0};
-	UINT mode_map = 0;
-	UINT num_subcarrier = 0;
-	UINT code_bits = 0;
-	float code_rate = 0;	// use max code rate
-	int NSS = 0;
-	UINT Symbol_duration = 0;
-	UINT GI_duration = 0;
-	wifi_guard_interval_t gi = wifi_guard_interval_auto;
-	BOOL enable = FALSE;
-	float bit_rate = 0;
-	int ant_bitmap = 0, res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	wifi_getRadioEnable(radioIndex, &enable);
-	if (enable == FALSE) {
-		res = snprintf(output_string, 64, "0 Mb/s");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	}
-
-	if (wifi_getRadioMode(radioIndex, mode, &mode_map) == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
-		return RETURN_ERR;
-	}
-
-	if (wifi_getGuardInterval(radioIndex, &gi) == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
-		return RETURN_ERR;
-	}
-
-	if (gi == wifi_guard_interval_3200)
-		GI_duration = 32;
-	else if (gi == wifi_guard_interval_1600)
-		GI_duration = 16;
-	else if (gi == wifi_guard_interval_800)
-		GI_duration = 8;
-	else	// auto, 400
-		GI_duration = 4;
-
-	if (wifi_getRadioOperatingChannelBandwidth(radioIndex, channel_bandwidth_str) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error\n");
-		return RETURN_ERR;
-	}
-
-	if (strstr(channel_bandwidth_str, "80+80") != NULL)
-		memcpy(channel_bandwidth_str, "160", strlen("160"));
-
-	if (mode_map & WIFI_MODE_AX) {
-		if (strstr(channel_bandwidth_str, "160") != NULL)
-			num_subcarrier = 1960;
-		else if (strstr(channel_bandwidth_str, "80") != NULL)
-			num_subcarrier = 980;
-		else if (strstr(channel_bandwidth_str, "40") != NULL)
-			num_subcarrier = 468;
-		else if (strstr(channel_bandwidth_str, "20") != NULL)
-			num_subcarrier = 234;
-		code_bits = 10;
-		code_rate = (float)5/6;
-		Symbol_duration = 128;
-		GI_duration = 8;/*HE no GI 400ns*/
-	} else if (mode_map & WIFI_MODE_AC) {
-		if (strstr(channel_bandwidth_str, "160") != NULL)
-			num_subcarrier = 468;
-		else if (strstr(channel_bandwidth_str, "80") != NULL)
-			num_subcarrier = 234;
-		else if (strstr(channel_bandwidth_str, "40") != NULL)
-			num_subcarrier = 108;
-		else if (strstr(channel_bandwidth_str, "20") != NULL)
-			num_subcarrier = 52;
-		code_bits = 8;
-		code_rate = (float)5/6;
-		Symbol_duration = 32;
-	} else if (mode_map & WIFI_MODE_N) {
-		if (strstr(channel_bandwidth_str, "160") != NULL)
-			num_subcarrier = 468;
-		else if (strstr(channel_bandwidth_str, "80") != NULL)
-			num_subcarrier = 234;
-		else if (strstr(channel_bandwidth_str, "40") != NULL)
-			num_subcarrier = 108;
-		else if (strstr(channel_bandwidth_str, "20") != NULL)
-			num_subcarrier = 52;
-		code_bits = 6;
-		code_rate = (float)3/4;
-		Symbol_duration = 32;
-	} else if ((mode_map & WIFI_MODE_G || mode_map & WIFI_MODE_B) || mode_map & WIFI_MODE_A) {
-		// mode b must run with mode g, so we output mode g bitrate in 2.4 G.
-		res = snprintf(output_string, 64, "65 Mb/s");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	} else {
-		res = snprintf(output_string, 64, "0 Mb/s");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	}
-
-	// Spatial streams
-	if (wifi_getRadioTxChainMask(radioIndex, &ant_bitmap) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioTxChainMask return error\n");
-		return RETURN_ERR;
-	}
-	for (; ant_bitmap > 0; ant_bitmap >>= 1)
-		NSS += ant_bitmap & 1;
-
-	// multiple 10 is to align duration unit (0.1 us)
-	bit_rate = (num_subcarrier * code_bits * code_rate * NSS) / (Symbol_duration + GI_duration) * 10;
-	res = snprintf(output_string, 64, "%.1f Mb/s", bit_rate);
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("%s:num_subcarrier=%d, code_bits=%d, code_rate=%.3f, nss=%d, symbol time=%u, %.1f Mb/s\n",
-		__func__, num_subcarrier, code_bits, code_rate, NSS, Symbol_duration + GI_duration, bit_rate);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Get Supported frequency bands at which the radio can operate. eg: "2.4GHz,5GHz"
-//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.
-INT wifi_getRadioSupportedFrequencyBands(INT radioIndex, CHAR *output_string)	//RDKB
-{
-	wifi_band band = band_invalid;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-
-	memset(output_string, 0, 10);
-	if (band == band_2_4)
-		memcpy(output_string, "2.4GHz", strlen("2.4GHz"));
-	else if (band == band_5)
-		memcpy(output_string, "5GHz", strlen("5GHz"));
-	else if (band == band_6)
-		memcpy(output_string, "6GHz", strlen("6GHz"));
-	else
-		return RETURN_ERR;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Get the frequency band at which the radio is operating, eg: "2.4GHz"
-//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.
-INT wifi_getRadioOperatingFrequencyBand(INT radioIndex, CHAR *output_string) //Tr181
-{
-	wifi_band band = band_invalid;
-	int res = -1;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-	band = radio_index_to_band(radioIndex);
-
-	if (band == band_2_4)
-		res = snprintf(output_string, 64, "2.4GHz");
-	else if (band == band_5)
-		res = snprintf(output_string, 64, "5GHz");
-	else if (band == band_6)
-		res = snprintf(output_string, 64, "6GHz");
-
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Get the Supported Radio Mode. eg: "b,g,n"; "n,ac"
-//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.
-INT wifi_getRadioSupportedStandards(INT radioIndex, CHAR *output_string) //Tr181
-{
-	char buf[128]={0};
-	char temp_output[128] = {0};
-	wifi_band band;
-	int phyId = 0, res;
-	char dat_file[MAX_BUF_SIZE] = {0};
-	char str_radio_mode[16] = {0};
-	unsigned long radio_mode;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_2_4) {
-		strncat(temp_output, "b,g,", sizeof(temp_output) - strlen(temp_output) - 1);
-	} else if (band == band_5) {
-		strncat(temp_output, "a,", sizeof(temp_output) - strlen(temp_output) - 1);
-	}
-	phyId = radio_index_to_phy(radioIndex);
-	// ht capabilities
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep '[^PHY|MAC|VHT].Capabilities' | head -n 1 | cut -d ':' -f2 | sed 's/^.//' | tr -d '\\n'", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) >= 4 && strncmp(buf, "0x00", 4) != 0) {
-		if (strlen(temp_output) >= sizeof(temp_output) - 2)
-			return RETURN_ERR;
-		strncat(temp_output, "n,", sizeof(temp_output) - strlen(temp_output) - 1);
-	}
-
-	// vht capabilities
-	if (band == band_5) {
-		res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'VHT Capabilities' | cut -d '(' -f2 | cut -c1-10 | tr -d '\\n'", phyId);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		if (strlen(buf) >= 10 && strncmp(buf, "0x00000000", 10) != 0) {
-			if (strlen(temp_output) >= sizeof(temp_output) - 3)
-				return RETURN_ERR;
-			strncat(temp_output, "ac,", sizeof(temp_output) - strlen(temp_output) - 1);
-		}
-	}
-
-	// he capabilities
-	res = _syscmd_secure(buf, sizeof(buf),  "iw phy%d info | grep 'HE MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
-		if (strlen(temp_output) >= sizeof(temp_output) - 3)
-			return RETURN_ERR;
-		strncat(temp_output, "ax,", sizeof(temp_output) - strlen(temp_output) - 1);
-	}
-
-	// eht capabilities
-	/*res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'EHT MAC Capabilities' | head -n 2 | tail -n 1 | cut -d '(' -f2 | cut -c1-6 | tr -d '\\n'", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) >= 6 && strncmp (buf, "0x0000", 6) != 0) {
-		if (strlen(temp_output) >= sizeof(temp_output) - 3)
-			return RETURN_ERR;
-		strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
-	}*/
-	/* iw phy info cannot get EHT MAC Capabilities due to the backport version*/
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileRead(dat_file, "WirelessMode", str_radio_mode, sizeof(str_radio_mode));
-	if (hal_strtoul(str_radio_mode, 10, &radio_mode) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	if (radio_mode >= PHY_11BE_24G) {
-		if (strlen(temp_output) >= sizeof(temp_output) - 3)
-			return RETURN_ERR;
-		strncat(temp_output, "be,", sizeof(temp_output) - strlen(temp_output) - 1);
-	}
-
-	// Remove the last comma
-	if (strlen(temp_output) != 0)
-		temp_output[strlen(temp_output)-1] = '\0';
-	strncpy(output_string, temp_output, strlen(temp_output));
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get the radio operating mode, and pure mode flag. eg: "ac"
-//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.
-INT wifi_getRadioStandard(INT radioIndex, CHAR *output_string, BOOL *gOnly, BOOL *nOnly, BOOL *acOnly)	//RDKB
-{
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	if (radioIndex == 0) {
-		res = snprintf(output_string, 64, "n");			   //"ht" needs to be translated to "n" or others
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		*gOnly = FALSE;
-		*nOnly = TRUE;
-		*acOnly = FALSE;
-	} else {
-		res = snprintf(output_string, 64, "ac");			  //"vht" needs to be translated to "ac"
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		*gOnly = FALSE;
-		*nOnly = FALSE;
-		*acOnly = FALSE;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-#define RADIO_MODE_LEN 32
-
-int get_radio_mode_handler(struct nl_msg *msg, void *cb)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
-	struct genlmsghdr *gnlh;
-	unsigned int *phymode;
-	int err = 0;
-	struct mtk_nl80211_cb_data *cb_data = cb;
-
-	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
-		return NL_SKIP;
-	}
-	gnlh = nlmsg_data(nlmsg_hdr(msg));
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse radio nl80211 msg fails,error.\n");
-		return NL_SKIP;
-	}
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]) {
-			phymode = (unsigned int *)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE]);
-
-			memset(cb_data->out_buf, 0, cb_data->out_len);
-			memmove(cb_data->out_buf, phymode, sizeof(unsigned int));
-		}
-	} else
-		wifi_debug(DEBUG_ERROR, "No Stats from driver.\n");
-
-	return NL_OK;
-}
-
-void phymode_to_puremode(INT radioIndex, CHAR *output_string, UINT *pureMode, UINT phymode)
-{
-	wifi_band band;
-	unsigned char radio_mode_tem_len;
-	int res;
-
-	band = radio_index_to_band(radioIndex);
-	// puremode is a bit map
-	*pureMode = 0;
-	memset(output_string, 0, RADIO_MODE_LEN);
-
-	radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-
-	switch (band) {
-	case band_2_4:
-		if (phymode & WMODE_B) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "b,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_B;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "g,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_G;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_GN) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_N;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_AX_24G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_AX;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_BE_24G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_BE;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		break;
-	case band_5:
-		if (phymode & WMODE_A) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "a,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_A;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_AN) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "n,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_N;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_AC) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ac,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_AC;
-		}
-		if (phymode & WMODE_AX_5G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_AX;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_BE_5G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_BE;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		break;
-	case band_6:
-		if (phymode & WMODE_AX_6G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "ax,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_AX;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		if (phymode & WMODE_BE_6G) {
-			res = snprintf(output_string + strlen(output_string), radio_mode_tem_len, "%s", "be,");
-			if (os_snprintf_error(radio_mode_tem_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return;
-			}
-			*pureMode |= WIFI_MODE_BE;
-			radio_mode_tem_len = RADIO_MODE_LEN - strlen(output_string);
-		}
-		break;
-	default:
-		wifi_debug(DEBUG_ERROR, "%s band_idx invalid\n", __func__);
-		break;
-	}
-
-	/* Remove the last comma */
-	if (strlen(output_string) != 0)
-		output_string[strlen(output_string)-1] = '\0';
-
-}
-
-INT wifi_getRadioMode(INT radioIndex, CHAR *output_string, UINT *pureMode)
-{
-	unsigned int phymode;
-	char interface_name[IF_NAME_SIZE] = {0};
-	int ret = -1;
-	unsigned int if_idx = 0;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct mtk_nl80211_cb_data cb_data;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string || NULL == pureMode)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_WMODE, 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put GET_RUNTIME_INFO_GET_WMODE attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	cb_data.out_buf = (char *)&phymode;
-	cb_data.out_len = sizeof(unsigned int);
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_radio_mode_handler, &cb_data);
-
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-
-	phymode_to_puremode(radioIndex, output_string, pureMode, phymode);
-	wifi_debug(DEBUG_INFO,"send cmd success\n");
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-// Set the radio operating mode, and pure mode flag.
-INT wifi_setRadioChannelMode(INT radioIndex, CHAR *channelMode, BOOL gOnlyFlag, BOOL nOnlyFlag, BOOL acOnlyFlag)	//RDKB
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s_%d_%d:%d\n",__func__,channelMode,nOnlyFlag,gOnlyFlag,__LINE__);
-	if (strcmp (channelMode,"11A") == 0)
-	{
-		writeBandWidth(radioIndex,"20MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11a (5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11NAHT20") == 0)
-	{
-		writeBandWidth(radioIndex,"20MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11n-20MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11NAHT40PLUS") == 0)
-	{
-		writeBandWidth(radioIndex,"40MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11n-40MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11NAHT40MINUS") == 0)
-	{
-		writeBandWidth(radioIndex,"40MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11n-40MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11ACVHT20") == 0)
-	{
-		writeBandWidth(radioIndex,"20MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11ac-20MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11ACVHT40PLUS") == 0)
-	{
-		writeBandWidth(radioIndex,"40MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11ACVHT40MINUS") == 0)
-	{
-		writeBandWidth(radioIndex,"40MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11ac-40MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11ACVHT80") == 0)
-	{
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"80MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11ac-80MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11ACVHT160") == 0)
-	{
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"160MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11ac-160MHz(5GHz)\n");
-	}
-	else if (strcmp (channelMode,"11B") == 0)
-	{
-		writeBandWidth(radioIndex,"20MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11b(2.4GHz)\n");
-	}
-	else if (strcmp (channelMode,"11G") == 0)
-	{
-		writeBandWidth(radioIndex,"20MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11g(2.4GHz)\n");
-	}
-	else if (strcmp (channelMode,"11NGHT20") == 0)
-	{
-		writeBandWidth(radioIndex,"20MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"20MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11n-20MHz(2.4GHz)\n");
-	}
-	else if (strcmp (channelMode,"11NGHT40PLUS") == 0)
-	{
-		writeBandWidth(radioIndex,"40MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
-	}
-	else if (strcmp (channelMode,"11NGHT40MINUS") == 0)
-	{
-		writeBandWidth(radioIndex,"40MHz");
-		wifi_setRadioOperatingChannelBandwidth(radioIndex,"40MHz");
-		wifi_debug(DEBUG_INFO,"\nChannel Mode is 802.11n-40MHz(2.4GHz)\n");
-	}
-	else
-	{
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-unsigned int puremode_to_wireless_mode(INT radioIndex, UINT pureMode)
-{
-	unsigned char wireless_mode = PHY_MODE_MAX;
-
-	switch (radioIndex) {
-	case band_2_4:
-		if (pureMode == (WIFI_MODE_G | WIFI_MODE_N))
-			wireless_mode = PHY_11GN_MIXED;
-		if (pureMode == (WIFI_MODE_B | WIFI_MODE_G | WIFI_MODE_N))
-			wireless_mode = PHY_11BGN_MIXED;
-		if (pureMode & WIFI_MODE_AX)
-			wireless_mode = PHY_11AX_24G;
-		if (pureMode & WIFI_MODE_BE)
-			wireless_mode = PHY_11BE_24G;
-		break;
-	case band_5:
-		if (pureMode == WIFI_MODE_N)
-			wireless_mode = PHY_11N_5G;
-		if ((pureMode == WIFI_MODE_AC) || (pureMode == (WIFI_MODE_N | WIFI_MODE_AC)))
-			wireless_mode = PHY_11VHT_N_MIXED;
-		if (pureMode == (WIFI_MODE_A | WIFI_MODE_N | WIFI_MODE_AC))
-			wireless_mode = PHY_11VHT_N_A_MIXED;
-		if (pureMode & WIFI_MODE_AX)
-			wireless_mode = PHY_11AX_5G;
-		if (pureMode & WIFI_MODE_BE)
-			wireless_mode = PHY_11BE_5G;
-		break;
-	case band_6:
-		if (pureMode & WIFI_MODE_AX)
-			wireless_mode = PHY_11AX_6G;
-		if (pureMode & WIFI_MODE_BE)
-			wireless_mode = PHY_11BE_6G;
-		break;
-	default:
-		if (fprintf(stderr, "%s band_idx invalid\n", __func__) < 0)
-			wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-		break;
-	}
-
-	return wireless_mode;
-}
-
-int wifi_setRadioMode_netlink(int radioIndex, unsigned char *wireless_mode, int bss_num)
-{
-	int ret;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int bss_idx, ap_idx;
-	char interface_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-
-	for (bss_idx = 0; bss_idx < bss_num; bss_idx++) {
-		if (array_index_to_vap_index(radioIndex, bss_idx, &ap_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radioIndex, bss_idx);
-			continue;
-		}
-
-		if (getVapEnableConfig(ap_idx) == FALSE)
-			continue;
-
-		if (wifi_GetInterfaceName(ap_idx, interface_name) != RETURN_OK)
-			return RETURN_ERR;
-
-		if_idx = if_nametoindex(interface_name);
-		if (!if_idx) {
-			wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", interface_name);
-			return RETURN_ERR;
-		}
-		/*init mtk nl80211 vendor cmd*/
-		param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
-		param.if_type = NL80211_ATTR_IFINDEX;
-		param.if_idx = if_idx;
-
-		ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-		if (ret) {
-			wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-			return RETURN_ERR;
-		}
-
-		/*add mtk vendor cmd data*/
-		if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_WIRELESS_MODE, *wireless_mode)) {
-			wifi_debug(DEBUG_ERROR, "Nla put AP_WIRELESS_MODE attribute error\n");
-			nlmsg_free(msg);
-			goto err;
-		}
-		/*send mtk nl80211 vendor msg*/
-		ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-		if (ret) {
-			wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-			goto err;
-		}
-		/*deinit mtk nl80211 vendor msg*/
-		mtk_nl80211_deint(&unl_ins);
-		wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	 }
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-// Set the radio operating mode, and pure mode flag.
-INT wifi_setRadioMode(INT radioIndex, CHAR *channelMode, UINT pureMode)
-{
-	unsigned char wireless_mode = PHY_MODE_MAX;
-	char buf[MAX_BUF_SIZE] = {0};
-	char dat_file[MAX_BUF_SIZE] = {0};
-	struct params params={0};
-	int res;
-	int ret;
-	int bss_num;
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int pos = 0, i;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s_%s:%d_%d\n", __func__, channelMode, pureMode, __LINE__);
-
-	wireless_mode = puremode_to_wireless_mode(radioIndex, pureMode);
-
-	if (wireless_mode == PHY_MODE_MAX) {
-		wifi_debug(DEBUG_ERROR, "invalid pureMode = %x\n", pureMode);
-		return RETURN_ERR;
-	}
-
-	ret = wifi_BandProfileRead(0, radioIndex, "BssidNum", ret_buf, sizeof(ret_buf), "1");
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
-		return RETURN_ERR;
-	}
-
-	bss_num = atoi(ret_buf);
-	if (bss_num <= 0)  {
-		wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", ret_buf);
-		return RETURN_ERR;
-	}
-
-	if (bss_num > LOGAN_MAX_NUM_VAP_PER_RADIO) {
-		wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
-		bss_num = LOGAN_MAX_NUM_VAP_PER_RADIO;
-	}
-
-	if (wifi_setRadioMode_netlink(radioIndex, &wireless_mode, bss_num) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_setRadioMode_netlink fail\n");
-		return RETURN_ERR;
-	}
-
-	/*update dat profile*/
-	params.name = "WirelessMode";
-	for (i = 0; i < bss_num; i++) {
-		pos += snprintf(buf + pos, sizeof(buf) - pos, "%d;", wireless_mode);
-		if (os_snprintf_error(sizeof(buf), pos)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			break;
-		}
-	}
-	if (strlen(buf) != 0)
-		buf[pos - 1] = '\0';
-
-	params.value = buf;
-
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileWrite(dat_file, &params, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_setRadioHwMode(INT radioIndex, CHAR *hw_mode) {
-
-	char config_file[64] = {0};
-	char buf[64] = {0};
-	struct params params = {0};
-	wifi_band band = band_invalid;
-	int res, main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	band = radio_index_to_band(radioIndex);
-
-	if (strncmp(hw_mode, "a", 1) == 0 && (band != band_5 && band != band_6))
-		return RETURN_ERR;
-	else if ((strncmp(hw_mode, "b", 1) == 0 || strncmp(hw_mode, "g", 1) == 0) && band != band_2_4)
-		return RETURN_ERR;
-	else if ((strncmp(hw_mode, "a", 1) && strncmp(hw_mode, "b", 1) && strncmp(hw_mode, "g", 1)) || band == band_invalid)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.name = "hw_mode";
-	params.value = hw_mode;
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(radioIndex, &params, 1);
-
-	if (band == band_2_4) {
-		if (strncmp(hw_mode, "b", 1) == 0) {
-			wifi_setRadioMode(radioIndex, "20MHz", WIFI_MODE_B);
-			res = snprintf(buf, sizeof(buf), "%s", "1,2,5.5,11");
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-			wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
-			res = snprintf(buf, sizeof(buf), "%s", "1,2");
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-			wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
-		} else {
-			// We don't set mode here, because we don't know whitch mode should be set (g, n or ax?).
-
-			res = snprintf(buf, sizeof(buf), "%s", "6,9,12,18,24,36,48,54");
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-			wifi_setRadioOperationalDataTransmitRates(radioIndex, buf);
-			res = snprintf(buf, sizeof(buf), "%s", "6,12,24");
-			if (os_snprintf_error(sizeof(buf), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-			wifi_setRadioBasicDataTransmitRates(radioIndex, buf);
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setNoscan(INT radioIndex, CHAR *noscan)
-{
-	char config_file[64] = {0};
-	struct params params = {0};
-	wifi_band band = band_invalid;
-	int res, main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	band = radio_index_to_band(radioIndex);
-	if (band != band_2_4)
-		return RETURN_OK;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.name = "noscan";
-	params.value = noscan;
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(radioIndex, &params, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getRadioCapChannels(INT radioIndex, CHAR *output_string)
-{
-	wifi_band band = band_invalid;
-	int ret;
-	char ch_string_2G[] = "1,2,3,4,5,6,7,8,9,10,11,12,13,14";
-	char ch_string_5G[] = "36,40,44,48,52,56,60,64,100,104,108,112,116,120,124,128,132,136,140,144,149,153,157,161,165,169,173,177";
-	char ch_string_6G[] = "1,5,9,13,17,21,25,29,33,37,41,45,49,53,57,61,65,69,73,77,81,85,89,93,97,101,105,109,113,117,121,125,129,133,137,141,145,149,153,157,161,165,169,173,177,181,185,189,193,197,201,205,209,213,217,221,225,229,233";
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-
-	if (band == band_2_4) {
-		ret = snprintf(output_string, 512, "%s", ch_string_2G);
-		if (os_snprintf_error(512, ret)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if (band == band_5) {
-		ret = snprintf(output_string, 512, "%s", ch_string_5G);
-		if (os_snprintf_error(512, ret)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if (band == band_6) {
-		ret = snprintf(output_string, 512, "%s", ch_string_6G);
-		if (os_snprintf_error(512, ret)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get the list of supported channel. eg: "1-11"
-//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.
-INT wifi_getRadioPossibleChannels(INT radioIndex, CHAR *output_string)	//RDKB
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	char buf[256] = {0};
-	BOOL dfs_enable = false;
-	int phyId = 0, res;
-
-	// Parse possible channel number and separate them with commas.
-	wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
-	phyId = radio_index_to_phy(radioIndex);
-	// Channel 68 and 96 only allow bandwidth 20MHz, so we remove them with their frequency.
-	if (dfs_enable)
-		res = _syscmd_secure(buf, sizeof(buf), "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);
-	else
-		res = _syscmd_secure(buf, sizeof(buf), "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);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	strncpy(output_string, buf, strlen(buf));
-	output_string[strlen(buf)]='\0';
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-//Getting current radio extension channel
-INT wifi_halgetRadioExtChannel(CHAR *file,CHAR *Value)
-{
-	CHAR buf[150] = {0};
-	int len;
-
-	wifi_datfileRead(file, "HT_EXTCHA", buf, sizeof(buf));
-
-	if (strncmp(buf, "0", 1) == 0) {
-		len = strlen("BelowControlChannel");
-		memcpy(Value, "BelowControlChannel", len);
-		Value[len] = '\0';
-	}
-	else if(strncmp(buf, "1", 1) == 0) {
-		len = strlen("AboveControlChannel");
-		memcpy(Value, "AboveControlChannel", len);
-		Value[len] = '\0';
-	}
-
-	return RETURN_OK;
-}
-
-enum bw_idx {
-	BAND_WIDTH_20,
-	BAND_WIDTH_40,
-	BAND_WIDTH_80,
-	BAND_WIDTH_160,
-	BAND_WIDTH_8080 = 6,
-	BAND_WIDTH_320
-};
-
-struct hal_ch_layout {
-	UCHAR ch_low_bnd;
-	UCHAR ch_up_bnd;
-	UCHAR cent_freq_idx;
-};
-
-static struct hal_ch_layout ch_5G_40M[] = {
-	{36, 40, 38},
-	{44, 48, 46},
-	{52, 56, 54},
-	{60, 64, 62},
-	{100, 104, 102},
-	{108, 112, 110},
-	{116, 120, 118},
-	{124, 128, 126},
-	{132, 136, 134},
-	{140, 144, 142},
-	{149, 153, 151},
-	{157, 161, 159},
-	{0, 0, 0},
-};
-
-static struct hal_ch_layout ch_5G_80M[] = {
-	{36, 48, 42},
-	{52, 64, 58},
-	{100, 112, 106},
-	{116, 128, 122},
-	{132, 144, 138},
-	{149, 161, 155},
-	{165, 177, 171},
-	{0, 0, 0},
-};
-
-static struct hal_ch_layout ch_5G_160M[] = {
-	{36, 64, 50},
-	{100, 128, 114},
-	{149, 177, 163},
-	{0, 0, 0},
-};
-
-static struct hal_ch_layout ch_6G_40M[] = {
-	{1, 5, 3},
-	{9, 13, 11},
-	{17, 21, 19},
-	{25, 29, 27},
-	{33, 37, 35},
-	{41, 45, 43},
-	{49, 53, 51},
-	{57, 61, 59},
-	{65, 69, 67},
-	{73, 77, 75},
-	{81, 85, 83},
-	{89, 93, 91},
-	{97, 101, 99},
-	{105, 109, 107},
-	{113, 117, 115},
-	{121, 125, 123},
-	{129, 133, 131},
-	{137, 141, 139},
-	{145, 149, 147},
-	{153, 157, 155},
-	{161, 165, 163},
-	{169, 173, 171},
-	{177, 181, 179},
-	{185, 189, 187},
-	{193, 197, 195},
-	{201, 205, 203},
-	{209, 213, 211},
-	{217, 221, 219},
-	{225, 229, 227},
-	{0, 0, 0},
-};
-
-static struct hal_ch_layout ch_6G_80M[] = {
-	{1, 13, 7},
-	{17, 29, 23},
-	{33, 45, 39},
-	{49, 61, 55},
-	{65, 77, 71},
-	{81, 93, 87},
-	{97, 109, 103},
-	{113, 125, 119},
-	{129, 141, 135},
-	{145, 157, 151},
-	{161, 173, 167},
-	{177, 189, 183},
-	{193, 205, 199},
-	{209, 221, 215},
-	{0, 0, 0},
-};
-
-static struct hal_ch_layout ch_6G_160M[] = {
-	{1, 29, 15},
-	{33, 61, 47},
-	{65, 93, 79},
-	{97, 125, 111},
-	{129, 157, 143},
-	{161, 189, 175},
-	{193, 221, 207},
-	{0, 0, 0},
-};
-
-static struct  hal_ch_layout ch_6G_320M[] = {
-	{1, 61, 31},
-	{33, 93, 63},
-	{65, 125, 95},
-	{97, 157, 127},
-	{129, 189, 159},
-	{161, 221, 191},
-	{0, 0, 0},
-};
-
-struct hal_ch_layout *hal_get_ch_array(UCHAR bw, UCHAR ch_band, UCHAR *layout_size)
-{
-	switch (ch_band) {
-	case band_5:
-		if (bw == BAND_WIDTH_40) {
-			*layout_size = ARRAY_SIZE(ch_5G_40M);
-			return ch_5G_40M;
-		} else if (bw == BAND_WIDTH_80) {
-			*layout_size = ARRAY_SIZE(ch_5G_80M);
-			return ch_5G_80M;
-		} else if (bw == BAND_WIDTH_160) {
-			*layout_size = ARRAY_SIZE(ch_5G_160M);
-			return ch_5G_160M;
-		} else
-			return NULL;
-
-	case band_6:
-		if (bw == BAND_WIDTH_40) {
-			*layout_size = ARRAY_SIZE(ch_6G_40M);
-			return ch_6G_40M;
-		} else if (bw == BAND_WIDTH_80) {
-			*layout_size = ARRAY_SIZE(ch_6G_80M);
-			return ch_6G_80M;
-		} else if (bw == BAND_WIDTH_160) {
-			*layout_size = ARRAY_SIZE(ch_6G_160M);
-			return ch_6G_160M;
-		} else if (bw == BAND_WIDTH_320) {
-			*layout_size = ARRAY_SIZE(ch_6G_320M);
-			return ch_6G_320M;
-		} else
-			return NULL;
-
-	default:
-		return NULL;
-	}
-}
-
-enum ext_ch {
-	EXT_NONE,
-	EXT_ABOVE,
-	EXT_BELOW = 3
-};
-
-int get_ExtCh_callback(struct nl_msg *msg, void *arg)
-{
-	UCHAR *data = (UCHAR *)arg;
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return NL_SKIP;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL]) {
-			*data = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL]);
-		}
-	}
-
-	return NL_OK;
-}
-
-//Get the extension channel via netlink
-UCHAR wifi_getExtCh_netlink(INT radioIndex)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	int ret = -1;
-	unsigned int if_idx = 0;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	UCHAR ext_ch = EXT_NONE;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RUNTIME_INFO;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL, 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_EXTENSION_CHANNEL attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_ExtCh_callback, &ext_ch);
-
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO,"send cmd success\n");
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return ext_ch;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return EXT_NONE;
-
-}
-
-//Get the list for used channel. eg: "1,6,9,11"
-//the returned channels will be the all sub channels that the whole operating bw covers
-//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.
-INT wifi_getRadioChannelsInUse(INT radioIndex, CHAR *output_string)	//RDKB
-{
-	wifi_band band;
-	ULONG pri_ch = 0;
-	UCHAR bw = BAND_WIDTH_20;
-	CHAR bw_str[64] = {0};
-	UCHAR ext_ch = EXT_NONE;
-	UCHAR sub_ch_list[16] = {0};
-	UCHAR sub_ch_num = 0;
-	struct hal_ch_layout *layout = NULL;
-	UCHAR layout_size = 0;
-	UCHAR sub_ch = 0;
-	UCHAR count = 0;
-	int res;
-
-	if (output_string == NULL) {
-		wifi_debug(DEBUG_ERROR, "output_string is NULL, return\n");
-		return RETURN_ERR;
-	}
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "invalid band, return\n");
-		return RETURN_ERR;
-	}
-
-	/*get pri_ch*/
-	if (wifi_getRadioChannel(radioIndex, &pri_ch) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "Fail to get primary ch, return\n");
-		return RETURN_ERR;
-	}
-
-	if (pri_ch == 0) {
-		wifi_debug(DEBUG_ERROR, "invalid primary ch, return\n");
-		return RETURN_ERR;
-	}
-
-	/*get bw*/
-	if (wifi_getRadioOperatingChannelBandwidth(radioIndex, bw_str) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
-		return RETURN_ERR;
-	}
-
-	if (!strcmp(bw_str, "20MHz")) bw = BAND_WIDTH_20;
-	else if (!strcmp(bw_str, "40MHz")) bw = BAND_WIDTH_40;
-	else if (!strcmp(bw_str, "80MHz")) bw = BAND_WIDTH_80;
-	else if (!strcmp(bw_str, "160MHz")) bw = BAND_WIDTH_160;
-	else if (!strcmp(bw_str, "320MHz")) bw = BAND_WIDTH_320;
-	else {
-		wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", bw_str);
-		bw = BAND_WIDTH_20;
-	}
-
-	/*get ext_ch for 2G 40M and 6G 320M*/
-	if ((band == band_2_4 && bw == BAND_WIDTH_40) ||
-		(band == band_6 && bw == BAND_WIDTH_320)) {
-		char ext_ch_str[64]= {0};
-		wifi_getRadioExtChannel(radioIndex, ext_ch_str);
-		if (!strcmp(ext_ch_str, "AboveControlChannel"))
-			ext_ch = EXT_ABOVE;
-		else if (!strcmp(ext_ch_str, "BelowControlChannel"))
-			ext_ch = EXT_BELOW;
-		else
-			ext_ch = EXT_NONE;
-	}
-
-	/*2G 40M ext_ch sainity check, if check fail, only return primary ch*/
-	if (band == band_2_4 && bw == BAND_WIDTH_40) {
-		if (((ext_ch == EXT_ABOVE) && ((pri_ch + 4) > 14))
-			|| ((ext_ch == EXT_BELOW) && ((pri_ch - 4) < 1))) {
-			wifi_debug(DEBUG_ERROR, "EXTCHA channels out of range\n");
-			bw = BAND_WIDTH_20;
-		} else if (ext_ch == EXT_NONE) {
-			wifi_debug(DEBUG_ERROR, "EXTCHA is NONE for 40M\n");
-			bw = BAND_WIDTH_20;
-		}
-	}
-
-	/*20M case, only return primary ch*/
-	if (bw == BAND_WIDTH_20) {
-		sub_ch_list[0] = pri_ch;
-		sub_ch_num = 1;
-		goto output;
-	}
-
-	/*2G/40M case, return all sub channels*/
-	if ((band == band_2_4) && (bw == BAND_WIDTH_40)) {
-		if (ext_ch == EXT_ABOVE) {
-			for (count = 0, sub_ch = pri_ch; (sub_ch <= 14) && (sub_ch <= pri_ch + 4); count++, sub_ch++)
-				sub_ch_list[count] = sub_ch;
-			sub_ch_num = count;
-		} else if (ext_ch == EXT_BELOW) {
-				for (count = 0, sub_ch = pri_ch - 4; (sub_ch > 0) && (sub_ch <= pri_ch); count++, sub_ch++)
-					sub_ch_list[count] = sub_ch;
-				sub_ch_num = count;
-		}
-		goto output;
-	}
-
-	/*for 5G/6G, need find layout*/
-	if ((band == band_5) || (band == band_6)) {
-		UCHAR index;
-		UCHAR i;
-		UCHAR ch_find = FALSE;
-
-		layout = hal_get_ch_array(bw, band, &layout_size);
-		/*can not find, only return primary ch*/
-		if (layout == NULL) {
-			sub_ch_list[0] = pri_ch;
-			sub_ch_num = 1;
-			goto output;
-		}
-
-		/*find the layout[index] which contains the channels in use*/
-		/*need consider 320M EXT here*/
-		for (i = 0; i < layout_size; i++) {
-			if (bw == BAND_WIDTH_320) {
-				if ((pri_ch >= layout[i].ch_low_bnd) && (pri_ch <= layout[i].ch_up_bnd)
-					&& (ext_ch == EXT_ABOVE) && (pri_ch < layout[i].cent_freq_idx)) {
-					ch_find = TRUE;
-					index = i;
-					break;
-				} else if ((pri_ch >= layout[i].ch_low_bnd) && (pri_ch <= layout[i].ch_up_bnd)
-					&& (ext_ch == EXT_BELOW) && (pri_ch > layout[i].cent_freq_idx)) {
-					ch_find = TRUE;
-					index = i;
-					break;
-				}
-			} else {
-				if ((pri_ch >= layout[i].ch_low_bnd) && (pri_ch <= layout[i].ch_up_bnd)) {
-					ch_find = TRUE;
-					index = i;
-					break;
-				}
-			}
-		}
-
-		/*fill in sub_ch_list from layout[index]*/
-		if (ch_find) {
-			UCHAR start_ch = layout[index].ch_low_bnd;
-			UCHAR end_ch = layout[index].ch_up_bnd;
-			for (count = 0, sub_ch = start_ch; sub_ch <= end_ch; count++, sub_ch = sub_ch + 4)
-				sub_ch_list[count] = sub_ch;
-			sub_ch_num = count;
-		} else
-			wifi_debug(DEBUG_ERROR, "find layout[index] fail\n");
-	}
-
-output:
-	for (count = 0; (count < sub_ch_num) && (sub_ch_num <= 16); count++) {
-		if (count == (sub_ch_num - 1))
-			res = snprintf(output_string + strlen(output_string), 256 - strlen(output_string), "%d", sub_ch_list[count]);
-		else
-			res = snprintf(output_string + strlen(output_string), 256 - strlen(output_string), "%d,", sub_ch_list[count]);
-		if (os_snprintf_error(256, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	return RETURN_OK;
-}
-
-int get_channel_handler(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char *channel = (unsigned char *)data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return err;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return err;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL]) {
-			*channel = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL]);
-		}
-	}
-
-	return 0;
-}
-
-INT mtk_wifi_get_radio_info(
-	INT radioIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, void *output)
-{
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_BAND_INFO;
-	param.if_type = NL80211_ATTR_WIPHY;
-	param.if_idx = radio_index_to_phy(radioIndex);
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, vendor_data_attr, 1)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "send cmd success.\n");
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-//Get the running channel number
-INT wifi_getRadioChannel(INT radioIndex, ULONG *output_ulong)	//RDKB
-{
-	char channel_str[16] = {0};
-	char config_file[128] = {0};
-	wifi_band band = band_invalid;
-	unsigned char channel;
-	int res;
-
-	if (output_ulong == NULL)
-		return RETURN_ERR;
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileRead(config_file, "Channel", channel_str, sizeof(channel_str));
-	if (hal_strtoul(channel_str, 10, output_ulong) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	if (*output_ulong == 0) {
-		if (mtk_wifi_get_radio_info(radioIndex, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL,
-			get_channel_handler, &channel)!= RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_CHANNEL cmd fails\n");
-			return RETURN_ERR;
-		}
-		*output_ulong = channel;
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_getApChannel(INT apIndex,ULONG *output_ulong) //RDKB
-{
-	char buf[5] = {0};
-	char interface_name[16] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_ulong)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw dev %s info |grep channel | cut -d ' ' -f2", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	*output_ulong = (strlen(buf) >= 1)? atol(buf): 0;
-	if (*output_ulong == 0) {
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-//Storing the previous channel value
-INT wifi_storeprevchanval(INT radioIndex)
-{
-	char output[4]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "Invalid radio index");
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat",LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileRead(config_file, "Channel", output, sizeof(output));
-
-	if(band == band_2_4)
-		res = v_secure_system("echo %s > /var/prevchanval2G_AutoChannelEnable", output);
-	else if(band == band_5)
-		res = v_secure_system("echo %s > /var/prevchanval5G_AutoChannelEnable", output);
-	else
-		res = v_secure_system("echo %s > /var/prevchanval6G_AutoChannelEnable", output);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-	}
-	Radio_flag = FALSE;
-	return RETURN_OK;
-}
-
-//Set the running channel number
-INT wifi_setRadioChannel(INT radioIndex, ULONG channel)	//RDKB	//AP only
-{
-	// We only write hostapd config here
-	char str_channel[8]={0};
-	char *list_channel;
-	char possible_channels[256] = {0};
-	char config_file_dat[128] = {0};
-	struct params dat = {0};
-	struct params acs = {0};
-	wifi_band band = band_invalid;
-	bool acs_channel = false;
-	int res;
-	int ret = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (channel == 0)
-		acs_channel = true;
-	// Check valid
-	res = snprintf(str_channel, sizeof(str_channel), "%lu", channel);
-	if (os_snprintf_error(sizeof(str_channel), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_getRadioPossibleChannels(radioIndex, possible_channels);
-	list_channel = strtok(possible_channels, ",");
-	while(true)
-	{
-		if(list_channel == NULL) {   // input not in the list
-			wifi_debug(DEBUG_ERROR, "Channel %s is not in possible list\n", str_channel);
-			return RETURN_ERR;
-		}
-		if (strncmp(str_channel, list_channel, strlen(list_channel)) == 0 || strncmp(str_channel, "0", 1) == 0)
-			break;
-		list_channel = strtok(NULL, ",");
-	}
-	/*
-	list.name = "channel";
-	list.value = str_channel;
-	wifi_getMaxRadioNumber(&max_radio_num);
-	for(int i=0; i<=MAX_APS/max_radio_num;i++)
-	{
-		sprintf(config_file, "%s%d.conf", CONFIG_PREFIX, radioIndex+(max_radio_num*i));
-		wifi_hostapdWrite(config_file, &list, 1);
-	}
-	*/
-	dat.name = "Channel";
-	dat.value = str_channel;
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file_dat), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileWrite(config_file_dat, &dat, 1);
-
-	if (acs_channel == true) {
-		acs.name = "AutoChannelSelect";
-		acs.value = "3";
-	} else {
-		acs.name = "AutoChannelSelect";
-		acs.value = "0";
-	}
-	wifi_datfileWrite(config_file_dat, &acs, 1);
-
-	/*do channel quick setting*/
-	if (channel != 0) {
-		ret = wifi_setChannel_netlink(radioIndex, &channel, NULL, NULL, NULL);
-		if (ret != RETURN_OK)
-			wifi_debug(DEBUG_ERROR, "channel quick setting fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setRadioCenterChannel(INT radioIndex, ULONG channel)
-{
-	struct params list[2];
-	char str_idx[16];
-	char config_file[64];
-	int res, bss_idx, vap_idx;
-	wifi_band band = band_invalid;
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_2_4)
-		return RETURN_OK;
-
-	res = snprintf(str_idx, sizeof(str_idx), "%lu", channel);
-	if (os_snprintf_error(sizeof(str_idx), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	list[0].name = "vht_oper_centr_freq_seg0_idx";
-	list[0].value = str_idx;
-	list[1].name = "he_oper_centr_freq_seg0_idx";
-	list[1].value = str_idx;
-
-	for (bss_idx = 0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++)
-	{
-		if (array_index_to_vap_index(radioIndex, bss_idx, &vap_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radioIndex[%d], bss_idx[%d]\n", radioIndex, bss_idx);
-			return RETURN_ERR;
-		}
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_idx);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		if (band == band_6)
-			wifi_hostapdWrite(config_file, &list[1], 1);
-		else
-			wifi_hostapdWrite(config_file, list, 2);
-	}
-
-	return RETURN_OK;
-}
-
-//Enables or disables a driver level variable to indicate if auto channel selection is enabled on this radio
-//This "auto channel" means the auto channel selection when radio is up. (which is different from the dynamic channel/frequency selection (DFC/DCS))
-INT wifi_setRadioAutoChannelEnable(INT radioIndex, BOOL enable) //RDKB
-{
-	//Set to wifi config only. Wait for wifi reset to apply.
-	ULONG Value = 0;
-	char config_file_dat[128] = {0};
-	struct params acs = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	if(enable == TRUE) {
-		wifi_setRadioChannel(radioIndex,Value);
-	} else {
-		acs.name = "AutoChannelSelect";
-		acs.value = "0";
-		band = radio_index_to_band(radioIndex);
-		res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-		if (os_snprintf_error(sizeof(config_file_dat), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_datfileWrite(config_file_dat, &acs, 1);
-	}
-	return RETURN_OK;
-}
-
-INT wifi_getRadioAutoChannelSupported(INT radioIndex, BOOL *output_bool)
-{
-	if (output_bool == NULL)
-		return RETURN_ERR;
-
-	*output_bool = TRUE;
-
-	return RETURN_OK;
-}
-
-INT wifi_getRadioDCSSupported(INT radioIndex, BOOL *output_bool) 	//RDKB
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-	*output_bool=TRUE;
-	return RETURN_OK;
-}
-
-INT wifi_getRadioDCSEnable(INT radioIndex, BOOL *output_bool)		//RDKB
-{
-	unsigned long period = 0;
-
-	if (NULL == output_bool)
-		return RETURN_ERR;
-
-	if (wifi_getRadioAutoChannelRefreshPeriod(radioIndex, &period) != RETURN_OK)
-		return RETURN_OK;
-
-	*output_bool = (period > 0) ? TRUE : FALSE;
-
-	return RETURN_OK;
-}
-
-INT wifi_setRadioDCSEnable(INT radioIndex, BOOL enable)            //RDKB
-{
-	ULONG period = 1800;
-
-	if (enable == TRUE) {
-		if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, period) != RETURN_OK)
-		return RETURN_ERR;
-	}
-	else {
-		if (wifi_setRadioAutoChannelRefreshPeriod(radioIndex, 0) != RETURN_OK)
-		return RETURN_ERR;
-	}
-	return RETURN_OK;
-}
-
-INT wifi_setApEnableOnLine(ULONG wlanIndex,BOOL enable)
-{
-	return RETURN_OK;
-}
-
-INT wifi_factoryResetAP(int apIndex)
-{
-	char ap_config_file[MAX_SUB_CMD_SIZE] = {0};
-
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	int radio_idx = 0;
-	int bss_idx = 0;
-	char ssid[32] = {0};
-	char interface[IF_NAME_SIZE] = {0};
-	char psk_file[MAX_SUB_CMD_SIZE] = {0};
-	struct params params[3] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	/*del old config file*/
-	res = snprintf(ap_config_file, sizeof(ap_config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(ap_config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(ret_buf, sizeof(ret_buf), "rm %s", ap_config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-
-	memset(ret_buf, 0, sizeof(ret_buf));
-
-	vap_index_to_radio_array_index(apIndex, &radio_idx, &bss_idx);
-
-	/*prepare new config file*/
-
-	res = _syscmd_secure(ret_buf, sizeof(ret_buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[radio_idx], ap_config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-
-	if (radio_idx == band_2_4) {
-		res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_2G, bss_idx);
-		if (os_snprintf_error(sizeof(ssid), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI2G, bss_idx);
-		if (os_snprintf_error(sizeof(interface), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if (radio_idx == band_5) {
-		res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_5G, bss_idx);
-		if (os_snprintf_error(sizeof(ssid), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI5G, bss_idx);
-		if (os_snprintf_error(sizeof(interface), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if (radio_idx == band_6) {
-		res = snprintf(ssid, sizeof(ssid), "%s_%d", PREFIX_SSID_6G, bss_idx);
-		if (os_snprintf_error(sizeof(ssid), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		res = snprintf(interface, sizeof(interface), "%s%d", PREFIX_WIFI6G, bss_idx);
-		if (os_snprintf_error(sizeof(interface), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	/* fix wpa_psk_file path */
-	res = snprintf(psk_file, sizeof(psk_file), "/nvram/hostapd%d.psk", apIndex);
-	if (os_snprintf_error(sizeof(psk_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	params[0].name = "ssid";
-	params[0].value = ssid;
-	params[1].name = "interface";
-	params[1].value = interface;
-	params[2].name = "wpa_psk_file";
-	params[2].value = psk_file;
-
-	wifi_hostapdWrite(ap_config_file, params, 3);
-
-	/*clear psk file*/
-
-	memset(ret_buf, 0, sizeof(ret_buf));
-
-	res = snprintf(psk_file, sizeof(psk_file), "%s%d.psk", PSK_FILE, apIndex);
-	if (os_snprintf_error(sizeof(psk_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (access(psk_file, F_OK) != 0) {
-		res = _syscmd_secure(ret_buf,sizeof(ret_buf), "touch %s", psk_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-	} else {
-
-		res = _syscmd_secure(ret_buf,sizeof(ret_buf), "echo '' > %s", psk_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-	}
-
-	wifi_setApEnable(apIndex, FALSE);
-	wifi_setApEnable(apIndex, TRUE);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-
-INT wifi_setBandSteeringApGroup(char *ApGroup)
-{
-	int array[2];
-	char buf[MAX_BUF_SIZE] = {0};
-	char output[MAX_BUF_SIZE] = {0};
-	int ret;
-	int res;
-
-	if (ApGroup == NULL)
-		return RETURN_ERR;
-
-	if (sscanf(ApGroup, "%d,%d", &array[0], &array[1]) != 2) {
-		wifi_debug(DEBUG_ERROR, "Unable to parse the input ApGroup\n");
-		return RETURN_ERR;
-	}
-
-	ret = wifi_getBaseBSSID(array[0]-1, output);
-	if (ret != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getBaseBSSID return error\n");
-		return RETURN_ERR;
-	} else {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl bss_group_set %s 1", output);
-		if (res)
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	memset(output, 0, sizeof(output));
-	ret = wifi_getBaseBSSID(array[1]-1, output);
-	if (ret != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getBaseBSSID return error\n");
-		return RETURN_ERR;
-	} else {
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl bss_group_set %s 1", output);
-		if (res)
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	memset(buf, 0, sizeof(buf));
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl restrict_bss_group_steering enable");
-	if (res)
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-	return RETURN_OK;
-}
-
-INT wifi_getApDTIMInterval(INT apIndex, INT *dtimInterval)
-{
-	char config_file[128] = {'\0'};
-	char buf[128] = {'\0'};
-	int res;
-	long int tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (dtimInterval == NULL)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdRead(config_file, "dtim_period", buf, sizeof(buf));
-
-	if (strlen(buf) == 0) {
-		*dtimInterval = 2;
-	} else {
-		if (hal_strtol(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		*dtimInterval = tmp;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setApDTIMInterval(INT apIndex, INT dtimInterval)
-{
-	struct params params={0};
-	char config_file[MAX_BUF_SIZE] = {'\0'};
-	char buf[MAX_BUF_SIZE] = {'\0'};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (dtimInterval < 1 || dtimInterval > 255) {
-		WIFI_ENTRY_EXIT_DEBUG("Invalid dtimInterval: %d\n", dtimInterval);
-		return RETURN_ERR;
-	}
-
-	params.name = "dtim_period";
-	res = snprintf(buf, sizeof(buf), "%d", dtimInterval);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.value = buf;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Check if the driver support the Dfs
-INT wifi_getRadioDfsSupport(INT radioIndex, BOOL *output_bool) //Tr181
-{
-	wifi_band band = band_invalid;
-	if (NULL == output_bool)
-		return RETURN_ERR;
-	*output_bool=FALSE;
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_5)
-		*output_bool = TRUE;
-	return RETURN_OK;
-}
-
-//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.
-//The value of this parameter is a comma seperated list of channel number
-INT wifi_getRadioDCSChannelPool(INT radioIndex, CHAR *output_pool)			//RDKB
-{
-
-	#define CHANNEL_AVAILABLE 0
-	#define CHANNEL_INVALID 1
-	#define CHANNEL_LIST_MAX_LENGTH 256
-	#define MAX_CHANNEL_NUMBER 255
-
-	char config_file[MAX_BUF_SIZE] = {0};
-	char possible_channels[CHANNEL_LIST_MAX_LENGTH] = {0};
-	char skip_list[CHANNEL_LIST_MAX_LENGTH] = {0};
-	int skip_table[MAX_CHANNEL_NUMBER +1] = {0};
-	wifi_band band = band_invalid;
-	char *token_channel = NULL, *token_skip = NULL;
-	int res;
-
-	if (NULL == output_pool)
-		return RETURN_ERR;
-	// get skiplist, possible_channels list
-	wifi_getRadioPossibleChannels(radioIndex, possible_channels);
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileRead(config_file, "AutoChannelSkipList", skip_list, sizeof(skip_list));
-
-	if (skip_list[0] != '\0') {
-		int len = strlen(skip_list);
-		for (int i = 0; i < len; i++) {
-			if (skip_list[i] == ';') {
-				skip_list[i] = ',';
-			}
-		}
-		// skip list
-		token_skip = strtok(skip_list, ",");
-		while (token_skip != NULL) {
-			int channel = atoi(token_skip);
-			if (channel <= MAX_CHANNEL_NUMBER && strstr(possible_channels, token_skip) != NULL)
-				skip_table[atoi(token_skip)] = CHANNEL_INVALID;
-			token_skip = strtok(NULL, ",");
-		}
-	}
-
-	int count = 0;
-	token_channel = strtok(possible_channels, ",");
-	while (token_channel != NULL) {
-		int channel = atoi(token_channel);
-		if (channel <= MAX_CHANNEL_NUMBER  && skip_table[channel] == CHANNEL_AVAILABLE) {
-			count += snprintf(&output_pool[count], CHANNEL_LIST_MAX_LENGTH-count, "%d,", channel);
-			if (count >= CHANNEL_LIST_MAX_LENGTH-1)
-				break;
-		}
-		token_channel = strtok(NULL, ",");
-	}
-	//delete the last one ','
-	if (count >0 && output_pool[count-1] == ',')
-		output_pool[count-1] = '\0';
-	return RETURN_OK;
-}
-
-INT wifi_setRadioDCSChannelPool(INT radioIndex, CHAR *pool)			//RDKB
-{
-	char config_file_dat[128] = {0};
-	struct params dat = {0};
-	wifi_band band = band_invalid;
-	char new_pool[128] = {0};
-	int res;
-
-	if (NULL == pool)
-		return RETURN_ERR;
-
-	strncpy(new_pool, pool, sizeof(new_pool) - 1);
-	new_pool[sizeof(new_pool) - 1] = '\0';
-	for (int i = 0; new_pool[i] != '\0'; i++) {
-		if (new_pool[i] == ',')
-			new_pool[i] = ';';
-	}
-
-	dat.name = "AutoChannelSkipList";
-	dat.value = new_pool;
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file_dat), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (wifi_datfileWrite(config_file_dat, &dat, 1) != 0)
-		return RETURN_ERR;
-	wifi_reloadAp(radioIndex);
-
-	return RETURN_OK;
-}
-
-INT wifi_getRadioDCSScanTime(INT radioIndex, INT *output_interval_seconds, INT *output_dwell_milliseconds)
-{
-	if (NULL == output_interval_seconds || NULL == output_dwell_milliseconds)
-		return RETURN_ERR;
-	//Should refresh period time be filled in here? output_interval_seconds is INT type
-	//wifi_getRadioAutoChannelRefreshPeriod is Ulong type
-	*output_interval_seconds = 1800;
-	*output_dwell_milliseconds = 200;
-
-	return RETURN_OK;
-}
-
-INT wifi_setRadioDCSScanTime(INT radioIndex, INT interval_seconds, INT dwell_milliseconds)
-{
-	//Set to wifi config. And apply instantly.
-	return RETURN_OK;
-}
-
-INT wifi_getRadioDfsAtBootUpEnable(INT radioIndex, BOOL *output_bool)	//Tr181
-{
-	if (output_bool == NULL)
-		 return RETURN_ERR;
-	 *output_bool = true;
-	return RETURN_OK;
-}
-
-INT wifi_setRadioDfsAtBootUpEnable(INT radioIndex, BOOL enable)	//Tr181
-{
-	return RETURN_OK;
-}
-
-//Get the Dfs enable status
-INT wifi_getRadioDfsEnable(INT radioIndex, BOOL *output_bool)	//Tr181
-{
-	char buf[16] = {0};
-	char config_file_dat[128] = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (output_bool == NULL)
-		return RETURN_ERR;
-	*output_bool = TRUE;		// default
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file_dat, sizeof(config_file_dat), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file_dat), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileRead(config_file_dat, "DfsEnable", buf, sizeof(buf));
-
-	if (strncmp(buf, "0", 1) == 0)
-		*output_bool = FALSE;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Set the Dfs enable status
-INT wifi_setRadioDfsEnable(INT radioIndex, BOOL enable)	//Tr181
-{
-	char config_dat_file[128] = {0};
-	FILE *f = NULL;
-	struct params dat = {0};
-	wifi_band band = band_invalid;
-	int res, ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	f = fopen(DFS_ENABLE_FILE, "w");
-	if (f == NULL)
-		return RETURN_ERR;
-	ret = fprintf(f, "%d", enable);
-	if (ret < 0)
-		wifi_debug(DEBUG_ERROR, "fprintf fail\n");
-	if (fclose(f) != 0) {
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_setRadioIEEE80211hEnabled(radioIndex, enable);
-
-	dat.name = "DfsEnable";
-	dat.value = enable?"1":"0";
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileWrite(config_dat_file, &dat, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Check if the driver support the AutoChannelRefreshPeriod
-INT wifi_getRadioAutoChannelRefreshPeriodSupported(INT radioIndex, BOOL *output_bool) //Tr181
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-	*output_bool = TRUE;
-
-	return RETURN_OK;
-}
-
-
-int get_ACS_RefreshPeriod_callback(struct nl_msg *msg, void *arg)
-{
-	ULONG *data = (ULONG *)arg;
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return NL_SKIP;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]) {
-			*data = nla_get_u32(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_RUNTIME_INFO_GET_ACS_REFRESH_PERIOD]);
-		}
-	}
-
-	return NL_OK;
-}
-
-//Get the ACS refresh period in seconds
-INT wifi_getRadioAutoChannelRefreshPeriod(INT radioIndex, ULONG *output_ulong) //Tr181
-{
-	wifi_band band = band_invalid;
-	int res;
-	char config_file[128] = {0};
-	char period_str[16] = {0};
-
-	if (output_ulong == NULL)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileRead(config_file, "ACSCheckTime", period_str, sizeof(period_str));
-	if (hal_strtoul(period_str, 10, output_ulong) < 0)
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-
-	return RETURN_OK;
-}
-
-//Set the ACS refresh period in seconds
-INT wifi_setRadioDfsRefreshPeriod(INT radioIndex, ULONG seconds) //Tr181
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	int ret = -1;
-	unsigned int if_idx = 0;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", interface_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AUTO_CH_SEL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-	if (nla_put_u32(msg, MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME, seconds)) {
-		wifi_debug(DEBUG_ERROR, "Nla put MTK_NL80211_VENDOR_ATTR_AUTO_CH_CHECK_TIME attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO,"send cmd success\n");
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-int get_bandwidth_handler(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char *bw = (unsigned char *)data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return err;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return err;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_BANDWIDTH]) {
-			*bw = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_BAND_INFO_BANDWIDTH]);
-		}
-	}
-
-	return 0;
-}
-
-int bwidx_to_string(unsigned char bw, char *buf)
-{
-	int res;
-	switch (bw) {
-	case BAND_WIDTH_20:
-		res = snprintf(buf, 32, "%s", "20");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-		break;
-	case BAND_WIDTH_40:
-		res = snprintf(buf, 32, "%s", "40");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-		break;
-	case BAND_WIDTH_80:
-		res = snprintf(buf, 32, "%s", "80");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-		break;
-	case BAND_WIDTH_160:
-		res = snprintf(buf, 32, "%s", "160");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-		break;
-	case BAND_WIDTH_8080:
-		res = snprintf(buf, 32, "%s", "80+80");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-		break;
-	case BAND_WIDTH_320:
-		res = snprintf(buf, 32, "%s", "320");
-		if (os_snprintf_error(64, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return -1;
-		}
-		break;
-	default:
-		wifi_debug(DEBUG_ERROR, "unkown bw[%d]\n", bw);
-		return -1;
-	}
-
-	return 0;
-}
-
-/*Calculate radio bw from ht_bw, vht_bw and eht bw*/
-UCHAR calculate_radio_bw(UCHAR ht_bw, UCHAR vht_bw, UCHAR eht_bw) {
-	UCHAR bw = BAND_WIDTH_20;
-
-	if (ht_bw == HT_BW_20)
-		return bw;
-
-	if (ht_bw == HT_BW_40) {
-		if (vht_bw == VHT_BW_2040)
-			bw = BAND_WIDTH_40;
-		else if (vht_bw == VHT_BW_80)
-			bw = BAND_WIDTH_80;
-		else if (vht_bw == VHT_BW_160) {
-			if (eht_bw == EHT_BW_320)
-				bw = BAND_WIDTH_320;
-			else
-				bw = BAND_WIDTH_160;
-		} else if (vht_bw == VHT_BW_8080)
-			bw = BAND_WIDTH_8080;
-	}
-
-	return bw;
-}
-//Get the Configured Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
-//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.
-INT wifi_getRadioConfiguredChannelBandwidth(INT radioIndex, CHAR *output_string)
-{
-	char config_file[128] = {0};
-	wifi_band band = band_invalid;
-	char ht_bw_str[16] = {0};
-	char vht_bw_str[16] = {0};
-	char eht_bw_str[16] = {0};
-	UCHAR ht_bw;
-	UCHAR vht_bw;
-	UCHAR eht_bw;
-	UCHAR bw;
-	char buf[32] = {0};
-	int res;
-	int ret;
-
-	if (output_string == NULL) {
-		wifi_debug(DEBUG_ERROR, "output_string is NULL\n");
-		return RETURN_ERR;
-	}
-
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	/*parse HT_BW*/
-	wifi_datfileRead(config_file, "HT_BW", ht_bw_str, sizeof(ht_bw_str));
-	if (strncmp(ht_bw_str, "1", 1) == 0)
-		ht_bw = HT_BW_40;
-	else
-		ht_bw = HT_BW_20;
-
-	/*parse VHT_BW*/
-	wifi_datfileRead(config_file, "VHT_BW", vht_bw_str, sizeof(vht_bw_str));
-	if (strncmp(vht_bw_str, "0", 1) == 0)
-		vht_bw = VHT_BW_2040;
-	else if (strncmp(vht_bw_str, "1", 1) == 0)
-		vht_bw = VHT_BW_80;
-	else if (strncmp(vht_bw_str, "2", 1) == 0)
-		vht_bw = VHT_BW_160;
-	else if (strncmp(vht_bw_str, "3", 1) == 0)
-		vht_bw = VHT_BW_8080;
-	else
-		vht_bw = VHT_BW_2040;
-
-	/*parse EHT_BW*/
-	wifi_datfileRead(config_file, "EHT_ApBw", eht_bw_str, sizeof(eht_bw_str));
-	if (strncmp(eht_bw_str, "0", 1) == 0)
-		eht_bw = EHT_BW_20;
-	else if (strncmp(eht_bw_str, "1", 1) == 0)
-		eht_bw = EHT_BW_40;
-	else if (strncmp(eht_bw_str, "2", 1) == 0)
-		eht_bw = EHT_BW_80;
-	else if (strncmp(eht_bw_str, "3", 1) == 0)
-		eht_bw = EHT_BW_160;
-	else if (strncmp(eht_bw_str, "4", 1) == 0)
-		eht_bw = EHT_BW_320;
-	else
-		eht_bw = EHT_BW_20;
-
-	bw = calculate_radio_bw(ht_bw, vht_bw, eht_bw);
-	ret = bwidx_to_string(bw, buf);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "bwidx_to_string fails\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(output_string, 64, "%sMHz", buf);
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Get the Operating Channel Bandwidth. eg "20MHz", "40MHz", "80MHz", "80+80", "160"
-//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.
-INT wifi_getRadioOperatingChannelBandwidth(INT radioIndex, CHAR *output_string) //Tr181
-{
-	char buf[32] = {0};
-	int ret = 0, res;
-	BOOL radio_enable = FALSE;
-	unsigned char bw;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (NULL == output_string) {
-		WIFI_ENTRY_EXIT_DEBUG("output_string is nuill %s: %d \n", __func__, __LINE__);
-		return RETURN_ERR;
-	}
-	if (wifi_getRadioEnable(radioIndex, &radio_enable) == RETURN_ERR) {
-		WIFI_ENTRY_EXIT_DEBUG("wifi_getRadioEnable failed %s: %d \n", __func__, __LINE__);
-		return RETURN_ERR;
-	}
-	if (radio_enable != TRUE) {
-		WIFI_ENTRY_EXIT_DEBUG("Radio %d is not enable failed %s: %d \n", radioIndex, __func__, __LINE__);
-		return RETURN_OK;
-	}
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	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");
-	}
-	ret = bwidx_to_string(bw, buf);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "bwidx_to_string fails\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(output_string, 64, "%sMHz", buf);
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Set the Operating Channel Bandwidth.
-INT wifi_setRadioOperatingChannelBandwidth(INT radioIndex, CHAR *bandwidth) //Tr181	//AP only
-{
-	char config_file[128];
-	char ht_value[16];
-	char vht_value[16];
-	char eht_value[16];
-	struct params dat[3];
-	wifi_band band = band_invalid;
-	unsigned int bw = 20;
-	int ret = 0, res1, res2, res3;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if(NULL == bandwidth)
-		return RETURN_ERR;
-	band = radio_index_to_band(radioIndex);
-
-	if(strstr(bandwidth,"320") != NULL) {
-		res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
-		res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
-		res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_320);
-		bw = 320;
-	} else if(strstr(bandwidth,"160") != NULL) {
-		res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
-		res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_160);
-		res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_160);
-		bw = 160;
-	} else if(strstr(bandwidth,"80") != NULL) {
-		res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
-		res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_80);
-		res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_80);
-		bw = 80;
-	} else if(strstr(bandwidth,"40") != NULL) {
-		res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_40);
-		res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
-		res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_40);
-		bw = 40;
-	} else if(strstr(bandwidth,"20") != NULL) {
-		res1 = snprintf(ht_value, sizeof(ht_value), "%d", HT_BW_20);
-		res2 = snprintf(vht_value, sizeof(vht_value), "%d", VHT_BW_2040);
-		res3 = snprintf(eht_value, sizeof(eht_value), "%d", EHT_BW_20);
-		bw = 20;
-	} else {
-		if (fprintf(stderr, "%s: Invalid Bandwidth %s\n", __func__, bandwidth) < 0)
-			wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (os_snprintf_error(sizeof(ht_value), res1) ||
-		os_snprintf_error(sizeof(vht_value), res2) ||
-		os_snprintf_error(sizeof(eht_value), res3)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res1 = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res1)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	dat[0].name = "HT_BW";
-	dat[0].value = ht_value;
-	dat[1].name = "VHT_BW";
-	dat[1].value = vht_value;
-	dat[2].name = "EHT_ApBw";
-	dat[2].value = eht_value;
-	wifi_datfileWrite(config_file, dat, 3);
-
-	/*do bw quick setting*/
-	ret = wifi_setChannel_netlink(radioIndex, NULL, &bw, NULL, NULL);
-	if (ret != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "bw quick setting fail\n");
-		if (fprintf(stderr, "%s: wifi_setChannel return error.\n", __func__) < 0)
-			wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get the secondary extension channel position, "AboveControlChannel" or "BelowControlChannel". (this is for 40MHz and 80MHz bandwith only)
-//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.
-INT wifi_getRadioExtChannel(INT radioIndex, CHAR *output_string) //Tr181
-{
-	char buf[64] = {0};
-	char cmd[MAX_CMD_SIZE] = {0};
-	char interface_name[64] = {0};
-	int ret = 0, len = 0;
-	ULONG channel = 0;
-	int centr_channel = 0;
-	int freq = 0, res;
-	int main_vap_idx;
-
-	if (output_string == NULL)
-		return RETURN_ERR;
-
-	/*default output_string is "Auto"*/
-	res = snprintf(output_string, 64, "Auto");
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	/*get primary ch*/
-	wifi_getRadioChannel(radioIndex, &channel);
-	if (channel == 0) {
-		wifi_debug(DEBUG_ERROR, "RadioChannel is 0, return\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(cmd, sizeof(cmd),"iw dev %s info | grep 'center1' | cut -d  ' ' -f9 | tr -d '\\n'", interface_name);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	/*get center ch freq*/
-	ret = _syscmd_secure(buf, sizeof(buf), "iw dev %s info | grep 'center1' | cut -d  ' ' -f9 | tr -d '\\n'", interface_name);
-	if(ret)
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	len = strlen(buf);
-	if((ret != 0) || (len == 0))
-	{
-		wifi_debug(DEBUG_ERROR, "failed with Command %s %s:%d\n", cmd, __func__, __LINE__);
-		return RETURN_ERR;
-	}
-
-	sscanf(buf, "%d", &freq);
-	centr_channel = ieee80211_frequency_to_channel(freq);
-
-	/*compare centr_channel and primary ch*/
-	if (centr_channel > (int)channel)
-		res = snprintf(output_string, 64, "AboveControlChannel");
-	else
-		res = snprintf(output_string, 64, "BelowControlChannel");
-
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Set the extension channel.
-INT wifi_setRadioExtChannel(INT radioIndex, CHAR *string) //Tr181	//AP only
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	struct params params={0};
-	char config_file[64] = {0};
-	char config_dat_file[64] = {0};
-	char ext_channel[64] = {0};
-	unsigned char ext_ch;
-	char buf[128] = {0};
-	int ret = 0;
-	long int bandwidth = 0;
-	unsigned long channel = 0;
-	params.name = "ht_capab";
-	wifi_band band;
-	int res, main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (wifi_getRadioOperatingChannelBandwidth(radioIndex, buf) != RETURN_OK)
-		return RETURN_ERR;
-	if (hal_strtol(buf, 10, &bandwidth) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	// TDK expected to get error with 20MHz
-	// we handle 20MHz in function wifi_RemoveRadioExtChannel().
-	if (bandwidth == 20 || strstr(buf, "80+80") != NULL)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_invalid)
-		return RETURN_ERR;
-
-	if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = snprintf(buf, sizeof(buf), "HT%ld", bandwidth);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	ret = util_get_sec_chan_offset(channel, buf);
-	if (ret == -EINVAL)
-		return RETURN_ERR;
-
-	if(NULL!= strstr(string,"Above")) {
-		if ((band == band_2_4 && channel > 9) || (band == band_5 && ret == -1))
-			return RETURN_OK;
-		memcpy(ext_channel, "1", strlen("1"));
-		ext_ch = 1;
-	} else if(NULL!= strstr(string,"Below")) {
-		if ((band == band_2_4 && channel < 5) || (band == band_5 && ret == -1))
-			return RETURN_OK;
-		memcpy(ext_channel, "0", strlen("0"));
-		ext_ch = 0;
-	} else {
-		wifi_debug(DEBUG_ERROR, "invalid EXT_CHA:%s\n", string);
-		return RETURN_ERR;
-	}
-	params.name = "HT_EXTCHA";
-	params.value = ext_channel;
-
-	res = snprintf (config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileWrite(config_dat_file, &params, 1);
-
-	/*do ext_ch quicking setting*/
-	if (ext_ch != -1) {
-		ret = wifi_setChannel_netlink(radioIndex, NULL, NULL, &ext_ch, NULL);
-		if (ret != RETURN_OK)
-			wifi_debug(DEBUG_ERROR, "ext_ch quicking setting fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get the guard interval value. eg "400nsec" or "800nsec"
-//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.
-INT wifi_getRadioGuardInterval(INT radioIndex, CHAR *output_string)	//Tr181
-{
-	wifi_guard_interval_t GI;
-	unsigned long len;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (output_string == NULL || wifi_getGuardInterval(radioIndex, &GI) == RETURN_ERR)
-		return RETURN_ERR;
-
-	if (GI == wifi_guard_interval_400) {
-		len = strlen("400nsec");
-		memcpy(output_string, "400nsec", len);
-	} else if (GI == wifi_guard_interval_800) {
-		len = strlen("800nsec");
-		memcpy(output_string, "800nsec", strlen("800nsec"));
-	} else if (GI == wifi_guard_interval_1600) {
-		len = strlen("1600nsec");
-		memcpy(output_string, "1600nsec", strlen("1600nsec"));
-	} else if (GI == wifi_guard_interval_3200) {
-		len = strlen("3200nsec");
-		memcpy(output_string, "3200nsec", strlen("3200nsec"));
-	} else {
-		len = strlen("Auto");
-		memcpy(output_string, "Auto", strlen("Auto"));
-	}
-	output_string[len] = '\0';
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Set the guard interval value.
-INT wifi_setRadioGuardInterval(INT radioIndex, CHAR *string)	//Tr181
-{
-	wifi_guard_interval_t GI;
-	int ret = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (strcmp(string, "400nsec") == 0)
-		GI = wifi_guard_interval_400;
-	else if (strcmp(string , "800nsec") == 0)
-		GI = wifi_guard_interval_800;
-	else if (strcmp(string , "1600nsec") == 0)
-		GI = wifi_guard_interval_1600;
-	else if (strcmp(string , "3200nsec") == 0)
-		GI = wifi_guard_interval_3200;
-	else
-		GI = wifi_guard_interval_auto;
-
-	ret = wifi_setGuardInterval(radioIndex, GI);
-
-	if (ret == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "wifi_setGuardInterval return error\n");
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get the Modulation Coding Scheme index, eg: "-1", "1", "15"
-INT wifi_getRadioMCS(INT radioIndex, INT *output_int) //Tr181
-{
-	char buf[32]={0};
-	char mcs_file[64] = {0};
-
-	UINT mode_bitmap = 0;
-	int res;
-	long int tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(output_int == NULL)
-		return RETURN_ERR;
-	res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(mcs_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null", mcs_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) > 0) {
-		if (hal_strtol(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		*output_int = tmp;
-	} else {
-		// output the max MCS for the current radio mode
-		if (wifi_getRadioMode(radioIndex, buf, &mode_bitmap) == RETURN_ERR) {
-			wifi_debug(DEBUG_ERROR, "wifi_getradiomode return error.\n");
-			return RETURN_ERR;
-		}
-		if (mode_bitmap & WIFI_MODE_AX) {
-			*output_int = 11;
-		} else if (mode_bitmap & WIFI_MODE_AC) {
-			*output_int = 9;
-		} else if (mode_bitmap & WIFI_MODE_N) {
-			*output_int = 7;
-		}
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Set the Modulation Coding Scheme index
-INT wifi_setRadioMCS(INT radioIndex, INT MCS) //Tr181
-{
-	/*Only HE mode can specify MCS capability. We don't support MCS in HT mode,
-	because that would be ambiguous (MCS code 8~11 refer to 2 NSS in HT but 1 NSS in HE adn VHT).*/
-	char config_file[64] = {0};
-	char set_value[16] = {0};
-	char mcs_file[32] = {0};
-	struct params set_config = {0};
-	FILE *f = NULL;
-	INT nss = 0;
-	int ant_bitmap = 0;
-	unsigned short cal_value = 0;
-	UCHAR tval = 0, i = 0;
-	int res, main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	// -1 means auto
-	if (MCS > 15 || MCS < -1) {
-		wifi_debug(DEBUG_ERROR, "invalid MCS %d\n", MCS);
-		return RETURN_ERR;
-	}
-	wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);/*nss is a bit map value,1111*/
-	for(; ant_bitmap > 0; ant_bitmap >>= 1)
-	nss += 1;
-	//printf("%s:nss = %d\n", __func__, nss);
-	/*16-bit combination of 2-bit values of Max HE-MCS For 1..8 SS;each 2-bit value have following meaning:
-	0 = HE-MCS 0-7, 1 = HE-MCS 0-9, 2 = HE-MCS 0-11, 3 = not supported*/
-	if (MCS > 9 || MCS == -1)
-		tval = 2;/*one stream value*/
-	else if (MCS > 7)
-		tval = 1;
-	else
-		tval = 0;
-	for (i = 0; i < nss; i++)
-	   cal_value |= (tval << (2*i));
-	res = snprintf(set_value, sizeof(set_value), "%x", cal_value);
-	if (os_snprintf_error(sizeof(set_value), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("%s:set=%s, cal=%x\n", __func__, set_value, cal_value);
-	set_config.name = "he_basic_mcs_nss_set";/*He capability in beacon or response*/
-	set_config.value = set_value;
-
-	wifi_hostapdWrite(config_file, &set_config, 1);
-	wifi_hostapdProcessUpdate(radioIndex, &set_config, 1);
-
-	// For pass tdk test, we need to record last MCS setting. No matter whether it is effective or not.
-	res = snprintf(mcs_file, sizeof(mcs_file), "%s%d.txt", MCS_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(mcs_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	f = fopen(mcs_file, "w");
-	if (f == NULL) {
-		if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
-			wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (fprintf(f, "%d", MCS) < 0)
-		wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-	if (fclose(f) == EOF) {
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Get supported Transmit Power list, eg : "0,25,50,75,100"
-//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.
-INT wifi_getRadioTransmitPowerSupported(INT radioIndex, CHAR *output_list) //Tr181
-{
-	int res;
-	if (NULL == output_list)
-		return RETURN_ERR;
-	res = snprintf(output_list, 64,"0,25,50,75,100");
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Get current Transmit Power in dBm units.
-//The transmite power level is in units of full power for this radio.
-INT wifi_getRadioTransmitPower(INT radioIndex, ULONG *output_ulong)	//RDKB
-{
-	char config_dat_file[MAX_BUF_SIZE] = {0};
-	char buf[64]={'\0'};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if(output_ulong == NULL)
-		return RETURN_ERR;
-
-	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_index_to_band(radioIndex));
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileRead(config_dat_file, "TxPower", buf, sizeof(buf));
-	if (strlen(buf) > 0) {
-		if (hal_strtoul(buf, 10, output_ulong) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-	} else
-		*output_ulong = 100;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Set Transmit Power
-//The transmite power level is in units of full power for this radio.
-INT wifi_setRadioTransmitPower(INT radioIndex, ULONG TransmitPower)	//RDKB
-{
-	char interface_name[16] = {0};
-	char *support;
-	char buf[128]={0};
-	char txpower_str[64] = {0};
-	int if_idx, ret = 0;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-	int res;
-	int main_vap_idx;
-	char config_dat_file[MAX_BUF_SIZE] = {0};
-	struct params dat={0};
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	// Get the Tx power supported list and check that is the input in the list
-	res = snprintf(txpower_str, sizeof(txpower_str), "%lu", TransmitPower);
-	if (os_snprintf_error(sizeof(txpower_str), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_getRadioTransmitPowerSupported(radioIndex, buf);
-	support = strtok(buf, ",");
-	while(true)
-	{
-		if(support == NULL) {   // input not in the list
-			wifi_debug(DEBUG_ERROR, "Input value is invalid.\n");
-			return RETURN_ERR;
-		}
-		if (strncmp(txpower_str, support, strlen(support)) == 0) {
-			break;
-		}
-		support = strtok(NULL, ",");
-	}
-
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_PERCENTAGE_EN, 1)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_DROP_CTRL, TransmitPower)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-
-	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, radio_index_to_band(radioIndex));
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	dat.name = "TxPower";
-	dat.value = txpower_str;
-	wifi_datfileWrite(config_dat_file, &dat, 1);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-//get 80211h Supported.  80211h solves interference with satellites and radar using the same 5 GHz frequency band
-INT wifi_getRadioIEEE80211hSupported(INT radioIndex, BOOL *Supported)  //Tr181
-{
-	if (NULL == Supported)
-		return RETURN_ERR;
-	*Supported = TRUE;
-
-	return RETURN_OK;
-}
-
-//Get 80211h feature enable
-INT wifi_getRadioIEEE80211hEnabled(INT radioIndex, BOOL *enable) //Tr181
-{
-	char buf[64]={'\0'};
-	char config_dat_file[64] = {'\0'};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(enable == NULL)
-		return RETURN_ERR;
-
-	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	/* wifi_hostapdRead(config_file, "ieee80211h", buf, sizeof(buf)); */
-	wifi_datfileRead(config_dat_file, "IEEE80211H", buf, sizeof(buf));
-
-	if (strncmp(buf, "1", 1) == 0)
-		*enable = TRUE;
-	else
-		*enable = FALSE;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//Set 80211h feature enable
-INT wifi_setRadioIEEE80211hEnabled(INT radioIndex, BOOL enable)  //Tr181
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	struct params params={'\0'};
-	struct params dat={0};
-	char config_dat_file[MAX_BUF_SIZE] = {0};
-	wifi_band band = band_invalid;
-	int res;
-	int ret = -1;
-	unsigned char en_80211h;
-
-	if (enable) {
-		params.value = "1";
-		en_80211h = 1;
-	} else {
-		params.value = "0";
-		en_80211h = 0;
-	}
-
-	dat.name = "IEEE80211H";
-	dat.value = params.value;
-
-	band = radio_index_to_band(radioIndex);
-
-	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileWrite(config_dat_file, &dat, 1);
-
-	/*do IEEE80211h quick setting*/
-	ret = wifi_set80211h_netlink(radioIndex, en_80211h);
-	if (ret != RETURN_OK)
-		wifi_debug(DEBUG_ERROR, "IEEE80211h quick setting fail\n");
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//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.
-INT wifi_getRadioCarrierSenseThresholdRange(INT radioIndex, INT *output)  //P3
-{
-	if (NULL == output)
-		return RETURN_ERR;
-	*output=100;
-
-	return RETURN_OK;
-}
-
-//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.
-INT wifi_getRadioCarrierSenseThresholdInUse(INT radioIndex, INT *output)	//P3
-{
-	if (NULL == output)
-		return RETURN_ERR;
-	*output = -99;
-
-	return RETURN_OK;
-}
-
-INT wifi_setRadioCarrierSenseThresholdInUse(INT radioIndex, INT threshold)	//P3
-{
-	return RETURN_ERR;
-}
-
-
-//Time interval between transmitting beacons (expressed in milliseconds). This parameter is based ondot11BeaconPeriod from [802.11-2012].
-INT wifi_getRadioBeaconPeriod(INT radioIndex, UINT *output)
-{
-	char interface_name[16] = {0};
-	char config_file[128] = {0};
-	char buf[MAX_CMD_SIZE]={'\0'};
-	int res;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(output == NULL)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s status | grep beacon_int | cut -d '=' -f2 | tr -d '\n'", interface_name);
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	*output = atoi(buf);
-	if (*output == 0) {
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_hostapdRead(config_file, "beacon_int", buf, sizeof(buf));
-		*output = atoi(buf);
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setRadioBeaconPeriod(INT radioIndex, UINT BeaconPeriod)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	struct params params={'\0'};
-	char buf[MAX_BUF_SIZE] = {'\0'};
-	char config_file[MAX_BUF_SIZE] = {'\0'};
-	int res, main_vap_idx;
-
-	if (BeaconPeriod < 15 || BeaconPeriod > 65535)
-		return RETURN_ERR;
-
-	params.name = "beacon_int";
-	res = snprintf(buf, sizeof(buf), "%u", BeaconPeriod);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	params.value = buf;
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-
-	wifi_hostapdProcessUpdate(radioIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//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.
-INT wifi_getRadioBasicDataTransmitRates(INT radioIndex, CHAR *output)
-{
-	//TODO: need to revisit below implementation
-	char *temp;
-	char temp_output[128] = {0};
-	char temp_TransmitRates[64] = {0};
-	char config_file[64] = {0};
-	int res, main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file,"basic_rates",temp_TransmitRates,64);
-
-	if (strlen(temp_TransmitRates) == 0) {  // config not set, use supported rate
-		wifi_getRadioSupportedDataTransmitRates(radioIndex, output);
-	} else {
-		temp = strtok(temp_TransmitRates," ");
-		while(temp!=NULL)
-		{
-			// Convert 100 kbps to Mbps
-			temp[strlen(temp)-1]=0;
-			if((temp[0]=='5') && (temp[1]=='\0'))
-			{
-				temp="5.5";
-			}
-			if (strlen(temp) >= sizeof(temp_output))
-				return RETURN_ERR;
-			strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
-			temp = strtok(NULL," ");
-			if(temp!=NULL)
-			{
-				if (strlen(temp_output) >= (sizeof(temp_output) - 1))
-				strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
-			}
-		}
-		memcpy(output, temp_output, strlen(temp_output));
-		output[strlen(temp_output)] = '\0';
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setRadioBasicDataTransmitRates(INT radioIndex, CHAR *TransmitRates)
-{
-	char *temp;
-	char temp1[128] = {0};
-	char temp_output[128] = {0};
-	char temp_TransmitRates[128] = {0};
-	char set[128] = {0};
-	char sub_set[128] = {0};
-	int set_count=0,subset_count=0;
-	int set_index=0,subset_index=0;
-	char *token;
-	int flag=0, i=0;
-	struct params params={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	wifi_band band = radio_index_to_band(radioIndex);
-	int res, main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if(NULL == TransmitRates)
-		return RETURN_ERR;
-	if (strlen(TransmitRates) >= sizeof(sub_set))
-		return RETURN_ERR;
-
-	memcpy(sub_set, TransmitRates, strlen(TransmitRates));
-
-	//Allow only supported Data transmit rate to be set
-	wifi_getRadioSupportedDataTransmitRates(radioIndex,set);
-	token = strtok(sub_set,",");
-	while( token != NULL  )  /* split the basic rate to be set, by comma */
-	{
-		sub_set[subset_count]=atoi(token);
-		subset_count++;
-		token=strtok(NULL,",");
-	}
-	token=strtok(set,",");
-	while(token!=NULL)   /* split the supported rate by comma */
-	{
-		set[set_count]=atoi(token);
-		set_count++;
-		token=strtok(NULL,",");
-	}
-	for(subset_index=0;subset_index < subset_count;subset_index++) /* Compare each element of subset and set */
-	{
-		for(set_index=0;set_index < set_count;set_index++)
-		{
-			flag=0;
-			if(sub_set[subset_index]==set[set_index])
-				break;
-			else
-				flag=1; /* No match found */
-		}
-		if(flag==1)
-			return RETURN_ERR; //If value not found return Error
-	}
-
-	if (strlen(TransmitRates) >= sizeof(temp_TransmitRates))
-		return RETURN_ERR;
-
-	memcpy(temp_TransmitRates, TransmitRates, strlen(TransmitRates));
-
-	for(i=0;i<strlen(temp_TransmitRates);i++)
-	{
-	//if (((temp_TransmitRates[i]>=48) && (temp_TransmitRates[i]<=57)) | (temp_TransmitRates[i]==32))
-		if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
-		{
-			continue;
-		}
-		else
-		{
-			return RETURN_ERR;
-		}
-	}
-	temp = strtok(temp_TransmitRates,",");
-	while(temp!=NULL)
-	{
-		if (strlen(temp) >= sizeof(temp1))
-			return RETURN_ERR;
-		strncpy(temp1, temp, strlen(temp));
-		if(band == band_5)
-		{
-			if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
-			{
-				return RETURN_ERR;
-			}
-		}
-
-		if(strcmp(temp,"5.5")==0)
-		{
-			memcpy(temp1, "55", 2);
-		}
-		else
-		{
-			if (strlen(temp1) >= (sizeof(temp1) - 1))
-				return RETURN_ERR;
-			strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
-		}
-		if (strlen(temp1) >= (sizeof(temp_output) - strlen(temp_output)))
-			return RETURN_ERR;
-		strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
-		temp = strtok(NULL,",");
-		if(temp!=NULL)
-		{
-			if (strlen(temp_output) >= (sizeof(temp_output) - 1))
-				return RETURN_ERR;
-			strncat(temp_output," ", sizeof(temp_output) - strlen(temp_output) - 1);
-		}
-	}
-	memcpy(TransmitRates, temp_output, strlen(temp_output));
-	TransmitRates[strlen(temp_output)] = '\0';
-
-	params.name= "basic_rates";
-	params.value =TransmitRates;
-
-	wifi_debug(DEBUG_INFO, "params.value=%s, Transmit rates=%s\n", params.value, TransmitRates);
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file,&params,1);
-	wifi_hostapdProcessUpdate(radioIndex, &params, 1);
-	wifi_quick_reload_ap(radioIndex);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_halGetIfStatsNull(wifi_radioTrafficStats2_t *output_struct)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-	output_struct->radio_BytesSent = 0;
-	output_struct->radio_BytesReceived = 0;
-	output_struct->radio_PacketsSent = 0;
-	output_struct->radio_PacketsReceived = 0;
-	output_struct->radio_ErrorsSent = 0;
-	output_struct->radio_ErrorsReceived = 0;
-	output_struct->radio_DiscardPacketsSent = 0;
-	output_struct->radio_DiscardPacketsReceived = 0;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-
-INT wifi_halGetIfStats(char *ifname, wifi_radioTrafficStats2_t *pStats)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	CHAR Value[MAX_BUF_SIZE] = {0};
-	FILE *fp = NULL;
-	int res;
-	unsigned long ret;
-
-	if (ifname == NULL || strlen(ifname) <= 1)
-		return RETURN_OK;
-
-	res = v_secure_system("ifconfig -a %s > /tmp/Radio_Stats.txt", ifname);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-		return RETURN_ERR;
-	}
-
-	fp = fopen("/tmp/Radio_Stats.txt", "r");
-	if(fp == NULL)
-	{
-		wifi_debug(DEBUG_ERROR, "/tmp/Radio_Stats.txt not exists\n");
-		return RETURN_ERR;
-	}
-	if (fclose(fp) != 0) {
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-	}
-
-	pStats->radio_PacketsReceived = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	pStats->radio_PacketsSent = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX bytes' | tr -s ' ' | cut -d ':' -f2 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	pStats->radio_BytesReceived = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX bytes' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	pStats->radio_BytesSent = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	pStats->radio_ErrorsReceived = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f3 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	pStats->radio_ErrorsSent = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'RX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	pStats->radio_DiscardPacketsReceived = ret;
-
-	res = _syscmd_secure(Value, sizeof(Value), "cat /tmp/Radio_Stats.txt | grep 'TX packets' | tr -s ' ' | cut -d ':' -f4 | cut -d ' ' -f1");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(Value, 10, &ret) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	pStats->radio_DiscardPacketsSent = ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT GetIfacestatus(CHAR *interface_name, CHAR *status)
-{
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	if (interface_name != NULL && (strlen(interface_name) > 1) && status != NULL) {
-
-		res = _syscmd_secure(status, sizeof(status), "ifconfig -a %s | grep %s | wc -l", 
-				interface_name, interface_name);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-int mtk_get_radio_callback(struct nl_msg *msg, void *cb)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_RADIO_STATS_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh;
-	int err = 0;
-	unsigned short len = 0;
-	wifi_radio_stats_t *stats;
-	struct mtk_nl80211_cb_data *cb_data = cb;
-
-	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
-		return NL_SKIP;
-	}
-
-	gnlh = nlmsg_data(nlmsg_hdr(msg));
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
-		return NL_SKIP;
-	}
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_RADIO_STATS_ATTR_MAX ,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_RADIO_STATS]) {
-			len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_RADIO_STATS]);
-			stats = (wifi_radio_stats_t*)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_RADIO_STATS]);
-			if (len != sizeof(*stats)){
-				wifi_debug(DEBUG_ERROR,"result len(%u) is invalid, expected len(%lu)!!!\n", len, sizeof(*stats));
-				return NL_SKIP;
-			}
-			memcpy(cb_data->out_buf, stats, len);
-		} else
-			wifi_debug(DEBUG_ERROR, "no MTK_NL80211_VENDOR_ATTR_RADIO_STATS attr\n");
-	} else
-		wifi_debug(DEBUG_ERROR, "no any station result from driver\n");
-	return NL_OK;
-}
-
-INT mtk_get_radio_stats(INT apIndex, wifi_radio_stats_t *Stats)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param nl_param;
-	struct mtk_nl80211_cb_data cb_data;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-			return RETURN_ERR;
-
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_RADIO_STATS;
-	nl_param.if_type = NL80211_ATTR_IFINDEX;
-	nl_param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_RADIO_STATS)) {
-		wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
-		nlmsg_free(msg);
-		mtk_nl80211_deint(&unl_ins);
-		return RETURN_ERR;
-	}
-	cb_data.out_buf = (void*)Stats;
-	cb_data.out_len =sizeof(wifi_bss_stats_t);
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_radio_callback, &cb_data);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		mtk_nl80211_deint(&unl_ins);
-		return RETURN_ERR;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-
-	return RETURN_OK;
-}
-
-//Get detail radio traffic static info
-INT wifi_getRadioTrafficStats2(INT radioIndex, wifi_radioTrafficStats2_t *output_struct) //Tr181
-{
-	CHAR interface_name[64] = {0};
-	wifi_radio_stats_t radioTrafficStats = {0};
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-	if (NULL == output_struct)
-		return RETURN_ERR;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	mtk_get_radio_stats(main_vap_idx, &radioTrafficStats);
-
-	output_struct->radio_BytesSent = radioTrafficStats.BytesSent;
-	output_struct->radio_BytesReceived = radioTrafficStats.BytesReceived;
-	output_struct->radio_PacketsSent = radioTrafficStats.PacketsSent;
-	output_struct->radio_PacketsReceived = radioTrafficStats.PacketsReceived;
-	output_struct->radio_ErrorsSent = radioTrafficStats.ErrorsSent;
-	output_struct->radio_ErrorsReceived = radioTrafficStats.ErrorsReceived;
-	output_struct->radio_DiscardPacketsSent = radioTrafficStats.DiscardPacketsSent;
-	output_struct->radio_DiscardPacketsReceived = radioTrafficStats.DiscardPacketsReceived;
-
-	output_struct->radio_PLCPErrorCount = 0;				  //The number of packets that were received with a detected Physical Layer Convergence Protocol (PLCP) header error.
-	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].
-	output_struct->radio_InvalidMACCount = 0;				  //The number of packets that were received with a detected invalid MAC header error.
-	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.
-	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
-	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
-	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
-	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
-	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
-
-	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
-	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
-	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
-	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.
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Set radio traffic static Measureing rules
-INT wifi_setRadioTrafficStatsMeasure(INT radioIndex, wifi_radioTrafficStatsMeasure_t *input_struct) //Tr181
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD,
-        sizeof(wifi_radioTrafficStatsMeasure_t), input_struct)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
-            MTK_NL80211_VENDOR_ATTR_RADIO_SET_STATS_MEASURING_METHOD);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-//To start or stop RadioTrafficStats
-INT wifi_setRadioTrafficStatsRadioStatisticsEnable(INT radioIndex, BOOL enable)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_RADIO_STATS;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL, enable)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n",
-            MTK_NL80211_VENDOR_ATTR_RADIO_SET_MEASURE_ENABEL);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-//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
-INT wifi_getRadioStatsReceivedSignalLevel(INT radioIndex, INT signalIndex, INT *SignalLevel) //Tr181
-{
-	if (NULL == SignalLevel)
-		return RETURN_ERR;
-
-	*SignalLevel = -19;
-
-	return RETURN_OK;
-}
-
-//Not all implementations may need this function.  If not needed for a particular implementation simply return no-error (0)
-INT wifi_applyRadioSettings(INT radioIndex)
-{
-	return RETURN_OK;
-}
-
-//Get the radio index assocated with this SSID entry
-INT wifi_getSSIDRadioIndex(INT ssidIndex, INT *radioIndex)
-{
-	int bss_idx;
-
-	if(NULL == radioIndex)
-		return RETURN_ERR;
-
-	if (vap_index_to_radio_array_index(ssidIndex, radioIndex, &bss_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid ssidIndex[%d]\n", ssidIndex);
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Device.WiFi.SSID.{i}.Enable
-//Get SSID enable configuration parameters (not the SSID enable status)
-INT wifi_getSSIDEnable(INT ssidIndex, BOOL *output_bool) //Tr181
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-
-	return wifi_getApEnable(ssidIndex, output_bool);
-}
-
-//Device.WiFi.SSID.{i}.Enable
-//Set SSID enable configuration parameters
-INT wifi_setSSIDEnable(INT ssidIndex, BOOL enable) //Tr181
-{
-	return wifi_setApEnable(ssidIndex, enable);
-}
-
-//Device.WiFi.SSID.{i}.Status
-//Get the SSID enable status
-INT wifi_getSSIDStatus(INT ssidIndex, CHAR *output_string) //Tr181
-{
-	BOOL output_bool = 0;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	wifi_getApEnable(ssidIndex,&output_bool);
-	res = snprintf(output_string, 32, output_bool==1?"Enabled":"Disabled");
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-// Outputs a 32 byte or less string indicating the SSID name.  Sring buffer must be preallocated by the caller.
-INT wifi_getSSIDName(INT apIndex, CHAR *output)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if (NULL == output)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file,"ssid",output, MAX_SSID_NAME_LEN);
-
-	wifi_debug(DEBUG_INFO, "SSID Name is : %s\n", output);
-	return RETURN_OK;
-}
-
-// Set a max 32 byte string and sets an internal variable to the SSID name
-INT wifi_setSSIDName(INT apIndex, CHAR *ssid_string)
-{
-	struct params params;
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-	char ssid[64] = {0};
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(NULL == ssid_string || strlen(ssid_string) > 32 || strlen(ssid_string) == 0 )
-		return RETURN_ERR;
-
-	params.name = "ssid";
-	params.value = ssid_string;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &params, 1);
-
-	res = snprintf(ssid, sizeof(ssid), "\"%s\"", ssid_string);
-	if (os_snprintf_error(sizeof(ssid), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	params.name = "ssid2";
-	params.value = ssid;
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Get the BSSID
-INT wifi_getBaseBSSID(INT ssidIndex, CHAR *output_string)	//RDKB
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	int res;
-
-	if (!output_string)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(ssidIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (ssidIndex < 0 || ssidIndex > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "innvalide ssidIdex(%d)\n", ssidIndex);
-		strncpy(output_string, "\0", 1);
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(output_string,64,"hostapd_cli -i %s get_config | grep bssid | cut -d '=' -f2 | tr -d '\\n'", inf_name);
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	/* if hostapd does not control interface even if this interface has been brought up,
-	 * try to get its mac address by iw command.
-	 */
-	if(strlen(output_string) == 0) {
-		res = _syscmd_secure(output_string, 64, "iw dev %s info | grep \"addr\" | awk \'{print $2}\'", inf_name);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	}
-
-	return RETURN_OK;
-}
-
-//Get the MAC address associated with this Wifi SSID
-INT wifi_getSSIDMACAddress(INT ssidIndex, CHAR *output_string) //Tr181
-{
-	wifi_getBaseBSSID(ssidIndex,output_string);
-	return RETURN_OK;
-}
-
-//Get the basic SSID traffic static info
-//Apply SSID and AP (in the case of Acess Point devices) to the hardware
-//Not all implementations may need this function.  If not needed for a particular implementation simply return no-error (0)
-INT wifi_applySSIDSettings(INT ssidIndex)
-{
-	char interface_name[16] = {0};
-	BOOL status = false;
-	char buf[MAX_CMD_SIZE] = {0};
-	int apIndex, ret;
-	int radioIndex = 0, bss_idx;
-	int res;
-
-	wifi_getApEnable(ssidIndex,&status);
-	// Do not apply when ssid index is disabled
-	if (status == false)
-		return RETURN_OK;
-
-	/* Doing full remove and add for ssid Index
-	 * Not all hostapd options are supported with reload
-	 * for example macaddr_acl
-	 */
-	if(wifi_setApEnable(ssidIndex,false) != RETURN_OK)
-		   return RETURN_ERR;
-
-	ret = wifi_setApEnable(ssidIndex,true);
-
-	/* Workaround for hostapd issue with multiple bss definitions
-	 * when first created interface will be removed
-	 * then all vaps other vaps on same phy are removed
-	 * after calling setApEnable to false readd all enabled vaps */
-	if (vap_index_to_radio_array_index(ssidIndex, &radioIndex, &bss_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid ssidIndex[%d]\n", ssidIndex);
-		return RETURN_ERR;
-	}
-
-	for (bss_idx=0; bss_idx < LOGAN_MAX_NUM_VAP_PER_RADIO; bss_idx++) {
-		if (array_index_to_vap_index(radioIndex, bss_idx, &apIndex) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid radioIndex[%d] bss_idx[%d]\n", radioIndex, bss_idx);
-			continue;
-		}
-		if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-			return RETURN_ERR;
-
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep %s | cut -d'=' -f2", VAP_STATUS_FILE, interface_name);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		if(*buf == '1')
-			   wifi_setApEnable(apIndex, true);
-	}
-
-	return ret;
-}
-
-struct channels_noise {
-	int channel;
-	int noise;
-};
-
-// Return noise array for each channel
-int get_noise(int radioIndex, struct channels_noise *channels_noise_arr, int channels_num)
-{
-	char interface_name[16] = {0};
-	FILE *f = NULL;
-	char cmd[128] = {0};
-	char line[256] = {0};
-	int tmp = 0, arr_index = -1, res;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	f = v_secure_popen("r", "iw dev %s survey dump | grep 'frequency\\|noise' | awk '{print $2}'", interface_name);
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR, "v_secure_popen %s error\n", cmd);
-		return RETURN_ERR;
-	}
-
-	while(fgets(line, sizeof(line), f) != NULL) {
-		if(arr_index < channels_num){
-			if (sscanf(line, "%d", &tmp) == EOF)
-				continue;
-			if (tmp > 0) {	  // channel frequency, the first line must be frequency
-				arr_index++;
-				channels_noise_arr[arr_index].channel = ieee80211_frequency_to_channel(tmp);
-			} else {			// noise
-				channels_noise_arr[arr_index].noise = tmp;
-			}
-		}else{
-			break;
-		}
-	}
-	v_secure_pclose(f);
-	return RETURN_OK;
-}
-
-//Start the wifi scan and get the result into output buffer for RDKB to parser. The result will be used to manage endpoint list
-//HAL funciton should allocate an data structure array, and return to caller with "neighbor_ap_array"
-INT wifi_getNeighboringWiFiDiagnosticResult2(INT radioIndex, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size) //Tr181
-{
-	int index = -1;
-	wifi_neighbor_ap2_t *scan_array = NULL;
-	char cmd[256]={0};
-	char buf[128]={0};
-	char file_name[32] = {0};
-	char filter_SSID[32] = {0};
-	char line[256] = {0};
-	char interface_name[16] = {0};
-	char *ret = NULL;
-	int freq=0;
-	FILE *f = NULL;
-	unsigned long channels_num = 0;
-	int vht_channel_width = 0;
-	int get_noise_ret = RETURN_ERR;
-	bool filter_enable = false;
-	bool filter_BSS = false;	 // The flag determine whether the BSS information need to be filterd.
-	int phyId = 0, res;
-	unsigned long len, tmp;
-	unsigned int DTIM_count;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, main_vap_idx);
-	if (os_snprintf_error(sizeof(file_name), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	f = fopen(file_name, "r");
-	if (f != NULL) {
-		if (fgets(buf, sizeof(file_name), f) == NULL)
-			wifi_debug(DEBUG_ERROR, "fgets failed\n");
-		if ((strncmp(buf, "0", 1)) != 0) {
-			if (fgets(filter_SSID, sizeof(file_name), f) == NULL)
-				wifi_debug(DEBUG_ERROR, "fgets failed\n");
-			if (strlen(filter_SSID) != 0)
-				filter_enable = true;
-		}
-		if (fclose(f) != 0) {
-			wifi_debug(DEBUG_ERROR, "fclose fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	phyId = radio_index_to_phy(radioIndex);
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtoul(buf, 10, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	channels_num = tmp;
-	res = snprintf(cmd, sizeof(cmd), "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
-	// WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_INFO,  "cmd: %s\n", cmd);
-
-	f = v_secure_popen("r", "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
-	// WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
-
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR, "v_secure_popen error\n");
-		return RETURN_ERR;
-	}
-	struct channels_noise *channels_noise_arr = NULL;
-	if(channels_num > 0 && channels_num <= 243){
-		channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
-	} else{
-		wifi_debug(DEBUG_ERROR, "channel num = %ld!!\n", channels_num);
-	}
-
-	if(channels_noise_arr != NULL){
-		get_noise_ret = get_noise(radioIndex, channels_noise_arr, channels_num);
-	} else{
-		wifi_debug(DEBUG_ERROR, "channels_noise_arr is NULL!!\n");
-	}
-
-
-	ret = fgets(line, sizeof(line), f);
-	while (ret != NULL) {
-		if(strstr(line, "BSS") != NULL) {	// new neighbor info
-			// The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
-			// And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
-			// If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
-
-			if (!filter_BSS) {
-				index++;
-				wifi_neighbor_ap2_t *tmp;
-				tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
-				if (tmp == NULL) {			  // no more memory to use
-					index--;
-					wifi_debug(DEBUG_INFO, "realloc failed\n");
-					break;
-				}
-				scan_array = tmp;
-			}
-			memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
-
-			filter_BSS = false;
-			if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				goto err;
-			}
-			memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
-			memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
-			memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
-			memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
-			memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
-			memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
-		} else if (strstr(line, "freq:") != NULL) {
-			if (sscanf(line,"	freq: %d", &freq) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-			}
-
-			scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
-
-			if (freq >= 2412 && freq <= 2484) {
-				memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
-				memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
-				memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
-				memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
-				memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
-				memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
-			}
-			else if (freq >= 5160 && freq <= 5805) {
-				memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
-				memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
-				memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
-				memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
-				memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
-				memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
-			}
-
-			scan_array[index].ap_Noise = 0;
-			if (get_noise_ret == RETURN_OK) {
-				for (int i = 0; i < channels_num; i++) {
-					if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
-						scan_array[index].ap_Noise = channels_noise_arr[i].noise;
-						break;
-					}
-				}
-			}
-		} else if (strstr(line, "beacon interval") != NULL) {
-			if (sscanf(line,"	beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				goto err;
-			}
-		} else if (strstr(line, "signal") != NULL) {
-			if (sscanf(line,"	signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				goto err;
-			}
-		} else if (strstr(line,"	SSID:") != NULL) {
-			if (sscanf(line,"	SSID: %32s", scan_array[index].ap_SSID) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				//goto err;
-			}
-			if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) != 0) {
-				filter_BSS = true;
-			}
-		} else if (strstr(line, "Supported rates") != NULL) {
-			char SRate[80] = {0}, *tmp = NULL;
-			memset(buf, 0, sizeof(buf));
-			if (strlen(line) >= sizeof(SRate))
-				goto err;
-			strncpy(SRate, line, strlen(line));
-			tmp = strtok(SRate, ":");
-			if (tmp == NULL)
-				goto err;
-			tmp = strtok(NULL, ":");
-			if (tmp == NULL)
-				goto err;
-			if (strlen(tmp) >= sizeof(buf))
-				goto err;
-			strncpy(buf, tmp, strlen(tmp));
-			memset(SRate, 0, sizeof(SRate));
-
-			tmp = strtok(buf, " \n");
-			while (tmp != NULL) {
-				if (strlen(tmp) >= (sizeof(SRate) - strlen(SRate)))
-					goto err;
-				strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
-				if (SRate[strlen(SRate) - 1] == '*') {
-					SRate[strlen(SRate) - 1] = '\0';
-				}
-				if (strlen(SRate) >= (sizeof(SRate) - 1))
-					goto err;
-				strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
-
-				tmp = strtok(NULL, " \n");
-			}
-			SRate[strlen(SRate) - 1] = '\0';
-			if (sizeof(scan_array[index].ap_SupportedDataTransferRates) <= strlen(SRate))
-				goto err;
-			strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, strlen(SRate));
-		} else if (strstr(line, "DTIM") != NULL) {
-			if (sscanf(line,"	TIM: DTIM Count %u DTIM Period %u", &DTIM_count, &(scan_array[index].ap_DTIMPeriod)) != 2) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-			}
-		} else if (strstr(line, "VHT capabilities") != NULL) {
-			if (sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) <= 4)
-				goto err;
-			strncat(scan_array[index].ap_SupportedStandards, ",ac",
-				sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
-			memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
-			scan_array[index].ap_OperatingStandards[2] = '\0';
-		} else if (strstr(line, "HT capabilities") != NULL) {
-			strncat(scan_array[index].ap_SupportedStandards, ",n", sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
-			memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
-			scan_array[index].ap_OperatingStandards[1] = '\0';
-		} else if (strstr(line, "VHT operation") != NULL) {
-			if (fgets(line, sizeof(line), f) == NULL) 	{
-				wifi_debug(DEBUG_ERROR, "fgets fail\n");
-				break;
-			}
-			if (sscanf(line,"		 * channel width: %d", &vht_channel_width) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				goto err;
-			}
-			if(vht_channel_width == 1) {
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
-			} else {
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
-			}
-			if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				goto err;
-			}
-
-			if (strstr(line, "BSS") != NULL)   // prevent to get the next neighbor information
-				continue;
-		} else if (strstr(line, "HT operation") != NULL) {
-			if (fgets(line, sizeof(line), f) == NULL) 	{
-				wifi_debug(DEBUG_ERROR, "fgets fail\n");
-				break;
-			}
-			if (sscanf(line,"		 * secondary channel offset: %127s", buf) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				goto err;
-			}
-			if (!strcmp(buf, "above")) {
-				//40Mhz +
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radioIndex%1 ? "A": "G");
-			}
-			else if (!strcmp(buf, "below")) {
-				//40Mhz -
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radioIndex%1 ? "A": "G");
-			} else {
-				//20Mhz
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radioIndex%1 ? "A": "G");
-			}
-			if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				goto err;
-			}
-
-			if (strstr(line, "BSS") != NULL)   // prevent to get the next neighbor information
-				continue;
-		} else if (strstr(line, "HE capabilities") != NULL) {
-			strncat(scan_array[index].ap_SupportedStandards, ",ax",
-				sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
-			memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
-			scan_array[index].ap_OperatingStandards[2] = '\0';
-			if (fgets(line, sizeof(line), f) == NULL) 	{
-				wifi_debug(DEBUG_ERROR, "fgets fail\n");
-				break;
-			}
-			if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
-				if (strstr(line, "HE40/2.4GHz") != NULL) {
-					len = strlen("11AXHE40PLUS");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
-				} else {
-					len = strlen("11AXHE20");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
-				}
-				scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
-			} else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
-				if (strstr(line, "HE80/5GHz") != NULL) {
-					len = strlen("11AXHE80");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
-					scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
-					if (fgets(line, sizeof(line), f) == NULL) 	{
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						break;
-					}
-				} else
-					continue;
-				if (strstr(line, "HE160/5GHz") != NULL) {
-					len = strlen("11AXHE160");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
-					scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
-				}
-			}
-			continue;
-		} else if (strstr(line, "WPA") != NULL) {
-			memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
-			scan_array[index].ap_SecurityModeEnabled[3] = '\0';
-		} else if (strstr(line, "RSN") != NULL) {
-			memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
-			scan_array[index].ap_SecurityModeEnabled[3] = '\0';
-		} else if (strstr(line, "Group cipher") != NULL) {
-			if (sscanf(line, "		 * Group cipher: %64s", scan_array[index].ap_EncryptionMode) != 1) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				goto err;
-			}
-			if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
-				memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
-				scan_array[index].ap_EncryptionMode[3] = '\0';
-			}
-		}
-		ret = fgets(line, sizeof(line), f);
-	}
-
-	if (!filter_BSS) {
-		*output_array_size = index + 1;
-	} else {
-		memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
-		*output_array_size = index;
-	}
-	*neighbor_ap_array = scan_array;
-	v_secure_pclose(f);
-	free(channels_noise_arr);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	v_secure_pclose(f);
-	free(channels_noise_arr);
-	if (scan_array)
-		free(scan_array);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_ERR;
-}
-int mtk_get_bss_callback(struct nl_msg *msg, void *cb)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_STATS_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh;
-	int err = 0;
-	unsigned short len = 0;
-	wifi_bss_stats_t *stats;
-	struct mtk_nl80211_cb_data *cb_data = cb;
-
-	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
-		return NL_SKIP;
-	}
-
-	gnlh = nlmsg_data(nlmsg_hdr(msg));
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
-		return NL_SKIP;
-	}
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_BSS_STATS_ATTR_MAX ,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_STATS]) {
-			len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_STATS]);
-			stats = (wifi_bss_stats_t*)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_BSS_STATS]);
-			if (len != sizeof(*stats)){
-				wifi_debug(DEBUG_ERROR,"result len(%u) is invalid, expected len(%lu)!!!\n", len, sizeof(*stats));
-				return NL_SKIP;
-			}
-			memcpy(cb_data->out_buf, stats, len);
-		} else
-			wifi_debug(DEBUG_ERROR, "no MTK_NL80211_VENDOR_ATTR_BSS_STATS attr\n");
-	} else
-		wifi_debug(DEBUG_ERROR, "no any station result from driver\n");
-	return NL_OK;
-}
-
-INT mtk_get_ssid_stats(INT apIndex, wifi_bss_stats_t *Stats)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param nl_param;
-	struct mtk_nl80211_cb_data cb_data;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-			return RETURN_ERR;
-
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_BSS_STATS;
-	nl_param.if_type = NL80211_ATTR_IFINDEX;
-	nl_param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_BSS_STATS)) {
-		wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
-		nlmsg_free(msg);
-		mtk_nl80211_deint(&unl_ins);
-		return RETURN_ERR;
-	}
-	cb_data.out_buf = (void*)Stats;
-	cb_data.out_len =sizeof(wifi_bss_stats_t);
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_bss_callback, &cb_data);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		mtk_nl80211_deint(&unl_ins);
-		return RETURN_ERR;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-
-	return RETURN_OK;
-}
-
-//>> Deprecated: used for old RDKB code.
-INT wifi_getRadioWifiTrafficStats(INT radioIndex, wifi_radioTrafficStats_t *output_struct)
-{
-	INT status = RETURN_ERR;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	output_struct->wifi_PLCPErrorCount = 0;
-	output_struct->wifi_FCSErrorCount = 0;
-	output_struct->wifi_InvalidMACCount = 0;
-	output_struct->wifi_PacketsOtherReceived = 0;
-	output_struct->wifi_Noise = 0;
-	status = RETURN_OK;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return status;
-}
-
-INT wifi_getBasicTrafficStats(INT apIndex, wifi_basicTrafficStats_t *output_struct)
-{
-	char interface_name[16] = {0};
-	int res;
-	wifi_bss_stats_t stat;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_struct)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	memset(output_struct, 0, sizeof(wifi_basicTrafficStats_t));
-	res = mtk_get_ssid_stats(apIndex, &stat);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "cmd_fail\n");
-	}
-
-	output_struct->wifi_PacketsReceived = stat.PacketsSent;
-	output_struct->wifi_PacketsSent = stat.PacketsSent;
-	output_struct->wifi_BytesReceived = stat.BytesReceived;
-	output_struct->wifi_BytesSent = stat.BytesSent;
-
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getWifiTrafficStats(INT apIndex, wifi_trafficStats_t *output_struct)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	char interface_status[MAX_BUF_SIZE] = {0};
-	int res;
-	wifi_bss_stats_t stat;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == output_struct)
-		return RETURN_ERR;
-
-	memset(output_struct, 0, sizeof(wifi_trafficStats_t));
-
-	if (wifi_GetInterfaceName(apIndex,interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	GetIfacestatus(interface_name, interface_status);
-
-	if(0 != strncmp(interface_status, "1", 1))
-		return RETURN_ERR;
-
-	res = mtk_get_ssid_stats(apIndex, &stat);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "cmd_fail\n");
-	}
-
-	output_struct->wifi_ErrorsReceived = stat.ErrorsReceived;
-	output_struct->wifi_ErrorsSent = stat.ErrorsSent;
-	output_struct->wifi_DiscardedPacketsReceived = stat.DiscardPacketsReceived;
-	output_struct->wifi_DiscardedPacketsSent = stat.DiscardPacketsSent;
-	output_struct->wifi_UnicastPacketsSent = stat.UnicastPacketsSent;
-	output_struct->wifi_UnicastPacketsReceived = stat.UnicastPacketsReceived;
-	output_struct->wifi_MulticastPacketsSent = stat.MulticastPacketsSent;
-	output_struct->wifi_MulticastPacketsReceived = stat.MulticastPacketsReceived;
-	output_struct->wifi_BroadcastPacketsSent = stat.BroadcastPacketsSent;
-	output_struct->wifi_BroadcastPacketsRecevied = stat.BroadcastPacketsReceived;
-	output_struct->wifi_UnknownPacketsReceived = stat.UnknownProtoPacketsReceived;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getSSIDTrafficStats(INT apIndex, wifi_ssidTrafficStats_t *output_struct)
-{
-	INT status = RETURN_ERR;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	//Below values should get updated from hal
-	output_struct->wifi_RetransCount=0;
-	output_struct->wifi_FailedRetransCount=0;
-	output_struct->wifi_RetryCount=0;
-	output_struct->wifi_MultipleRetryCount=0;
-	output_struct->wifi_ACKFailureCount=0;
-	output_struct->wifi_AggregatedPacketCount=0;
-
-	status = RETURN_OK;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return status;
-}
-
-INT wifi_getNeighboringWiFiDiagnosticResult(wifi_neighbor_ap_t **neighbor_ap_array, UINT *output_array_size)
-{
-	INT status = RETURN_ERR;
-	UINT index;
-	wifi_neighbor_ap_t *pt=NULL;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	*output_array_size=2;
-	//zqiu: HAL alloc the array and return to caller. Caller response to free it.
-	*neighbor_ap_array=(wifi_neighbor_ap_t *)calloc(sizeof(wifi_neighbor_ap_t), *output_array_size);
-	if (*neighbor_ap_array == NULL) {
-		wifi_debug(DEBUG_ERROR, "calloc fail!\n");
-		return RETURN_ERR;
-	}
-	for (index = 0, pt=*neighbor_ap_array; index < *output_array_size; index++, pt++) {
-		pt->ap_Radio[0] = '\0';
-		pt->ap_SSID[0] = '\0';
-		pt->ap_BSSID[0] = '\0';
-		pt->ap_Mode[0] = '\0';
-		pt->ap_Channel=1;
-		pt->ap_SignalStrength=0;
-		pt->ap_SecurityModeEnabled[0] = '\0';
-		pt->ap_EncryptionMode[0] = '\0';
-		pt->ap_OperatingFrequencyBand[0] = '\0';
-		pt->ap_SupportedStandards[0] = '\0';
-		pt->ap_OperatingStandards[0] = '\0';
-		pt->ap_OperatingChannelBandwidth[0] = '\0';
-		pt->ap_BasicDataTransferRates[0] = '\0';
-		pt->ap_SupportedDataTransferRates[0] = '\0';
-		pt->ap_BeaconPeriod=1;
-		pt->ap_Noise=0;
-		pt->ap_DTIMPeriod=1;
-		pt->ap_ChannelUtilization = 1;
-	}
-
-	status = RETURN_OK;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return status;
-}
-
-//----------------- AP HAL -------------------------------
-
-//>> Deprecated: used for old RDKB code.
-INT wifi_getAllAssociatedDeviceDetail(INT apIndex, ULONG *output_ulong, wifi_device_t **output_struct)
-{
-	if (NULL == output_ulong || NULL == output_struct)
-		return RETURN_ERR;
-	*output_ulong = 0;
-	*output_struct = NULL;
-	return RETURN_OK;
-}
-
-#ifdef HAL_NETLINK_IMPL
-static int AssoDevInfo_callback(struct nl_msg *msg, void *arg) {
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
-	struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
-	char mac_addr[20];
-	static int count=0;
-	int rate=0;
-
-	wifi_device_info_t *out = (wifi_device_info_t*)arg;
-
-	nla_parse(tb,
-			  NL80211_ATTR_MAX,
-			  genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0),
-			  NULL);
-
-	if(!tb[NL80211_ATTR_STA_INFO]) {
-		wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
-		return NL_SKIP;
-	}
-
-
-	if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
-		wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
-		return NL_SKIP;
-	}
-
-	//devIndex starts from 1
-	if( ++count == out->wifi_devIndex )
-	{
-		mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
-		//Getting the mac addrress
-		mac_addr_aton(out->wifi_devMacAddress,mac_addr);
-		if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
-			if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
-				wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
-				return NL_SKIP;
-			}
-		}
-
-		if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
-			if(rinfo[NL80211_RATE_INFO_BITRATE]) {
-				rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
-				out->wifi_devTxRate = rate/10;
-			}
-		}
-
-		if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
-			if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy)) {
-				wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
-				return NL_SKIP;
-			}
-		}
-		if(sinfo[NL80211_STA_INFO_RX_BITRATE]) {
-			if(rinfo[NL80211_RATE_INFO_BITRATE]) {
-				rate=nla_get_u16(rinfo[NL80211_RATE_INFO_BITRATE]);
-				out->wifi_devRxRate = rate/10;
-			}
-		}
-		if(sinfo[NL80211_STA_INFO_SIGNAL_AVG])
-			out->wifi_devSignalStrength = (int8_t)nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL_AVG]);
-
-		out->wifi_devAssociatedDeviceAuthentiationState = 1;
-		count = 0; //starts the count for next cycle
-		return NL_STOP;
-	}
-
-	return NL_SKIP;
-
-}
-#endif
-
-INT wifi_getAssociatedDeviceDetail(INT apIndex, INT devIndex, wifi_device_t *output_struct)
-{
-	Netlink nl = {0};
-	char if_name[IF_NAME_SIZE] = {0};
-	char interface_name[16] = {0};
-	int res;
-
-	wifi_device_info_t info = {0};
-	info.wifi_devIndex = devIndex;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = snprintf(if_name,sizeof(if_name),"%s", interface_name);
-	if (os_snprintf_error(sizeof(if_name), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	nl.id = initSock80211(&nl);
-
-	if (nl.id < 0) {
-		wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
-		return -1;
-	}
-
-	struct nl_msg* msg = nlmsg_alloc();
-
-	if (!msg) {
-		wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
-		nlfree(&nl);
-		return -2;
-	}
-
-	genlmsg_put(msg,
-				NL_AUTO_PID,
-				NL_AUTO_SEQ,
-				nl.id,
-				0,
-				NLM_F_DUMP,
-				NL80211_CMD_GET_STATION,
-				0);
-
-	nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
-	nl_send_auto_complete(nl.socket, msg);
-	nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,AssoDevInfo_callback,&info);
-	nl_recvmsgs(nl.socket, nl.cb);
-	nlmsg_free(msg);
-	nlfree(&nl);
-
-	output_struct->wifi_devAssociatedDeviceAuthentiationState = info.wifi_devAssociatedDeviceAuthentiationState;
-	output_struct->wifi_devRxRate = info.wifi_devRxRate;
-	output_struct->wifi_devTxRate = info.wifi_devTxRate;
-	output_struct->wifi_devSignalStrength = info.wifi_devSignalStrength;
-	memcpy(&output_struct->wifi_devMacAddress, &info.wifi_devMacAddress, sizeof(info.wifi_devMacAddress));
-	return RETURN_OK;
-}
-
-INT wifi_kickAssociatedDevice(INT apIndex, wifi_device_t *device)
-{
-	if (NULL == device)
-		return RETURN_ERR;
-	return RETURN_OK;
-}
-//<<
-
-
-//--------------wifi_ap_hal-----------------------------
-//enables CTS protection for the radio used by this AP
-INT wifi_setRadioCtsProtectionEnable(INT apIndex, BOOL enable)
-{
-	//save config and Apply instantly
-	return RETURN_ERR;
-}
-
-// enables OBSS Coexistence - fall back to 20MHz if necessary for the radio used by this ap
-INT wifi_setRadioObssCoexistenceEnable(INT apIndex, BOOL enable)
-{
-	char config_file[64] = {'\0'};
-	char config_dat_file[64] = {'\0'};
-	char buf[64] = {'\0'};
-	struct params list = {0};
-	struct params dat = {0};
-	wifi_band band = band_invalid;
-	int res;
-	unsigned char ht_coex = 0;
-	int ret = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (enable)
-		ht_coex = 1;
-
-	list.name = "ht_coex";
-	res = snprintf(buf, sizeof(buf), "%d", enable);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	list.value = buf;
-
-	dat.name = "HT_BSSCoexistence";
-	dat.value = buf;
-
-	band = wifi_index_to_band(apIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_dat_file, sizeof(config_dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_datfileWrite(config_dat_file, &dat, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-
-	/*do ht_coex quick setting*/
-	ret = wifi_setChannel_netlink(band, NULL, NULL, NULL, &ht_coex);
-	if (ret != RETURN_OK)
-		wifi_debug(DEBUG_ERROR, "ht_coex quick setting fail\n");
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//P3 // sets the fragmentation threshold in bytes for the radio used by this ap
-INT wifi_setRadioFragmentationThreshold(INT apIndex, UINT threshold)
-{
-	char config_file[MAX_BUF_SIZE] = {'\0'};
-	char buf[MAX_BUF_SIZE] = {'\0'};
-	struct params list;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (threshold < 256 || threshold > 2346 )
-		return RETURN_ERR;
-	list.name = "fragm_threshold";
-	res = snprintf(buf, sizeof(buf), "%d", threshold);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	list.value = buf;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// enable STBC mode in the hardwarwe, 0 == not enabled, 1 == enabled
-INT wifi_setRadioSTBCEnable(INT radioIndex, BOOL STBC_Enable)
-{
-	char config_file[64] = {'\0'};
-
-	char buf[512] = {'\0'};
-	wifi_band band;
-	int iterator = 0;
-	int ant_count = 0;
-	int ant_bitmap = 0;
-	struct params list;
-	char dat_file[64] = {'\0'};
-	int res, main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_invalid)
-		return RETURN_ERR;
-
-	if (band == band_2_4)
-		iterator = 1;
-	else if ((band == band_5) || (band == band_6))
-		iterator = 2;
-	else
-		return RETURN_OK;
-
-	wifi_getRadioTxChainMask(radioIndex, &ant_bitmap);
-	for (; ant_bitmap > 0; ant_bitmap >>= 1)
-		ant_count += ant_bitmap & 1;
-
-	if (ant_count == 1 && STBC_Enable == TRUE) {
-		wifi_debug(DEBUG_ERROR, "can not enable STBC when using only one antenna\n");
-		return RETURN_OK;
-	}
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	// set ht and vht config
-	for (int i = 0; i < iterator; i++) {
-
-		memset(buf, 0, sizeof(buf));
-		list.name = (i == 0)?"ht_capab":"vht_capab";
-		if (STBC_Enable == TRUE) {
-			// Append the STBC flags in capab config
-
-			if (i == 0)
-				res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC][RX-STBC1]/' %s", config_file);
-			else
-				res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1][RX-STBC-1]/' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-		} else if (STBC_Enable == FALSE) {
-			// Remove the STBC flags and remain other flags in capab
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[RX-STBC-?[1-3]*\\]//' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-		}
-		wifi_hostapdRead(config_file, list.name, buf, sizeof(buf));
-		list.value = buf;
-		wifi_hostapdProcessUpdate(radioIndex, &list, 1);
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^HT_STBC=.*/HT_STBC=%d/g' %s", STBC_Enable, dat_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if ((band == band_5) || (band == band_6)) {
-		res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^VHT_STBC=.*/VHT_STBC=%d/g' %s", STBC_Enable, dat_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-	}
-	/*wifi_reloadAp(radioIndex);
-	the caller do this.*/
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-int mtk_get_ap_amsdu_callback(struct nl_msg *msg, void *data) {
-    struct nlattr *tb[NL80211_ATTR_MAX + 1];
-    struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX + 1];
-    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-    unsigned char status;
-    unsigned char *out_status = data;
-    int err = 0;
-
-    err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-              genlmsg_attrlen(gnlh, 0), NULL);
-    if (err < 0){
-        wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-        return err;
-    }
-
-    if (tb[NL80211_ATTR_VENDOR_DATA]) {
-        err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX,
-            tb[NL80211_ATTR_VENDOR_DATA], NULL);
-        if (err < 0){
-            wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
-            return err;
-        }
-
-        if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN]) {
-            status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN]);
-            if (status == 0) {
-                wifi_debug(DEBUG_INFO, "disabled\n");
-            } else {
-                wifi_debug(DEBUG_INFO, "enabled\n");
-            }
-            *out_status = status;
-        }
-    }
-    return 0;
-}
-
-// outputs A-MSDU enable status, 0 == not enabled, 1 == enabled
-INT wifi_getRadioAMSDUEnable(INT radioIndex, BOOL *output_bool)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN, 0xf)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_amsdu_callback, output_bool);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO,"send cmd success, get output_bool:%d\n", *output_bool);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-// enables A-MSDU in the hardware, 0 == not enabled, 1 == enabled
-INT wifi_setRadioAMSDUEnable(INT radioIndex, BOOL amsduEnable)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int ret = -1;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN, amsduEnable)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-//P2  // outputs the number of Tx streams
-INT wifi_getRadioTxChainMask(INT radioIndex, INT *output_int)
-{
-	char buf[8] = {0};
-	int phyId = 0;
-	int res;
-	long int tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	phyId = radio_index_to_phy(radioIndex);
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'Configured Antennas' | awk '{print $4}'", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-
-	if (hal_strtol(buf, 16, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	*output_int = tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT fitChainMask(INT radioIndex, int antcount)
-{
-	char buf[128] = {0};
-
-	char config_file[64] = {0};
-	wifi_band band;
-	struct params list[2] = {0};
-	int res, main_vap_idx;
-
-	band = radio_index_to_band(radioIndex);
-	if (band == band_invalid)
-		return RETURN_ERR;
-
-	list[0].name = "he_mu_beamformer";
-	list[1].name = "he_su_beamformer";
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (antcount == 1) {
-		// remove config about multiple antennas
-		res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[TX-STBC(-2BY1)?*\\]//' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[SOUNDING-DIMENSION-.\\]//' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[SU-BEAMFORMER\\]//' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[MU-BEAMFORMER\\]//' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		list[0].value = "0";
-		list[1].value = "0";
-	} else {
-		// 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.
-		if (band == band_2_4 || band == band_5) {
-			res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '^ht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-
-			if (strlen(buf) > 0) {
-				res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^ht_capab=.*/s/$/[TX-STBC]/' %s", config_file);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-				}
-			}
-		}
-		if (band == band_5) {
-			res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '^vht_capab=.*RX-STBC' | grep -v 'TX-STBC'", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-			if (strlen(buf) > 0) {
-				res = _syscmd_secure(buf, sizeof(buf) , "sed -r -i '/^vht_capab=.*/s/$/[TX-STBC-2BY1]/' %s", config_file);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-				}
-			}
-		}
-
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '\\[SU-BEAMFORMER\\]'", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		if (strlen(buf) == 0) {
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[SU-BEAMFORMER]/' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '\\[MU-BEAMFORMER\\]'", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		if (strlen(buf) == 0) {
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[MU-BEAMFORMER]/' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '\\[SOUNDING-DIMENSION-.\\]'", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		if (strlen(buf) == 0) {
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[SOUNDING-DIMENSION-%d]/' %s", antcount, config_file);
-		} else {
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/(SOUNDING-DIMENSION-)./\\1%d/' %s", antcount, config_file);
-		}
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		list[0].value = "1";
-		list[1].value = "1";
-	}
-	wifi_hostapdWrite(config_file, list, 2);
-	return RETURN_OK;
-}
-
-//P2  // sets the number of Tx streams to an enviornment variable
-INT wifi_setRadioTxChainMask(INT radioIndex, INT numStreams)
-{
-	char cmd[128] = {0};
-	char buf[128] = {0};
-	int phyId = 0;
-	int cur_mask = 0;
-	int antcountmsk = 0;
-	INT cur_nss = 0;
-	CHAR dat_file[64] = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (numStreams <= 0) {
-		wifi_debug(DEBUG_ERROR, "chainmask is not supported %d.\n", numStreams);
-		return RETURN_ERR;
-	}
-
-	wifi_getRadioTxChainMask(radioIndex, &cur_mask);//this is mask value
-	for(; cur_mask > 0; cur_mask >>= 1)//convert to number of streams.
-		cur_nss += 1;
-	WIFI_ENTRY_EXIT_DEBUG("%s:cur_nss=%d, new_nss=%d\n", __func__, cur_nss, numStreams);
-	if (cur_nss == numStreams)
-		return RETURN_OK;
-
-	wifi_setRadioEnable(radioIndex, FALSE);
-
-	phyId = radio_index_to_phy(radioIndex);
-	//iw need mask value.
-	for (;numStreams > 0; numStreams--)
-		antcountmsk |= 0x1 << (numStreams - 1);
-	res = snprintf(cmd, sizeof(cmd), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res=_syscmd_secure(buf, sizeof(buf), "iw phy%d set antenna 0x%x 2>&1", phyId, antcountmsk);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) > 0) {
-		wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
-		return RETURN_ERR;
-	}
-	band = radio_index_to_band(radioIndex);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "Band Error\n");
-		return RETURN_ERR;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-        res=_syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^HT_TxStream=.*/HT_TxStream=%d/g' %s", numStreams, dat_file);
-        if (res) {
-                wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-        }
-
-	if (strlen(buf) > 0) {
-		wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(cmd, sizeof(cmd), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-        res=_syscmd_secure(buf, sizeof(buf), "sed -r -i 's/^HT_RxStream=.*/HT_RxStream=%d/g' %s", numStreams, dat_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) > 0) {
-		wifi_debug(DEBUG_ERROR, "cmd %s error, output: %s\n", cmd, buf);
-		return RETURN_ERR;
-	}
-	fitChainMask(radioIndex, numStreams);
-	wifi_setRadioEnable(radioIndex, TRUE);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//P2  // outputs the number of Rx streams
-INT wifi_getRadioRxChainMask(INT radioIndex, INT *output_int)
-{
-	char buf[8] = {0};
-	int phyId = 0;
-	int res;
-	long int tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	phyId = radio_index_to_phy(radioIndex);
-
-	res=_syscmd_secure(buf, sizeof(buf), "iw phy%d info | grep 'Configured Antennas' | awk '{print $6}'", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (hal_strtol(buf, 16, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-	*output_int = tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//P2  // sets the number of Rx streams to an enviornment variable
-INT wifi_setRadioRxChainMask(INT radioIndex, INT numStreams)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (wifi_setRadioTxChainMask(radioIndex, numStreams) == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "wifi_setRadioTxChainMask return error.\n");
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_ERR;
-}
-
-//Get radio RDG enable setting
-INT wifi_getRadioReverseDirectionGrantSupported(INT radioIndex, BOOL *output_bool)
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-
-	*output_bool = TRUE;
-	return RETURN_OK;
-}
-
-//Get radio RDG enable setting
-INT wifi_getRadioReverseDirectionGrantEnable(INT radioIndex, BOOL *output_bool)
-{
-	char rdg_status[2] = {0};
-	char dat_file[MAX_CMD_SIZE] = {0};
-	int res;
-
-	if (NULL == output_bool)
-		return RETURN_ERR;
-
-	/*prepare dat file path*/
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_datfileRead(dat_file, "HT_RDG", rdg_status, sizeof(rdg_status));
-	if (!strncmp(rdg_status, "1", sizeof(rdg_status)))
-		*output_bool = TRUE;
-	else
-		*output_bool = FALSE;
-
-	return RETURN_OK;
-}
-
-//Set radio RDG enable setting
-INT wifi_setRadioReverseDirectionGrantEnable(INT radioIndex, BOOL enable)
-{
-	char dat_file[MAX_CMD_SIZE] = {0};
-	struct params params = {0};
-	int res;
-
-	/*prepare dat file path*/
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, radioIndex);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	params.name = "HT_RDG";
-
-	if (enable) {
-		params.value = "1";
-	} else {
-		params.value = "0";
-	}
-
-	wifi_datfileWrite(dat_file, &params, 1);
-
-	return RETURN_OK;
-}
-
-
-int mtk_get_ba_auto_status_callback(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char status;
-	unsigned char *out_status = data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0){
-		wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-		return err;
-	}
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0){
-			wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
-			return err;
-		}
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]) {
-			status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO]);
-			if (status == 0) {
-				wifi_debug(DEBUG_NOTICE, "disabled\n");
-			} else {
-				wifi_debug(DEBUG_NOTICE, "enabled\n");
-			}
-			*out_status = status;
-		}
-	}
-
-	return 0;
-}
-
-int mtk_get_ba_decline_status_callback(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BA_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char status;
-	unsigned char *out_status = data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-		return err;
-	}
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BA_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0) {
-			wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
-			return err;
-		}
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]) {
-			status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO]);
-			if (status == 0) {
-				wifi_debug(DEBUG_NOTICE, "disabled\n");
-			} else {
-				wifi_debug(DEBUG_NOTICE, "enabled\n");
-			}
-			*out_status = status;
-		}
-	}
-
-	return NL_OK;
-}
-
-INT mtk_wifi_get_ba_decl_auto_status(
-	INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back, BOOL *output_bool)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, vendor_data_attr, 0xf)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO,"send cmd success, get output_bool:%d\n", *output_bool);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-INT mtk_wifi_set_auto_ba_en(
-	INT apIndex, INT vendor_data_attr, BOOL enable)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_BA;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, vendor_data_attr, enable)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-//Get radio ADDBA enable setting
-INT wifi_getRadioDeclineBARequestEnable(INT radioIndex, BOOL *output_bool)
-{
-	if (output_bool == NULL) {
-		wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
-		return RETURN_ERR;
-	}
-	if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
-	 	MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO, mtk_get_ba_decline_status_callback, output_bool) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "cmd MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO(0x%x) fails\n",
-			MTK_NL80211_VENDOR_ATTR_AP_BA_DECLINE_INFO);
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_NOTICE, "cmd success:output_bool(%d)\n", *output_bool);
-	return RETURN_OK;
-}
-
-//Set radio ADDBA enable setting
-INT wifi_setRadioDeclineBARequestEnable(INT radioIndex, BOOL enable)
-{
-	return RETURN_ERR;
-}
-
-//Get radio auto block ack enable setting
-INT wifi_getRadioAutoBlockAckEnable(INT radioIndex, BOOL *output_bool)
-{
-	if (output_bool == NULL) {
-		wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
-		return RETURN_ERR;
-	}
-
-	if (mtk_wifi_get_ba_decl_auto_status(radioIndex,
-	 	MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO,
-	 	mtk_get_ba_auto_status_callback, output_bool) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "cmd  MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO(0x%x) fails\n",
-			MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO);
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_INFO, "cmd success:output_bool(%d)\n", *output_bool);
-	return RETURN_OK;
-}
-
-//Set radio auto block ack enable setting
-INT wifi_setRadioAutoBlockAckEnable(INT radioIndex, BOOL enable)
-{
-	if (mtk_wifi_set_auto_ba_en
-		(radioIndex, MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO, enable) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send  MTK_NL80211_VENDOR_ATTR_AP_BA_EN_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_ERROR, "send cmd success: set auto ba enable(%d)\n", enable);
-	return RETURN_OK;
-}
-
-//Get radio 11n pure mode enable support
-INT wifi_getRadio11nGreenfieldSupported(INT radioIndex, BOOL *output_bool)
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-	*output_bool = TRUE;
-	return RETURN_OK;
-}
-
-//Get radio 11n pure mode enable setting
-INT wifi_getRadio11nGreenfieldEnable(INT radioIndex, BOOL *output_bool)
-{
-	if (NULL == output_bool)
-		return RETURN_ERR;
-	*output_bool = TRUE;
-	return RETURN_OK;
-}
-
-//Set radio 11n pure mode enable setting
-INT wifi_setRadio11nGreenfieldEnable(INT radioIndex, BOOL enable)
-{
-	char interface_name[16] = {0};
-	int if_idx, ret = 0;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-	int main_vap_idx;
-
-	if (radioIndex > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", radioIndex);
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_HT_OP_MODE, enable)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set Gf cmd success.\n");
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-int mtk_get_igmp_status_callback(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char status = 0, *out_status = data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-		return err;
-	}
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0){
-			wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_MCAST_SNOOP_ATTR_MAX fails\n");
-			return err;
-		}
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]) {
-			status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE]);
-			if (status == 0) {
-				wifi_debug(DEBUG_NOTICE, "disabled\n");
-			} else {
-				wifi_debug(DEBUG_NOTICE, "enabled\n");
-			}
-			*out_status = status;
-			wifi_debug(DEBUG_NOTICE, "status: %d\n", *out_status);
-		}
-	}
-
-	return 0;
-}
-
-INT mtk_wifi_set_igmp_en_status(
-	INT apIndex, INT vendor_data_attr, mtk_nl80211_cb call_back,
-	unsigned char in_en_stat, BOOL *output_bool)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_MULTICAST_SNOOPING;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, vendor_data_attr, in_en_stat)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output_bool);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	if (output_bool) {
-		wifi_debug(DEBUG_NOTICE, "send cmd success, get output_bool:%d\n", *output_bool);
-	} else {
-		wifi_debug(DEBUG_NOTICE, "send cmd success.\n");
-	}
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-
-//Get radio IGMP snooping enable setting
-INT wifi_getRadioIGMPSnoopingEnable(INT radioIndex, BOOL *output_bool)
-{
-	if (output_bool == NULL) {
-		wifi_debug(DEBUG_ERROR, "invalid: output_bool is null\n");
-		return RETURN_ERR;
-	}
-	if (mtk_wifi_set_igmp_en_status
-		(radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
-		mtk_get_igmp_status_callback, 0xf, output_bool)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_INFO, "send cmd success: get igmp status:(%d)\n", *output_bool);
-	return RETURN_OK;
-}
-
-//Set radio IGMP snooping enable setting
-INT wifi_setRadioIGMPSnoopingEnable(INT radioIndex, BOOL enable)
-{
-	if (mtk_wifi_set_igmp_en_status
-		(radioIndex, MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE,
-		NULL, enable, NULL) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send  MTK_NL80211_VENDOR_ATTR_MCAST_SNOOP_ENABLE cmd fails\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_INFO, "send cmd success: set igmp enable(%d)\n", enable);
-	return RETURN_OK;
-}
-
-//Get the Reset count of radio
-INT wifi_getRadioResetCount(INT radioIndex, ULONG *output_int)
-{
-	if (NULL == output_int)
-		return RETURN_ERR;
-	*output_int = get_radio_reset_cnt(radioIndex);
-
-	return RETURN_OK;
-}
-
-
-//---------------------------------------------------------------------------------------------------
-//
-// Additional Wifi AP level APIs used for Access Point devices
-//
-//---------------------------------------------------------------------------------------------------
-
-// creates a new ap and pushes these parameters to the hardware
-INT wifi_createAp(INT apIndex, INT radioIndex, CHAR *essid, BOOL hideSsid)
-{
-	// Deprecated when use hal version 3, use wifi_createVap() instead.
-	return RETURN_OK;
-}
-
-// deletes this ap entry on the hardware, clears all internal variables associaated with this ap
-INT wifi_deleteAp(INT apIndex)
-{
-	char interface_name[16] = {0};
-	char buf[MAX_BUF_SIZE];
-	int res;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	wifi_removeApSecVaribles(apIndex);
-
-	return RETURN_OK;
-}
-
-// Outputs a 16 byte or less name assocated with the AP.  String buffer must be pre-allocated by the caller
-INT wifi_getApName(INT apIndex, CHAR *output_string)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	int radio_idx = 0;
-	int bss_idx = 0;
-	int res;
-
-	if(!output_string)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
-		vap_index_to_radio_array_index(apIndex, &radio_idx, &bss_idx);
-
-		res = snprintf(output_string, IF_NAME_SIZE, "%s%d", ext_prefix[radio_idx], bss_idx);	// For wifiagent generating data model.
-	} else
-		res = snprintf(output_string, IF_NAME_SIZE, "%s", interface_name);
-
-	if (os_snprintf_error(IF_NAME_SIZE, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-// Outputs the index number in that corresponds to the SSID string
-INT wifi_getIndexFromName(CHAR *inputSsidString, INT *output_int)
-{
-	int ap_idx = 0;
-	char radio_idx = 0;
-	char bss_idx = 0;
-	unsigned char i;
-	char inf_name[IF_NAME_SIZE] = {0};
-
-	for (i = 0; i < MAX_APS; i++) {
-		if (wifi_GetInterfaceName(i, inf_name) != RETURN_OK)
-			continue;
-
-		if (strncmp(inf_name, inputSsidString, strlen(inf_name)) == 0) {
-			wifi_debug(DEBUG_INFO, "hostapd conf find, inf(%s), use inf idx(%d).\n",
-				inputSsidString, i);
-			*output_int = i;
-			return RETURN_OK;
-		}
-	}
-
-	/* If interface name is not in hostapd config, the caller maybe wifi agent to generate data model.*/
-	if (strstr(inputSsidString, PREFIX_WIFI6G)) {
-		bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI6G));
-		radio_idx = 2;
-	} else if (strstr(inputSsidString, PREFIX_WIFI5G)) {
-		bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI5G));
-		radio_idx = 1;
-	} else if (strstr(inputSsidString, PREFIX_WIFI2G)) {
-		bss_idx = atoi(inputSsidString + strlen(PREFIX_WIFI2G));
-		radio_idx = 0;
-	} else {
-		wifi_debug(DEBUG_ERROR, "hostapd conf not find, unknow inf(%s), return ERROR!!!(%d).\n",
-			inputSsidString, ap_idx);
-		*output_int = -1;
-		return RETURN_ERR;
-	}
-
-	if(array_index_to_vap_index(radio_idx, bss_idx, &ap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_idx %d, bss_idx %d\n", radio_idx, bss_idx);
-		return RETURN_ERR;
-	}
-
-	if (ap_idx >= 0 && ap_idx < MAX_APS) {
-		wifi_debug(DEBUG_INFO, "hostapd conf find, inf(%s), use inf idx(%d).\n",
-			inputSsidString, ap_idx);
-		*output_int = ap_idx;
-		return RETURN_OK;
-	}
-
-	return RETURN_ERR;
-}
-
-INT wifi_getApIndexFromName(CHAR *inputSsidString, INT *output_int)
-{
-	return wifi_getIndexFromName(inputSsidString, output_int);
-}
-
-// Outputs a 32 byte or less string indicating the beacon type as "None", "Basic", "WPA", "11i", "WPAand11i"
-INT wifi_getApBeaconType(INT apIndex, CHAR *output_string)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if(NULL == output_string)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "wpa", buf, sizeof(buf));
-	if((strcmp(buf,"3")==0))
-		res = snprintf(output_string, 32, "WPAand11i");
-	else if((strcmp(buf,"2")==0))
-		res = snprintf(output_string, 32, "11i");
-	else if((strcmp(buf,"1")==0))
-		res = snprintf(output_string, 32, "WPA");
-	else
-		res = snprintf(output_string, 32, "None");
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-// Sets the beacon type enviornment variable. Allowed input strings are "None", "Basic", "WPA, "11i", "WPAand11i"
-INT wifi_setApBeaconType(INT apIndex, CHAR *beaconTypeString)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	if (NULL == beaconTypeString)
-		return RETURN_ERR;
-	list.name = "wpa";
-	list.value = "0";
-
-	if((strcmp(beaconTypeString,"WPAand11i")==0))
-		list.value="3";
-	else if((strcmp(beaconTypeString,"11i")==0))
-		list.value="2";
-	else if((strcmp(beaconTypeString,"WPA")==0))
-		list.value="1";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-	//save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
-	return RETURN_OK;
-}
-
-// sets the beacon interval on the hardware for this AP
-INT wifi_setApBeaconInterval(INT apIndex, INT beaconInterval)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	struct params params={'\0'};
-	char buf[MAX_BUF_SIZE] = {'\0'};
-	char config_file[MAX_BUF_SIZE] = {'\0'};
-	int res;
-
-	params.name = "beacon_int";
-	res = snprintf(buf, sizeof(buf), "%u", beaconInterval);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.value = buf;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setDTIMInterval(INT apIndex, INT dtimInterval)
-{
-	if (wifi_setApDTIMInterval(apIndex, dtimInterval) != RETURN_OK)
-		return RETURN_ERR;
-	return RETURN_OK;
-}
-
-// Get the packet size threshold supported.
-INT wifi_getApRtsThresholdSupported(INT apIndex, BOOL *output_bool)
-{
-	//save config and apply instantly
-	if (NULL == output_bool)
-		return RETURN_ERR;
-	*output_bool = TRUE;
-	return RETURN_OK;
-}
-
-// sets the packet size threshold in bytes to apply RTS/CTS backoff rules.
-INT wifi_setApRtsThreshold(INT apIndex, UINT threshold)
-{
-	char buf[16] = {0};
-	char config_file[128] = {0};
-	struct params param = {0};
-	int res;
-
-	if (threshold > 65535) {
-		wifi_debug(DEBUG_ERROR, "rts threshold %u is too big.\n", threshold);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(buf, sizeof(buf), "%u", threshold);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	param.name = "rts_threshold";
-	param.value = buf;
-	wifi_hostapdWrite(config_file, &param, 1);
-	wifi_hostapdProcessUpdate(apIndex, &param, 1);
-	wifi_reloadAp(apIndex);
-
-	return RETURN_OK;
-}
-
-// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
-INT wifi_getApWpaEncryptoinMode(INT apIndex, CHAR *output_string)
-{
-	int res;
-
-	if (NULL == output_string)
-		return RETURN_ERR;
-	res = snprintf(output_string, 32, "TKIPandAESEncryption");
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	return RETURN_OK;
-
-}
-
-// outputs up to a 32 byte string as either "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
-INT wifi_getApWpaEncryptionMode(INT apIndex, CHAR *output_string)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	char *param_name = NULL;
-	char buf[32] = {0}, config_file[MAX_BUF_SIZE] = {0};
-	unsigned int len;
-	int res;
-
-	if(NULL == output_string)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
-
-	if(strcmp(buf,"0")==0)
-	{
-		wifi_debug(DEBUG_OFF, "wpa_mode is %s ......... \n", buf);
-		res = snprintf(output_string, 32, "None");
-		if (os_snprintf_error(32, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	}
-	else if((strcmp(buf,"3")==0) || (strcmp(buf,"2")==0))
-		param_name = "rsn_pairwise";
-	else if((strcmp(buf,"1")==0))
-		param_name = "wpa_pairwise";
-	else
-		return RETURN_ERR;
-	memset(output_string,'\0',32);
-	wifi_hostapdRead(config_file,param_name,output_string,32);
-	if (strlen(output_string) == 0) {	   // rsn_pairwise is optional. When it is empty use wpa_pairwise instead.
-		param_name = "wpa_pairwise";
-		memset(output_string, '\0', 32);
-		wifi_hostapdRead(config_file, param_name, output_string, 32);
-	}
-	wifi_debug(DEBUG_INFO, "output_string=%s\n", output_string);
-
-	if(strcmp(output_string,"TKIP CCMP") == 0) {
-		len = strlen("TKIPandAESEncryption");
-		memcpy(output_string,"TKIPandAESEncryption", len);
-		output_string[len] = '\0';
-	} else if(strcmp(output_string,"TKIP") == 0) {
-		len = strlen("TKIPEncryption");
-		memcpy(output_string,"TKIPEncryption", len);
-		output_string[len] = '\0';
-	} else if(strcmp(output_string,"CCMP") == 0) {
-		len = strlen("AESEncryption");
-		memcpy(output_string,"AESEncryption", len);
-		output_string[len] = '\0';
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-// sets the encyption mode enviornment variable.  Valid string format is "TKIPEncryption", "AESEncryption", or "TKIPandAESEncryption"
-INT wifi_setApWpaEncryptionMode(INT apIndex, CHAR *encMode)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	struct params params={'\0'};
-	char output_string[32];
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	memset(output_string,'\0',32);
-	wifi_getApBeaconType(apIndex,output_string);
-
-	if(strcmp(encMode, "TKIPEncryption") == 0)
-		params.value = "TKIP";
-	else if(strcmp(encMode,"AESEncryption") == 0)
-		params.value = "CCMP";
-	else if(strcmp(encMode,"TKIPandAESEncryption") == 0)
-		params.value = "TKIP CCMP";
-
-	if((strcmp(output_string,"WPAand11i")==0))
-	{
-		params.name = "wpa_pairwise";
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_hostapdWrite(config_file, &params, 1);
-		wifi_hostapdProcessUpdate(apIndex, &params, 1);
-
-		params.name = "rsn_pairwise";
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_hostapdWrite(config_file, &params, 1);
-		wifi_hostapdProcessUpdate(apIndex, &params, 1);
-
-		return RETURN_OK;
-	}
-	else if((strcmp(output_string,"11i")==0))
-	{
-		params.name = "rsn_pairwise";
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_hostapdWrite(config_file, &params, 1);
-		wifi_hostapdProcessUpdate(apIndex, &params, 1);
-		return RETURN_OK;
-	}
-	else if((strcmp(output_string,"WPA")==0))
-	{
-		params.name = "wpa_pairwise";
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_hostapdWrite(config_file, &params, 1);
-		wifi_hostapdProcessUpdate(apIndex, &params, 1);
-		return RETURN_OK;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-// deletes internal security varable settings for this ap
-INT wifi_removeApSecVaribles(INT apIndex)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	list.name = "wpa";
-	list.value = "0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &list, 1);
-
-	return RETURN_OK;
-}
-
-// changes the hardware settings to disable encryption on this ap
-INT wifi_disableApEncryption(INT apIndex)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	list.name = "wpa";
-	list.value = "0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-	wifi_reloadAp(apIndex);
-
-	return RETURN_OK;
-}
-
-// set the authorization mode on this ap
-// mode mapping as: 1: open, 2: shared, 4:auto
-INT wifi_setApAuthMode(INT apIndex, INT mode)
-{
-	struct params params={0};
-	char config_file[64] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	wifi_debug(DEBUG_INFO, "algo_mode=%d\n", mode);
-	params.name = "auth_algs";
-
-	if ((mode & 1 && mode & 2) || mode & 4)
-		params.value = "3";
-	else if (mode & 2)
-		params.value = "2";
-	else if (mode & 1)
-		params.value = "1";
-	else
-		params.value = "0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	wifi_reloadAp(apIndex);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
-INT wifi_setApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
-{
-	//save to wifi config, and wait for wifi restart to apply
-	struct params params={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(authMode ==  NULL)
-		return RETURN_ERR;
-
-	wifi_debug(DEBUG_INFO, "AuthMode=%s\n", authMode);
-	params.name = "wpa_key_mgmt";
-
-	if((strcmp(authMode,"PSKAuthentication") == 0) || (strcmp(authMode,"SharedAuthentication") == 0))
-		params.value = "WPA-PSK";
-	else if(strcmp(authMode,"EAPAuthentication") == 0)
-		params.value = "WPA-EAP";
-	else if (strcmp(authMode, "SAEAuthentication") == 0)
-		params.value = "SAE";
-	else if (strcmp(authMode, "EAP_192-bit_Authentication") == 0)
-		params.value = "WPA-EAP-SUITE-B-192";
-	else if (strcmp(authMode, "PSK-SAEAuthentication") == 0)
-		params.value = "WPA-PSK WPA-PSK-SHA256 SAE";
-	else if (strcmp(authMode, "Enhanced_Open") == 0)
-		params.value = "OWE";
-	else if(strcmp(authMode,"None") == 0) //Donot change in case the authMode is None
-		return RETURN_OK;			  //This is taken careof in beaconType
-
-	ret = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
-	if (os_snprintf_error(sizeof(config_file), ret)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	ret=wifi_hostapdWrite(config_file,&params,1);
-	if(!ret)
-		ret=wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return ret;
-}
-
-// sets an enviornment variable for the authMode. Valid strings are "None", "EAPAuthentication" or "SharedAuthentication"
-INT wifi_getApBasicAuthenticationMode(INT apIndex, CHAR *authMode)
-{
-	//save to wifi config, and wait for wifi restart to apply
-	char BeaconType[50] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-	unsigned long len;
-
-	*authMode = 0;
-	wifi_getApBeaconType(apIndex,BeaconType);
-	wifi_debug(DEBUG_INFO, "%s____%s \n",__FUNCTION__,BeaconType);
-
-	if(strcmp(BeaconType,"None") == 0) {
-		memcpy(authMode, "None", 4);
-		authMode[4] = '\0';
-	} else {
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wifi_hostapdRead(config_file, "wpa_key_mgmt", authMode, 32);
-		wifi_debug(DEBUG_INFO, "AuthMode Name is : %s\n", authMode);
-		if(strcmp(authMode,"WPA-PSK") == 0) {
-			len = strlen("SharedAuthentication");
-			memcpy(authMode, "SharedAuthentication", len);
-			authMode[len] = '\0';
-		} else if(strcmp(authMode,"WPA-EAP") == 0) {
-			len = strlen("EAPAuthentication");
-			memcpy(authMode, "EAPAuthentication", len);
-			authMode[len] = '\0';
-		}
-	}
-
-	return RETURN_OK;
-}
-
-// Outputs the number of stations associated per AP
-INT wifi_getApNumDevicesAssociated(INT apIndex, ULONG *output_ulong)
-{
-	char interface_name[16] = {0};
-	char buf[128]={0};
-	BOOL status = false;
-	int res;
-
-	if(apIndex > MAX_APS)
-		return RETURN_ERR;
-
-	wifi_getApEnable(apIndex,&status);
-	if (!status)
-		return RETURN_OK;
-
-	//sprintf(cmd, "iw dev %s station dump | grep Station | wc -l", interface_name);//alternate method
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s list_sta | wc -l", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-
-	if (sscanf(buf,"%lu", output_ulong) != 1) {
-		wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-// manually removes any active wi-fi association with the device specified on this ap
-INT wifi_kickApAssociatedDevice(INT apIndex, CHAR *client_mac)
-{
-	char inf_name[16] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf),"hostapd_cli -i %s disassociate %s", inf_name, client_mac);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	return RETURN_OK;
-}
-
-// outputs the radio index for the specified ap. similar as wifi_getSsidRadioIndex
-INT wifi_getApRadioIndex(INT apIndex, INT *output_int)
-{
-	int radioIndex, bss_idx;
-
-	if(NULL == output_int)
-		return RETURN_ERR;
-
-	if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
-		return RETURN_ERR;
-	}
-
-	*output_int = radioIndex;
-
-	return RETURN_OK;
-}
-
-// sets the radio index for the specific ap
-INT wifi_setApRadioIndex(INT apIndex, INT radioIndex)
-{
-	//set to config only and wait for wifi reset to apply settings
-	return RETURN_ERR;
-}
-
-int mtk_get_ap_metrics(struct nl_msg *msg, void *cb)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX + 1];
-	struct genlmsghdr *gnlh;
-	wdev_ap_metric ap_metric;
-	wdev_ap_metric *p_ap_metric = &ap_metric;
-	int err = 0;
-	struct mtk_nl80211_cb_data *cb_data = cb;
-
-	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msgor cb_data is null,error.\n");
-		return NL_SKIP;
-	}
-	gnlh = nlmsg_data(nlmsg_hdr(msg));
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse ap_metrics nl80211 msg fails,error.\n");
-		return err;
-	}
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_GET_STATISTIC_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0) {
-			wifi_debug(DEBUG_ERROR, "GET_STATISTIC_MAX fails,error.\n");
-			return err;
-		}
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]) {
-			p_ap_metric = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS]);
-			if (p_ap_metric) {
-				memcpy(cb_data->out_buf , &p_ap_metric->cu, sizeof(unsigned char));
-			}
-		}
-	}
-
-	return NL_OK;
-}
-
-
-#define MAX_ACL_DUMP_LEN 4096
-int mtk_acl_list_dump_callback(struct nl_msg *msg, void *cb)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh;
-	char *show_str = NULL;
-	int err = 0;
-	unsigned short acl_result_len = 0;
-	struct mtk_nl80211_cb_data *cb_data = cb;
-	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
-		return NL_SKIP;
-	}
-
-	gnlh = nlmsg_data(nlmsg_hdr(msg));
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
-		return NL_SKIP;
-	}
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_ACL_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]) {
-			acl_result_len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
-			show_str = nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_ACL_LIST_INFO]);
-			if (acl_result_len > MAX_ACL_DUMP_LEN) {
-				wifi_debug(DEBUG_ERROR,"the scan result len is invalid !!!\n");
-				return NL_SKIP;
-			} else if (*(show_str + acl_result_len - 1) != '\0') {
-				wifi_debug(DEBUG_INFO, "the result string is not ended with right terminator, handle it!!!\n");
-				*(show_str + acl_result_len - 1) = '\0';
-			}
-			wifi_debug(DEBUG_INFO, "driver msg:%s\n", show_str);
-
-			if (cb_data->out_len >= acl_result_len) {
-				memset(cb_data->out_buf, 0, cb_data->out_len);
-				/*skip the first line: 'policy=1\n' to find the acl mac addrs*/
-				memmove(cb_data->out_buf, show_str, acl_result_len);
-				wifi_debug(DEBUG_INFO, "out buff:%s\n", cb_data->out_buf);
-			} else {
-				memset(cb_data->out_buf, 0, cb_data->out_len);
-			}
-		} else
-			wifi_debug(DEBUG_ERROR, "no acl result attr\n");
-	} else
-		wifi_debug(DEBUG_ERROR, "no any acl result from driver\n");
-	return NL_OK;
-}
-// Get the ACL MAC list per AP
-INT mtk_wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct mtk_nl80211_cb_data cb_data;
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_SHOW_ALL)) {
-		wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	cb_data.out_buf = macArray;
-	cb_data.out_len = buf_size;
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_acl_list_dump_callback, &cb_data);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_NOTICE,"send cmd success, get out_buf:%s\n", macArray);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-INT wifi_getApAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
-{
-	char *mac_arry_buf = NULL;
-
-	mac_arry_buf =  malloc(buf_size);
-	if (!mac_arry_buf) {
-		wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
-		return RETURN_ERR;
-	}
-	memset(mac_arry_buf, 0, buf_size);
-	if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
-		free(mac_arry_buf);
-		mac_arry_buf = NULL;
-		return RETURN_ERR;
-	}
-	/*
-	mtk format to wifi hal format:
-	"policy=1
-	 00:11:22:33:44:55
-	 00:11:22:33:44:66
-	"
-	-->
-	"00:11:22:33:44:55
-	00:11:22:33:44:66
-	"
-	*/
-	memset(macArray, 0, buf_size);
-	if (*mac_arry_buf != '\0' && strchr(mac_arry_buf,'\n')) {
-		memmove(macArray, strchr(mac_arry_buf,'\n')+1, strlen(strchr(mac_arry_buf,'\n')+1)+1);
-		wifi_debug(DEBUG_NOTICE,"macArray:\n%s\n", macArray);
-	}
-	free(mac_arry_buf);
-	mac_arry_buf = NULL;
-	return RETURN_OK;
-}
-
-INT wifi_getApDenyAclDevices(INT apIndex, CHAR *macArray, UINT buf_size)
-{
-
-	wifi_getApAclDevices(apIndex, macArray, buf_size);
-
-	return RETURN_OK;
-}
-
-
-// Get the list of stations associated per AP
-INT wifi_getApDevicesAssociated(INT apIndex, CHAR *macArray, UINT buf_size)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	int res;
-
-	if(apIndex > 3) //Currently supporting apIndex upto 3
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(macArray, buf_size, "hostapd_cli -i %s list_sta", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-        }
-
-	return RETURN_OK;
-}
-
-int hex2num(char c)
-{
-	if (c >= '0' && c <= '9')
-		return c - '0';
-	if (c >= 'a' && c <= 'f')
-		return c - 'a' + 10;
-	if (c >= 'A' && c <= 'F')
-		return c - 'A' + 10;
-	return -1;
-}
-
-/**
- * hwaddr_aton2 - Convert ASCII string to MAC address (in any known format)
- * @txt: MAC address as a string (e.g., 00:11:22:33:44:55 or 0011.2233.4455)
- * @addr: Buffer for the MAC address (ETH_ALEN = 6 bytes)
- * Returns: Characters used (> 0) on success, -1 on failure
- */
-int hwaddr_aton2(const char *txt, unsigned char *addr)
-{
-	int i;
-	const char *pos = txt;
-
-	for (i = 0; i < 6; i++) {
-		int a, b;
-
-		while (*pos == ':' || *pos == '.' || *pos == '-')
-			pos++;
-
-		a = hex2num(*pos++);
-		if (a < 0)
-			return -1;
-		b = hex2num(*pos++);
-		if (b < 0)
-			return -1;
-		*addr++ = (a << 4) | b;
-	}
-
-	return pos - txt;
-}
-
-// adds the mac address to the filter list
-//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
-INT wifi_addApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	int if_idx, ret = 0;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	unsigned char mac[ETH_ALEN] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
-	struct unl unl_ins;
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if (!DeviceMacAddress)
-		return RETURN_ERR;
-	if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
-		wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
-		return RETURN_ERR;
-	}
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_ADD_MAC, ETH_ALEN, mac)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-// deletes the mac address from the filter list
-//DeviceMacAddress is in XX:XX:XX:XX:XX:XX format
-INT wifi_delApAclDevice(INT apIndex, CHAR *DeviceMacAddress)
-{
-	struct unl unl_ins;
-	int if_idx = 0, ret = 0;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned char mac[ETH_ALEN] = {0};
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (!DeviceMacAddress)
-		return RETURN_ERR;
-
-	if (hwaddr_aton2(DeviceMacAddress, mac) < 0) {
-		wifi_debug(DEBUG_ERROR, "error device mac address=%s\n", DeviceMacAddress);
-		return RETURN_ERR;
-	}
-
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_ACL_DEL_MAC, ETH_ALEN, mac)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-// outputs the number of devices in the filter list
-INT wifi_getApAclDeviceNum(INT apIndex, UINT *output_uint)
-{
-	char *mac_arry = NULL, *ptr = NULL, mac_str[18] = {0};
-	UINT buf_size = 1024;
-	UINT sta_num = 0;
-	unsigned char mac[ETH_ALEN] = {0};
-	if(output_uint == NULL)
-		return RETURN_ERR;
-
-	mac_arry = (char *)malloc(buf_size);
-	if (mac_arry == NULL) {
-		wifi_debug(DEBUG_ERROR, "malloc mac_arry fails\n");
-		return RETURN_ERR;
-	}
-	memset(mac_arry, 0, buf_size);
-	/*mac_arry str format: 00:11:22:33:44:55\n00:11:22:33:44:66\0*/
-	if (wifi_getApAclDevices(apIndex, mac_arry, buf_size)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "get acl list entries fails\n");
-		free(mac_arry);
-		return RETURN_ERR;
-	}
-	/*count the acl str nums:*/
-	wifi_debug(DEBUG_NOTICE, "mac_arry: %s\n", mac_arry);
-
-	/*mac addr string format:
-	exp1: 00:11:22:33:44:55\0
-	exp2: 00:11:22:33:44:55\n00:11:22:33:44:66\0
-	*/
-	ptr = mac_arry;
-	while (sscanf(ptr, "%17s", mac_str) == 1) {
-		if (hwaddr_aton2(mac_str, mac) >= 0)
-			sta_num++;
-		ptr = strstr(ptr, mac_str) + strlen(mac_str);
-	}
-	*output_uint = sta_num;
-	wifi_debug(DEBUG_NOTICE, "output_uint: %d\n", *output_uint);
-	free(mac_arry);
-	mac_arry = NULL;
-	return RETURN_OK;
-}
-
-INT apply_rules(INT apIndex, CHAR *client_mac,CHAR *action,CHAR *interface)
-{
-	int res;
-
-	if(strcmp(action,"DENY")==0)
-	{
-		res = v_secure_system("iptables -A WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j DROP",
-			apIndex, interface, client_mac);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	}
-
-	if(strcmp(action,"ALLOW")==0)
-	{
-		res = v_secure_system("iptables -I WifiServices%d -m physdev --physdev-in %s -m mac --mac-source %s -j RETURN",
-			apIndex, interface, client_mac);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	}
-
-	return RETURN_ERR;
-
-}
-
-// enable kick for devices on acl black list
-INT wifi_kickApAclAssociatedDevices(INT apIndex, BOOL enable)
-{
-	char aclArray[MAX_BUF_SIZE] = {0}, *acl = NULL;
-	char assocArray[MAX_BUF_SIZE] = {0};
-	int policy = 0;
-
-	/*only when the policy is black list, do it*/
-	wifi_getApMacAddressControlMode(apIndex, &policy);
-
-	if (policy != 2)
-		return RETURN_OK;
-
-	wifi_getApDenyAclDevices(apIndex, aclArray, sizeof(aclArray));
-	wifi_getApDevicesAssociated(apIndex, assocArray, sizeof(assocArray));
-
-	/* if there are no devices connected there is nothing to do */
-	if (strlen(assocArray) < 17)
-		return RETURN_OK;
-
-	if (enable == TRUE) {
-		/* kick off the MAC which is in ACL array (deny list) */
-		acl = strtok(aclArray, "\n");
-		while (acl != NULL) {
-			if (strlen(acl) >= 17 && strcasestr(assocArray, acl))
-				wifi_kickApAssociatedDevice(apIndex, acl);
-
-			acl = strtok(NULL, "\n");
-		}
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_setPreferPrivateConnection(BOOL enable)
-{
-	return RETURN_OK;
-}
-
-// sets the mac address filter control mode.  0 == filter disabled, 1 == filter as whitelist, 2 == filter as blacklist
-INT wifi_setApMacAddressControlMode(INT apIndex, INT filterMode)
-{
-	int if_idx = 0, ret = 0;
-	struct unl unl_ins;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	int acl_policy = -1;
-	char inf_name[IF_NAME_SIZE] = {0};
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (filterMode == 0) {
-		acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_DISABLE;
-	} else if (filterMode == 1) {
-		acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_WHITE_LIST;
-	} else if (filterMode == 2) {
-		acl_policy = MTK_NL80211_VENDOR_ATTR_ACL_ENABLE_BLACK_LIST;
-	} else {
-		wifi_debug(DEBUG_ERROR, "filtermode(%d) not support error\n", filterMode);
-		nlmsg_free(msg);
-		goto err;
-	}
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, acl_policy)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-// 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.
-INT wifi_setApVlanEnable(INT apIndex, BOOL VlanEnabled)
-{
-	return RETURN_ERR;
-}
-
-// gets the vlan ID for this ap from an internal enviornment variable
-INT wifi_getApVlanID(INT apIndex, INT *output_int)
-{
-	if(apIndex==0)
-	{
-		*output_int=100;
-		return RETURN_OK;
-	}
-
-	return RETURN_ERR;
-}
-
-// sets the vlan ID for this ap to an internal enviornment variable
-INT wifi_setApVlanID(INT apIndex, INT vlanId)
-{
-	//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)
-	char interface_name[16] = {0};
-	int if_idx, ret = 0;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-
-	if (apIndex > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
-		return RETURN_ERR;
-	}
-	if (vlanId > 4095 || vlanId < 1) {
-		wifi_debug(DEBUG_ERROR, "Invalid vlanId %d\n", vlanId);
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	/*step 1. mwctl dev %s set vlan_tag 0*/
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, vlanId)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlanId = %d cmd success.\n", vlanId);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-char br_name[IFNAMSIZ] = "brlan0";
-
-// gets bridgeName, IP address and Subnet. bridgeName is a maximum of 32 characters,
-INT wifi_getApBridgeInfo(INT index, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
-{
-	int sock = socket(AF_INET, SOCK_DGRAM, 0);
-	struct ifreq ifr;
-	struct sockaddr_in *sin;
-
-	memcpy(bridgeName, br_name, strlen(br_name));
-
-	if (sock == -1) {
-		wifi_debug(DEBUG_ERROR, "socket failed");
-		return RETURN_ERR;
-	}
-
-	strncpy(ifr.ifr_name, br_name, strlen(br_name));
-	ifr.ifr_addr.sa_family = AF_INET;
-	if (ioctl(sock, SIOCGIFADDR, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFADDR) failed, %s, bridge_name=%s\n",
-			strerror(errno), br_name);
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	sin = (struct sockaddr_in *)&ifr.ifr_addr;
-	wifi_debug(DEBUG_ERROR, "Bridge device %s has IP address: %s\n", br_name, inet_ntoa(sin->sin_addr));
-	memcpy(IP, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
-
-	if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFNETMASK) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	wifi_debug(DEBUG_OFF, "Bridge device %s has subnet mask: %s\n", br_name, inet_ntoa(sin->sin_addr));
-	memcpy(subnet, inet_ntoa(sin->sin_addr), strlen(inet_ntoa(sin->sin_addr)));
-	close(sock);
-
-	return RETURN_OK;
-}
-
-//sets bridgeName, IP address and Subnet to internal enviornment variables. bridgeName is a maximum of 32 characters
-INT wifi_setApBridgeInfo(INT apIndex, CHAR *bridgeName, CHAR *IP, CHAR *subnet)
-{
-	//save settings, wait for wifi reset or wifi_pushBridgeInfo to apply.
-	struct ifreq ifr;
-	struct sockaddr_in sin;
-	int sock = socket(AF_INET, SOCK_DGRAM, 0);
-
-	if(sock < 0) {
-		wifi_debug(DEBUG_ERROR, "sock init fail\n");
-		return RETURN_ERR;
-	}
-
-	if (strlen(bridgeName) >= IFNAMSIZ) {
-		wifi_debug(DEBUG_ERROR, "invalide bridgeName length=%ld\n", strlen(bridgeName));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	if (strlen(br_name) >= IFNAMSIZ) {
-		wifi_debug(DEBUG_ERROR, "invalide br_name length=%ld in strorage\n", strlen(br_name));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	if (sock == -1) {
-		wifi_debug(DEBUG_ERROR, "socket failed");
-		return RETURN_ERR;
-	}
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, br_name, strlen(br_name));
-	if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	ifr.ifr_flags = (short)(ifr.ifr_flags & ~IFF_UP);
-	if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, br_name, IFNAMSIZ);
-	strncpy(ifr.ifr_newname, bridgeName, strlen(bridgeName));
-	if (ioctl(sock, SIOCSIFNAME, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNAME) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	memset(br_name, 0, sizeof(br_name));
-	memcpy(br_name, bridgeName, strlen(bridgeName));
-
-	memset(&ifr, 0, sizeof(ifr));
-	strncpy(ifr.ifr_name, bridgeName, IFNAMSIZ);
-	if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCGIFFLAGS) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-	ifr.ifr_flags = (short)(ifr.ifr_flags | IFF_UP);
-	if (ioctl(sock, SIOCSIFFLAGS, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFFLAGS) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	memset(&ifr, 0, sizeof(ifr));
-	memcpy(ifr.ifr_name, bridgeName, strlen(bridgeName));
-
-	memset(&sin, 0, sizeof(struct sockaddr_in));
-	sin.sin_family = AF_INET;
-	if (inet_aton(IP, &(sin.sin_addr)) == 0) {
-		wifi_debug(DEBUG_ERROR, "inet_aton failed");
-		close(sock);
-		return RETURN_ERR;
-	}
-	memcpy(&ifr.ifr_addr, &sin, sizeof(struct sockaddr_in));
-	if (ioctl(sock, SIOCSIFADDR, &ifr) < 0) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFADDR) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	if (inet_aton(subnet, &((struct sockaddr_in *)&ifr.ifr_netmask)->sin_addr) == 0) {
-		wifi_debug(DEBUG_ERROR, "inet_aton failed");
-		close(sock);
-		return RETURN_ERR;
-	}
-	if (ioctl(sock, SIOCSIFNETMASK, &ifr) < -1) {
-		wifi_debug(DEBUG_ERROR, "ioctl(SIOCSIFNETMASK) failed, %s", strerror(errno));
-		close(sock);
-		return RETURN_ERR;
-	}
-
-	close(sock);
-	return RETURN_ERR;
-}
-
-// reset the vlan configuration for this ap
-INT wifi_resetApVlanCfg(INT apIndex)
-{
-	char interface_name[16] = {0};
-	int if_idx, ret = 0;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-	struct vlan_policy_param vlan_param;
-
-	if (apIndex > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	/*step 1. mwctl dev %s set vlan_tag 0*/
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_VLAN;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_TAG_INFO, 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlan_tag 0 cmd success.\n");
-
-	/*step 2. mwctl dev %s set vlan_priority 0*/
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_PRIORITY_INFO, 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlan_priority 0 cmd success.\n");
-
-	/*step 3. mwctl dev %s set vlan_id 0*/
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put_u16(msg, MTK_NL80211_VENDOR_ATTR_VLAN_ID_INFO, 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlan_id cmd success.\n");
-
-	/*step 4. mwctl dev %s set vlan_en 0*/
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_VLAN_EN_INFO, 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlan_id cmd success.\n");
-
-	/*step 5. mwctl dev %s set vlan_policy 0:4*/
-	vlan_param.direction = 0;
-	vlan_param.policy = 4;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlan_policy 0:4 cmd success.\n");
-
-	/*step 6. mwctl dev %s set vlan_policy 1:0*/
-	vlan_param.direction = 1;
-	vlan_param.policy = 0;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_VLAN_POLICY_INFO, sizeof(vlan_param), &vlan_param)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set vlan_policy 1:0 cmd success.\n");
-
-	/*TODO need to modify VLAN config in dat file*/
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-// 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.
-INT wifi_createHostApdConfig(INT apIndex, BOOL createWpsCfg)
-{
-	return RETURN_OK;
-}
-
-// starts hostapd, uses the variables in the hostapd config with format compatible with the specific hostapd implementation
-INT wifi_startHostApd()
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	v_secure_system("systemctl start hostapd.service");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-	//sprintf(cmd, "hostapd  -B `cat /tmp/conf_filename` -e /nvram/etc/wpa2/entropy -P /tmp/hostapd.pid 1>&2");
-}
-
-// stops hostapd
-INT wifi_stopHostApd()
-{
-	char buf[128] = {0};
-	int res;
-
-	res = _syscmd_secure(buf, sizeof(buf), "systemctl stop hostapd");
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	return RETURN_OK;
-}
-
-// restart hostapd dummy function
-INT wifi_restartHostApd()
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	v_secure_system("systemctl restart hostapd-global");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// sets the AP enable status variable for the specified ap.
-INT wifi_setApEnable(INT apIndex, BOOL enable)
-{
-	char interface_name[16] = {0};
-	char config_file[MAX_SUB_CMD_SIZE] = {0};
-
-	char buf[MAX_BUF_SIZE] = {0};
-	BOOL status = FALSE;
-	int radioIndex, bss_idx;
-	int phyId = 0;
-	int res;
-
-	wifi_getApEnable(apIndex, &status);
-
-	if (enable == status)
-		return RETURN_OK;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (enable == TRUE) {
-		if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
-			return RETURN_ERR;
-		}
-		phyId = radio_index_to_phy(radioIndex);
-
-		res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(MAX_BUF_SIZE, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		if (!is_main_vap_index(apIndex) && strncmp(buf, "FAIL", 4) == 0) {
-			wifi_debug(DEBUG_ERROR, "hostapd_cli raw ADD %s fail.\n", interface_name);
-			res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-			enable = FALSE;
-		}
-	} else {
-		/*Do not REMOVE main interfaces in hostapd*/
-		if (!is_main_vap_index(apIndex)) {
-			res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
-		    if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		} else {
-			res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
-		    if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			}
-		}
-	}
-	res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
-				interface_name, interface_name, enable, VAP_STATUS_FILE);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	//Wait for wifi up/down to apply
-	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_ERROR, "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};
-	int res;
-	char ctrl_interface[64] = {0};
-	char config_file[128] = {0};
-	BOOL is_ap_enable, hostapd_state;
-
-	if ((!output_bool) || (apIndex < 0) || (apIndex >= MAX_APS))
-		return RETURN_ERR;
-
-	*output_bool = 0;
-
-	if ((apIndex >= 0) && (apIndex < MAX_APS)) {
-		if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK) {
-			*output_bool = FALSE;
-			return RETURN_OK;
-		}
-		if (strlen(interface_name) == 0)
-			return RETURN_ERR;
-
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		if (wifi_hostapdRead(config_file, "ctrl_interface", ctrl_interface, sizeof(ctrl_interface))) {
-			wifi_debug(DEBUG_ERROR, "ctrl_interface for %s not exist\n", interface_name);
-		}
-
-		if (get_ctrl_interface(ctrl_interface, interface_name) == FALSE)
-			return RETURN_OK;
-
-		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 = wifi_get_ap_status_ioctl(interface_name);
-
-		if (hostapd_state && is_ap_enable)
-			*output_bool = TRUE;
-	}
-
-	return RETURN_OK;
-}
-
-// Outputs the AP "Enabled" "Disabled" status from driver
-INT wifi_getApStatus(INT apIndex, CHAR *output_string)
-{
-	BOOL output_bool = 0;
-	int res;
-
-	if (!output_string) {
-		wifi_debug(DEBUG_ERROR, "null pointer!");
-		return RETURN_ERR;
-	}
-
-	wifi_getApEnable(apIndex, &output_bool);
-
-	if(output_bool == 1)
-		res = snprintf(output_string, 32, "Up");
-	else
-		res = snprintf(output_string, 32, "Disable");
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Indicates whether or not beacons include the SSID name.
-// outputs a 1 if SSID on the AP is enabled, else outputs 0
-INT wifi_getApSsidAdvertisementEnable(INT apIndex, BOOL *output)
-{
-	//get the running status
-	char config_file[MAX_BUF_SIZE] = {0};
-	char buf[16] = {0};
-	int res;
-
-	if (!output)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file),
-		"%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "ignore_broadcast_ssid", buf, sizeof(buf));
-	// default is enable
-	if (strlen(buf) == 0 || strncmp("0", buf, 1) == 0)
-		*output = TRUE;
-
-	return RETURN_OK;
-}
-
-// sets an internal variable for ssid advertisement.  Set to 1 to enable, set to 0 to disable
-INT wifi_setApSsidAdvertisementEnable(INT apIndex, BOOL enable)
-{
-	//store the config, apply instantly
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	list.name = "ignore_broadcast_ssid";
-	list.value = enable?"0":"1";
-
-	res = snprintf(config_file, sizeof(config_file),
-		"%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-	//TODO: call hostapd_cli for dynamic_config_control
-	wifi_reloadAp(apIndex);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//The maximum number of retransmission for a packet. This corresponds to IEEE 802.11 parameter dot11ShortRetryLimit.
-INT wifi_getApRetryLimit(INT apIndex, UINT *output_uint)
-{
-	/* get the running status */
-	if(!output_uint)
-		return RETURN_ERR;
-
-	*output_uint = 15;
-	return RETURN_OK;
-}
-
-/*Do not support AP retry limit fix*/
-INT wifi_setApRetryLimit(INT apIndex, UINT number)
-{
-	return RETURN_ERR;
-}
-
-int get_wmm_cap_status_callback(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_WMM_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char *status = (unsigned char *)data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return err;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_WMM_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return err;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]) {
-			*status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO]);
-		}
-	}
-
-	return 0;
-}
-
-//Indicates whether this access point supports WiFi Multimedia (WMM) Access Categories (AC).
-INT wifi_getApWMMCapability(INT apIndex, BOOL *output)
-{
-	int if_idx, ret = 0;
-	char interface_name[16] = {0};
-	unsigned char status = 0;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(!output)
-		return RETURN_ERR;
-
-	if (apIndex > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, 0xf)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, get_wmm_cap_status_callback,
-		(void *)&status);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-
-	*output = status == 0 ? FALSE : TRUE;
-	wifi_debug(DEBUG_NOTICE, "wmm cap (%u).\n", (unsigned int)(*output));
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-//Indicates whether this access point supports WMM Unscheduled Automatic Power Save Delivery (U-APSD). Note: U-APSD support implies WMM support.
-INT wifi_getApUAPSDCapability(INT apIndex, BOOL *output)
-{
-	//get the running status from driver
-	char buf[128] = {0};
-	int radioIndex = 0, bss_idx;
-	int phyId = 0;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
-		return RETURN_ERR;
-	}
-	phyId = radio_index_to_phy(radioIndex);
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw phy phy%d info | grep u-APSD", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) > 0)
-		*output = true;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//Whether WMM support is currently enabled. When enabled, this is indicated in beacon frames.
-INT wifi_getApWmmEnable(INT apIndex, BOOL *output)
-{
-	return wifi_getApWMMCapability(apIndex, output);
-}
-
-// enables/disables WMM on the hardwawre for this AP.  enable==1, disable == 0
-INT wifi_setApWmmEnable(INT apIndex, BOOL enable)
-{
-	int if_idx, ret = 0;
-	char interface_name[16] = {0};
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (apIndex > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "Invalid apIndex %d\n", apIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_WMM;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_WMM_AP_CAP_INFO, enable ? 1 : 0)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vendor msg fails\n");
-		goto err;
-	}
-	mtk_nl80211_deint(&unl_ins);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-
-//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.
-INT wifi_getApWmmUapsdEnable(INT apIndex, BOOL *output)
-{
-	int res;
-
-	//get the running status from driver
-	if(!output)
-		return RETURN_ERR;
-
-	char config_file[128] = {0};
-	char buf[16] = {0};
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "uapsd_advertisement_enabled", buf, sizeof(buf));
-	if (strlen(buf) == 0 || strncmp("1", buf, 1) == 0)
-		*output = TRUE;
-	else
-		*output = FALSE;
-
-	return RETURN_OK;
-}
-
-// enables/disables Automatic Power Save Delivery on the hardwarwe for this AP
-INT wifi_setApWmmUapsdEnable(INT apIndex, BOOL enable)
-{
-	//save config and apply instantly.
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	list.name = "uapsd_advertisement_enabled";
-	list.value = enable?"1":"0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-	wifi_quick_reload_ap(apIndex);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// Sets the WMM ACK policy on the hardware. AckPolicy false means do not acknowledge, true means acknowledge
-INT wifi_setApWmmOgAckPolicy(INT apIndex, INT class, BOOL ackPolicy)  //RDKB
-{
-	char interface_name[16] = {0};
-	// assume class 0->BE, 1->BK, 2->VI, 3->VO
-
-	char buf[128] = {0};
-	char ack_filepath[128] = {0};
-	uint16_t bitmap = 0;
-	uint16_t class_map[4] = {0x0009, 0x0006, 0x0030, 0x00C0};
-	FILE *f = NULL;
-	int res;
-	unsigned long tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	// Get current setting
-	res = snprintf(ack_filepath, sizeof(ack_filepath), "%s%d.txt", NOACK_MAP_FILE, apIndex);
-	if (os_snprintf_error(sizeof(ack_filepath), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null", ack_filepath);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strlen(buf) > 0) {
-		if (hal_strtoul(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		bitmap = tmp;
-	}
-
-	if (ackPolicy == TRUE) {	// True, unset this class
-		bitmap &= ~class_map[class];
-	} else {					// False, set this class
-		bitmap |= class_map[class];
-	}
-
-	f = fopen(ack_filepath, "w");
-	if (f == NULL) {
-		if (fprintf(stderr, "%s: fopen failed\n", __func__) < 0)
-			wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (fprintf(f, "%hu", bitmap) < 0)
-		wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-
-	if (fclose(f) == EOF) {
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw dev %s set noack_map 0x%04x\n", interface_name, bitmap);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-//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.
-INT wifi_getApMaxAssociatedDevices(INT apIndex, UINT *output_uint)
-{
-	int res;
-
-	//get the running status from driver
-	if(!output_uint)
-		return RETURN_ERR;
-
-	char output[16]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "max_num_sta", output, sizeof(output));
-	if (strlen(output) == 0) *output_uint = MAX_ASSOCIATED_STA_NUM;
-	else {
-		int device_num = atoi(output);
-		if (device_num > MAX_ASSOCIATED_STA_NUM || device_num < 0) {
-			wifi_debug(DEBUG_ERROR, "\nget max_num_sta error: %d", device_num);
-			return RETURN_ERR;
-		}
-		else {
-			*output_uint = device_num;
-		}
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_setApMaxAssociatedDevices(INT apIndex, UINT number)
-{
-	//store to wifi config, apply instantly
-	char str[MAX_BUF_SIZE]={'\0'};
-	struct params params;
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res, ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (number > MAX_ASSOCIATED_STA_NUM) {
-		WIFI_ENTRY_EXIT_DEBUG("%s: Invalid input\n",__func__);
-		return RETURN_ERR;
-	}
-	res = snprintf(str, sizeof(str), "%d", number);
-	if (os_snprintf_error(sizeof(str), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.name = "max_num_sta";
-	params.value = str;
-
-	res = snprintf(config_file,
-		sizeof(config_file), "%s%d.conf",CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	ret = wifi_hostapdWrite(config_file, &params, 1);
-	if (ret) {
-		WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdWrite() return %d\n"
-				,__func__, ret);
-	}
-
-	ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	if (ret) {
-		WIFI_ENTRY_EXIT_DEBUG("Inside %s: wifi_hostapdProcessUpdate() return %d\n"
-				,__func__, ret);
-	}
-	wifi_reloadAp(apIndex);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-//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.
-INT wifi_getApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT *output_uint)
-{
-	//get the current threshold
-	if(!output_uint)
-		return RETURN_ERR;
-	wifi_getApMaxAssociatedDevices(apIndex, output_uint);
-	if (*output_uint == 0)
-		*output_uint = 50;
-	return RETURN_OK;
-}
-
-INT wifi_setApAssociatedDevicesHighWatermarkThreshold(INT apIndex, UINT Threshold)
-{
-	//store the config, reset threshold, reset AssociatedDevicesHighWatermarkThresholdReached, reset AssociatedDevicesHighWatermarkDate to current time
-	if (!wifi_setApMaxAssociatedDevices(apIndex, Threshold))
-		return RETURN_OK;
-	return RETURN_ERR;
-}
-
-//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.
-INT wifi_getApAssociatedDevicesHighWatermarkThresholdReached(INT apIndex, UINT *output_uint)
-{
-	if(!output_uint)
-		return RETURN_ERR;
-	*output_uint = 3;
-	return RETURN_OK;
-}
-
-//Maximum number of associated devices that have ever associated with the access point concurrently since the last reset of the device or WiFi module.
-INT wifi_getApAssociatedDevicesHighWatermark(INT apIndex, UINT *output_uint)
-{
-	if(!output_uint)
-		return RETURN_ERR;
-	*output_uint = 3;
-	return RETURN_OK;
-}
-
-//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.
-INT wifi_getApAssociatedDevicesHighWatermarkDate(INT apIndex, ULONG *output_in_seconds)
-{
-	if(!output_in_seconds)
-		return RETURN_ERR;
-	*output_in_seconds = 0;
-	return RETURN_OK;
-}
-
-//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
-INT wifi_getApSecurityModesSupported(INT apIndex, CHAR *output)
-{
-	int res;
-
-	if(!output || apIndex>=MAX_APS)
-		return RETURN_ERR;
-	//res = snprintf(output, 128, "None,WPA-Personal,WPA2-Personal,WPA-WPA2-Personal,WPA-Enterprise,WPA2-Enterprise,WPA-WPA2-Enterprise");
-	res = snprintf(output, 128, "None,WPA2-Personal,WPA-WPA2-Personal,WPA2-Enterprise,WPA-WPA2-Enterprise,WPA3-Personal,WPA3-Enterprise,WPA3-Personal-Transition");
-	if (os_snprintf_error(128, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	return RETURN_OK;
-}
-
-//The value MUST be a member of the list reported by the ModesSupported parameter. Indicates which security mode is enabled.
-INT wifi_getApSecurityModeEnabled(INT apIndex, CHAR *output)
-{
-	char config_file[128] = {0};
-	char wpa[16] = {0};
-	char key_mgmt[64] = {0};
-	int res = -1;
-
-	if (!output)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "wpa", wpa, sizeof(wpa));
-
-	memcpy(output, "None", 4);//Copying "None" to output string for default case
-	output[4] = '\0';
-	if (!strcmp(wpa, "0"))
-		return RETURN_OK;
-
-	wifi_hostapdRead(config_file, "wpa_key_mgmt", key_mgmt, sizeof(key_mgmt));
-	if (strstr(key_mgmt, "WPA-PSK") && strstr(key_mgmt, "SAE") == NULL) {
-		if (!strcmp(wpa, "1"))
-			res = snprintf(output, 32, "WPA-Personal");
-		else if (!strcmp(wpa, "2"))
-			res = snprintf(output, 32, "WPA2-Personal");
-		else if (!strcmp(wpa, "3"))
-			res = snprintf(output, 32, "WPA-WPA2-Personal");
-
-	} else if (strstr(key_mgmt, "WPA-EAP-SUITE-B-192")) {
-		res = snprintf(output, 32, "WPA3-Enterprise");
-	} else if (strstr(key_mgmt, "WPA-EAP")) {
-		if (!strcmp(wpa, "1"))
-			res = snprintf(output, 32, "WPA-Enterprise");
-		else if (!strcmp(wpa, "2"))
-			res = snprintf(output, 32, "WPA2-Enterprise");
-		else if (!strcmp(wpa, "3"))
-			res = snprintf(output, 32, "WPA-WPA2-Enterprise");
-	} else if (strstr(key_mgmt, "SAE")) {
-		if (strstr(key_mgmt, "WPA-PSK") == NULL)
-			res = snprintf(output, 32, "WPA3-Personal");
-		else
-			res = snprintf(output, 32, "WPA3-Personal-Transition");
-	}
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	//save the beaconTypeString to wifi config and hostapd config file. Wait for wifi reset or hostapd restart to apply
-	return RETURN_OK;
-}
-
-INT wifi_setApSecurityModeEnabled(INT apIndex, CHAR *encMode)
-{
-	char securityType[32] = {0};
-	char authMode[32] = {0};
-	unsigned long len_sec, len_auth;
-	//store settings and wait for wifi up to apply
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(!encMode)
-		return RETURN_ERR;
-
-	if (strcmp(encMode, "None")==0)
-	{
-		len_sec = strlen("None");
-		len_auth = strlen("None");
-		memcpy(securityType, "None", len_sec);
-		memcpy(authMode, "None", len_auth);
-	} else if (strcmp(encMode, "WPA-WPA2-Personal")==0) {
-		len_sec = strlen("WPAand11i");
-		memcpy(securityType, "WPAand11i", len_sec);
-		len_auth = strlen("PSKAuthentication");
-		memcpy(authMode, "PSKAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA-WPA2-Enterprise")==0) {
-		len_sec = strlen("WPAand11i");
-		memcpy(securityType, "WPAand11i", len_sec);
-		len_auth = strlen("EAPAuthentication");
-		memcpy(authMode, "EAPAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA-Personal")==0) {
-		len_sec = strlen("WPA");
-		memcpy(securityType, "WPA", len_sec);
-		len_auth = strlen("PSKAuthentication");
-		memcpy(authMode, "PSKAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA-Enterprise")==0) {
-		len_sec = strlen("WPA");
-		memcpy(securityType, "WPA", len_sec);
-		len_auth = strlen("EAPAuthentication");
-		memcpy(authMode, "EAPAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA2-Personal")==0) {
-		len_sec = strlen("11i");
-		memcpy(securityType, "11i", len_sec);
-		len_auth = strlen("PSKAuthentication");
-		memcpy(authMode, "PSKAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA2-Enterprise")==0) {
-		len_sec = strlen("11i");
-		memcpy(securityType, "11i", len_sec);
-		len_auth = strlen("EAPAuthentication");
-		memcpy(authMode, "EAPAuthentication", len_auth);
- 	} else if (strcmp(encMode, "WPA3-Personal") == 0) {
-		len_sec = strlen("11i");
-		memcpy(securityType, "11i", len_sec);
-		len_auth = strlen("SAEAuthentication");
-		memcpy(authMode, "SAEAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA3-Personal-Transition") == 0) {
-		len_sec = strlen("11i");
-		memcpy(securityType, "11i", len_sec);
-		len_auth = strlen("PSK-SAEAuthentication");
-		memcpy(authMode, "PSK-SAEAuthentication", len_auth);
-	} else if (strcmp(encMode, "WPA3-Enterprise") == 0) {
-		len_sec = strlen("11i");
-		memcpy(securityType, "11i", len_sec);
-		len_auth = strlen("EAP_192-bit_Authentication");
-		memcpy(authMode, "EAP_192-bit_Authentication", len_auth);
-	} else if (strcmp(encMode, "OWE") == 0) {
-		len_sec = strlen("11i");
-		memcpy(securityType, "11i", len_sec);
-		len_auth = strlen("Enhanced_Open");
-		memcpy(authMode, "Enhanced_Open", len_auth);
- 	} else {
-		len_sec = strlen("None");
-		memcpy(securityType, "None", len_sec);
-		len_auth = strlen("None");
-		memcpy(authMode, "None", len_auth);
-	}
-	securityType[len_sec] = '\0';
-	authMode[len_auth] = '\0';
-	wifi_setApBeaconType(apIndex, securityType);
-	wifi_setApBasicAuthenticationMode(apIndex, authMode);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-
-//A literal PreSharedKey (PSK) expressed as a hexadecimal string.
-// output_string must be pre-allocated as 64 character string by caller
-// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
-INT wifi_getApSecurityPreSharedKey(INT apIndex, CHAR *output_string)
-{
-	char buf[16] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if(output_string==NULL)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
-
-	if(strcmp(buf,"0")==0)
-	{
-		wifi_debug(DEBUG_ERROR, "wpa_mode is %s ......... \n",buf);
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file,"wpa_psk",output_string,65);
-	wifi_debug(DEBUG_INFO, "output_string=%s\n", output_string);
-
-	return RETURN_OK;
-}
-
-// sets an enviornment variable for the psk. Input string preSharedKey must be a maximum of 64 characters
-// PSK Key of 8 to 63 characters is considered an ASCII string, and 64 characters are considered as HEX value
-INT wifi_setApSecurityPreSharedKey(INT apIndex, CHAR *preSharedKey)
-{
-	//save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
-	struct params params={'\0'};
-	int ret;
-	char config_file[MAX_BUF_SIZE] = {0};
-
-	if(NULL == preSharedKey)
-		return RETURN_ERR;
-
-	params.name = "wpa_psk";
-
-	if(strlen(preSharedKey) != 64)
-	{
-		wifi_debug(DEBUG_ERROR, "\nCannot Set Preshared Key length of preshared key should be 64 chars\n");
-		return RETURN_ERR;
-	}
-	params.value = preSharedKey;
-	ret = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), ret)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	ret = wifi_hostapdWrite(config_file, &params, 1);
-	if(!ret) {
-		ret = wifi_hostapdProcessUpdate(apIndex, &params, 1);
-		wifi_reloadAp(apIndex);
-	}
-	return ret;
-	//TODO: call hostapd_cli for dynamic_config_control
-}
-
-//A passphrase from which the PreSharedKey is to be generated, for WPA-Personal or WPA2-Personal or WPA-WPA2-Personal security modes.
-// outputs the passphrase, maximum 63 characters
-INT wifi_getApSecurityKeyPassphrase(INT apIndex, CHAR *output_string)
-{
-	char config_file[MAX_BUF_SIZE] = {0}, buf[32] = {0};
-	int res;
-
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdRead(config_file,"wpa",buf,sizeof(buf));
-	if(strcmp(buf,"0")==0)
-	{
-		wifi_debug(DEBUG_ERROR, "wpa_mode is %s ......... \n",buf);
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdRead(config_file,"wpa_passphrase",output_string,64);
-	wifi_debug(DEBUG_INFO, "output_string=%s\n", output_string);
-
-	return RETURN_OK;
-}
-
-// sets the passphrase enviornment variable, max 63 characters
-INT wifi_setApSecurityKeyPassphrase(INT apIndex, CHAR *passPhrase)
-{
-	//save to wifi config and hotapd config. wait for wifi reset or hostapd restet to apply
-	struct params params={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int ret;
-
-	if(NULL == passPhrase)
-		return RETURN_ERR;
-
-	if(strlen(passPhrase)<8 || strlen(passPhrase)>63)
-	{
-		wifi_debug(DEBUG_ERROR, "\nCannot Set Preshared Key length of preshared key should be 8 to 63 chars\n");
-		return RETURN_ERR;
-	}
-	params.name = "wpa_passphrase";
-	params.value = passPhrase;
-	ret = snprintf(config_file, sizeof(config_file),
-		"%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), ret)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	ret=wifi_hostapdWrite(config_file,&params,1);
-	if(!ret) {
-		wifi_hostapdProcessUpdate(apIndex, &params, 1);
-		wifi_reloadAp(apIndex);
-	}
-
-	return ret;
-}
-
-//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.
-INT wifi_setApSecurityReset(INT apIndex)
-{
-	char original_config_file[64] = {0};
-	char current_config_file[64] = {0};
-	char buf[64] = {0};
-
-	char wpa[4] = {0};
-	char wpa_psk[64] = {0};
-	char wpa_passphrase[64] = {0};
-	char wpa_psk_file[128] = {0};
-	char wpa_key_mgmt[64] = {0};
-	char wpa_pairwise[32] = {0};
-	wifi_band band;
-	struct params list[6];
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	band = wifi_index_to_band(apIndex);
-	if (band == band_2_4) {
-		res = snprintf(original_config_file, sizeof(original_config_file),
-			"/etc/hostapd-2G.conf");
-		if (os_snprintf_error(sizeof(original_config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-	} else if (band == band_5) {
-		res = snprintf(original_config_file, sizeof(original_config_file),
-			"/etc/hostapd-5G.conf");
-		if (os_snprintf_error(sizeof(original_config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if (band == band_6) {
-		res = snprintf(original_config_file, sizeof(original_config_file),
-			"/etc/hostapd-6G.conf");
-		if (os_snprintf_error(sizeof(original_config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else
-		return RETURN_ERR;
-
-	wifi_hostapdRead(original_config_file, "wpa", wpa, sizeof(wpa));
-	list[0].name = "wpa";
-	list[0].value = wpa;
-
-	wifi_hostapdRead(original_config_file, "wpa_psk", wpa_psk, sizeof(wpa_psk));
-	list[1].name = "wpa_psk";
-	list[1].value = wpa_psk;
-
-	wifi_hostapdRead(original_config_file, "wpa_passphrase", wpa_passphrase, sizeof(wpa_passphrase));
-	list[2].name = "wpa_passphrase";
-	list[2].value = wpa_passphrase;
-
-	wifi_hostapdRead(original_config_file, "wpa_psk_file", wpa_psk_file, sizeof(wpa_psk_file));
-
-	if (strlen(wpa_psk_file) == 0)
-		memcpy(wpa_psk_file, PSK_FILE, strlen(PSK_FILE));
-
-	if (access(wpa_psk_file, F_OK) != 0) {
-		res = _syscmd_secure(buf, sizeof(buf),"touch %s", wpa_psk_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-	}
-	list[3].name = "wpa_psk_file";
-	list[3].value = wpa_psk_file;
-
-	wifi_hostapdRead(original_config_file, "wpa_key_mgmt", wpa_key_mgmt, sizeof(wpa_key_mgmt));
-	list[4].name = "wpa_key_mgmt";
-	list[4].value = wpa_key_mgmt;
-
-	wifi_hostapdRead(original_config_file, "wpa_pairwise", wpa_pairwise, sizeof(wpa_pairwise));
-	list[5].name = "wpa_pairwise";
-	list[5].value = wpa_pairwise;
-
-	res = snprintf(current_config_file, sizeof(current_config_file),
-		"%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(current_config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(current_config_file, list, 6);
-
-	wifi_setApEnable(apIndex, FALSE);
-	wifi_setApEnable(apIndex, TRUE);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//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).
-INT wifi_getApSecurityRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
-{
-	char config_file[64] = {0};
-	char buf[64] = {0};
-
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if(!IP_output || !Port_output || !RadiusSecret_output)
-		return RETURN_ERR;
-
-	// Read the first matched config
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	res = _syscmd_secure(buf, sizeof(buf),
-		"cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	strncpy(IP_output, buf, 64);
-
-	memset(buf, 0, sizeof(buf));
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	*Port_output = atoi(buf);
-
-	memset(buf, 0, sizeof(buf));
-	res = _syscmd_secure(buf, sizeof(buf),  "cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	strncpy(RadiusSecret_output, buf, 64);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setApSecurityRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
-{
-	char config_file[64] = {0};
-	char port_str[8] = {0};
-	char cmd[256] = {0};
-	char buf[128] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (strstr(buf, "Enterprise") == NULL)  // non Enterprise mode sould not set radius server info
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '# radius 1'", config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	memset(cmd, 0, sizeof(cmd));
-
-	res = snprintf(port_str, sizeof(port_str), "%d", port);
-	if (os_snprintf_error(sizeof(port_str), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (strlen(buf) == 0) {
-		// Append
-		res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 1\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
-		if (os_snprintf_error(sizeof(cmd), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		if(_syscmd_secure(buf, sizeof(buf), "echo -e '# radius 1\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file)) {
-			wifi_debug(DEBUG_ERROR, "command failed, cmd: %s\n", cmd);
-			return RETURN_ERR;
-		}
-	} else {
-		// Delete the three lines setting after the "# radius 1" comment
-		res = _syscmd_secure(buf, sizeof(buf), "sed -i '/# radius 1/{n;N;N;d}' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-		memset(cmd, 0, sizeof(cmd));
-		// Use "# radius 1" comment to find the location to insert the radius setting
-		res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 1/"
-								"# radius 1\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
-		if (os_snprintf_error(sizeof(cmd), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		if(_syscmd_secure(buf, sizeof(buf), "sed -i 's/# radius 1/"
-								"# radius 1\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file)) {
-			wifi_debug(DEBUG_ERROR, "command failed, cmd: %s\n", cmd);
-			return RETURN_ERR;
-		}
-	}
-
-	wifi_reloadAp(apIndex);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IP_output, UINT *Port_output, CHAR *RadiusSecret_output)
-{
-	char config_file[64] = {0};
-	char buf[64] = {0};
-
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if(!IP_output || !Port_output || !RadiusSecret_output)
-		return RETURN_ERR;
-
-	// Read the second matched config
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf),
-		"cat %s | grep \"^auth_server_addr=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
-		config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	strncpy(IP_output, buf, 64);
-
-	memset(buf, 0, sizeof(buf));
-	res = _syscmd_secure(buf, sizeof(buf),
-		"cat %s | grep \"^auth_server_port=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
-		config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	*Port_output = atoi(buf);
-
-	memset(buf, 0, sizeof(buf));
-	res = _syscmd_secure(buf, sizeof(buf),
-		"cat %s | grep \"^auth_server_shared_secret=\" | cut -d \"=\" -f 2 | tail -n +2 | head -n1 | tr -d \"\\n\"",
-		config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	strncpy(RadiusSecret_output, buf, 64);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setApSecuritySecondaryRadiusServer(INT apIndex, CHAR *IPAddress, UINT port, CHAR *RadiusSecret)
-{
-	char config_file[64] = {0};
-	char port_str[8] = {0};
-	char cmd[256] = {0};
-	char buf[128] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (wifi_getApSecurityModeEnabled(apIndex, buf) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (strstr(buf, "Enterprise") == NULL)  // non Enterprise mode sould not set radius server info
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep '# radius 2'", config_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	memset(cmd, 0, sizeof(cmd));
-
-	res = snprintf(port_str, sizeof(port_str), "%d", port);
-	if (os_snprintf_error(sizeof(port_str), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (strlen(buf) == 0) {
-		// Append
-		res = snprintf(cmd, sizeof(cmd), "echo -e '# radius 2\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file);
-		if (os_snprintf_error(sizeof(cmd), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		if(_syscmd_secure(buf, sizeof(buf), "echo -e '# radius 2\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s' >> %s", IPAddress, port_str, RadiusSecret, config_file)){
-			wifi_debug(DEBUG_ERROR, "command failed, cmd: %s\n", cmd);
-			return RETURN_ERR;
-		}
-	} else {
-		// Delete the three lines setting after the "# radius 2" comment
-		res = _syscmd_secure(buf, sizeof(buf), "sed -i '/# radius 2/{n;N;N;d}' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		}
-
-		memset(cmd, 0, sizeof(cmd));
-		// Use "# radius 2" comment to find the location to insert the radius setting
-		res = snprintf(cmd, sizeof(cmd), "sed -i 's/# radius 2/"
-								"# radius 2\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file);
-		if (os_snprintf_error(sizeof(cmd), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		if(_syscmd_secure(buf, sizeof(buf), "sed -i 's/# radius 2/"
-								"# radius 2\\n"
-								"auth_server_addr=%s\\n"
-								"auth_server_port=%s\\n"
-								"auth_server_shared_secret=%s/' %s", IPAddress, port_str, RadiusSecret, config_file)){
-			wifi_debug(DEBUG_ERROR, "command failed, cmd: %s\n", cmd);
-			return RETURN_ERR;
-		}
-	}
-
-	wifi_reloadAp(apIndex);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//RadiusSettings
-INT wifi_getApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *output)
-{
-	if(!output)
-		return RETURN_ERR;
-
-	output->RadiusServerRetries = 3; 				//Number of retries for Radius requests.
-	output->RadiusServerRequestTimeout = 5; 		//Radius request timeout in seconds after which the request must be retransmitted for the # of retries available.
-	output->PMKLifetime = 28800; 					//Default time in seconds after which a Wi-Fi client is forced to ReAuthenticate (def 8 hrs).
-	output->PMKCaching = FALSE; 					//Enable or disable caching of PMK.
-	output->PMKCacheInterval = 300; 				//Time interval in seconds after which the PMKSA (Pairwise Master Key Security Association) cache is purged (def 5 minutes).
-	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.
-	output->BlacklistTableTimeout = 600; 			//Time interval in seconds for which a client will continue to be blacklisted once it is marked so.
-	output->IdentityRequestRetryInterval = 5; 	//Time Interval in seconds between identity requests retries. A value of 0 (zero) disables it.
-	output->QuietPeriodAfterFailedAuthentication = 5;  	//The enforced quiet period (time interval) in seconds following failed authentication. A value of 0 (zero) disables it.
-	//res = 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.
-
-	return RETURN_OK;
-}
-
-INT wifi_setApSecurityRadiusSettings(INT apIndex, wifi_radius_setting_t *input)
-{
-	//store the paramters, and apply instantly
-	return RETURN_ERR;
-}
-
-//Device.WiFi.AccessPoint.{i}.WPS.Enable
-//Enables or disables WPS functionality for this access point.
-// outputs the WPS enable state of this ap in output_bool
-INT wifi_getApWpsEnable(INT apIndex, BOOL *output_bool)
-{
-	char interface_name[16] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if(!output_bool)
-		return RETURN_ERR;
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = _syscmd_secure(buf, sizeof(buf),
-		"hostapd_cli -i %s get_config | grep wps_state | cut -d '=' -f2",
-		interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	if(strstr(buf, "configured"))
-		*output_bool=TRUE;
-	else
-		*output_bool=FALSE;
-
-	return RETURN_OK;
-}
-
-//Device.WiFi.AccessPoint.{i}.WPS.Enable
-// sets the WPS enable enviornment variable for this ap to the value of enableValue, 1==enabled, 0==disabled
-INT wifi_setApWpsEnable(INT apIndex, BOOL enable)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	char buf[128] = {0};
-	struct params params;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	//store the paramters, and wait for wifi up to apply
-	params.name = "wps_state";
-	if (enable == TRUE) {
-		wifi_getApBeaconType(apIndex, buf);
-		if (strncmp(buf, "None", 4) == 0)   // If ap didn't set encryption
-			params.value = "1";
-		else								// If ap set encryption
-			params.value = "2";
-	} else {
-		params.value = "0";
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	wifi_reloadAp(apIndex);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-//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
-INT wifi_getApWpsConfigMethodsSupported(INT apIndex, CHAR *output)
-{
-	int res;
-	if(!output)
-		return RETURN_ERR;
-	res = snprintf(output, 128, "PushButton,PIN");
-	if (os_snprintf_error(128, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
-//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.
-// Outputs a common separated list of the enabled WPS config methods, 64 bytes max
-INT wifi_getApWpsConfigMethodsEnabled(INT apIndex, CHAR *output)
-{
-	int res;
-	if(!output)
-		return RETURN_ERR;
-	res = snprintf(output, 64, "PushButton,PIN");//Currently, supporting these two methods
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-//Device.WiFi.AccessPoint.{i}.WPS.ConfigMethodsEnabled
-// 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
-INT wifi_setApWpsConfigMethodsEnabled(INT apIndex, CHAR *methodString)
-{
-	//apply instantly. No setting need to be stored.
-	char methods[MAX_BUF_SIZE], *token, *next_token;
-	char config_file[MAX_BUF_SIZE], config_methods[MAX_BUF_SIZE] = {0};
-	struct params params;
-	int res;
-
-	if(!methodString)
-		return RETURN_ERR;
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	//store the paramters, and wait for wifi up to apply
-
-	res = snprintf(methods, sizeof(methods), "%s", methodString);
-	if (os_snprintf_error(sizeof(methods), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	for(token=methods; *token; token=next_token) {
-		strtok_r(token, ",", &next_token);
-		if(*token=='U' && !strcmp(methods, "USBFlashDrive"))
-			res = snprintf(config_methods, sizeof(config_methods), "%s ", "usba");
-		else if(*token=='E')
-		{
-			if(!strcmp(methods, "Ethernet"))
-				res = snprintf(config_methods, sizeof(config_methods), "%s ", "ethernet");
-			else if(!strcmp(methods, "ExternalNFCToken"))
-				res = snprintf(config_methods, sizeof(config_methods), "%s ", "ext_nfc_token");
-			else
-				wifi_debug(DEBUG_ERROR, "Unknown WpsConfigMethod\n");
-		}
-		else if(*token=='I' && !strcmp(token, "IntegratedNFCToken"))
-			res = snprintf(config_methods, sizeof(config_methods), "%s ", "int_nfc_token");
-		else if(*token=='N' && !strcmp(token, "NFCInterface"))
-			res = snprintf(config_methods, sizeof(config_methods), "%s ", "nfc_interface");
-		else if(*token=='P' )
-		{
-			if(!strcmp(token, "PushButton"))
-				res = snprintf(config_methods, sizeof(config_methods), "%s ", "push_button");
-			else if(!strcmp(token, "PIN"))
-				res = snprintf(config_methods, sizeof(config_methods), "%s ", "keypad");
-			else
-				wifi_debug(DEBUG_ERROR, "Unknown WpsConfigMethod\n");
-		}
-		else
-			wifi_debug(DEBUG_ERROR, "Unknown WpsConfigMethod\n");
-
-		if (os_snprintf_error(sizeof(config_methods), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-	params.name = "config_methods";
-	params.value = config_methods;
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// outputs the pin value, ulong_pin must be allocated by the caller
-INT wifi_getApWpsDevicePIN(INT apIndex, ULONG *output_ulong)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-
-	int res;
-
-	if(!output_ulong)
-		return RETURN_ERR;
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s%d.conf | grep ap_pin | cut -d '=' -f2", CONFIG_PREFIX, apIndex);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	if(strlen(buf) > 0) {
-		if (hal_strtoul(buf, 10, output_ulong) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-	}
-
-	return RETURN_OK;
-}
-
-// set an enviornment variable for the WPS pin for the selected AP. Normally, Device PIN should not be changed.
-INT wifi_setApWpsDevicePIN(INT apIndex, ULONG pin)
-{
-	//set the pin to wifi config and hostpad config. wait for wifi reset or hostapd reset to apply
-	char ap_pin[16] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params params;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	res = snprintf(ap_pin, sizeof(ap_pin), "%lu", pin);
-	if (os_snprintf_error(sizeof(ap_pin), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.name = "ap_pin";
-	params.value = ap_pin;
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// Output string is either Not configured or Configured, max 32 characters
-INT wifi_getApWpsConfigurationState(INT apIndex, CHAR *output_string)
-{
-	char interface_name[16] = {0};
-	char buf[MAX_BUF_SIZE]={0};
-	int res;
-
-	if(!output_string)
-		return RETURN_ERR;
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	res = snprintf(output_string, 32, "Not configured");
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s get_config | grep wps_state | cut -d'=' -f2", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if(!strncmp(buf, "configured", 10)) {
-		res = snprintf(output_string, 32, "Configured");
-		if (os_snprintf_error(32, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-// sets the WPS pin for this AP
-INT wifi_setApWpsEnrolleePin(INT apIndex, CHAR *pin)
-{
-	char interface_name[16] = {0};
-	char buf[MAX_BUF_SIZE]={0};
-	BOOL enable = 0;
-	int res;
-
-	wifi_getApEnable(apIndex, &enable);
-	if (!enable)
-		return RETURN_ERR;
-	wifi_getApWpsEnable(apIndex, &enable);
-	if (!enable)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s wps_pin any %s", interface_name, pin);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if((strstr(buf, "OK"))!=NULL)
-		return RETURN_OK;
-
-	return RETURN_ERR;
-}
-
-// This function is called when the WPS push button has been pressed for this AP
-INT wifi_setApWpsButtonPush(INT apIndex)
-{
-	char buf[MAX_BUF_SIZE]={0};
-	char interface_name[16] = {0};
-	BOOL enable=FALSE;
-	int res;
-
-	wifi_getApEnable(apIndex, &enable);
-	if (!enable)
-		return RETURN_ERR;
-
-	wifi_getApWpsEnable(apIndex, &enable);
-	if (!enable)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s wps_cancel; hostapd_cli -i%s wps_pbc", interface_name, interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if((strstr(buf, "OK"))!=NULL)
-		return RETURN_OK;
-	return RETURN_ERR;
-}
-
-// cancels WPS mode for this AP
-INT wifi_cancelApWPS(INT apIndex)
-{
-	char interface_name[16] = {0};
-	char buf[MAX_BUF_SIZE]={0};
-	int res;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s wps_cancel", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if((strstr(buf, "OK"))!=NULL)
-		return RETURN_OK;
-	return RETURN_ERR;
-}
-
-//Device.WiFi.AccessPoint.{i}.AssociatedDevice.*
-//HAL funciton should allocate an data structure array, and return to caller with "associated_dev_array"
-INT wifi_getApAssociatedDeviceDiagnosticResult(INT apIndex, wifi_associated_dev_t **associated_dev_array, UINT *output_array_size)
-{
-	char interface_name[16] = {0};
-	FILE *f = NULL;
-	int read_flag=0, auth_temp=0, mac_temp=0;
-	char buf[2048] = {0};
-	char count[8] = {0};
-	char *param = NULL, *value = NULL, *line=NULL;
-	size_t len = 0;
-	wifi_associated_dev_t *dev=NULL;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	*associated_dev_array = NULL;
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i%s all_sta > /tmp/connected_devices.txt" , interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	res = _syscmd_secure(count, sizeof(count), "cat /tmp/connected_devices.txt | grep AUTHORIZED | wc -l");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	*output_array_size = atoi(count);
-
-	if (*output_array_size <= 0)
-		return RETURN_OK;
-
-	dev=(wifi_associated_dev_t *) calloc (*output_array_size, sizeof(wifi_associated_dev_t));
-	if (!dev) {
-		wifi_debug(DEBUG_ERROR, "Unexpected calloc fail\n");
-		return RETURN_ERR;
-	}
-	*associated_dev_array = dev;
-
-	f = fopen("/tmp/connected_devices.txt", "r");
-	if (f==NULL)
-	{
-		*output_array_size=0;
-		return RETURN_ERR;
-	}
-	while ((getline(&line, &len, f)) != -1)
-	{
-		param = strtok(line,"=");
-		if (!param)
-			continue;
-		value = strtok(NULL,"=");
-		if (!value)
-			continue;
-
-		if( strcmp("flags",param) == 0 )
-		{
-			value[strlen(value)-1]='\0';
-			if(strstr (value,"AUTHORIZED") != NULL )
-			{
-				if (auth_temp < *output_array_size) {
-					dev[auth_temp].cli_AuthenticationState = 1;
-					dev[auth_temp].cli_Active = 1;
-					auth_temp++;
-					read_flag=1;
-				} else
-					wifi_debug(DEBUG_ERROR, "auth_temp = %d, output_array_size = %d\n", auth_temp ,*output_array_size);
-			}
-		}
-		if(read_flag==1)
-		{
-			if( strcmp("dot11RSNAStatsSTAAddress",param) == 0 )
-			{
-				if (mac_temp < *output_array_size) {
-					value[strlen(value)-1]='\0';
-					if (sscanf(value, "%x:%x:%x:%x:%x:%x",
-							(unsigned int *)&dev[mac_temp].cli_MACAddress[0],
-							(unsigned int *)&dev[mac_temp].cli_MACAddress[1],
-							(unsigned int *)&dev[mac_temp].cli_MACAddress[2],
-							(unsigned int *)&dev[mac_temp].cli_MACAddress[3],
-							(unsigned int *)&dev[mac_temp].cli_MACAddress[4],
-							(unsigned int *)&dev[mac_temp].cli_MACAddress[5] ) == EOF)
-							continue;
-					mac_temp++;
-					read_flag=0;
-				} else
-					wifi_debug(DEBUG_ERROR, "mac_temp = %d, output_array_size = %d\n", auth_temp ,*output_array_size);
-			}
-		}
-	}
-	*output_array_size = auth_temp;
-	auth_temp=0;
-	mac_temp=0;
-	free(line);
-	if (fclose(f) == EOF) {
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-#define MACADDRESS_SIZE 6
-
-INT wifihal_AssociatedDevicesstats3(INT apIndex,CHAR *interface_name,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
-{
-	FILE *fp = NULL;
-	char str[MAX_BUF_SIZE] = {0};
-	int wificlientindex = 0 ;
-	int count = 0;
-	int signalstrength = 0;
-	int arr[MACADDRESS_SIZE] = {0};
-	unsigned char mac[MACADDRESS_SIZE] = {0};
-	UINT wifi_count = 0;
-	int res;
-	wifi_associated_dev3_t* temp = NULL;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	*output_array_size = 0;
-	*associated_dev_array = NULL;
-
-	fp = v_secure_popen("r", "iw dev %s station dump | grep %s | wc -l",
-		interface_name, interface_name);
-	if (fp == NULL)
-	{
-		wifi_debug(DEBUG_ERROR, "Failed to run command\n");
-		return RETURN_ERR;
-	}
-
-	/* Read the output a line at a time - output it. */
-	if (fgets(str, sizeof(str)-1, fp) == NULL) {
-		wifi_debug(DEBUG_ERROR, "fgets fail\n");
-		v_secure_pclose(fp);
-		return RETURN_ERR;
-	}
-	wifi_count = (unsigned int) atoi ( str );
-	*output_array_size = wifi_count;
-	wifi_debug(DEBUG_OFF, " In rdkb hal ,Wifi Client Counts and index %d and  %d \n",*output_array_size,apIndex);
-	v_secure_pclose(fp);
-
-	if(wifi_count == 0)
-	{
-		return RETURN_OK;
-	}
-	else
-	{
-		if(wifi_count <= 0 || wifi_count >  MAX_ASSOCIATED_STA_NUM){
-			return RETURN_ERR;
-		}
-		temp = (wifi_associated_dev3_t*)calloc(1, sizeof(wifi_associated_dev3_t)*wifi_count) ;
-		if(temp == NULL)
-		{
-			wifi_debug(DEBUG_ERROR, "Error Statement. Insufficient memory \n");
-			return RETURN_ERR;
-		}
-
-		res = v_secure_system("iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-			free(temp);
-			return RETURN_ERR;
-		}
-
-		if(apIndex == 0)
-			res = v_secure_system("iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_2G.txt", interface_name);
-		else if(apIndex == 1)
-			res = v_secure_system("iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-			free(temp);
-			return RETURN_ERR;
-		}
-
-		fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
-		if(fp == NULL)
-		{
-			wifi_debug(DEBUG_ERROR, "/tmp/AssociatedDevice_Stats.txt not exists \n");
-			free(temp);
-			return RETURN_ERR;
-		}
-		if (fclose(fp) == EOF) {
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-			free(temp);
-			return RETURN_ERR;
-		}
-
-		fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
-		if(fp)
-		{
-			for(count =0 ; count < wifi_count; count++)
-			{
-				if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-					wifi_debug(DEBUG_ERROR, "fgets fail\n");
-					goto err;
-				}
-				if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
-				{
-					for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
-					{
-						mac[wificlientindex] = (unsigned char) arr[wificlientindex];
-
-					}
-					memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
-					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]);
-				}
-				temp[count].cli_AuthenticationState = 1; //TODO
-				temp[count].cli_Active = 1; //TODO
-			}
-			v_secure_pclose(fp);
-		}
-
-		fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
-		if(fp)
-		{
-			v_secure_pclose(fp);
-		}
-		fp = v_secure_popen("r", "cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2");
-		if(fp)
-		{
-			for(count =0 ; count < wifi_count ;count++)
-			{
-				if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-					wifi_debug(DEBUG_ERROR, "fgets fail\n");
-					goto err;
-				}
-				signalstrength = atoi(str);
-				temp[count].cli_SignalStrength = signalstrength;
-				temp[count].cli_RSSI = signalstrength;
-				temp[count].cli_SNR = signalstrength + 95;
-			}
-			v_secure_pclose(fp);
-		}
-
-
-		if((apIndex == 0) || (apIndex == 4))
-		{
-			for(count =0 ; count < wifi_count ;count++)
-			{
-				memcpy(temp[count].cli_OperatingStandard,"g", 1);
-				temp[count].cli_OperatingStandard[1] = '\0';
-				memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
-				temp[count].cli_OperatingChannelBandwidth[5] = '\0';
-			}
-
-			//BytesSent
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Send.txt");
-			if(fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Bytes_Send.txt | tr -s ' ' | cut -f 2");
-			if(fp)
-			{
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						v_secure_pclose(fp);
-						free(temp);
-						return RETURN_ERR;
-					}
-					if (hal_strtoul(str, 10, &(temp[count].cli_BytesSent)) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-				}
-				v_secure_pclose(fp);
-			}
-
-			//BytesReceived
-
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bytes' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bytes_Received.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Bytes_Received.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-					if (hal_strtoul(str, 10, &(temp[count].cli_BytesReceived)) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-				}
-				v_secure_pclose(fp);
-			}
-
-			//PacketsSent
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Send.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-
-			fp = v_secure_popen("r", "cat /tmp/Ass_Packets_Send.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-					if (hal_strtoul(str, 10, &(temp[count].cli_PacketsSent)) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-				}
-				v_secure_pclose(fp);
-			}
-
-			//PacketsReceived
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx packets' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Packets_Received.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Packets_Received.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-					if (hal_strtoul(str, 10, &(temp[count].cli_PacketsReceived)) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-				}
-				v_secure_pclose(fp);
-			}
-
-			//ErrorsSent
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL){
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-					if (hal_strtoul(str, 10, &(temp[count].cli_ErrorsSent)) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-				}
-				v_secure_pclose(fp);
-			}
-
-			//ErrorsSent
-
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx failed' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Tx_Failed.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Tx_Failed.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-					if (hal_strtoul(str, 10, &(temp[count].cli_ErrorsSent)) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-				}
-				v_secure_pclose(fp);
-			}
-
-			//LastDataDownlinkRate
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				unsigned long tmp_u;
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-
-					if (hal_strtoul(str, 10, &tmp_u) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-					temp[count].cli_LastDataDownlinkRate = tmp_u;
-					temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
-				}
-				v_secure_pclose(fp);
-			}
-
-			//LastDataUplinkRate
-			fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
-			if (fp)
-			{
-				v_secure_pclose(fp);
-			}
-			fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2");
-			if (fp)
-			{
-				unsigned long tmp_u;
-				for (count = 0; count < wifi_count; count++)
-				{
-					if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-						wifi_debug(DEBUG_ERROR, "fgets fail\n");
-						goto err;
-					}
-					if (hal_strtoul(str, 10, &tmp_u) < 0) {
-						wifi_debug(DEBUG_ERROR, "strtol fail\n");
-					}
-					temp[count].cli_LastDataUplinkRate = tmp_u;
-
-					temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
-				}
-				v_secure_pclose(fp);
-			}
-
-		}
-		else if ((apIndex == 1) || (apIndex == 5))
-		{
-			for (count = 0; count < wifi_count; count++)
-			{
-				memcpy(temp[count].cli_OperatingStandard, "a", 1);
-				temp[count].cli_OperatingStandard[1] = '\0';
-				memcpy(temp[count].cli_OperatingChannelBandwidth, "20MHz", 5);
-				temp[count].cli_OperatingChannelBandwidth[5] = '\0';
-				temp[count].cli_BytesSent = 0;
-				temp[count].cli_BytesReceived = 0;
-				temp[count].cli_LastDataUplinkRate = 0;
-				temp[count].cli_LastDataDownlinkRate = 0;
-				temp[count].cli_PacketsSent = 0;
-				temp[count].cli_PacketsReceived = 0;
-				temp[count].cli_ErrorsSent = 0;
-			}
-		}
-
-		for (count = 0; count < wifi_count; count++)
-		{
-			temp[count].cli_Retransmissions = 0;
-			temp[count].cli_DataFramesSentAck = 0;
-			temp[count].cli_DataFramesSentNoAck = 0;
-			temp[count].cli_MinRSSI = 0;
-			temp[count].cli_MaxRSSI = 0;
-			strncpy(temp[count].cli_InterferenceSources, "", 64);
-			memset(temp[count].cli_IPAddress, 0, 64);
-			temp[count].cli_RetransCount = 0;
-			temp[count].cli_FailedRetransCount = 0;
-			temp[count].cli_RetryCount = 0;
-			temp[count].cli_MultipleRetryCount = 0;
-		}
-		*associated_dev_array = temp;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	if (temp)
-		free(temp);
-	v_secure_pclose(fp);
-	return RETURN_ERR;
-}
-
-int wifihal_interfacestatus(CHAR *wifi_status, CHAR *interface_name)
-{
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-	unsigned long len;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	res = _syscmd_secure(buf, MAX_BUF_SIZE, "ifconfig %s | grep RUNNING | tr -s ' ' | cut -d ' ' -f4 | tr -d '\\n'",
-		interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	len = strlen(buf);
-	if (len >= sizeof(buf)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected buf size\n");
-		return RETURN_ERR;
-	}
-	strncpy(wifi_status, buf, len); /* TBD: check wifi_status mem lenth and replace with strcpy later */
-	wifi_status[len] = '\0';
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-static const char *get_line_from_str_buf(const char *buf, char *line)
-{
-	int i;
-	int n = strlen(buf);
-
-	for (i = 0; i < n; i++) {
-		line[i] = buf[i];
-		if (buf[i] == '\n') {
-			line[i] = '\0';
-			return &buf[i + 1];
-		}
-	}
-
-	return NULL;
-}
-
-int mtk_get_station_callback(struct nl_msg *msg, void *cb)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh;
-	int err = 0;
-	unsigned short len = 0;
-	struct station_information *sta;
-	struct mtk_nl80211_cb_data *cb_data = cb;
-	if (!msg || !cb_data) {
-		wifi_debug(DEBUG_ERROR, "msg(%p) or cb_data(%p) is null,error.\n", msg, cb_data);
-		return NL_SKIP;
-	}
-
-	gnlh = nlmsg_data(nlmsg_hdr(msg));
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0) {
-		wifi_debug(DEBUG_ERROR, "nla_parse acl list nl80211 msg fails,error.\n");
-		return NL_SKIP;
-	}
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_ATTR_STA_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return NL_SKIP;
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_INFO]) {
-			len = nla_len(vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_INFO]);
-			sta = (struct station_information*)nla_data(vndr_tb[MTK_NL80211_VENDOR_ATTR_STA_INFO]);
-			if (len != sizeof(*sta)){
-				wifi_debug(DEBUG_ERROR,"result len(%u) is invalid, expected len(%lu)!!!\n", len, sizeof(*sta));
-				return NL_SKIP;
-			}
-			memcpy(cb_data->out_buf, sta, len);
-		} else
-			wifi_debug(DEBUG_ERROR, "no MTK_NL80211_VENDOR_ATTR_STA_INFO attr\n");
-	} else
-		wifi_debug(DEBUG_ERROR, "no any station result from driver\n");
-	return NL_OK;
-}
-INT station_info_2_dev3(struct station_information *sta, wifi_associated_dev3_t *dev3)
-{
-	int i = 0, n = 0;
-	UCHAR len = 0;
-	UCHAR phymode;
-	UCHAR bw;
-	dev3->cli_LastDataDownlinkRate = sta->rx_rate;
-	dev3->cli_LastDataUplinkRate = sta->tx_rate;
-	dev3->cli_SNR = sta->snr[0];
-	dev3->cli_BytesReceived = sta->rx_bytes;
-	dev3->cli_BytesSent = sta->tx_bytes;
-	for (i = 0; i < 4; i++) {
-		if (sta->rssi[0] == -127)
-			continue;
-		dev3->cli_RSSI += sta->rssi[i];
-		n++;
-	}
-	if (sta->cap_phymode < ARRAY_SIZE(phy_mode_str)) {
-		phymode = sta->cap_phymode;
-		len = sizeof(phy_mode_str[sta->cap_phymode]);
-		memcpy(dev3->cli_OperatingStandard, phy_mode_str[phymode], len);
-	}
-	if (MAX(sta->tx_bw, sta->rx_bw) < ARRAY_SIZE(phy_bw_str_txrx_stainfo)) {
-		bw = MAX(sta->tx_bw, sta->rx_bw);
-		len = sizeof(phy_mode_str[bw]);
-		memcpy(dev3->cli_OperatingChannelBandwidth, phy_bw_str_txrx_stainfo[bw], len);
-	}
-
-	dev3->cli_RSSI = dev3->cli_RSSI/n;
-	dev3->cli_PacketsReceived = sta->rx_packets;
-	dev3->cli_PacketsSent = sta->tx_packets;
-	dev3->mld_enable = sta->mlo_enable;
-	memcpy(dev3->mld_addr, sta->mld_mac, 6);
-	for (i = 0; i < 3; i++) {
-		dev3->mld_link_info[i].valid = sta->mlo_link[i].valid;
-		if (!dev3->mld_link_info[i].valid)
-			continue;
-		memcpy(dev3->mld_link_info[i].link_addr, sta->mlo_link[i].link_address, 6);
-		dev3->mld_link_info[i].rssi = sta->mlo_link[i].rssi[0];
-		dev3->mld_link_info[i].rx_bytes = sta->mlo_link[i].rx_bytes;
-		dev3->mld_link_info[i].tx_bytes = sta->mlo_link[i].tx_bytes;
-		dev3->mld_link_info[i].rx_rate = sta->mlo_link[i].rx_rate;
-		dev3->mld_link_info[i].tx_rate = sta->mlo_link[i].tx_rate;
-	}
-
-	return RETURN_OK;
-}
-
-INT fill_dev3_statistics_by_mac(INT apIndex, wifi_associated_dev3_t *dev3, unsigned char *mac)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	unsigned int if_idx = 0;
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param nl_param;
-	struct mtk_nl80211_cb_data cb_data;
-	struct station_information station;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-			return RETURN_ERR;
-
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STA;
-	nl_param.if_type = NL80211_ATTR_IFINDEX;
-	nl_param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_STA_MAC, ETH_ALEN, mac)) {
-		wifi_debug(DEBUG_ERROR, "Nla put ACL_SHOW_ALL attribute error\n");
-		nlmsg_free(msg);
-		mtk_nl80211_deint(&unl_ins);
-		return RETURN_ERR;
-	}
-	cb_data.out_buf = (void*)&station;
-
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_station_callback, &cb_data);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		mtk_nl80211_deint(&unl_ins);
-		return RETURN_ERR;
-	}
-	station_info_2_dev3(&station, dev3);
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-
-	return RETURN_OK;
-}
-
-INT wifi_getApAssociatedDeviceDiagnosticResult3(INT apIndex, wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
-{
-	char interface_name[16] = {0};
-	FILE *f = NULL;
-	int auth_temp= -1;
-	char buf[2048] = {0};
-	char count[8] = {0};
-	char *param = NULL, *value = NULL, *line=NULL;
-	size_t len = 0;
-	wifi_associated_dev3_t *dev=NULL;
-	int res, i;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	*associated_dev_array = NULL;
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf),
-		"hostapd_cli -i%s all_sta > /tmp/diagnostic3_devices.txt" , interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	res = _syscmd_secure(count, sizeof(count), "cat /tmp/diagnostic3_devices.txt | grep AUTHORIZED | wc -l");
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	*output_array_size = atoi(count);
-
-	if (*output_array_size <= 0)
-		return RETURN_OK;
-
-	dev=(wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
-
-	if (dev == NULL) {
-		wifi_debug(DEBUG_ERROR, "calloc fail\n");
-		return RETURN_ERR;
-	}
-	*associated_dev_array = dev;
-
-	f = fopen("/tmp/diagnostic3_devices.txt", "r");
-	if (f == NULL)
-	{
-		*output_array_size=0;
-		return RETURN_ERR;
-	}
-	while ((getline(&line, &len, f)) != -1)
-	{
-		param = strtok(line, "=");
-		if (!param)
-			continue;
-		value = strtok(NULL, "=");
-		if (!value)
-			continue;
-
-		if( strcmp("flags",param) == 0 )
-		{
-			value[strlen(value)-1]='\0';
-			if(strstr (value,"AUTHORIZED") != NULL )
-			{
-				auth_temp++;
-				if (auth_temp < *output_array_size) {
-					dev[auth_temp].cli_AuthenticationState = 1;
-					dev[auth_temp].cli_Active = 1;
-				} else
-					wifi_debug(DEBUG_ERROR, "auth_temp = %d, output_array_size = %d\n", auth_temp ,*output_array_size);
-			}
-		} else if (auth_temp < 0) {
-			continue;
-		} else if( strcmp("dot11RSNAStatsSTAAddress", param) == 0 )
-		{
-			if (auth_temp < *output_array_size) {
-				value[strlen(value)-1]='\0';
-				if (sscanf(value, "%x:%x:%x:%x:%x:%x",
-					(unsigned int *)&dev[auth_temp].cli_MACAddress[0],
-					(unsigned int *)&dev[auth_temp].cli_MACAddress[1],
-					(unsigned int *)&dev[auth_temp].cli_MACAddress[2],
-					(unsigned int *)&dev[auth_temp].cli_MACAddress[3],
-					(unsigned int *)&dev[auth_temp].cli_MACAddress[4],
-					(unsigned int *)&dev[auth_temp].cli_MACAddress[5]) == EOF)
-					continue;
-			} else
-				wifi_debug(DEBUG_ERROR, "auth_temp = %d, output_array_size = %d\n", auth_temp ,*output_array_size);
-		} else if (strcmp("signal", param) == 0) {
-			if (auth_temp < *output_array_size) {
-				value[strlen(value)-1]='\0';
-				if (sscanf(value, "%d", &dev[auth_temp].cli_RSSI) == EOF)
-					continue;
-				dev[auth_temp].cli_SNR = 95 + dev[auth_temp].cli_RSSI;
-			} else
-				wifi_debug(DEBUG_ERROR, "auth_temp = %d, output_array_size = %d\n", auth_temp ,*output_array_size);
-		}
-	}
-	if (line)
-		free(line);
-
-	if (fclose(f) != 0) {
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-	}
-
-	for (i = 0; i < *output_array_size; i++) {
-		if (fill_dev3_statistics_by_mac(apIndex, &dev[i], dev[i].cli_MACAddress)) {
-			wifi_debug(DEBUG_ERROR, "fail to get dev3(%02x:%02x:%02x:%02x:%02x:%02x)"
-				" statistic information from logan driver\n", dev[i].cli_MACAddress[0],
-				dev[i].cli_MACAddress[1], dev[i].cli_MACAddress[2], dev[i].cli_MACAddress[3],
-				dev[i].cli_MACAddress[4], dev[i].cli_MACAddress[5]);
-			continue;
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-/* getIPAddress function */
-/**
-* @description Returning IpAddress of the Matched String
-*
-* @param
-* @str Having MacAddress
-* @ipaddr Having ipaddr
-* @return The status of the operation
-* @retval RETURN_OK if successful
-* @retval RETURN_ERR if any error is detected
-*
-*/
-
-INT getIPAddress(char *str,char *ipaddr)
-{
-	FILE *fp = NULL;
-	char buf[1024] = {0},ipAddr[50] = {0},phyAddr[100] = {0},hostName[100] = {0};
-	int LeaseTime = 0,ret = 0;
-	unsigned long len;
-
-	if ( (fp=fopen("/nvram/dnsmasq.leases", "r")) == NULL )
-	{
-		return RETURN_ERR;
-	}
-
-	while ( fgets(buf, sizeof(buf), fp)!= NULL )
-	{
-		/*
-		Sample:sss
-		1560336751 00:cd:fe:f3:25:e6 10.0.0.153 NallamousiPhone 01:00:cd:fe:f3:25:e6
-		1560336751 12:34:56:78:9a:bc 10.0.0.154 NallamousiPhone 01:00:cd:fe:f3:25:e6
-		*/
-		ret = sscanf(buf, LM_DHCP_CLIENT_FORMAT,
-			&(LeaseTime),
-			phyAddr,
-			ipAddr,
-			hostName
-			);
-		if(ret != 4)
-			continue;
-		if (strcmp(str,phyAddr) == 0) {
-			len = strlen(ipAddr);
-			strncpy(ipaddr, ipAddr, len);
-			ipaddr[len] = '\0';
-		}
-	}
-	if (fclose(fp) == EOF) {
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		return RETURN_ERR;
-	}
-	return RETURN_OK;
-}
-
-/* wifi_getApInactiveAssociatedDeviceDiagnosticResult function */
-/**
-* @description Returning Inactive wireless connected clients informations
-*
-* @param
-* @filename Holding private_wifi 2g/5g content files
-* @associated_dev_array  Having inactiv wireless clients informations
-* @output_array_size Returning Inactive wireless counts
-* @return The status of the operation
-* @retval RETURN_OK if successful
-* @retval RETURN_ERR if any error is detected
-*
-*/
-
-INT wifi_getApInactiveAssociatedDeviceDiagnosticResult(char *filename,wifi_associated_dev3_t **associated_dev_array, UINT *output_array_size)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	int count = 0,maccount = 0,i = 0,wificlientindex = 0;
-	FILE *fp = NULL;
-	int arr[MACADDRESS_SIZE] = {0};
-	unsigned char mac[MACADDRESS_SIZE] = {0};
-	char path[1024] = {0},str[1024] = {0},ipaddr[50] = {0},buf[512] = {0};
-	int res;
-
-	fp = v_secure_popen("r","cat %s | grep Station | sort | uniq | wc -l",filename);
-	if(fp == NULL)
-		return RETURN_ERR;
-	else
-	{
-		if (fgets(path,sizeof(path),fp) == NULL) {
-			wifi_debug(DEBUG_ERROR, "fgets fail\n");
-			v_secure_pclose(fp);
-			return RETURN_ERR;
-		}
-		maccount = atoi(path);
-	}
-	v_secure_pclose(fp);
-	*output_array_size = maccount;
-	wifi_associated_dev3_t* temp = NULL;
-	if(*output_array_size > 0 && *output_array_size < MAX_ASSOCIATED_STA_NUM){
-		temp = (wifi_associated_dev3_t *) calloc (*output_array_size, sizeof(wifi_associated_dev3_t));
-	} else {
-		return RETURN_ERR;
-	}
-
-	*associated_dev_array = temp;
-	if(temp == NULL)
-	{
-		wifi_debug(DEBUG_ERROR, "Error Statement. Insufficient memory \n");
-		return RETURN_ERR;
-	}
-	memset(buf,0,sizeof(buf));
-	res = snprintf(buf, sizeof(buf),
-		"cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	fp = v_secure_popen("r", "cat %s | grep Station | cut -d ' ' -f2 | sort | uniq",filename);
-	if (fp == NULL) {
-		res = fprintf(stderr, "%s: failed pipe command %s.\n", __func__, buf);
-		if (res < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-		}
-		return RETURN_ERR;
-	}
-	for(count = 0; count < maccount ; count++)
-	{
-		if (fgets(path,sizeof(path),fp) == NULL)
-			continue;
-		for(i = 0; path[i]!='\n';i++)
-			str[i]=path[i];
-		str[i]='\0';
-		getIPAddress(str,ipaddr);
-		if(strlen(ipaddr) > 0)
-		{
-			if (v_secure_system("ping -q -c 1 -W 1  \"%s\"  > /dev/null 2>&1", ipaddr))  //InActive wireless clients info
-			{
-				if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
-				{
-					for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
-					{
-						mac[wificlientindex] = (unsigned char) arr[wificlientindex];
-
-					}
-					memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
-					if (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]) < 0) {
-						wifi_debug(DEBUG_ERROR, "Unexpected fprintf fail\n");
-						break;
-					}
-				}
-				temp[count].cli_AuthenticationState = 0; //TODO
-				temp[count].cli_Active = 0; //TODO
-				temp[count].cli_SignalStrength = 0;
-			}
-			else //Active wireless clients info
-			{
-				if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
-				{
-					for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
-					{
-						mac[wificlientindex] = (unsigned char) arr[wificlientindex];
-
-					}
-					memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
-					wifi_debug(DEBUG_ERROR, "%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]);
-				}
-				temp[count].cli_Active = 1;
-			}
-		}
-		memset(ipaddr,0,sizeof(ipaddr));
-	}
-	v_secure_pclose(fp);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering object
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Capability bool r/o
-//To get Band Steering Capability
-INT wifi_getBandSteeringCapability(BOOL *support)
-{
-	*support = TRUE;
-	return RETURN_OK;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.Enable bool r/w
-//To get Band Steering enable status
-INT wifi_getBandSteeringEnable(BOOL *enable)
-{
-	*enable = bs_curr_status;
-	return RETURN_OK;
-}
-
-//To turn on/off Band steering
-INT wifi_setBandSteeringEnable(BOOL enable)
-{
-	int res;
-	char buf[256] = {0};
-	int bs_set_status;
-
-	bs_set_status = enable ? 0 : 1;
-
-	/*To Disable/Enable Upgrade steer <2G to 5G> for ACTIVE clients*/
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set disable_active_ug %d", bs_set_status);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-	memset(buf, 0, sizeof(buf));
-
-	/*To Disable/Enable Upgrade steer <2G to 5G> for IDLE clients*/
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set disable_idle_ug %d", bs_set_status);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-	memset(buf, 0, sizeof(buf));
-
-	/*To Disable/Enable Downgrade steer <2G to 5G> for ACTIVE clients*/
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set disable_active_dg %d", bs_set_status);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-	memset(buf, 0, sizeof(buf));
-
-	/*To Disable/Enable Downgrade steer <2G to 5G> for IDLE clients*/
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set disable_idle_dg %d", bs_set_status);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-	memset(buf, 0, sizeof(buf));
-
-	/*To Disable/Enable offloading (Radio is overloaded) <2G to 5G> or <5G to 2G> for ACTIVE clients*/
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set disable_offloading %d", bs_set_status);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-	bs_curr_status = enable;
-
-	return RETURN_OK;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.APGroup string r/w
-//To get Band Steering AP group
-INT wifi_getBandSteeringApGroup(char *output_ApGroup)
-{
-	char buf[MAX_APS * 20];
-	int res;
-	int macIndex = 0;
-	char apIndexesStr[(MAX_APS * 3) + 1] = {0};
-	int count = 0;
-
-	if (NULL == output_ApGroup)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl bss_group_list_get" );
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-	char *token = strtok(buf, "\n");
-
-	while (token != NULL) {
-
-		char bssid[64] ;
-		int foundApIndex = 0;
-		char mac[64] = {0};
-
-		count++;
-
-		if (count < 3) {
-			token = strtok(NULL, "\n");
-			continue;
-		}
-
-		if (sscanf(token, "%s", mac) != 1) {
-			wifi_debug(DEBUG_ERROR, "Error parsing MAC address, sscanf failed\n");
-			return RETURN_ERR;
-		}
-
-		for (int apIndex = 0; apIndex < MAX_APS; apIndex++) {
-			wifi_getBaseBSSID(apIndex, bssid);
-			if (strcmp(bssid, mac) == 0) {
-				foundApIndex = apIndex;
-				break;
-			}
-		}
-
-		if (foundApIndex + 1) {
-			char apIndexStr[4];
-
-			if (macIndex % 2 == 1)
-				snprintf(apIndexStr, sizeof(apIndexStr), "%d%s", foundApIndex, ";");
-			else
-				snprintf(apIndexStr, sizeof(apIndexStr), "%d%s", foundApIndex, ",");
-			strcat(apIndexesStr, apIndexStr);
-			macIndex++;
-		}
-		token = strtok(NULL, "\n");
-	}
-
-	if (strlen(apIndexesStr) == 0) {
-		wifi_debug(DEBUG_ERROR, "BSS group list empty\n");
-		return RETURN_ERR;
-	} else {
-		apIndexesStr[strlen(apIndexesStr)-1] = '\0'; /* to remove trailing ';' */
-		memcpy(output_ApGroup, apIndexesStr, strlen(apIndexesStr));
-		output_ApGroup[strlen(apIndexesStr)] = '\0';
-	}
-
-	return RETURN_OK;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.UtilizationThreshold int r/w
-//to set and read the band steering BandUtilizationThreshold parameters
-INT wifi_getBandSteeringBandUtilizationThreshold (INT radioIndex, INT *pBuThreshold)
-{
-	wifi_band band = band_invalid;
-	int res;
-	char buf[256] = {0};
-	char conf_file[MAX_BUF_SIZE] = {0};
-
-	if (NULL == pBuThreshold)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-
-	res = snprintf(conf_file, sizeof(conf_file), "/etc/mapd_strng.conf");
-	if (os_snprintf_error(sizeof(conf_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (band == band_invalid) {
-		return RETURN_ERR;
-	} else if (band == band_2_4) {
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^CUOverloadTh_2G=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-
-	} else if (band == band_5) {
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^CUOverloadTh_5G_L=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-	} else if (band == band_6) {
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^CUOverloadTh_6G=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	*pBuThreshold = atoi(buf);
-	return RETURN_OK;
-}
-
-INT wifi_setBandSteeringBandUtilizationThreshold (INT radioIndex, INT buThreshold)
-{
-	wifi_band band = band_invalid;
-	int res;
-	char buf[256] = {0};
-	char conf_file[MAX_BUF_SIZE] = {0};
-
-	band = radio_index_to_band(radioIndex);
-
-	res = snprintf(conf_file, sizeof(conf_file), "/etc/mapd_strng.conf");
-	if (os_snprintf_error(sizeof(conf_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (band == band_invalid) {
-		return RETURN_ERR;
-	} else if (band == band_2_4) {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set CUOverloadTh_2G %d", buThreshold);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set CUOverloadTh_2G %d", conf_file, buThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	} else if (band == band_5) {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set CUOverloadTh_5G %d", buThreshold);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set CUOverloadTh_5G_L %d", conf_file, buThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set CUOverloadTh_5G_H %d", conf_file, buThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	} else if (band == band_6) {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set CUOverloadTh_6G %d", buThreshold );
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set CUOverloadTh_6G %d", conf_file, buThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	}
-
-	return RETURN_ERR;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.RSSIThreshold int r/w
-//to set and read the band steering RSSIThreshold parameters
-INT wifi_getBandSteeringRSSIThreshold (INT radioIndex, INT *pRssiThreshold)
-{
-	wifi_band band = band_invalid;
-	int res;
-	char buf[256] = {0};
-	char conf_file[MAX_BUF_SIZE] = {0};
-
-	if (NULL == pRssiThreshold)
-		return RETURN_ERR;
-
-	band = radio_index_to_band(radioIndex);
-
-	res = snprintf(conf_file, sizeof(conf_file), "/etc/mapd_strng.conf");
-	if (os_snprintf_error(sizeof(conf_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (band == band_invalid) {
-		return RETURN_ERR;
-	} else if (band == band_2_4) {
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^RSSISteeringEdge_UG=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-
-	} else if (band == band_5) {
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^RSSISteeringEdge_DG=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-	} else if (band == band_6) {
-		res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null | grep \"^RSSISteeringEdge_6G_DG=\" | cut -d \"=\" -f 2 | head -n1 | tr -d \"\\n\"", conf_file);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	*pRssiThreshold = atoi(buf);
-
-	return RETURN_OK;
-}
-
-INT wifi_setBandSteeringRSSIThreshold (INT radioIndex, INT rssiThreshold)
-{
-	wifi_band band = band_invalid;
-	int res;
-	char buf[256] = {0};
-	char conf_file[MAX_BUF_SIZE] = {0};
-
-	if ((rssiThreshold >= 0 && rssiThreshold <= 60) || (rssiThreshold >= -94 && rssiThreshold <= -30)) {
-		wifi_debug(DEBUG_NOTICE, "Valid threshold!\n");
-	} else {
-		wifi_debug(DEBUG_ERROR, "ERROR! Input is invalid threshold!, Valid range from -30 to -94 or 0 to 60\n");
-		return RETURN_ERR;
-	}
-
-	band = radio_index_to_band(radioIndex);
-
-	res = snprintf(conf_file, sizeof(conf_file), "/etc/mapd_strng.conf");
-	if (os_snprintf_error(sizeof(conf_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (band == band_invalid) {
-		return RETURN_ERR;
-	} else if (band == band_2_4) {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set RSSIThreshold %d", rssiThreshold);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set RSSISteeringEdge_UG %d", conf_file, rssiThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	} else if (band == band_5) {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set RSSIThreshold5G %d", rssiThreshold);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set RSSISteeringEdge_DG %d", conf_file, rssiThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		return RETURN_OK;
-	} else if (band == band_6) {
-		res = _syscmd_secure(buf, sizeof(buf), "mapd_cli /tmp/mapd_ctrl set RSSIThreshold6G %d", rssiThreshold);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-		memset(buf, 0, sizeof(buf));
-		res = _syscmd_secure(buf, sizeof(buf), "datconf -f %s set RSSISteeringEdge_6G_DG %d", conf_file, rssiThreshold);
-		if(res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	return RETURN_OK;
-}
-
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.PhyRateThreshold int r/w
-//to set and read the band steering physical modulation rate threshold parameters
-INT wifi_getBandSteeringPhyRateThreshold (INT radioIndex, INT *pPrThreshold)
-{
-	//If chip is not support, return -1
-	return RETURN_ERR;
-}
-
-INT wifi_setBandSteeringPhyRateThreshold (INT radioIndex, INT prThreshold)
-{
-	//If chip is not support, return -1
-	return RETURN_ERR;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.OverloadInactiveTime int r/w
-//to set and read the inactivity time (in seconds) for steering under overload condition
-INT wifi_getBandSteeringOverloadInactiveTime(INT radioIndex, INT *pPrThreshold)
-{
-	return RETURN_ERR;
-}
-
-INT wifi_setBandSteeringOverloadInactiveTime(INT radioIndex, INT prThreshold)
-{
-	return RETURN_ERR;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.BandSetting.{i}.IdleInactiveTime int r/w
-//to set and read the inactivity time (in seconds) for steering under Idle condition
-INT wifi_getBandSteeringIdleInactiveTime(INT radioIndex, INT *pPrThreshold)
-{
-	return RETURN_ERR;
-}
-
-INT wifi_setBandSteeringIdleInactiveTime(INT radioIndex, INT prThreshold)
-{
-	return RETURN_ERR;
-}
-
-//Device.WiFi.X_RDKCENTRAL-COM_BandSteering.History string r/o
-//pClientMAC[64]
-//pSourceSSIDIndex[64]
-//pDestSSIDIndex[64]
-//pSteeringReason[256]
-INT wifi_getBandSteeringLog(INT record_index, ULONG *pSteeringTime, CHAR *pClientMAC, INT *pSourceSSIDIndex, INT *pDestSSIDIndex, INT *pSteeringReason)
-{
-	char buffer[256];
-	INT currentLine = 0;
-	INT result = -1;
-	const char *filePath = "/etc/steer_db.txt";
-	FILE *file = NULL;
-
-	if (!pSteeringTime || !pClientMAC || !pSourceSSIDIndex || !pDestSSIDIndex || !pSteeringReason) {
-		wifi_debug(DEBUG_ERROR, "Received variables are NULL\n");
-		return RETURN_ERR;
-	}
-
-	file = fopen(filePath, "r");
-	if (!file) {
-		wifi_debug(DEBUG_ERROR, "Error opening the file\n");
-		return RETURN_ERR;
-	}
-
-	while (fgets(buffer, sizeof(buffer), file)) {
-		currentLine++;
-
-		if (currentLine == record_index) {
-			if (sscanf(buffer, "%lu %17s %d %d %d", pSteeringTime, pClientMAC, pSourceSSIDIndex, pDestSSIDIndex, pSteeringReason) == 5) {
-				result = RETURN_OK;
-			} else {
-				wifi_debug(DEBUG_ERROR, "Error parsing the record.\n");
-				result = RETURN_ERR;
-			}
-			break;
-		}
-	}
-
-	if (fclose(file) != 0) {
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		return RETURN_ERR;
-	}
-
-	return result;
-}
-
-INT wifi_ifConfigDown(INT apIndex)
-{
-	INT status = RETURN_OK;
-	char cmd[64];
-	int res;
-
-	res = v_secure_system("ifconfig ath%d down", apIndex);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_OFF, "%s: %s\n", __func__, cmd);
-
-	return status;
-}
-
-INT wifi_ifConfigUp(INT apIndex)
-{
-	char interface_name[16] = {0};
-	char buf[1024];
-	int res;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up 2>/dev/null", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	return 0;
-}
-
-//>> Deprecated. Replace with wifi_applyRadioSettings
-INT wifi_pushBridgeInfo(INT apIndex)
-{
-	char ip[32] = {0};
-	char subnet[32] = {0};
-	char bridge[32] = {0};
-	char buf[1024] = {0};
-	int res;
-
-	wifi_getApBridgeInfo(apIndex, bridge, ip, subnet);
-
-	res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s %s netmask %s ", bridge, ip, subnet);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	return 0;
-}
-
-INT wifi_pushChannel(INT radioIndex, UINT channel)
-{
-	char interface_name[16] = {0};
-	char buf[1024];
-	int res;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = _syscmd_secure(buf, sizeof(buf), "iwconfig %s freq %d",interface_name,channel);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	return 0;
-}
-
-INT wifi_pushChannelMode(INT radioIndex)
-{
-	//Apply Channel mode, pure mode, etc that been set by wifi_setRadioChannelMode() instantly
-	return RETURN_ERR;
-}
-
-INT wifi_pushDefaultValues(INT radioIndex)
-{
-	//Apply Comcast specified default radio settings instantly
-	//AMPDU=1
-	//AMPDUFrames=32
-	//AMPDULim=50000
-	//txqueuelen=1000
-
-	return RETURN_ERR;
-}
-
-INT wifi_pushTxChainMask(INT radioIndex)
-{
-	//Apply default TxChainMask instantly
-	return RETURN_ERR;
-}
-
-INT wifi_pushRxChainMask(INT radioIndex)
-{
-	//Apply default RxChainMask instantly
-	return RETURN_ERR;
-}
-
-INT wifi_pushSSID(INT apIndex, CHAR *ssid)
-{
-	INT status;
-
-	status = wifi_setSSIDName(apIndex, ssid);
-	wifi_quick_reload_ap(apIndex);
-
-	return status;
-}
-
-INT wifi_pushSsidAdvertisementEnable(INT apIndex, BOOL enable)
-{
-	int ret;
-	ret = wifi_setApSsidAdvertisementEnable(apIndex, enable);
-
-	return ret;
-}
-
-INT wifi_getRadioUpTime(INT radioIndex, ULONG *UpTime)
-{
-	unsigned long SysUpSecs = 0 ;
-	int ret = RETURN_ERR;
-	*UpTime = 0;
-	if ( radioIndex < MAX_NUM_RADIOS ) {
-		SysUpSecs = wifi_getSystemUpSecs();
-
-		if (SysUpSecs > radio_start_uptime[radioIndex]) {
-			*UpTime = SysUpSecs - radio_start_uptime[radioIndex];
-			ret = RETURN_OK;
-		}
-	}
-	return ret;
-}
-
-INT wifi_getApEnableOnLine(INT wlanIndex, BOOL *enabled)
-{
-	return RETURN_OK;
-}
-
-INT wifi_getApSecurityWpaRekeyInterval(INT apIndex, INT *output_int)
-{
-	return RETURN_OK;
-}
-
-//To-do
-INT wifi_getApSecurityMFPConfig(INT apIndex, CHAR *output_string)
-{
-	char output[16]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if (!output_string)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "ieee80211w", output, sizeof(output));
-
-	if (strlen(output) == 0)
-		res = snprintf(output_string, 64, "Disabled");
-	else if (strncmp(output, "0", 1) == 0)
-		res = snprintf(output_string, 64, "Disabled");
-	else if (strncmp(output, "1", 1) == 0)
-		res = snprintf(output_string, 64, "Optional");
-	else if (strncmp(output, "2", 1) == 0)
-		res = snprintf(output_string, 64, "Required");
-	else {
-		wifi_debug(DEBUG_ERROR, "Unexpected ieee80211w=%s\n", output);
-		return RETURN_ERR;
-	}
-	if (os_snprintf_error(64, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_debug(DEBUG_INFO, "ieee80211w is : %s\n", output);
-	return RETURN_OK;
-}
-INT wifi_setApMBOConfig(INT apIndex)
-{
-	struct params params;
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	params.name = "mbo";
-	params.value = "0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	return RETURN_OK;
-}
-
-INT wifi_setApSecurityMFPConfig(INT apIndex, CHAR *MfpConfig)
-{
-	struct params params;
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(NULL == MfpConfig || strlen(MfpConfig) >= 32 )
-		return RETURN_ERR;
-
-	params.name = "ieee80211w";
-	if (strncmp(MfpConfig, "Disabled", strlen("Disabled")) == 0) {
-		params.value = "0";
-		/* mbo should disable when pmf = 0*/
-		wifi_setApMBOConfig(apIndex);
-	}
-	else if (strncmp(MfpConfig, "Optional", strlen("Optional")) == 0)
-		params.value = "1";
-	else if (strncmp(MfpConfig, "Required", strlen("Required")) == 0)
-		params.value = "2";
-	else{
-		wifi_debug(DEBUG_ERROR, "invalid MfpConfig. Input has to be Disabled, Optional or Required\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(apIndex, &params, 1);
-	wifi_quick_reload_ap(apIndex);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-INT wifi_getRadioAutoChannelEnable(INT radioIndex, BOOL *output_bool)
-{
-	char output[16]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileRead(config_file, "AutoChannelSelect" , output, sizeof(output));
-
-	if (strncmp(output, "0", 1) == 0)
-		*output_bool = FALSE;
-	else if (strncmp(output, "1", 1) == 0)
-		*output_bool = TRUE;
-	else if (strncmp(output, "2", 1) == 0)
-		*output_bool = TRUE;
-	else if (strncmp(output, "3", 1) == 0)
-		*output_bool = TRUE;
-	else
-		*output_bool = FALSE;
-	WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_getRouterEnable(INT wlanIndex, BOOL *enabled)
-{
-	return RETURN_OK;
-}
-
-INT wifi_setApSecurityWpaRekeyInterval(INT apIndex, INT *rekeyInterval)
-{
-	return RETURN_OK;
-}
-
-INT wifi_setRouterEnable(INT wlanIndex, INT *RouterEnabled)
-{
-	return RETURN_OK;
-}
-
-INT wifi_getRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	char config_file[MAX_BUF_SIZE] = {0};
-	char tmp_output[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if (NULL == output)
-		return RETURN_ERR;
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file,"hw_mode",output,64);
-
-	if(strcmp(output,"b")==0) {
-		res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,11");
-		if (os_snprintf_error(sizeof(tmp_output), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if (strcmp(output,"a")==0) {
-		res = snprintf(tmp_output, sizeof(tmp_output), "%s", "6,9,11,12,18,24,36,48,54");
-		if (os_snprintf_error(sizeof(tmp_output), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	} else if ((strcmp(output,"n")==0) | (strcmp(output,"g")==0)) {
-		res = snprintf(tmp_output, sizeof(tmp_output), "%s", "1,2,5.5,6,9,11,12,18,24,36,48,54");
-		if (os_snprintf_error(sizeof(tmp_output), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-	}
-	memcpy(output, tmp_output, strlen(tmp_output));
-	output[strlen(tmp_output)] = '\0';
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	char *temp;
-	char temp_output[128] = {0};
-	char temp_TransmitRates[128] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-	unsigned long len;
-
-	if (NULL == output)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file,"supported_rates",output,64);
-
-	if (strlen(output) == 0) {
-		wifi_getRadioSupportedDataTransmitRates(wlanIndex, output);
-		return RETURN_OK;
-	}
-	len = strlen(output);
-	if (len >= sizeof(temp_TransmitRates)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strlen(output)\n");
-		return RETURN_ERR;
-	}
-	strncpy(temp_TransmitRates, output, len);
-	temp = strtok(temp_TransmitRates," ");
-	while(temp!=NULL)
-	{
-		temp[strlen(temp)-1]=0;
-		if((temp[0]=='5') && (temp[1]=='\0'))
-		{
-			temp="5.5";
-		}
-		if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp)) {
-			wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
-			return RETURN_ERR;
-		}
-		strncat(temp_output, temp, sizeof(temp_output) - strlen(temp_output) - 1);
-		temp = strtok(NULL," ");
-		if(temp!=NULL)
-		{
-			if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
-				wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
-				return RETURN_ERR;
-			}
-			strncat(temp_output, ",", sizeof(temp_output) - strlen(temp_output) - 1);
-		}
-	}
-	len = strlen(temp_output);
-	strncpy(output, temp_output, len);
-	output[len] = '\0';
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_setRadioSupportedDataTransmitRates(INT wlanIndex,CHAR *output)
-{
-		return RETURN_OK;
-}
-
-
-INT wifi_setRadioOperationalDataTransmitRates(INT wlanIndex,CHAR *output)
-{
-	int i=0;
-	char *temp;
-	char temp1[128] = {0};
-	char temp_output[128] = {0};
-	char temp_TransmitRates[128] = {0};
-	struct params params={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	wifi_band band = wifi_index_to_band(wlanIndex);
-	unsigned long len;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(NULL == output)
-		return RETURN_ERR;
-
-	len = strlen(output);
-	if (len >= sizeof(temp_TransmitRates)) {
-		wifi_debug(DEBUG_ERROR, "not enough room in temp_TransmitRates\n");
-		return RETURN_ERR;
-	}
-	strncpy(temp_TransmitRates, output, len);
-	temp_TransmitRates[len] = '\0';
-
-	for(i=0;i<strlen(temp_TransmitRates);i++)
-	{
-		if (((temp_TransmitRates[i]>='0') && (temp_TransmitRates[i]<='9')) || (temp_TransmitRates[i]==' ') || (temp_TransmitRates[i]=='.') || (temp_TransmitRates[i]==','))
-		{
-			continue;
-		}
-		else
-		{
-			return RETURN_ERR;
-		}
-	}
-	temp = strtok(temp_TransmitRates,",");
-	while(temp!=NULL)
-	{
-		len = strlen(temp);
-		if (len >= sizeof(temp1)) {
-			wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
-			return RETURN_ERR;
-		}
-		strncpy(temp1, temp, len);
-		temp1[len] = '\0';
-		if(band == band_5)
-		{
-			if((strcmp(temp,"1")==0) || (strcmp(temp,"2")==0) || (strcmp(temp,"5.5")==0))
-			{
-				return RETURN_ERR;
-			}
-		}
-
-		if(strcmp(temp,"5.5")==0) {
-			strncpy(temp1, "55", 2);
-			temp1[2] = '\0';
-		} else {
-			if ((sizeof(temp1) - strlen(temp1)) <= 1) {
-				wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
-				return RETURN_ERR;
-			}
-			strncat(temp1, "0", sizeof(temp1) - strlen(temp1) - 1);
-		}
-
-		if ((sizeof(temp_output) - strlen(temp_output)) <= strlen(temp1)) {
-			wifi_debug(DEBUG_ERROR, "not enough room in temp_output\n");
-			return RETURN_ERR;
-		}
-		strncat(temp_output, temp1, sizeof(temp_output) - strlen(temp_output) - 1);
-		temp = strtok(NULL,",");
-		if(temp!=NULL)
-		{
-			if ((sizeof(temp_output) - strlen(temp_output)) <= 1) {
-				wifi_debug(DEBUG_ERROR, "not enough room in temp1\n");
-				return RETURN_ERR;
-			}
-			strncat(temp_output, " ", sizeof(temp_output) - strlen(temp_output) - 1);
-		}
-	}
-	len = strlen(temp_output);
-	strncpy(output, temp_output, len);
-	output[len] = '\0';
-
-	params.name = "supported_rates";
-	params.value = output;
-
-	wifi_debug(DEBUG_INFO, "params.value=%s\n", params.value);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,wlanIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file,&params,1);
-	wifi_hostapdProcessUpdate(wlanIndex, &params, 1);
-	wifi_quick_reload_ap(wlanIndex);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-
-static char *sncopy(char *dst, int dst_sz, const char *src)
-{
-	if (src && dst && dst_sz > 0) {
-		strncpy(dst, src, dst_sz);
-		dst[dst_sz - 1] = '\0';
-	}
-	return dst;
-}
-
-static int util_get_sec_chan_offset(int channel, const char* ht_mode)
-{
-	if (0 == strcmp(ht_mode, "HT40") ||
-		0 == strcmp(ht_mode, "HT80") ||
-		0 == strcmp(ht_mode, "HT160")) {
-		switch (channel) {
-			case 1 ... 7:
-			case 36:
-			case 44:
-			case 52:
-			case 60:
-			case 100:
-			case 108:
-			case 116:
-			case 124:
-			case 132:
-			case 140:
-			case 149:
-			case 157:
-				return 1;
-			case 8 ... 13:
-			case 40:
-			case 48:
-			case 56:
-			case 64:
-			case 104:
-			case 112:
-			case 120:
-			case 128:
-			case 136:
-			case 144:
-			case 153:
-			case 161:
-				return -1;
-			default:
-				return -EINVAL;
-		}
-	}
-
-	return -EINVAL;
-}
-
-static int util_get_6g_sec_chan_offset(int channel, const char* ht_mode)
-{
-	int idx = channel%8;
-	if (0 == strcmp(ht_mode, "HT40") ||
-		0 == strcmp(ht_mode, "HT80") ||
-		0 == strcmp(ht_mode, "HT160")) {
-		switch (idx) {
-			case 1:
-				return 1;
-			case 5:
-				return -1;
-			default:
-				return -EINVAL;
-		}
-	}
-
-	return -EINVAL;
-}
-static void util_hw_mode_to_bw_mode(const char* hw_mode, char *bw_mode, int bw_mode_len)
-{
-	if (NULL == hw_mode) return;
-
-	if (0 == strcmp(hw_mode, "ac"))
-		sncopy(bw_mode, bw_mode_len, "ht vht");
-
-	if (0 == strcmp(hw_mode, "n"))
-		sncopy(bw_mode, bw_mode_len, "ht");
-
-	return;
-}
-
-static int util_chan_to_freq(int chan)
-{
-	if (chan == 14)
-		return 2484;
-	else if (chan < 14)
-		return 2407 + chan * 5;
-	else if (chan >= 182 && chan <= 196)
-		return 4000 + chan * 5;
-	else
-		return 5000 + chan * 5;
-	return 0;
-}
-
-static int util_6G_chan_to_freq(int chan)
-{
-	if (chan)
-		return 5950 + chan * 5;
-	else
-		return 0;
-
-}
-const int *util_unii_5g_chan2list(int chan, int width)
-{
-	static const int lists[] = {
-		// <width>, <chan1>, <chan2>..., 0,
-		20, 36, 0,
-		20, 40, 0,
-		20, 44, 0,
-		20, 48, 0,
-		20, 52, 0,
-		20, 56, 0,
-		20, 60, 0,
-		20, 64, 0,
-		20, 100, 0,
-		20, 104, 0,
-		20, 108, 0,
-		20, 112, 0,
-		20, 116, 0,
-		20, 120, 0,
-		20, 124, 0,
-		20, 128, 0,
-		20, 132, 0,
-		20, 136, 0,
-		20, 140, 0,
-		20, 144, 0,
-		20, 149, 0,
-		20, 153, 0,
-		20, 157, 0,
-		20, 161, 0,
-		20, 165, 0,
-		40, 36, 40, 0,
-		40, 44, 48, 0,
-		40, 52, 56, 0,
-		40, 60, 64, 0,
-		40, 100, 104, 0,
-		40, 108, 112, 0,
-		40, 116, 120, 0,
-		40, 124, 128, 0,
-		40, 132, 136, 0,
-		40, 140, 144, 0,
-		40, 149, 153, 0,
-		40, 157, 161, 0,
-		80, 36, 40, 44, 48, 0,
-		80, 52, 56, 60, 64, 0,
-		80, 100, 104, 108, 112, 0,
-		80, 116, 120, 124, 128, 0,
-		80, 132, 136, 140, 144, 0,
-		80, 149, 153, 157, 161, 0,
-		160, 36, 40, 44, 48, 52, 56, 60, 64, 0,
-		160, 100, 104, 108, 112, 116, 120, 124, 128, 0,
-		-1 // final delimiter
-	};
-	const int *start;
-	const int *p;
-
-	for (p = lists; *p != -1; p++) {
-		if (*p == width) {
-			for (start = ++p; *p != 0; p++) {
-				if (*p == chan)
-					return start;
-			}
-		}
-		// move to the end of channel list of given width
-		while (*p != 0) {
-			p++;
-		}
-	}
-
-	return NULL;
-}
-
-static int util_unii_5g_centerfreq(const char *ht_mode, int channel)
-{
-	if (NULL == ht_mode)
-		return 0;
-
-	const int width = atoi(strlen(ht_mode) > 2 ? ht_mode + 2 : "20");
-	const int *chans = util_unii_5g_chan2list(channel, width);
-	int sum = 0;
-	int cnt = 0;
-
-	if (NULL == chans)
-		return 0;
-
-	while (*chans) {
-		sum += *chans;
-		cnt++;
-		chans++;
-	}
-	if (cnt == 0)
-		return 0;
-	return sum / cnt;
-}
-
-static int util_unii_6g_centerfreq(const char *ht_mode, int channel)
-{
-	long int width;
-	int idx = 0 ;
-	int centerchan = 0;
-	int chan_ofs = 1;
-
-	if (NULL == ht_mode)
-		return 0;
-
-	if (hal_strtol((char *)(ht_mode + 2), 10, &width) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	if (width == 40){
-		idx = ((channel/4) + chan_ofs)%2;
-		switch (idx) {
-			case 0:
-				centerchan = (channel - 2);
-				break;
-			case 1:
-				centerchan = (channel + 2);
-				break;
-			default:
-				return -EINVAL;
-		}
-	}else if (width == 80){
-		idx = ((channel/4) + chan_ofs)%4;
-		switch (idx) {
-			case 0:
-				centerchan = (channel - 6);
-				break;
-			case 1:
-				centerchan = (channel + 6);
-				break;
-			case 2:
-				centerchan = (channel + 2);
-				break;
-			case 3:
-				centerchan = (channel - 2);
-				break;
-			default:
-				return -EINVAL;
-		}
-	}else if (width == 160){
-		switch (channel) {
-			case 1 ... 29:
-				centerchan = 15;
-				break;
-			case 33 ... 61:
-				centerchan = 47;
-				break;
-			case 65 ... 93:
-				centerchan = 79;
-				break;
-			case 97 ... 125:
-				centerchan = 111;
-				break;
-			case 129 ... 157:
-				centerchan = 143;
-				break;
-			case 161 ... 189:
-				centerchan = 175;
-				break;
-			case 193 ... 221:
-				centerchan = 207;
-				break;
-			default:
-				return -EINVAL;
-		}
-	}
-	return centerchan;
-}
-static int util_radio_get_hw_mode(int radioIndex, char *hw_mode, int hw_mode_size)
-{
-	BOOL onlyG, onlyN, onlyA;
-	CHAR tmp[64];
-	int ret = wifi_getRadioStandard(radioIndex, tmp, &onlyG, &onlyN, &onlyA);
-	if (ret == RETURN_OK) {
-		sncopy(hw_mode, hw_mode_size, tmp);
-	}
-	return ret;
-}
-
-INT wifi_pushRadioChannel2(INT radioIndex, UINT channel, UINT channel_width_MHz, UINT csa_beacon_count)
-{
-	// Sample commands:
-	//   hostapd_cli -i wifi1 chan_switch 30 5200 sec_channel_offset=-1 center_freq1=5190 bandwidth=40 ht vht
-	//   hostapd_cli -i wifi0 chan_switch 30 2437
-	int ret = 0;
-	char center_freq1_str[32] = ""; // center_freq1=%d
-	char opt_chan_info_str[32] = ""; // bandwidth=%d ht vht
-	char sec_chan_offset_str[32] = ""; // sec_channel_offset=%d
-	char hw_mode[16] = ""; // n|ac
-	char bw_mode[16] = ""; // ht|ht vht
-	char ht_mode[16] = ""; // HT20|HT40|HT80|HT160
-	char interface_name[16] = {0};
-	int sec_chan_offset;
-	int width;
-	char config_file[64] = {0};
-	char *ext_str = "None";
-	wifi_band band = band_invalid;
-	int center_chan = 0;
-	int center_freq1 = 0;
-	int res;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, main_vap_idx);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	band = wifi_index_to_band(main_vap_idx);
-
-	width = channel_width_MHz > 20 ? channel_width_MHz : 20;
-
-	// Get radio mode HT20|HT40|HT80 etc.
-	if (channel){
-		res = snprintf(ht_mode, sizeof(ht_mode), "HT%d", width);
-		if (os_snprintf_error(sizeof(ht_mode), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		// Provide bandwith if specified
-		if (channel_width_MHz > 20) {
-			// Select bandwidth mode from hardware n --> ht | ac --> ht vht
-			util_radio_get_hw_mode(radioIndex, hw_mode, sizeof(hw_mode));
-			util_hw_mode_to_bw_mode(hw_mode, bw_mode, sizeof(bw_mode));
-
-			res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d %s", width, bw_mode);
-		}else if (channel_width_MHz == 20){
-			res = snprintf(opt_chan_info_str, sizeof(opt_chan_info_str), "bandwidth=%d ht", width);
-		}
-
-		if (os_snprintf_error(sizeof(opt_chan_info_str), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		if (channel_width_MHz > 20) {
-			if (band == band_6){
-				center_chan = util_unii_6g_centerfreq(ht_mode, channel);
-				if(center_chan){
-					center_freq1 = util_6G_chan_to_freq(center_chan);
-				}
-			}else{
-				center_chan = util_unii_5g_centerfreq(ht_mode, channel);
-				if(center_chan){
-					center_freq1 = util_chan_to_freq(center_chan);
-				}
-			}
-
-			if (center_freq1)
-				res = snprintf(center_freq1_str, sizeof(center_freq1_str), "center_freq1=%d", center_freq1);
-
-		}
-		if (os_snprintf_error(sizeof(center_freq1_str), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		// Find channel offset +1/-1 for wide modes (HT40|HT80|HT160)
-		if (band == band_6){
-			sec_chan_offset = util_get_6g_sec_chan_offset(channel, ht_mode);
-		}else{
-			sec_chan_offset = util_get_sec_chan_offset(channel, ht_mode);
-		}
-		if (sec_chan_offset != -EINVAL) {
-			res = snprintf(sec_chan_offset_str, sizeof(sec_chan_offset_str), "sec_channel_offset=%d", sec_chan_offset);
-			if (os_snprintf_error(sizeof(sec_chan_offset_str), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-		}
-		// Only the first AP, other are hanging on the same radio
-		/* wifi_dbg_printf("execute: '%s'\n", cmd);
-		ret = _syscmd(cmd, buf, sizeof(buf));
-		wifi_reloadAp(radioIndex); */
-
-		ret = wifi_setRadioChannel(radioIndex, channel);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR,"wifi_setRadioChannel return error.\n");
-			return RETURN_ERR;
-		}
-
-		if (sec_chan_offset == 1)
-			ext_str = "Above";
-		else if (sec_chan_offset == -1)
-			ext_str = "Below";
-
-		/*wifi_setRadioCenterChannel(radioIndex, center_chan); */
-
-	} else {
-		if (channel_width_MHz > 20)
-			ext_str = "Above";
-	}
-
-	wifi_setRadioExtChannel(radioIndex, ext_str);
-
-	char mhz_str[16];
-	res = snprintf(mhz_str, sizeof(mhz_str), "%dMHz", width);
-	if (os_snprintf_error(sizeof(mhz_str), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_setRadioOperatingChannelBandwidth(radioIndex, mhz_str);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_getNeighboringWiFiStatus(INT radio_index, wifi_neighbor_ap2_t **neighbor_ap_array, UINT *output_array_size)
-{
-	int index = -1;
-	wifi_neighbor_ap2_t *scan_array = NULL;
-	char cmd[256]={0};
-	char buf[128]={0};
-	char file_name[32] = {0};
-	char filter_SSID[32] = {0};
-	char line[256] = {0};
-	char interface_name[16] = {0};
-	char *ret = NULL;
-	int freq=0;
-	FILE *f = NULL;
-	long int channels_num = 0;
-	int vht_channel_width = 0;
-	int get_noise_ret = RETURN_ERR;
-	bool filter_enable = false;
-	bool filter_BSS = false;	 // The flag determine whether the BSS information need to be filterd.
-	int phyId = 0;
-	int res;
-	unsigned long len;
-	struct channels_noise *channels_noise_arr = NULL;
-	int main_vap_idx;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s: %d\n", __func__, __LINE__);
-
-	res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, radio_index);
-	if (os_snprintf_error(sizeof(file_name), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	f = fopen(file_name, "r");
-	if (f != NULL) {
-		if (fgets(filter_SSID, sizeof(file_name), f) == NULL) {
-			wifi_debug(DEBUG_ERROR, "fgets fail\n");
-			if (fclose(f) != 0) {
-				wifi_debug(DEBUG_ERROR, "fclose fail\n");
-			}
-			return RETURN_ERR;
-		}
-		if (strlen(filter_SSID) != 0)
-			filter_enable = true;
-		if (fclose(f) != 0) {
-			wifi_debug(DEBUG_ERROR, "fclose fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	if (array_index_to_vap_index(radio_index, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radio_index);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	phyId = radio_index_to_phy(radio_index);
-
-	res = _syscmd_secure(buf, sizeof(buf), "iw phy phy%d channels | grep * | grep -v disable | wc -l", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	if (hal_strtol(buf, 10, &channels_num) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(cmd, sizeof(cmd), "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
-	// WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_debug(DEBUG_INFO,  "cmd: %s\n", cmd);
-
-	f = v_secure_popen("r", "iw dev %s scan | grep '%s\\|SSID\\|freq\\|beacon interval\\|capabilities\\|signal\\|Supported rates\\|DTIM\\| \
-	// WPA\\|RSN\\|Group cipher\\|HT operation\\|secondary channel offset\\|channel width\\|HE.*GHz' | grep -v -e '*.*BSS'", interface_name, interface_name);
-
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR, "v_secure_popen %s error\n", cmd);
-		return RETURN_ERR;
-	}
-
-	if (channels_num > 0 && channels_num <= 243) {
-		channels_noise_arr = calloc(channels_num, sizeof(struct channels_noise));
-
-		if (channels_noise_arr == NULL) {
-			wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-			goto err;
-		}
-		get_noise_ret = get_noise(radio_index, channels_noise_arr, channels_num);
-	}
-
-	ret = fgets(line, sizeof(line), f);
-	while (ret != NULL) {
-		if(strstr(line, "BSS") != NULL) {	// new neighbor info
-			// The SSID field is not in the first field. So, we should store whole BSS informations and the filter flag.
-			// And we will determine whether we need the previous BSS infomation when parsing the next BSS field or end of while loop.
-			// If we don't want the BSS info, we don't realloc more space, and just clean the previous BSS.
-
-			if (!filter_BSS) {
-				index++;
-				wifi_debug(DEBUG_OFF, "index=%d\n", index);
-				wifi_neighbor_ap2_t *tmp;
-				tmp = realloc(scan_array, sizeof(wifi_neighbor_ap2_t)*(index+1));
-				if (tmp == NULL) {			  // no more memory to use
-					index--;
-					wifi_debug(DEBUG_ERROR, "realloc failed\n");
-					break;
-				}
-				scan_array = tmp;
-			}
-			memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
-
-			filter_BSS = false;
-			if (sscanf(line, "BSS %17s", scan_array[index].ap_BSSID) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-			memset(scan_array[index].ap_Mode, 0, sizeof(scan_array[index].ap_Mode));
-			memcpy(scan_array[index].ap_Mode, "Infrastructure", strlen("Infrastructure"));
-			memset(scan_array[index].ap_SecurityModeEnabled, 0, sizeof(scan_array[index].ap_SecurityModeEnabled));
-			memcpy(scan_array[index].ap_SecurityModeEnabled, "None", strlen("None"));
-			memset(scan_array[index].ap_EncryptionMode, 0, sizeof(scan_array[index].ap_EncryptionMode));
-			memcpy(scan_array[index].ap_EncryptionMode, "None", strlen("None"));
-		} else if (strstr(line, "freq:") != NULL) {
-			if (sscanf(line,"	freq: %d", &freq) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				//goto err;
-			}
-			scan_array[index].ap_Channel = ieee80211_frequency_to_channel(freq);
-
-			if (freq >= 2412 && freq <= 2484) {
-				memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
-				memcpy(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz"));
-				memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
-				memcpy(scan_array[index].ap_SupportedStandards, "b,g", strlen("b,g"));
-				memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
-				memcpy(scan_array[index].ap_OperatingStandards, "g", strlen("g"));
-			}
-			else if (freq >= 5160 && freq <= 5805) {
-				memset(scan_array[index].ap_OperatingFrequencyBand, 0, sizeof(scan_array[index].ap_OperatingFrequencyBand));
-				memcpy(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz"));
-				memset(scan_array[index].ap_SupportedStandards, 0, sizeof(scan_array[index].ap_SupportedStandards));
-				memcpy(scan_array[index].ap_SupportedStandards, "a", strlen("a"));
-				memset(scan_array[index].ap_OperatingStandards, 0, sizeof(scan_array[index].ap_OperatingStandards));
-				memcpy(scan_array[index].ap_OperatingStandards, "a", strlen("a"));
-			}
-
-			scan_array[index].ap_Noise = 0;
-			if (get_noise_ret == RETURN_OK) {
-				for (int i = 0; i < channels_num; i++) {
-					if (scan_array[index].ap_Channel == channels_noise_arr[i].channel) {
-						scan_array[index].ap_Noise = channels_noise_arr[i].noise;
-						break;
-					}
-				}
-			}
-		} else if (strstr(line, "beacon interval") != NULL) {
-			if (sscanf(line,"	beacon interval: %d TUs", &(scan_array[index].ap_BeaconPeriod)) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-		} else if (strstr(line, "signal") != NULL) {
-			if (sscanf(line,"	signal: %d", &(scan_array[index].ap_SignalStrength)) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-		} else if (strstr(line,"SSID:") != NULL) {
-			int i;
-			char *new_line = NULL;
-
-			for (i = 0; line[i] == '\t'; i++) {
-				;
-			}
-			new_line = &line[i];
-
-			if (strncmp(new_line, "SSID: \n", strlen("SSID: \n")) == 0) {
-				ret = fgets(line, sizeof(line), f);
-				continue;
-			}
-			if (strstr(new_line, "HESSID") == NULL) {
-				if (sscanf(new_line, "SSID: %63s", scan_array[index].ap_SSID) != 1) {
-					wifi_debug(DEBUG_ERROR, "sscanf fail, index = %d\n", index);
-					goto err;
-				} else
-					wifi_debug(DEBUG_OFF, "index = %d, ssid=%s\n", index, scan_array[index].ap_SSID);
-				if (filter_enable && strcmp(scan_array[index].ap_SSID, filter_SSID) == 0) {
-					filter_BSS = true;
-				}
-			}
-		} else if (strstr(line, "Supported rates") != NULL) {
-			char SRate[80] = {0}, *tmp = NULL;
-			memset(buf, 0, sizeof(buf));
-			len = strlen(line);
-			if (len >= sizeof(SRate)) {
-				wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
-				goto err;
-			}
-			strncpy(SRate, line, len);
-			tmp = strtok(SRate, ":");
-			if (tmp == NULL)
-				goto err;
-			tmp = strtok(NULL, ":");
-			if (tmp == NULL)
-				goto err;
-
-			len = strlen(tmp);
-			if (len >= sizeof(buf)) {
-				wifi_debug(DEBUG_ERROR, "not enough room in buf\n");
-				goto err;
-			}
-			strncpy(buf, tmp, len);
-			memset(SRate, 0, sizeof(SRate));
-
-			tmp = strtok(buf, " \n");
-			while (tmp != NULL) {
-				if ((sizeof(SRate) - strlen(SRate)) <= strlen(tmp)) {
-					wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
-					goto err;
-				}
-				strncat(SRate, tmp, sizeof(SRate) - strlen(SRate) - 1);
-				if (SRate[strlen(SRate) - 1] == '*') {
-					SRate[strlen(SRate) - 1] = '\0';
-				}
-				if ((sizeof(SRate) - strlen(SRate)) <= 1) {
-					wifi_debug(DEBUG_ERROR, "not enough room in SRate\n");
-					goto err;
-				}
-				strncat(SRate, ",", sizeof(SRate) - strlen(SRate) - 1);
-
-				tmp = strtok(NULL, " \n");
-			}
-			SRate[strlen(SRate) - 1] = '\0';
-			len = strlen(SRate);
-			if (len >= sizeof(scan_array[index].ap_SupportedDataTransferRates)) {
-				wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedDataTransferRates\n");
-				goto err;
-			}
-			strncpy(scan_array[index].ap_SupportedDataTransferRates, SRate, len);
-			scan_array[index].ap_SupportedDataTransferRates[len] = '\0';
-		} else if (strstr(line, "DTIM") != NULL) {
-			if (sscanf(line,"	TIM: DTIM Count %*d DTIM Period %d %*s", &(scan_array[index].ap_DTIMPeriod)) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-		} else if (strstr(line, "VHT capabilities") != NULL) {
-			if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
-				wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
-				goto err;
-			}
-			strncat(scan_array[index].ap_SupportedStandards, ",ac",
-				sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
-			memcpy(scan_array[index].ap_OperatingStandards, "ac", 2);
-			scan_array[index].ap_OperatingStandards[2] = '\0';
-		} else if (strstr(line, "HT capabilities") != NULL) {
-			if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 2) {
-				wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
-				goto err;
-			}
-			strncat(scan_array[index].ap_SupportedStandards, ",n",
-				sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
-			memcpy(scan_array[index].ap_OperatingStandards, "n", 1);
-			scan_array[index].ap_OperatingStandards[1] = '\0';
-		} else if (strstr(line, "VHT operation") != NULL) {
-			if (fgets(line, sizeof(line), f) == NULL) {
-				wifi_debug(DEBUG_ERROR, "fgets fail\n");
-				break;
-			}
-			if (sscanf(line,"		 * channel width: %d", &vht_channel_width) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-			if(vht_channel_width == 1) {
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT80");
-			} else {
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11AC_VHT40");
-			}
-			if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				goto err;
-			}
-
-			if (strstr(line, "BSS") != NULL)   // prevent to get the next neighbor information
-				continue;
-		} else if (strstr(line, "HT operation") != NULL) {
-			if (fgets(line, sizeof(line), f) == NULL) {
-				wifi_debug(DEBUG_ERROR, "fgets fail\n");
-				break;
-			}
-			if (sscanf(line,"		 * secondary channel offset: %127s", buf) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-			if (!strcmp(buf, "above")) {
-				//40Mhz +
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40PLUS", radio_index%1 ? "A": "G");
-			}
-			else if (!strcmp(buf, "below")) {
-				//40Mhz -
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT40MINUS", radio_index%1 ? "A": "G");
-			} else {
-				//20Mhz
-				res = snprintf(scan_array[index].ap_OperatingChannelBandwidth, sizeof(scan_array[index].ap_OperatingChannelBandwidth), "11N%s_HT20", radio_index%1 ? "A": "G");
-			}
-			if (os_snprintf_error(sizeof(scan_array[index].ap_OperatingChannelBandwidth), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				goto err;
-			}
-
-			if (strstr(line, "BSS") != NULL) {   // prevent to get the next neighbor information
-				wifi_debug(DEBUG_OFF, "continue\n");
-				continue;
-			}
-		} else if (strstr(line, "HE capabilities") != NULL) {
-			if ((sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards)) <= 3) {
-				wifi_debug(DEBUG_ERROR, "not enough room in scan_array[index].ap_SupportedStandards\n");
-				goto err;
-			}
-			strncat(scan_array[index].ap_SupportedStandards, ",ax",
-				sizeof(scan_array[index].ap_SupportedStandards) - strlen(scan_array[index].ap_SupportedStandards) - 1);
-			memcpy(scan_array[index].ap_OperatingStandards, "ax", 2);
-			scan_array[index].ap_OperatingStandards[2] = '\0';
-			if (fgets(line, sizeof(line), f) == NULL) {
-				wifi_debug(DEBUG_ERROR, "fgets fail\n");
-				break;
-			}
-			if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "2.4GHz", strlen("2.4GHz")) == 0) {
-				if (strstr(line, "HE40/2.4GHz") != NULL) {
-					len = strlen("11AXHE40PLUS");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE40PLUS", len);
-				} else {
-					len = strlen("11AXHE20");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE20", len);
-				}
-				scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
-			} else if (strncmp(scan_array[index].ap_OperatingFrequencyBand, "5GHz", strlen("5GHz")) == 0) {
-				if (strstr(line, "HE80/5GHz") != NULL) {
-					len = strlen("11AXHE80");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE80", len);
-					scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
-					ret = fgets(line, sizeof(line), f);
-				} else {
-					wifi_debug(DEBUG_OFF, "continue\n");
-					continue;
-				}
-				if (strstr(line, "HE160/5GHz") != NULL) {
-					len = strlen("11AXHE160");
-					memcpy(scan_array[index].ap_OperatingChannelBandwidth, "11AXHE160", len);
-					scan_array[index].ap_OperatingChannelBandwidth[len] = '\0';
-				}
-			}
-			wifi_debug(DEBUG_OFF, "continue\n");
-			continue;
-		} else if (strstr(line, "WPA") != NULL) {
-			memcpy(scan_array[index].ap_SecurityModeEnabled, "WPA", 3);
-			scan_array[index].ap_SecurityModeEnabled[3] = '\0';
-		} else if (strstr(line, "RSN") != NULL) {
-			memcpy(scan_array[index].ap_SecurityModeEnabled, "RSN", 3);
-			scan_array[index].ap_SecurityModeEnabled[3] = '\0';
-		} else if (strstr(line, "Group cipher") != NULL) {
-			if (sscanf(line, "		 * Group cipher: %63s", scan_array[index].ap_EncryptionMode) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf fail\n");
-				goto err;
-			}
-			if (strncmp(scan_array[index].ap_EncryptionMode, "CCMP", strlen("CCMP")) == 0) {
-				memcpy(scan_array[index].ap_EncryptionMode, "AES", 3);
-				scan_array[index].ap_EncryptionMode[3] = '\0';
-			}
-		}
-		ret = fgets(line, sizeof(line), f);
-	}
-
-	if (!filter_BSS) {
-		*output_array_size = index + 1;
-	} else {
-		memset(&(scan_array[index]), 0, sizeof(wifi_neighbor_ap2_t));
-		*output_array_size = index;
-	}
-	*neighbor_ap_array = scan_array;
-	v_secure_pclose(f);
-	free(channels_noise_arr);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	v_secure_pclose(f);
-	free(channels_noise_arr);
-	if (scan_array)
-		free(scan_array);
-	return RETURN_ERR;
-}
-
-INT wifi_getApAssociatedDeviceStats(
-		INT apIndex,
-		mac_address_t *clientMacAddress,
-		wifi_associated_dev_stats_t *associated_dev_stats,
-		u64 *handle)
-{
-	wifi_associated_dev_stats_t *dev_stats = associated_dev_stats;
-	char interface_name[50] = {0};
-	char cmd[1024] =  {0};
-	char mac_str[18] = {0};
-	char *key = NULL;
-	char *val = NULL;
-	FILE *f = NULL;
-	char *line = NULL;
-	size_t len = 0;
-	int res;
-
-	if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getApName failed\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(mac_str, sizeof(mac_str), "%x:%x:%x:%x:%x:%x",
-		(*clientMacAddress)[0], (*clientMacAddress)[1], (*clientMacAddress)[2],
-		(*clientMacAddress)[3], (*clientMacAddress)[4], (*clientMacAddress)[5]);
-	if (os_snprintf_error(sizeof(mac_str), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = snprintf(cmd, sizeof(cmd), "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	f = v_secure_popen("r", "iw dev %s station get %s | grep 'rx\\|tx' | tr -d '\t'", interface_name, mac_str);
-	if(f == NULL) {
-		wifi_debug(DEBUG_ERROR, "v_secure_popen %s error\n", cmd);
-		return RETURN_ERR;
-	}
-
-	while ((getline(&line, &len, f)) != -1) {
-		key = strtok(line,":");
-		if (key == NULL)
-			continue;
-		val = strtok(NULL,":");
-		if (val == NULL)
-			continue;
-
-		if(!strncmp(key,"rx bytes",8))
-			if (sscanf(val, "%llu", &dev_stats->cli_rx_bytes) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
-				continue;
-			}
-		if(!strncmp(key,"tx bytes",8))
-			if (sscanf(val, "%llu", &dev_stats->cli_tx_bytes) != 1) {
-				wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
-				continue;
-			}
-		if(!strncmp(key,"rx packets",10)) {
-			if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-		if(!strncmp(key,"tx packets",10)) {
-			if (sscanf(val, "%llu", &dev_stats->cli_tx_frames) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-		if(!strncmp(key,"tx retries",10)) {
-			if (sscanf(val, "%llu", &dev_stats->cli_tx_retries) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-		if(!strncmp(key,"tx failed",9)) {
-			if (sscanf(val, "%llu", &dev_stats->cli_tx_errors) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-		if(!strncmp(key,"rx drop misc",13)) {
-			if (sscanf(val, "%llu", &dev_stats->cli_rx_errors) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-		if(!strncmp(key,"rx bitrate",10)) {
-			val = strtok(val, " ");
-			if (val == NULL)
-				continue;
-			if (sscanf(val, "%lf", &dev_stats->cli_rx_rate) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-		if(!strncmp(key,"tx bitrate",10)) {
-			val = strtok(val, " ");
-			if (val == NULL)
-				continue;
-			if (sscanf(val, "%lf", &dev_stats->cli_tx_rate) == EOF) {
-				wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-				continue;
-			}
-		}
-	}
-	free(line);
-	v_secure_pclose(f);
-	return RETURN_OK;
-}
-
-INT wifi_getSSIDNameStatus(INT apIndex, CHAR *output_string)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	char buf[32] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	if (NULL == output_string)
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli  -i %s get_config | grep ^ssid | cut -d '=' -f2 | tr -d '\\n'", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	//size of SSID name restricted to value less than 32 bytes
-	res = snprintf(output_string, 32, "%s", buf);
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exit %s:%d\n", __func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_getApMacAddressControlMode(INT apIndex, INT *output_filterMode)
-{
-	char *mac_arry_buf = NULL;
-	INT policy = -1;
-	INT buf_size = 1024;
-
-	mac_arry_buf =	malloc(buf_size);
-	if (!mac_arry_buf) {
-		wifi_debug(DEBUG_ERROR,"malloc mac_arry_buf fails\n");
-		return RETURN_ERR;
-	}
-	memset(mac_arry_buf, 0, buf_size);
-	if (mtk_wifi_getApAclDevices(apIndex, mac_arry_buf, buf_size) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR,"mtk_wifi_getApAclDevices get fails\n");
-		goto err;
-	}
-	/*
-	mtk format to get policy:
-	"policy=1
-	 00:11:22:33:44:55
-	 00:11:22:33:44:66
-	"
-	*/
-	if (strlen(mac_arry_buf) < strlen("policy=1") || sscanf(mac_arry_buf, "policy=%01d", &policy) != 1) {
-		wifi_debug(DEBUG_ERROR,"mac_arry_buf(%s) invalid\n", mac_arry_buf);
-		goto err;
-	}
-	if (!(policy >=0 && policy <= 2)){
-		wifi_debug(DEBUG_ERROR,"policy(%d) is invalid\n", policy);
-		goto err;
-	}
-	*output_filterMode = policy;
-	wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), success\n", *output_filterMode);
-	free(mac_arry_buf);
-	mac_arry_buf = NULL;
-	return RETURN_OK;
-err:
-	free(mac_arry_buf);
-	mac_arry_buf = NULL;
-	wifi_debug(DEBUG_NOTICE, "output_filterMode(%d), fails\n", *output_filterMode);
-	return RETURN_ERR;
-}
-
-
-INT wifi_getApAssociatedDeviceDiagnosticResult2(INT apIndex,wifi_associated_dev2_t **associated_dev_array,UINT *output_array_size)
-{
-	FILE *fp = NULL;
-	char str[MAX_BUF_SIZE] = {0};
-	int wificlientindex = 0 ;
-	int count = 0;
-	int signalstrength = 0;
-	int arr[MACADDRESS_SIZE] = {0};
-	unsigned char mac[MACADDRESS_SIZE] = {0};
-	UINT wifi_count = 0;
-
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	*output_array_size = 0;
-	*associated_dev_array = NULL;
-	char interface_name[50] = {0};
-
-	if(wifi_getApName(apIndex, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getApName failed\n");
-		return RETURN_ERR;
-	}
-
-	fp = v_secure_popen( "r", "iw dev %s station dump | grep %s | wc -l", interface_name, interface_name);
-	if (fp == NULL)
-	{
-		wifi_debug(DEBUG_ERROR, "Failed to run command\n");
-		return RETURN_ERR;
-	}
-
-	/* Read the output a line at a time - output it. */
-	if (fgets(str, sizeof(str)-1, fp) == NULL) {
-		wifi_debug(DEBUG_ERROR, "fgets fail\n");
-		v_secure_pclose(fp);
-		return RETURN_ERR;
-	}
-	wifi_count = (unsigned int) atoi ( str );
-	*output_array_size = wifi_count;
-	wifi_debug(DEBUG_INFO, "In rdkb hal ,Wifi Client Counts and index %d and  %d \n", *output_array_size,apIndex);
-	v_secure_pclose(fp);
-
-	if(wifi_count == 0)
-	{
-		return RETURN_OK;
-	}
-	else
-	{
-		wifi_associated_dev2_t* temp = NULL;
-		temp = (wifi_associated_dev2_t*)calloc(wifi_count, sizeof(wifi_associated_dev2_t));
-		*associated_dev_array = temp;
-		if(temp == NULL)
-		{
-			wifi_debug(DEBUG_ERROR, "Error Statement. Insufficient memory \n");
-			return RETURN_ERR;
-		}
-
-		res = v_secure_system("iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-			return RETURN_ERR;
-		}
-
-		fp = fopen("/tmp/AssociatedDevice_Stats.txt", "r");
-		if(fp == NULL)
-		{
-			wifi_debug(DEBUG_ERROR, "/tmp/AssociatedDevice_Stats.txt not exists \n");
-			return RETURN_ERR;
-		}
-		if (fclose(fp) == EOF) {
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-			return RETURN_ERR;
-		}
-
-		fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep Station | cut -d ' ' -f 2");
-		if(fp)
-		{
-			for(count =0 ; count < wifi_count; count++)
-			{
-				if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-					wifi_debug(DEBUG_ERROR, "fgets fail\n");
-					v_secure_pclose(fp);
-					return RETURN_ERR;
-				}
-				if( MACADDRESS_SIZE == sscanf(str, "%02x:%02x:%02x:%02x:%02x:%02x",&arr[0],&arr[1],&arr[2],&arr[3],&arr[4],&arr[5]) )
-				{
-					for( wificlientindex = 0; wificlientindex < MACADDRESS_SIZE; ++wificlientindex )
-					{
-						mac[wificlientindex] = (unsigned char) arr[wificlientindex];
-
-					}
-					memcpy(temp[count].cli_MACAddress,mac,(sizeof(unsigned char))*6);
-					wifi_debug(DEBUG_INFO, "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]);
-				}
-				temp[count].cli_AuthenticationState = 1; //TODO
-				temp[count].cli_Active = 1; //TODO
-			}
-			v_secure_pclose(fp);
-		}
-
-		//Updating  RSSI per client
-		fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep signal | tr -s ' ' | cut -d ' ' -f 2 > /tmp/wifi_signalstrength.txt");
-		if(fp)
-		{
-			v_secure_pclose(fp);
-		}
-		fp = v_secure_popen("r", "cat /tmp/wifi_signalstrength.txt | tr -s ' ' | cut -f 2");
-		if(fp)
-		{
-			for(count =0 ; count < wifi_count ;count++)
-			{
-				if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-					wifi_debug(DEBUG_ERROR, "fgets fail\n");
-					v_secure_pclose(fp);
-					return RETURN_ERR;
-				}
-				signalstrength = atoi(str);
-				temp[count].cli_RSSI = signalstrength;
-			}
-			v_secure_pclose(fp);
-		}
-
-
-		//LastDataDownlinkRate
-		fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'tx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Send.txt");
-		if (fp)
-		{
-			v_secure_pclose(fp);
-		}
-		fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Send.txt | tr -s ' ' | cut -f 2");
-		if (fp)
-		{
-			unsigned long tmp_u;
-			for (count = 0; count < wifi_count; count++)
-			{
-				if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-					wifi_debug(DEBUG_ERROR, "fgets fail\n");
-					v_secure_pclose(fp);
-					return RETURN_ERR;
-				}
-				if (hal_strtoul(str, 10, &tmp_u) < 0) {
-					wifi_debug(DEBUG_ERROR, "strtol fail\n");
-				}
-				temp[count].cli_LastDataDownlinkRate = tmp_u;
-				temp[count].cli_LastDataDownlinkRate = (temp[count].cli_LastDataDownlinkRate * 1024); //Mbps -> Kbps
-			}
-			v_secure_pclose(fp);
-		}
-
-		//LastDataUplinkRate
-		fp = v_secure_popen("r", "cat /tmp/AssociatedDevice_Stats.txt | grep 'rx bitrate' | tr -s ' ' | cut -d ' ' -f 2 > /tmp/Ass_Bitrate_Received.txt");
-		if (fp)
-		{
-			v_secure_pclose(fp);
-		}
-		fp = v_secure_popen("r", "cat /tmp/Ass_Bitrate_Received.txt | tr -s ' ' | cut -f 2");
-		if (fp)
-		{
-			unsigned long tmp_u;
-			for (count = 0; count < wifi_count; count++)
-			{
-				if (fgets(str, MAX_BUF_SIZE, fp) == NULL) {
-					wifi_debug(DEBUG_ERROR, "fgets fail\n");
-					v_secure_pclose(fp);
-					return RETURN_ERR;
-				}
-				if (hal_strtoul(str, 10, &tmp_u) < 0) {
-					wifi_debug(DEBUG_ERROR, "strtol fail\n");
-				}
-				temp[count].cli_LastDataUplinkRate = tmp_u;
-				temp[count].cli_LastDataUplinkRate = (temp[count].cli_LastDataUplinkRate * 1024); //Mbps -> Kbps
-			}
-			v_secure_pclose(fp);
-		}
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-
-}
-
-INT wifi_getSSIDTrafficStats2(INT ssidIndex,wifi_ssidTrafficStats2_t *output_struct)
-{
-	FILE *fp = NULL;
-	char interface_name[50] = {0};
-
-	char str[256] = {0};
-	wifi_ssidTrafficStats2_t *out = output_struct;
-
-	unsigned int recv;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-	if (!output_struct)
-		return RETURN_ERR;
-
-	memset(out, 0, sizeof(wifi_ssidTrafficStats2_t));
-	if (wifi_GetInterfaceName(ssidIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-
-
-
-
-
-	fp = v_secure_popen("r", "cat /proc/net/dev | grep %s", interface_name);
-	if (fp == NULL) {
-		wifi_debug(DEBUG_ERROR, "%s: v_secure_popen failed\n", __func__);
-		return RETURN_ERR;
-	}
-	if (fgets(str, sizeof(str), fp) == NULL) {
-		wifi_debug(DEBUG_ERROR, "fgets fail\n");
-		v_secure_pclose(fp);
-		return RETURN_ERR;
-	}
-
-	v_secure_pclose(fp);
-
-	if (strlen(str) == 0)   // interface not exist
-		return RETURN_OK;
-
-	recv = sscanf(str, "%*[^:]: %lu %lu %lu %lu %*d %*d %*d %*d %lu %lu %lu %lu", &out->ssid_BytesReceived, &out->ssid_PacketsReceived, &out->ssid_ErrorsReceived, \
-	&out->ssid_DiscardedPacketsReceived, &out->ssid_BytesSent, &out->ssid_PacketsSent, &out->ssid_ErrorsSent, &out->ssid_DiscardedPacketsSent);
-	if (recv != 8) {
-		wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
-		return RETURN_ERR;
-	}
-
-	memset(str, 0, sizeof(str));
-
-
-
-
-
-
-	fp = v_secure_popen("r", "tail -n1 /proc/net/netstat");
-	if (fp == NULL) {
-		wifi_debug(DEBUG_ERROR, "v_secure_popen failed\n");
-		return RETURN_ERR;
-	}
-
-	if (fgets(str, sizeof(str), fp) == NULL) {
-		wifi_debug(DEBUG_ERROR, "fgets fail\n");
-		v_secure_pclose(fp);
-		return RETURN_ERR;
-	}
-
-	if (sscanf(str, "%*[^:]: %lu %lu %lu %lu", &out->ssid_MulticastPacketsReceived, &out->ssid_MulticastPacketsSent, &out->ssid_BroadcastPacketsRecevied, \
-	&out->ssid_BroadcastPacketsSent) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-	v_secure_pclose(fp);
-
-	out->ssid_UnicastPacketsSent = out->ssid_PacketsSent - out->ssid_MulticastPacketsSent - out->ssid_BroadcastPacketsSent - out->ssid_DiscardedPacketsSent;
-	out->ssid_UnicastPacketsReceived = out->ssid_PacketsReceived - out->ssid_MulticastPacketsReceived - out->ssid_BroadcastPacketsRecevied - out->ssid_DiscardedPacketsReceived;
-
-	// Not supported
-	output_struct->ssid_RetransCount = 0;
-	output_struct->ssid_FailedRetransCount = 0;
-	output_struct->ssid_RetryCount = 0;
-	output_struct->ssid_MultipleRetryCount = 0;
-	output_struct->ssid_ACKFailureCount = 0;
-	output_struct->ssid_AggregatedPacketCount = 0;
-
-	return RETURN_OK;
-}
-
-int mtk_get_ap_isolation_callback(struct nl_msg *msg, void *data) {
-    struct nlattr *tb[NL80211_ATTR_MAX + 1];
-    struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX + 1];
-    struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-    unsigned char status;
-    unsigned char *out_status = data;
-    int err = 0;
-
-    err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-              genlmsg_attrlen(gnlh, 0), NULL);
-    if (err < 0){
-        wifi_debug(DEBUG_ERROR, "get NL80211_ATTR_MAX fails\n");
-        return err;
-    }
-
-    if (tb[NL80211_ATTR_VENDOR_DATA]) {
-        err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_BSS_ATTR_MAX,
-            tb[NL80211_ATTR_VENDOR_DATA], NULL);
-        if (err < 0){
-            wifi_debug(DEBUG_ERROR, "get MTK_NL80211_VENDOR_AP_BA_ATTR_MAX fails\n");
-            return err;
-        }
-
-        if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_ISOLATION]) {
-            status = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_ISOLATION]);
-            if (status == 0) {
-                wifi_debug(DEBUG_INFO, "disabled\n");
-            } else {
-                wifi_debug(DEBUG_INFO, "enabled\n");
-            }
-            *out_status = status;
-        }
-    }
-    return 0;
-
-}
-
-//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).
-INT wifi_getApIsolationEnable(INT apIndex, BOOL *output)
-{
-    char inf_name[IF_NAME_SIZE] = {0};
-    unsigned int if_idx = 0;
-    int ret = -1;
-    struct unl unl_ins;
-    struct nl_msg *msg  = NULL;
-    struct nlattr * msg_data = NULL;
-    struct mtk_nl80211_param param;
-
-    if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-        return RETURN_ERR;
-    if_idx = if_nametoindex(inf_name);
-
-    /*init mtk nl80211 vendor cmd*/
-    param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
-    param.if_type = NL80211_ATTR_IFINDEX;
-    param.if_idx = if_idx;
-
-    ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-    if (ret) {
-        wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-        return RETURN_ERR;
-    }
-    /*add mtk vendor cmd data*/
-    if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_ISOLATION, 0xf)) {
-        wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_AMSDU_EN);
-        nlmsg_free(msg);
-        goto err;
-    }
-
-    /*send mtk nl80211 vendor msg*/
-    ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_isolation_callback, output);
-    if (ret) {
-        wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-        goto err;
-    }
-    /*deinit mtk nl80211 vendor msg*/
-    mtk_nl80211_deint(&unl_ins);
-    wifi_debug(DEBUG_INFO,"send cmd success, get output_bool:%d\n", *output);
-    return RETURN_OK;
-err:
-    mtk_nl80211_deint(&unl_ins);
-    wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-    return RETURN_ERR;
-}
-
-INT wifi_setApIsolationEnable(INT apIndex, BOOL enable)
-{
-    char inf_name[IF_NAME_SIZE] = {0};
-    unsigned int if_idx = 0;
-    int ret = -1;
-    struct unl unl_ins;
-    struct nl_msg *msg  = NULL;
-    struct nlattr * msg_data = NULL;
-    struct mtk_nl80211_param nl_param;
-
-    if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-        return RETURN_ERR;
-    if_idx = if_nametoindex(inf_name);
-
-    nl_param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_BSS;
-    nl_param.if_type = NL80211_ATTR_IFINDEX;
-    nl_param.if_idx = if_idx;
-    /*init mtk nl80211 vendor cmd*/
-    ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &nl_param);
-    if (ret) {
-        wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-        return RETURN_ERR;
-    }
-    /*add mtk vendor cmd data*/
-    if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_AP_ISOLATION, enable)) {
-        wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", MTK_NL80211_VENDOR_ATTR_AP_ISOLATION);
-        nlmsg_free(msg);
-        goto err;
-    }
-
-    /*send mtk nl80211 vendor msg*/
-    ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-    if (ret) {
-        wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-        goto err;
-    }
-    /*deinit mtk nl80211 vendor msg*/
-    mtk_nl80211_deint(&unl_ins);
-    return RETURN_OK;
-err:
-    mtk_nl80211_deint(&unl_ins);
-    wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-    return RETURN_ERR;
-}
-int get_mgmt_real_pwr_handler(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_TXPWR_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	unsigned char *mgmt_pwr = (unsigned char *)data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return err;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_TXPWR_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return err;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_TXPWR_GET_MGMT]) {
-			*mgmt_pwr = nla_get_u8(vndr_tb[MTK_NL80211_VENDOR_ATTR_TXPWR_GET_MGMT]);
-		}
-	}
-	wifi_debug(DEBUG_INFO, "get_mgmt_real_pwr_handler--\n");
-
-	return 0;
-}
-
-INT mtk_wifi_get_mgmt_real_pwr(
-	int if_idx, INT vendor_data_attr, mtk_nl80211_cb call_back, void *output)
-{
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_u8(msg, vendor_data_attr, 1)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "send cmd success.\n");
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails,%d\n", ret);
-	return RETURN_ERR;
-}
-INT wifi_getApManagementFramePowerControl(INT apIndex, INT *output_dBm)
-{
-	char mgmtpwr_file[32] = {0};
-
-	char buf[32]={0};
-	int res;
-	long int tmp;
-
-	if (NULL == output_dBm)
-		return RETURN_ERR;
-	res = snprintf(mgmtpwr_file, sizeof(mgmtpwr_file), "%s%d.txt", MGMT_POWER_CTRL, apIndex);
-	if (os_snprintf_error(sizeof(mgmtpwr_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s 2> /dev/null", mgmtpwr_file);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-	if (strlen(buf) > 0) {
-		if (hal_strtol(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		*output_dBm = tmp;
-	} else
- 		*output_dBm = 0;/*Agent range:-20 ~ 0*/
-	return RETURN_OK;
-}
-
-INT wifi_setApManagementFramePowerControl(INT wlanIndex, INT dBm)
-{
-	char interface_name[16] = {0};
-	char mgmt_pwr_file[128]={0};
-	FILE *f = NULL;
-	int if_idx, ret = 0;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-	char power[16] = {0};
-	int res;
-	unsigned char mgmt_real_pwr = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (wifi_GetInterfaceName(wlanIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if_idx = if_nametoindex(interface_name);
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_TXPOWER;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	if (dBm > 0)
-		dBm = 0;
-	if (dBm < -20)
-		dBm = -20;
-	/*Generally, management tx power is 23dBm, the input dBm is not a target power, it's range is -20 ~ 0,
-	it may be delta power.*/
-	mtk_wifi_get_mgmt_real_pwr(if_idx, MTK_NL80211_VENDOR_ATTR_TXPWR_GET_MGMT, get_mgmt_real_pwr_handler, &mgmt_real_pwr);
-	wifi_debug(DEBUG_INFO, "mgmt_real_pwr = %d\n", mgmt_real_pwr);
-	/*add mtk vendor cmd data*/
-	if (mgmt_real_pwr != 0)
-		res = snprintf(power, sizeof(power), "%d", (mgmt_real_pwr + dBm));
-	else
-		res = snprintf(power, sizeof(power), "%d", (23 + dBm));
-	if (os_snprintf_error(sizeof(power), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_TXPWR_MGMT, strlen(power), power)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-
-	res = snprintf(mgmt_pwr_file, sizeof(mgmt_pwr_file), "%s%d.txt", MGMT_POWER_CTRL, wlanIndex);
-	if (os_snprintf_error(sizeof(mgmt_pwr_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	f = fopen(mgmt_pwr_file, "w");
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR, "%s: fopen failed\n", __func__);
-		return RETURN_ERR;
-	}
-	fprintf(f, "%d", dBm);
-	if (fclose(f) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-
-   return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-INT wifi_getRadioDcsChannelMetrics(INT radioIndex,wifi_channelMetrics_t *input_output_channelMetrics_array,INT size)
-{
-	return RETURN_OK;
-}
-INT wifi_setRadioDcsDwelltime(INT radioIndex, INT ms)
-{
-	return RETURN_OK;
-}
-INT wifi_getRadioDcsDwelltime(INT radioIndex, INT *ms)
-{
-	return RETURN_OK;
-}
-INT wifi_setRadioDcsScanning(INT radioIndex, BOOL enable)
-{
-	return RETURN_OK;
-}
-
-INT wifi_setBSSTransitionActivation(UINT apIndex, BOOL activate)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	list.name = "bss_transition";
-	list.value = activate?"1":"0";
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf",CONFIG_PREFIX,apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-	wifi_quick_reload_ap(apIndex);
-
-	return RETURN_OK;
-}
-
-
-wifi_apAuthEvent_callback apAuthEvent_cb = NULL;
-
-void wifi_apAuthEvent_callback_register(wifi_apAuthEvent_callback callback_proc)
-{
-	return;
-}
-
-INT wifi_setApCsaDeauth(INT apIndex, INT mode)
-{
-	// TODO Implement me!
-	return RETURN_OK;
-}
-
-INT wifi_setApScanFilter(INT apIndex, INT mode, CHAR *essid)
-{
-	char file_name[128] = {0};
-	FILE *f = NULL;
-	int res, ret;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (essid == NULL || strlen(essid) == 0 || apIndex == -1) {
-		for (int index = 0; index < get_runtime_max_radio(); index++) {
-			res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, index);
-			if (os_snprintf_error(sizeof(file_name), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-
-			f = fopen(file_name, "w");
-			if (f == NULL)
-				return RETURN_ERR;
-			// For mode == 0 is to disable filter, just don't write to the file.
-			if (mode) {
-				ret = fprintf(f, "%s", essid);
-				if (ret < 0)
-					wifi_debug(DEBUG_ERROR, "fprintf fail\n");
-			}
-
-			if (fclose(f) != 0) {
-				wifi_debug(DEBUG_ERROR, "fclose fail\n");
-				return RETURN_ERR;
-			}
-		}
-	} else {		// special case, need to set AP's SSID as filter for each radio.
-		res = snprintf(file_name, sizeof(file_name), "%s%d.txt", ESSID_FILE, apIndex);
-		if (os_snprintf_error(sizeof(file_name), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		f = fopen(file_name, "w");
-		if (f == NULL)
-			return RETURN_ERR;
-
-		// For mode == 0 is to disable filter, just don't write to the file.
-		if (mode) {
-			ret = fprintf(f, "%s", essid);
-			if (ret < 0)
-				wifi_debug(DEBUG_ERROR, "fprintf fail\n");
-		}
-
-		if (fclose(f) == EOF) {
-			wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_pushRadioChannel(INT radioIndex, UINT channel)
-{
-	// TODO Implement me!
-	//Apply wifi_pushRadioChannel() instantly
-	return RETURN_ERR;
-}
-
-INT wifi_setRadioStatsEnable(INT radioIndex, BOOL enable)
-{
-	// TODO Implement me!
-	return RETURN_OK;
-}
-
-
-static int tidStats_callback(struct nl_msg *msg, void *arg) {
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1];
-	struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1],*tidattr;
-	int rem , tid_index = 0;
-
-	wifi_associated_dev_tid_stats_t *out = (wifi_associated_dev_tid_stats_t*)arg;
-	wifi_associated_dev_tid_entry_t *stats_entry;
-
-	static struct nla_policy stats_policy[NL80211_STA_INFO_MAX + 1] = {
-				 [NL80211_STA_INFO_TID_STATS] = { .type = NLA_NESTED },
-	};
-	static struct nla_policy tid_policy[NL80211_TID_STATS_MAX + 1] = {
-				 [NL80211_TID_STATS_TX_MSDU] = { .type = NLA_U64 },
-	};
-
-	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-				  genlmsg_attrlen(gnlh, 0), NULL);
-
-
-	if (!tb[NL80211_ATTR_STA_INFO]) {
-		wifi_debug(DEBUG_ERROR, "station stats missing!\n");
-		return NL_SKIP;
-	}
-
-	if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,
-							 tb[NL80211_ATTR_STA_INFO],
-							 stats_policy)) {
-		wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
-		return NL_SKIP;
-	}
-
-	if (sinfo[NL80211_STA_INFO_TID_STATS]) {
-		nla_for_each_nested(tidattr, sinfo[NL80211_STA_INFO_TID_STATS], rem)
-		{
-			stats_entry = &out->tid_array[tid_index];
-
-			stats_entry->tid = tid_index;
-			stats_entry->ac = _tid_ac_index_get[tid_index];
-
-			if(sinfo[NL80211_STA_INFO_TID_STATS])
-			{
-				if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,tidattr, tid_policy)) {
-					wifi_debug(DEBUG_ERROR, "failed to parse nested stats attributes!");
-					return NL_SKIP;
-				}
-			}
-			if(stats_info[NL80211_TID_STATS_TX_MSDU])
-				stats_entry->num_msdus = (unsigned long long)nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
-
-			if(tid_index < (PS_MAX_TID - 1))
-				tid_index++;
-		}
-	}
-	//ToDo: sum_time_ms, ewma_time_ms
-	return NL_SKIP;
-}
-
-INT wifi_getApAssociatedDeviceTidStatsResult(INT radioIndex,  mac_address_t *clientMacAddress, wifi_associated_dev_tid_stats_t *tid_stats,  ULLONG *handle)
-{
-	Netlink nl;
-	char  if_name[IF_NAME_SIZE];
-	char interface_name[IF_NAME_SIZE] = {0};
-	int res;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
-	if (os_snprintf_error(sizeof(if_name), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	nl.id = initSock80211(&nl);
-
-	if (nl.id < 0) {
-		wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
-		return -1;
-	}
-
-	struct nl_msg* msg = nlmsg_alloc();
-
-	if (!msg) {
-		wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
-		nlfree(&nl);
-		return -2;
-	}
-
-	genlmsg_put(msg,
-			  NL_AUTO_PID,
-			  NL_AUTO_SEQ,
-			  nl.id,
-			  0,
-			  0,
-			  NL80211_CMD_GET_STATION,
-			  0);
-
-	nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
-	nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
-	nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,tidStats_callback,tid_stats);
-	nl_send_auto_complete(nl.socket, msg);
-	nl_recvmsgs(nl.socket, nl.cb);
-	nlmsg_free(msg);
-	nlfree(&nl);
-	return RETURN_OK;
-}
-
-
-INT wifi_startNeighborScan(INT apIndex, wifi_neighborScanMode_t scan_mode, INT dwell_time, UINT chan_num, UINT *chan_list)
-{
-	char interface_name[16] = {0};
-	char buf[128]={0};
-	int freq = 0;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	// full mode is used to scan all channels.
-	// multiple channels is ambiguous, iw can not set multiple frequencies in one time.
-	if (scan_mode != WIFI_RADIO_SCAN_MODE_FULL)
-		ieee80211_channel_to_frequency(chan_list[0], &freq);
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (freq)
-		res = _syscmd_secure(buf, sizeof(buf), "iw dev %s scan trigger duration %d freq %d", interface_name, dwell_time, freq);
-	else
-		res = _syscmd_secure(buf, sizeof(buf), "iw dev %s scan trigger duration %d", interface_name, dwell_time);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-
-INT wifi_steering_setGroup(UINT steeringgroupIndex, wifi_steering_apConfig_t *cfg_2, wifi_steering_apConfig_t *cfg_5)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_steering_clientSet(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_steering_clientConfig_t *config)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_steering_clientRemove(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_steering_clientMeasure(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_steering_clientDisconnect(UINT steeringgroupIndex, INT apIndex, mac_address_t client_mac, wifi_disconnectType_t type, UINT reason)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_steering_eventRegister(wifi_steering_eventCB_t event_cb)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_steering_eventUnregister(void)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_delApAclDevices(INT apIndex)
-{
-	char inf_name[IF_NAME_SIZE] = {0};
-	struct unl unl_ins;
-	int if_idx = 0, ret = 0;
-	struct nl_msg *msg  = NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-	if (nla_put_flag(msg, MTK_NL80211_VENDOR_ATTR_ACL_CLEAR_ALL)) {
-		wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-
-	return RETURN_OK;
-}
-
-static int rxStatsInfo_callback(struct nl_msg *msg, void *arg) {
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
-	struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
-	struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
-	char mac_addr[20],dev[20];
-
-	nla_parse(tb,
-		NL80211_ATTR_MAX,
-		genlmsg_attrdata(gnlh, 0),
-		genlmsg_attrlen(gnlh, 0),
-		NULL);
-
-	if (!tb[NL80211_ATTR_STA_INFO]) {
-		wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
-		return NL_SKIP;
-	}
-
-	if (nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
-		wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
-		return NL_SKIP;
-	}
-	mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
-
-	if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
-
-	if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
-		if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_RX_BITRATE], rate_policy )) {
-			wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
-			return NL_SKIP;
-		}
-	}
-
-	if (sinfo[NL80211_STA_INFO_TID_STATS]) {
-		if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
-			wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
-			return NL_SKIP;
-		}
-	}
-	if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
-
-		if( nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]) )
-		{
-			wifi_debug(DEBUG_INFO, "Type is VHT\n");
-			if(rinfo[NL80211_RATE_INFO_VHT_NSS])
-				((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
-
-			if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 1;
-			if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
-			if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
-			if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
-				 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 2;
-			if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]) )
-							 ((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
-		} else {
-			wifi_debug(DEBUG_INFO, "OFDM or CCK\n");
-			((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bw = 0;
-			((wifi_associated_dev_rate_info_rx_stats_t*)arg)->nss = 0;
-		}
-	}
-
-	if (sinfo[NL80211_STA_INFO_RX_BITRATE]) {
-		if(rinfo[NL80211_RATE_INFO_MCS])
-			((wifi_associated_dev_rate_info_rx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
-	}
-	if (sinfo[NL80211_STA_INFO_RX_BYTES64])
-		((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_RX_BYTES64]);
-	else if (sinfo[NL80211_STA_INFO_RX_BYTES])
-		((wifi_associated_dev_rate_info_rx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_RX_BYTES]);
-
-	if (sinfo[NL80211_STA_INFO_TID_STATS]) {
-		if (stats_info[NL80211_TID_STATS_RX_MSDU])
-			((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_RX_MSDU]);
-	}
-
-	if (sinfo[NL80211_STA_INFO_SIGNAL])
-		((wifi_associated_dev_rate_info_rx_stats_t*)arg)->rssi_combined = nla_get_u8(sinfo[NL80211_STA_INFO_SIGNAL]);
-	//Assigning 0 for RETRIES ,PPDUS and MPDUS as we dont have rx retries attribute in libnl_3.3.0
-	((wifi_associated_dev_rate_info_rx_stats_t*)arg)->retries = 0;
-	((wifi_associated_dev_rate_info_rx_stats_t*)arg)->ppdus = 0;
-	((wifi_associated_dev_rate_info_rx_stats_t*)arg)->msdus = 0;
-	//rssi_array need to be filled
-	return NL_SKIP;
-}
-
-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)
-{
-	Netlink nl;
-	char if_name[32];
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, if_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	*output_array_size = sizeof(wifi_associated_dev_rate_info_rx_stats_t);
-
-	if (*output_array_size <= 0)
-		return RETURN_OK;
-
-	nl.id = initSock80211(&nl);
-
-	if (nl.id < 0) {
-	wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
-	return 0;
-	}
-
-	struct nl_msg* msg = nlmsg_alloc();
-
-	if (!msg) {
-		wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
-		nlfree(&nl);
-		return 0;
-	}
-
-	genlmsg_put(msg,
-		NL_AUTO_PID,
-		NL_AUTO_SEQ,
-		nl.id,
-		0,
-		0,
-		NL80211_CMD_GET_STATION,
-		0);
-
-	nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, *clientMacAddress);
-	nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
-	nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, rxStatsInfo_callback, stats_array);
-	nl_send_auto_complete(nl.socket, msg);
-	nl_recvmsgs(nl.socket, nl.cb);
-	nlmsg_free(msg);
-	nlfree(&nl);
-	return RETURN_OK;
-}
-
-static int txStatsInfo_callback(struct nl_msg *msg, void *arg) {
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct nlattr *sinfo[NL80211_STA_INFO_MAX + 1] = {NULL};
-	struct nlattr *rinfo[NL80211_RATE_INFO_MAX + 1] = {NULL};
-	struct nlattr *stats_info[NL80211_TID_STATS_MAX + 1];
-	char mac_addr[20],dev[20];
-
-	nla_parse(tb,
-			  NL80211_ATTR_MAX,
-			  genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0),
-			  NULL);
-
-	if(!tb[NL80211_ATTR_STA_INFO]) {
-		wifi_debug(DEBUG_ERROR, "sta stats missing!\n");
-		return NL_SKIP;
-	}
-
-	if(nla_parse_nested(sinfo, NL80211_STA_INFO_MAX,tb[NL80211_ATTR_STA_INFO], stats_policy)) {
-		wifi_debug(DEBUG_ERROR, "failed to parse nested attributes!\n");
-		return NL_SKIP;
-	}
-
-	mac_addr_ntoa(mac_addr, nla_data(tb[NL80211_ATTR_MAC]));
-
-	if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
-
-	if (sinfo[NL80211_STA_INFO_TX_BITRATE]) {
-		if(nla_parse_nested(rinfo, NL80211_RATE_INFO_MAX, sinfo[NL80211_STA_INFO_TX_BITRATE], rate_policy)) {
-			wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
-			return NL_SKIP;
-		}
-	}
-
-	if(sinfo[NL80211_STA_INFO_TID_STATS])
-	{
-		if(nla_parse_nested(stats_info, NL80211_TID_STATS_MAX,sinfo[NL80211_STA_INFO_TID_STATS], tid_policy)) {
-			wifi_debug(DEBUG_ERROR, "failed to parse nested rate attributes!");
-			return NL_SKIP;
-		}
-	}
-	if (tb[NL80211_ATTR_VHT_CAPABILITY]) {
-		if(nla_data(tb[NL80211_ATTR_VHT_CAPABILITY]))
-		{
-			wifi_debug(DEBUG_INFO, "Type is VHT\n");
-			if(rinfo[NL80211_RATE_INFO_VHT_NSS])
-				((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = nla_get_u8(rinfo[NL80211_RATE_INFO_VHT_NSS]);
-
-			if(rinfo[NL80211_RATE_INFO_40_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 1;
-			if(rinfo[NL80211_RATE_INFO_80_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
-			if(rinfo[NL80211_RATE_INFO_80P80_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
-			if(rinfo[NL80211_RATE_INFO_160_MHZ_WIDTH])
-				((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 2;
-			if((rinfo[NL80211_RATE_INFO_10_MHZ_WIDTH]) || (rinfo[NL80211_RATE_INFO_5_MHZ_WIDTH]))
-				((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
-		}
-		else
-		{
-			wifi_debug(DEBUG_INFO, "OFDM or CCK\n");
-			((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bw = 0;
-			((wifi_associated_dev_rate_info_tx_stats_t*)arg)->nss = 0;
-		}
-	}
-
-	if(sinfo[NL80211_STA_INFO_TX_BITRATE]) {
-	   if(rinfo[NL80211_RATE_INFO_MCS])
-		   ((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mcs = nla_get_u8(rinfo[NL80211_RATE_INFO_MCS]);
-	}
-
-	if(sinfo[NL80211_STA_INFO_TX_BYTES64])
-		((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u64(sinfo[NL80211_STA_INFO_TX_BYTES64]);
-	else if (sinfo[NL80211_STA_INFO_TX_BYTES])
-		((wifi_associated_dev_rate_info_tx_stats_t*)arg)->bytes = nla_get_u32(sinfo[NL80211_STA_INFO_TX_BYTES]);
-
-	//Assigning  0 for mpdus and ppdus , as we do not have attributes in netlink
-	((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
-	((wifi_associated_dev_rate_info_tx_stats_t*)arg)->mpdus = 0;
-
-	if(sinfo[NL80211_STA_INFO_TID_STATS]) {
-		if(stats_info[NL80211_TID_STATS_TX_MSDU])
-			((wifi_associated_dev_rate_info_tx_stats_t*)arg)->msdus = nla_get_u64(stats_info[NL80211_TID_STATS_TX_MSDU]);
-	}
-
-	if(sinfo[NL80211_STA_INFO_TX_RETRIES])
-		((wifi_associated_dev_rate_info_tx_stats_t*)arg)->retries = nla_get_u32(sinfo[NL80211_STA_INFO_TX_RETRIES]);
-
-	if(sinfo[NL80211_STA_INFO_TX_FAILED] && sinfo[NL80211_STA_INFO_TX_PACKETS])
-		((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]);
-
-	return NL_SKIP;
-}
-
-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)
-{
-	Netlink nl;
-	char if_name[IF_NAME_SIZE];
-	char interface_name[IF_NAME_SIZE] = {0};
-	int res;
-	int main_vap_idx;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	*output_array_size = sizeof(wifi_associated_dev_rate_info_tx_stats_t);
-
-	if (*output_array_size <= 0)
-		return RETURN_OK;
-
-	res = snprintf(if_name, sizeof(if_name), "%s", interface_name);
-	if (os_snprintf_error(sizeof(if_name), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	nl.id = initSock80211(&nl);
-
-	if(nl.id < 0) {
-		wifi_debug(DEBUG_ERROR, "Error initializing netlink \n");
-		return 0;
-	}
-
-	struct nl_msg* msg = nlmsg_alloc();
-
-	if(!msg) {
-		wifi_debug(DEBUG_ERROR, "Failed to allocate netlink message.\n");
-		nlfree(&nl);
-		return 0;
-	}
-
-	genlmsg_put(msg,
-				NL_AUTO_PID,
-				NL_AUTO_SEQ,
-				nl.id,
-				0,
-				0,
-				NL80211_CMD_GET_STATION,
-				0);
-
-	nla_put(msg, NL80211_ATTR_MAC, MAC_ALEN, clientMacAddress);
-	nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
-	nl_cb_set(nl.cb, NL_CB_VALID , NL_CB_CUSTOM, txStatsInfo_callback, stats_array);
-	nl_send_auto_complete(nl.socket, msg);
-	nl_recvmsgs(nl.socket, nl.cb);
-	nlmsg_free(msg);
-	nlfree(&nl);
-	return RETURN_OK;
-}
-
-INT wifi_getBSSTransitionActivation(UINT apIndex, BOOL *activate)
-{
-	// TODO Implement me!
-	char buf[MAX_BUF_SIZE] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "bss_transition", buf, sizeof(buf));
-	*activate = (strncmp("1",buf,1) == 0);
-
-	return RETURN_OK;
-}
-
-INT wifi_setNeighborReportActivation(UINT apIndex, BOOL activate)
-{
-	char config_file[MAX_BUF_SIZE] = {0};
-	struct params list;
-	int res;
-
-	list.name = "rrm_neighbor_report";
-	list.value = activate?"1":"0";
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	wifi_hostapdWrite(config_file, &list, 1);
-	wifi_hostapdProcessUpdate(apIndex, &list, 1);
-	wifi_quick_reload_ap(apIndex);
-
-	return RETURN_OK;
-}
-
-
-INT wifi_getNeighborReportActivation(UINT apIndex, BOOL *activate)
-{
-	char buf[32] = {0};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "rrm_neighbor_report", buf, sizeof(buf));
-	*activate = (strncmp("1",buf,1) == 0);
-
-	return RETURN_OK;
-}
-#undef HAL_NETLINK_IMPL
-#ifdef HAL_NETLINK_IMPL
-static int chanSurveyInfo_callback(struct nl_msg *msg, void *arg) {
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	struct nlattr *sinfo[NL80211_SURVEY_INFO_MAX + 1];
-	char dev[20];
-	int freq =0 ;
-	static int i=0;
-
-	wifi_channelStats_t_loc *out = (wifi_channelStats_t_loc*)arg;
-
-	static struct nla_policy survey_policy[NL80211_SURVEY_INFO_MAX + 1] = {
-	};
-
-	nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),genlmsg_attrlen(gnlh, 0), NULL);
-
-	if_indextoname(nla_get_u32(tb[NL80211_ATTR_IFINDEX]), dev);
-
-	if (!tb[NL80211_ATTR_SURVEY_INFO]) {
-		fprintf(stderr, "survey data missing!\n");
-		return NL_SKIP;
-	}
-
-	if (nla_parse_nested(sinfo, NL80211_SURVEY_INFO_MAX,tb[NL80211_ATTR_SURVEY_INFO],survey_policy))
-	{
-		fprintf(stderr, "failed to parse nested attributes!\n");
-		return NL_SKIP;
-	}
-
-
-	if(out[0].array_size == 1 )
-	{
-		if(sinfo[NL80211_SURVEY_INFO_IN_USE])
-		{
-			if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
-				freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
-			out[0].ch_number = ieee80211_frequency_to_channel(freq);
-
-			if (sinfo[NL80211_SURVEY_INFO_NOISE])
-				out[0].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
-				out[0].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
-				out[0].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
-				out[0].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
-				out[0].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME])
-				out[0].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
-			return NL_STOP;
-		}
-	} else {
-		if ( i <=  out[0].array_size ) {
-			if (sinfo[NL80211_SURVEY_INFO_FREQUENCY])
-				freq = nla_get_u32(sinfo[NL80211_SURVEY_INFO_FREQUENCY]);
-			out[i].ch_number = ieee80211_frequency_to_channel(freq);
-
-			if (sinfo[NL80211_SURVEY_INFO_NOISE])
-				out[i].ch_noise = nla_get_u8(sinfo[NL80211_SURVEY_INFO_NOISE]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_RX])
-				out[i].ch_utilization_busy_rx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_RX]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_TX])
-				out[i].ch_utilization_busy_tx = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_TX]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_BUSY])
-				out[i].ch_utilization_busy = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_BUSY]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY])
-				out[i].ch_utilization_busy_ext = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME_EXT_BUSY]);
-			if (sinfo[NL80211_SURVEY_INFO_TIME])
-				out[i].ch_utilization_total = nla_get_u64(sinfo[NL80211_SURVEY_INFO_TIME]);
-		}
-	}
-
-	i++;
-	return NL_SKIP;
-}
-#endif
-
-static int ieee80211_channel_to_frequency(int channel, int *freqMHz)
-{
-	char output[MAX_BUF_SIZE];
-	FILE *fp;
-
-
-	if(access("/tmp/freq-channel-map.txt", F_OK)==-1)
-	{
-		wifi_debug(DEBUG_OFF, "Creating Frequency-Channel Map\n");
-		v_secure_system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
-	}
-
-	if((fp = v_secure_popen("r", "cat /tmp/freq-channel-map.txt | grep '\\[%d\\]$' | cut -d' ' -f1", channel)))
-	{
-		if (fgets(output, sizeof(output), fp) == NULL) 	{
-			wifi_debug(DEBUG_ERROR, "fgets fail\n");
-			v_secure_pclose(fp);
-			return RETURN_ERR;
-		}
-		*freqMHz = atoi(output);
-		v_secure_pclose(fp);
-	}
-
-	return 0;
-}
-
-static int get_survey_dump_buf(INT radioIndex, int channel, char *buf, size_t bufsz)
-{
-	int freqMHz = -1;
-	char cmd[MAX_CMD_SIZE] = {'\0'};
-	char interface_name[16] = {0};
-	int res;
-	int main_vap_idx;
-
-	ieee80211_channel_to_frequency(channel, &freqMHz);
-	if (freqMHz == -1) {
-		wifi_debug(DEBUG_ERROR, "failed to get channel frequency for channel: %d\n", channel);
-		return -1;
-	}
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
-	}
-	res = snprintf(cmd, sizeof(cmd), "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (_syscmd_secure(buf, bufsz, "iw dev %s survey dump | grep -A5 %d | tr -d '\\t'", interface_name, freqMHz) == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "failed to execute '%s' for radioIndex=%d\n", cmd, radioIndex);
-		return -1;
-	}
-
-	return 0;
-}
-
-static int fetch_survey_from_buf(INT radioIndex, const char *buf, wifi_channelStats_t *stats)
-{
-	const char *ptr = buf;
-	char *key = NULL;
-	char *val = NULL;
-	char line[256] = { '\0' };
-
-	while ((ptr = get_line_from_str_buf(ptr, line))) {
-		if (strstr(line, "Frequency")) continue;
-
-		key = strtok(line, ":");
-		if (key == NULL)
-			continue;
-		val = strtok(NULL, " ");
-		if (val == NULL)
-			continue;
-		wifi_debug(DEBUG_INFO, "key='%s' val='%s'\n", key, val);
-
-		if (!strcmp(key, "noise")) {
-			if (sscanf(val, "%d", &stats->ch_noise) == EOF)
-				continue;
-			if (stats->ch_noise == 0) {
-				// Workaround for missing noise information.
-				// Assume -95 for 2.4G and -103 for 5G
-				if (radioIndex == 0) stats->ch_noise = -95;
-				if (radioIndex == 1) stats->ch_noise = -103;
-			}
-		}
-		else if (!strcmp(key, "channel active time")) {
-			if (sscanf(val, "%llu", &stats->ch_utilization_total) == EOF)
-				continue;
-		}
-		else if (!strcmp(key, "channel busy time")) {
-			if (sscanf(val, "%llu", &stats->ch_utilization_busy) == EOF)
-				continue;
-		}
-		else if (!strcmp(key, "channel receive time")) {
-			if (sscanf(val, "%llu", &stats->ch_utilization_busy_rx) == EOF)
-				continue;
-		}
-		else if (!strcmp(key, "channel transmit time")) {
-			if (sscanf(val, "%llu", &stats->ch_utilization_busy_tx) == EOF)
-				continue;
-		}
-	};
-
-	return 0;
-}
-
-INT wifi_getRadioChannelStats(INT radioIndex,wifi_channelStats_t *input_output_channelStats_array,INT array_size)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-#ifdef HAL_NETLINK_IMPL
-	Netlink nl;
-	wifi_channelStats_t_loc local[array_size];
-	char  if_name[32];
-	int main_vap_idx;
-
-	local[0].array_size = array_size;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, if_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	nl.id = initSock80211(&nl);
-
-	if (nl.id < 0) {
-		wifi_debug(DEBUG_ERROR,, "Error initializing netlink \n");
-		return -1;
-	}
-
-	struct nl_msg* msg = nlmsg_alloc();
-
-	if (!msg) {
-		wifi_debug(DEBUG_ERROR,, "Failed to allocate netlink message.\n");
-		nlfree(&nl);
-		return -2;
-	}
-
-	genlmsg_put(msg,
-				NL_AUTO_PID,
-				NL_AUTO_SEQ,
-				nl.id,
-				0,
-				NLM_F_DUMP,
-				NL80211_CMD_GET_SURVEY,
-				0);
-
-	nla_put_u32(msg, NL80211_ATTR_IFINDEX, if_nametoindex(if_name));
-	nl_send_auto_complete(nl.socket, msg);
-	nl_cb_set(nl.cb,NL_CB_VALID,NL_CB_CUSTOM,chanSurveyInfo_callback,local);
-	nl_recvmsgs(nl.socket, nl.cb);
-	nlmsg_free(msg);
-	nlfree(&nl);
-	//Copying the Values
-	for(int i=0;i<array_size;i++)
-	{
-		input_output_channelStats_array[i].ch_number = local[i].ch_number;
-		input_output_channelStats_array[i].ch_noise = local[i].ch_noise;
-		input_output_channelStats_array[i].ch_utilization_busy_rx = local[i].ch_utilization_busy_rx;
-		input_output_channelStats_array[i].ch_utilization_busy_tx = local[i].ch_utilization_busy_tx;
-		input_output_channelStats_array[i].ch_utilization_busy = local[i].ch_utilization_busy;
-		input_output_channelStats_array[i].ch_utilization_busy_ext = local[i].ch_utilization_busy_ext;
-		input_output_channelStats_array[i].ch_utilization_total = local[i].ch_utilization_total;
-		//TODO: ch_radar_noise, ch_max_80211_rssi, ch_non_80211_noise, ch_utilization_busy_self
-	}
-#else
-	ULONG channel = 0;
-	int i;
-	int number_of_channels = array_size;
-	char buf[512];
-
-	if (number_of_channels == 0) {
-		if (wifi_getRadioChannel(radioIndex, &channel) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "cannot get current channel for radioIndex=%d\n", radioIndex);
-			return RETURN_ERR;
-		}
-		number_of_channels = 1;
-		input_output_channelStats_array[0].ch_number = channel;
-	}
-
-	for (i = 0; i < number_of_channels; i++) {
-
-		input_output_channelStats_array[i].ch_noise = 0;
-		input_output_channelStats_array[i].ch_utilization_busy_rx = 0;
-		input_output_channelStats_array[i].ch_utilization_busy_tx = 0;
-		input_output_channelStats_array[i].ch_utilization_busy = 0;
-		input_output_channelStats_array[i].ch_utilization_busy_ext = 0; // XXX: unavailable
-		input_output_channelStats_array[i].ch_utilization_total = 0;
-
-		memset(buf, 0, sizeof(buf));
-		if (get_survey_dump_buf(radioIndex, input_output_channelStats_array[i].ch_number, buf, sizeof(buf))) {
-			return RETURN_ERR;
-		}
-		if (fetch_survey_from_buf(radioIndex, buf, &input_output_channelStats_array[i])) {
-			wifi_debug(DEBUG_ERROR, "cannot fetch survey from buf for radioIndex=%d\n", radioIndex);
-			return RETURN_ERR;
-		}
-
-		// XXX: fake missing 'self' counter which is not available in iw survey output
-		//	  the 'self' counter (a.k.a 'bss') requires Linux Kernel update
-		input_output_channelStats_array[i].ch_utilization_busy_self = input_output_channelStats_array[i].ch_utilization_busy_rx / 8;
-
-		input_output_channelStats_array[i].ch_utilization_busy_rx *= 1000;
-		input_output_channelStats_array[i].ch_utilization_busy_tx *= 1000;
-		input_output_channelStats_array[i].ch_utilization_busy_self *= 1000;
-		input_output_channelStats_array[i].ch_utilization_busy *= 1000;
-		input_output_channelStats_array[i].ch_utilization_total *= 1000;
-
-		wifi_debug(DEBUG_INFO, "%s: ch_number=%d ch_noise=%d total=%llu busy=%llu busy_rx=%llu busy_tx=%llu busy_self=%llu busy_ext=%llu\n",
-				   __func__,
-				   input_output_channelStats_array[i].ch_number,
-				   input_output_channelStats_array[i].ch_noise,
-				   input_output_channelStats_array[i].ch_utilization_total,
-				   input_output_channelStats_array[i].ch_utilization_busy,
-				   input_output_channelStats_array[i].ch_utilization_busy_rx,
-				   input_output_channelStats_array[i].ch_utilization_busy_tx,
-				   input_output_channelStats_array[i].ch_utilization_busy_self,
-				   input_output_channelStats_array[i].ch_utilization_busy_ext);
-	}
-#endif
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-#define HAL_NETLINK_IMPL
-
-/* Hostapd events */
-
-#ifndef container_of
-#define offset_of(st, m) ((size_t)&(((st *)0)->m))
-#define container_of(ptr, type, member) \
-				   ((type *)((char *)ptr - offset_of(type, member)))
-#endif /* container_of */
-
-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};
-static wifi_apDeAuthEvent_callback clients_deauth_cb[MAX_CB_SIZE] = {0};
-static struct ctrl wpa_ctrl[MAX_APS];
-static int initialized;
-
-static unsigned int ctrl_get_drops(struct ctrl *ctrl)
-{
-	char cbuf[256] = {};
-	struct msghdr msg = { .msg_control = cbuf, .msg_controllen = sizeof(cbuf) };
-	struct cmsghdr *cmsg;
-	unsigned int ovfl = ctrl->ovfl;
-	unsigned int drop = 0;
-
-	if (recvmsg(ctrl->io.fd, &msg, MSG_DONTWAIT) < 0)
-		return drop;
-	for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg))
-		if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SO_RXQ_OVFL)
-			ovfl = *(unsigned int *)CMSG_DATA(cmsg);
-
-	drop = ovfl - ctrl->ovfl;
-	ctrl->ovfl = ovfl;
-
-	return drop;
-}
-
-static void ctrl_close(struct ctrl *ctrl)
-{
-	if (ctrl->io.cb)
-		ev_io_stop(evloop, &ctrl->io);
-	if (ctrl->retry.cb)
-		ev_timer_stop(evloop, &ctrl->retry);
-	if (!ctrl->wpa)
-		return;
-
-	wpa_ctrl_detach(ctrl->wpa);
-	wpa_ctrl_close(ctrl->wpa);
-	ctrl->wpa = NULL;
-	wifi_debug(DEBUG_OFF, "WPA_CTRL: closed index=%d\n", ctrl->ssid_index);
-}
-
-static void ctrl_process(struct ctrl *ctrl)
-{
-	const char *str;
-	int drops;
-	int level, i;
-
-	/* Example events:
-	 *
-	 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19
-	 * <3>AP-STA-CONNECTED 60:b4:f7:f0:0a:19 keyid=sample_keyid
-	 * <3>AP-STA-DISCONNECTED 60:b4:f7:f0:0a:19
-	 * <3>CTRL-EVENT-CONNECTED - Connection to 00:1d:73:73:88:ea completed [id=0 id_str=]
-	 * <3>CTRL-EVENT-DISCONNECTED bssid=00:1d:73:73:88:ea reason=3 locally_generated=1
-	 */
-	if (!(str = index(ctrl->reply, '>')))
-		return;
-	if (sscanf(ctrl->reply, "<%d>", &level) != 1)
-		return;
-
-	str++;
-
-	if (strncmp("AP-STA-CONNECTED ", str, 17) == 0) {
-		wifi_debug(DEBUG_INFO, "AP-STA-CONNECTED received \n");
-		if (!(str = index(ctrl->reply, ' ')))
-			return;
-		wifi_associated_dev_t sta;
-		memset(&sta, 0, sizeof(sta));
-
-		if (sscanf(str, "%hhx:%hhx:%hhx:%hhx:%hhx:%hhx",
-			&sta.cli_MACAddress[0], &sta.cli_MACAddress[1], &sta.cli_MACAddress[2],
-			&sta.cli_MACAddress[3], &sta.cli_MACAddress[4], &sta.cli_MACAddress[5]) == EOF) {
-			wifi_debug(DEBUG_ERROR, "Unexpected sscanf fail\n");
-			return;
-		}
-
-		sta.cli_Active=true;
-		for(i=0; i < MAX_CB_SIZE; i++) {
-			if (clients_connect_cb[i]) {
-				(clients_connect_cb[i])(ctrl->ssid_index, &sta);
-			}
-		}
-		goto handled;
-	}
-
-	if (strncmp("AP-STA-DISCONNECTED ", str, 20) == 0) {
-		wifi_debug(DEBUG_INFO, "AP-STA-DISCONNECTED received \n");
-		if (!(str = index(ctrl->reply, ' ')))
-			return;
-		for(i=0; i < MAX_CB_SIZE; i++) {
-			if (clients_disconnect_cb[i]) {
-                                (clients_disconnect_cb[i])(ctrl->ssid_index, (char*)str, 0);
-                        }
-                }
-
-		goto handled;
-	}
-
-	if (strncmp("CTRL-EVENT-TERMINATING", str, 22) == 0) {
-		wifi_debug(DEBUG_ERROR, "CTRL_WPA: handle TERMINATING event\n");
-		goto retry;
-	}
-
-	if (strncmp("AP-DISABLED", str, 11) == 0) {
-		wifi_debug(DEBUG_ERROR, "CTRL_WPA: handle AP-DISABLED\n");
-		goto retry;
-	}
-
-	wifi_debug(DEBUG_INFO, "Event not supported!!\n");
-
-handled:
-
-	if ((drops = ctrl_get_drops(ctrl))) {
-		wifi_debug(DEBUG_OFF, "WPA_CTRL: dropped %d messages index=%d\n", drops, ctrl->ssid_index);
-		if (ctrl->overrun)
-			ctrl->overrun(ctrl);
-	}
-
-	return;
-
-retry:
-	wifi_debug(DEBUG_ERROR, "WPA_CTRL: closing\n");
-	ctrl_close(ctrl);
-	wifi_debug(DEBUG_ERROR, "WPA_CTRL: retrying from ctrl prcoess\n");
-	ev_timer_again(evloop, &ctrl->retry);
-}
-
-static void ctrl_ev_cb(EV_P_ struct ev_io *io, int events)
-{
-	struct ctrl *ctrl = container_of(io, struct ctrl, io);
-	int err;
-
-	memset(ctrl->reply, 0, sizeof(ctrl->reply));
-	ctrl->reply_len = sizeof(ctrl->reply) - 1;
-	err = wpa_ctrl_recv(ctrl->wpa, ctrl->reply, &ctrl->reply_len);
-	ctrl->reply[ctrl->reply_len] = 0;
-	if (err < 0) {
-		if (errno == EAGAIN || errno == EWOULDBLOCK)
-			return;
-		ctrl_close(ctrl);
-		ev_timer_again(EV_A_ &ctrl->retry);
-		return;
-	}
-
-	ctrl_process(ctrl);
-}
-
-static int ctrl_open(struct ctrl *ctrl)
-{
-	int fd;
-
-	if (ctrl->wpa)
-		return 0;
-
-	ctrl->wpa = wpa_ctrl_open(ctrl->sockpath);
-	if (!ctrl->wpa)
-		goto err;
-
-	if (wpa_ctrl_attach(ctrl->wpa) < 0)
-		goto err_close;
-
-	fd = wpa_ctrl_get_fd(ctrl->wpa);
-	if (fd < 0)
-		goto err_detach;
-
-	if (setsockopt(fd, SOL_SOCKET, SO_RXQ_OVFL, (int[]){1}, sizeof(int)) < 0)
-		goto err_detach;
-
-	ev_io_init(&ctrl->io, ctrl_ev_cb, fd, EV_READ);
-	ev_io_start(evloop, &ctrl->io);
-
-	return 0;
-
-err_detach:
-	wpa_ctrl_detach(ctrl->wpa);
-err_close:
-	wpa_ctrl_close(ctrl->wpa);
-err:
-	ctrl->wpa = NULL;
-	return -1;
-}
-
-static void ctrl_stat_cb(EV_P_ ev_stat *stat, int events)
-{
-	struct ctrl *ctrl = container_of(stat, struct ctrl, stat);
-
-	wifi_debug(DEBUG_OFF, "WPA_CTRL: index=%d file state changed\n", ctrl->ssid_index);
-	ctrl_open(ctrl);
-}
-
-static void ctrl_retry_cb(EV_P_ ev_timer *timer, int events)
-{
-	struct ctrl *ctrl = container_of(timer, struct ctrl, retry);
-
-	wifi_debug(DEBUG_INFO, "WPA_CTRL: index=%d retrying\n", ctrl->ssid_index);
-	if (ctrl_open(ctrl) == 0) {
-		wifi_debug(DEBUG_OFF, "WPA_CTRL: retry successful\n");
-		ev_timer_stop(evloop, &ctrl->retry);
-	}
-}
-
-int ctrl_enable(struct ctrl *ctrl)
-{
-	if (ctrl->wpa)
-		return 0;
-
-	if (!ctrl->stat.cb) {
-		ev_stat_init(&ctrl->stat, ctrl_stat_cb, ctrl->sockpath, 0.);
-		ev_stat_start(evloop, &ctrl->stat);
-	}
-
-	if (!ctrl->retry.cb) {
-		ev_timer_init(&ctrl->retry, ctrl_retry_cb, 0., 5.);
-	}
-
-	return ctrl_open(ctrl);
-}
-
-static void
-ctrl_msg_cb(char *buf, size_t len)
-{
-	struct ctrl *ctrl = container_of(buf, struct ctrl, reply);
-
-	wifi_debug(DEBUG_INFO, "WPA_CTRL: unsolicited message: index=%d len=%zu msg=%s\n", 
-		ctrl->ssid_index, len, buf);
-	ctrl_process(ctrl);
-}
-
-static int ctrl_request(struct ctrl *ctrl, const char *cmd, size_t cmd_len, char *reply, size_t *reply_len)
-{
-	int err;
-
-	if (!ctrl->wpa)
-		return -1;
-	if (*reply_len < 2)
-		return -1;
-
-	(*reply_len)--;
-	ctrl->reply_len = sizeof(ctrl->reply);
-	err = wpa_ctrl_request(ctrl->wpa, cmd, cmd_len, ctrl->reply, &ctrl->reply_len, ctrl_msg_cb);
-	wifi_debug(DEBUG_INFO, "WPA_CTRL: index=%d cmd='%s' err=%d\n", ctrl->ssid_index, cmd, err);
-	if (err < 0)
-		return err;
-
-	if (ctrl->reply_len > *reply_len)
-		ctrl->reply_len = *reply_len;
-
-	*reply_len = ctrl->reply_len;
-	memcpy(reply, ctrl->reply, *reply_len);
-	reply[*reply_len - 1] = 0;
-	wifi_debug(DEBUG_INFO, "WPA_CTRL: index=%d reply='%s'\n", ctrl->ssid_index, reply);
-	return 0;
-}
-
-static void ctrl_watchdog_cb(EV_P_ ev_timer *timer, int events)
-{
-	const char *pong = "PONG";
-	const char *ping = "PING";
-	char reply[1024];
-	size_t len = sizeof(reply);
-	int err;
-	ULONG s, snum;
-	INT ret;
-	BOOL status;
-
-	wifi_debug(DEBUG_INFO, "WPA_CTRL: watchdog cb\n");
-
-	ret = wifi_getSSIDNumberOfEntries(&snum);
-	if (ret != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "failed to get SSID count\n");
-		return;
-	}
-
-	if (snum > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "more ssid than supported! %lu\n", snum);
-		return;
-	}
-
-	for (s = 0; s < snum; s++) {
-		if (wifi_getApEnable(s, &status) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "failed to get AP Enable for index: %lu\n", s);
-			continue;
-		}
-		if (status == false) continue;
-
-		memset(reply, 0, sizeof(reply));
-		len = sizeof(reply);
-		wifi_debug(DEBUG_INFO, "WPA_CTRL: pinging index=%d\n", wpa_ctrl[s].ssid_index);
-		err = ctrl_request(&wpa_ctrl[s], ping, strlen(ping), reply, &len);
-		if (err == 0 && len > strlen(pong) && !strncmp(reply, pong, strlen(pong)))
-			continue;
-
-		wifi_debug(DEBUG_OFF, "WPA_CTRL: ping timeout index=%d\n", wpa_ctrl[s].ssid_index);
-
-		ctrl_close(&wpa_ctrl[s]);
-		wifi_debug(DEBUG_OFF, "WPA_CTRL: ev_timer_again %lu\n", s);
-		ev_timer_again(evloop, &wpa_ctrl[s].retry);
-	}
-}
-
-void *event_loop_thread(void *arg) {
-        struct ev_loop *loop = (struct ev_loop *)arg;
-        ev_run(loop,0);
-        return RETURN_OK;
-}
-
-static int init_wpa()
-{
-	int ret = 0;
-	char interface_name[IF_NAME_SIZE] = {0};
-	ULONG s, snum;
-	pthread_t thread_id;
-
-	ret = wifi_getSSIDNumberOfEntries(&snum);
-	if (ret != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "failed to get SSID count\n");
-		return RETURN_ERR;
-	}
-
-	if (snum > MAX_APS) {
-		wifi_debug(DEBUG_ERROR, "more ssid than supported! %lu\n", snum);
-		return RETURN_ERR;
-	}
-	evloop = ev_loop_new(0);
-	for (s = 0; s < snum; s++) {
-		memset(&wpa_ctrl[s], 0, sizeof(struct ctrl));
-		if (wifi_GetInterfaceName(s, interface_name) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "DEBUG: Invalid interface_name \n");
-			return RETURN_ERR;
-		}
-		ret = snprintf(wpa_ctrl[s].sockpath, sizeof(wpa_ctrl[s].sockpath), "%s%s", SOCK_PREFIX, interface_name);
-		if (os_snprintf_error(sizeof(wpa_ctrl[s].sockpath), ret)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		wpa_ctrl[s].ssid_index = s;
-		ctrl_enable(&wpa_ctrl[s]);
-	}
-
-	ev_timer_init(&wpa_ctrl->watchdog, ctrl_watchdog_cb, 0., 30.);
-	ev_timer_again(evloop, &wpa_ctrl->watchdog);
-	if (pthread_create(&thread_id, NULL, event_loop_thread, evloop)) {
-                wifi_debug(DEBUG_ERROR, "Failed to create pthread \n");
-                return RETURN_ERR;
-        }
-	initialized = 1;
-	wifi_debug(DEBUG_OFF, "WPA_CTRL: initialized\n");
-
-	return RETURN_OK;
-}
-
-void wifi_newApAssociatedDevice_callback_register(wifi_newApAssociatedDevice_callback callback_proc)
-{
-	int i;
-
-	WIFI_ENTRY_EXIT_DEBUG("Registered %s \n", __func__);
-	for (i=0; i < MAX_CB_SIZE; i++) {
-		if(clients_connect_cb[i] == NULL) {
-			clients_connect_cb[i] = callback_proc;
-			break;
-		}
-	}
-	if (!initialized)
-		init_wpa();
-}
-
-void wifi_apDisassociatedDevice_callback_register(wifi_apDisassociatedDevice_callback callback_proc)
-{
-	int i;
-
-	WIFI_ENTRY_EXIT_DEBUG("Registered %s \n", __func__);
-	for (i=0; i < MAX_CB_SIZE; i++) {
-		if(clients_disconnect_cb[i] == NULL) {
-			clients_disconnect_cb[i] = callback_proc;
-			break;
-		}
-	}
-	if (!initialized)
-		init_wpa();
-}
-
-void wifi_apDeAuthEvent_callback_register(wifi_apDeAuthEvent_callback callback_proc)
-{
-	int i;
-
-	WIFI_ENTRY_EXIT_DEBUG("Registered %s \n", __func__);
-	for (i=0; i < MAX_CB_SIZE; i++) {
-		if(clients_deauth_cb[i] == NULL) {
-			clients_deauth_cb[i] = callback_proc;
-			break;
-		}
-	}
-	if (!initialized)
-		init_wpa();
-}
-
-INT wifi_setBTMRequest(UINT apIndex, CHAR *peerMac, wifi_BTMRequest_t *request)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_setRMBeaconRequest(UINT apIndex, CHAR *peer, wifi_BeaconRequest_t *in_request, UCHAR *out_DialogToken)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_getRadioChannels(INT radioIndex, wifi_channelMap_t *outputMap, INT outputMapSize)
-{
-	int i;
-	int phyId = -1;
-	char cmd[256] = {0};
-	char channel_numbers_buf[256] = {0};
-	char dfs_state_buf[256] = {0};
-	char line[256] = {0};
-	const char *ptr;
-	BOOL dfs_enable = false;
-	int res;
-
-	memset(outputMap, 0, outputMapSize*sizeof(wifi_channelMap_t)); // all unused entries should be zero
-
-	wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
-	phyId = radio_index_to_phy(radioIndex);
-
-	res = 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\\|");
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (_syscmd_secure(channel_numbers_buf, sizeof(channel_numbers_buf), "iw phy phy%d info | grep -e '\\*.*MHz .*dBm' | grep -v '%sno IR\\|5340\\|5480' | awk '{print $4}' | tr -d '[]'", phyId, dfs_enable?"":"radar\\|") == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "failed to execute '%s'\n", cmd);
-		return RETURN_ERR;
-	}
-
-	ptr = channel_numbers_buf;
-	i = 0;
-	while ((ptr = get_line_from_str_buf(ptr, line))) {
-		if (i >= outputMapSize) {
-				wifi_debug(DEBUG_ERROR, "DFS map size too small\n");
-				return RETURN_ERR;
-		}
-		if (sscanf(line, "%d", &outputMap[i].ch_number) != 1) {
-			wifi_debug(DEBUG_ERROR, "sscanf format error.\n");
-			return RETURN_ERR;
-		}
-
-		memset(cmd, 0, sizeof(cmd));
-		// Below command should fetch string for DFS state (usable, available or unavailable)
-		// Example line: "DFS state: usable (for 78930 sec)"
-		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) {
-			wifi_debug(DEBUG_ERROR, "failed to build dfs state command\n");
-			return RETURN_ERR;
-		}
-
-		memset(dfs_state_buf, 0, sizeof(dfs_state_buf));
-		if (_syscmd_secure(dfs_state_buf, sizeof(dfs_state_buf),"iw list | grep -A 2 '\\[%d\\]' | tr -d '\\t' | grep 'DFS state' | awk '{print $3}' | tr -d '\\n'", outputMap[i].ch_number) == RETURN_ERR) {
-			wifi_debug(DEBUG_ERROR, "failed to execute '%s'\n", cmd);
-			return RETURN_ERR;
-		}
-
-		wifi_debug(DEBUG_INFO, "DFS state = '%s'\n", dfs_state_buf);
-
-		if (!strcmp(dfs_state_buf, "usable")) {
-			outputMap[i].ch_state = CHAN_STATE_DFS_NOP_FINISHED;
-		} else if (!strcmp(dfs_state_buf, "available")) {
-			outputMap[i].ch_state = CHAN_STATE_DFS_CAC_COMPLETED;
-		} else if (!strcmp(dfs_state_buf, "unavailable")) {
-			outputMap[i].ch_state = CHAN_STATE_DFS_NOP_START;
-		} else {
-			outputMap[i].ch_state = CHAN_STATE_AVAILABLE;
-		}
-		i++;
-	}
-
-	return RETURN_OK;
-
-	wifi_debug(DEBUG_ERROR, "wrong radio index (%d)\n", radioIndex);
-	return RETURN_ERR;
-}
-
-INT wifi_chan_eventRegister(wifi_chan_eventCB_t eventCb)
-{
-	// TODO Implement me!
-	return RETURN_ERR;
-}
-
-INT wifi_getRadioBandUtilization (INT radioIndex, INT *output_percentage)
-{
-	int ret = -1;
-	char inf_name[IF_NAME_SIZE] = {0};
-	int if_idx = 0;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct mtk_nl80211_cb_data cb_data;
-	wdev_ap_metric ap_metric;
-	int main_vap_idx;
-
-	/*init mtk nl80211 vendor cmd*/
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, inf_name) != RETURN_OK)
-		return RETURN_ERR;
-	if_idx = if_nametoindex(inf_name);
-	if (!if_idx) {
-		wifi_debug(DEBUG_ERROR,"can't finde ifname(%s) index,ERROR\n", inf_name);
-		return RETURN_ERR;
-	}
-
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_GET_STATISTIC;
-	param.if_type = NL80211_ATTR_IFINDEX;
-	param.if_idx = if_idx;
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-
-	/*add mtk vendor cmd data*/
-
-	if (nla_put(msg, MTK_NL80211_VENDOR_ATTR_GET_AP_METRICS, sizeof(wdev_ap_metric), (char *)&ap_metric)) {
-		wifi_debug(DEBUG_ERROR, "Nla put GET_AP_METRICS attribute error\n");
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	cb_data.out_buf = (char *)output_percentage;
-	cb_data.out_len = sizeof(wdev_ap_metric);
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, mtk_get_ap_metrics, &cb_data);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "set cmd success.\n");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR, "set cmd fails.\n");
-	return RETURN_ERR;
-}
-
-
-INT wifi_getApAssociatedClientDiagnosticResult(INT apIndex, char *mac_addr, wifi_associated_dev3_t *dev_conn)
-{
-	unsigned char mac[ETH_ALEN] = {0};
-
-	if (hwaddr_aton2(mac_addr, mac) < 0) {
-		wifi_debug(DEBUG_ERROR, "invalid device mac address %s\n", mac_addr);
-		return RETURN_ERR;
-	}
-
-	if (fill_dev3_statistics_by_mac(apIndex, dev_conn, (unsigned char *)mac)) {
-		wifi_debug(DEBUG_ERROR, "fail to get dev3(%02x:%02x:%02x:%02x:%02x:%02x)"
-			" statistic information from logan driver\n", mac[0],
-			mac[1], mac[2], mac[3], mac[4], mac[5]);
-		return RETURN_ERR;
-	}
-	memcpy(dev_conn->cli_MACAddress, mac, ETH_ALEN);
-	dev_conn->cli_Active = 1;
-	dev_conn->cli_AuthenticationState = 1;
-	
-	return RETURN_OK;
-}
-
-INT wifi_switchBand(char *interface_name,INT radioIndex,char *freqBand)
-{
-	// TODO API refrence Implementaion is present on RPI hal
-	return RETURN_ERR;
-}
-
-INT wifi_getRadioPercentageTransmitPower(INT apIndex, ULONG *txpwr_pcntg)
-{
-	ULONG pwr_percentage = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(txpwr_pcntg == NULL)
-		return RETURN_ERR;
-
-	wifi_getRadioTransmitPower(apIndex, &pwr_percentage);
-	*txpwr_pcntg = pwr_percentage;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setZeroDFSState(UINT radioIndex, BOOL enable, BOOL precac)
-{
-	// TODO precac feature.
-	struct params params[2] = {0};
-	char config_file[128] = {0};
-	BOOL dfs_enable = false;
-	wifi_band band = band_invalid;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	band = radio_index_to_band(radioIndex);
-	wifi_getRadioDfsEnable(radioIndex, &dfs_enable);
-
-	if (dfs_enable == false) {
-		WIFI_ENTRY_EXIT_DEBUG("Please enable DFS firstly!: %s\n", __func__);
-		return RETURN_ERR;
-	}
-	params[0].name = "DfsZeroWaitDefault";
-	params[0].value = enable?"1":"0";
-	params[1].name = "DfsDedicatedZeroWait";
-	params[1].value = enable?"1":"0";
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileWrite(config_file, params, 2);
-	wifi_reloadAp(radioIndex);
-	/* TODO precac feature */
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getZeroDFSState(UINT radioIndex, BOOL *enable, BOOL *precac)
-{
-	char config_file[128] = {0};
-	char buf1[32] = {0};
-	char buf2[32] = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (NULL == enable || NULL == precac)
-		return RETURN_ERR;
-	band = radio_index_to_band(radioIndex);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_datfileRead(config_file, "DfsZeroWaitDefault", buf1, sizeof(buf1));
-	wifi_datfileRead(config_file, "DfsDedicatedZeroWait", buf2, sizeof(buf2));
-	if ((strncmp(buf1, "1", 1) == 0) && (strncmp(buf2, "1", 1) == 0))
-		*enable = true;
-	else
-		*enable = false;
-
-	/* TODO precac feature */
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_isZeroDFSSupported(UINT radioIndex, BOOL *supported)
-{
-	*supported = TRUE;
-	return RETURN_OK;
-}
-
-INT wifi_setDownlinkMuType(INT radio_index, wifi_dl_mu_type_t mu_type)
-{
-	CHAR dat_file[64] = {0};
-	wifi_band band = band_invalid;
-	char ofdmabuf[32] = {'\0'};
-	char mimobuf[32] = {'\0'};
-	char new_ofdmabuf[32] = {'\0'};
-	char new_mimobuf[32] = {'\0'};
-	struct params params[2];
-	char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
-	char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
-	UCHAR bss_cnt = 0;
-	UCHAR val_cnt = 0;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if ((mu_type < WIFI_DL_MU_TYPE_NONE)
-		|| (mu_type > WIFI_DL_MU_TYPE_OFDMA_MIMO)) {
-		wifi_debug(DEBUG_ERROR, "%s:mu_type input Error", __func__);
-		return RETURN_ERR;
-	}
-	band = radio_index_to_band(radio_index);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "%s:Band Error\n", __func__);
-		return RETURN_ERR;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	/*get current value in dat file*/
-	wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
-	wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
-	WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
-	get_bssnum_byindex(radio_index, &bss_cnt);
-	val_cnt = 2*bss_cnt - 1;
-	WIFI_ENTRY_EXIT_DEBUG("bss number: %d\n", bss_cnt);
-	if ((val_cnt >= sizeof(new_ofdmabuf))
-		|| (val_cnt >= sizeof(new_mimobuf))) {
-		wifi_debug(DEBUG_ERROR, "%s:bss cnt Error", __func__);
-		return RETURN_ERR;
-	}
-	/*translate set value*/
-	if (mu_type == WIFI_DL_MU_TYPE_NONE) {
-		strncpy(new_ofdmabuf, str_zero, val_cnt);
-		strncpy(new_mimobuf, str_zero, val_cnt);
-	} else if (mu_type == WIFI_DL_MU_TYPE_OFDMA) {
-		strncpy(new_ofdmabuf, str_one, val_cnt);
-		strncpy(new_mimobuf, str_zero, val_cnt);
-	} else if (mu_type == WIFI_DL_MU_TYPE_MIMO) {
-		strncpy(new_ofdmabuf, str_zero, val_cnt);
-		strncpy(new_mimobuf, str_one, val_cnt);
-	} else if (mu_type == WIFI_DL_MU_TYPE_OFDMA_MIMO) {
-		strncpy(new_ofdmabuf, str_one, val_cnt);
-		strncpy(new_mimobuf, str_one, val_cnt);
-	}
-	WIFI_ENTRY_EXIT_DEBUG("%s:new_ofdmabuf-%s, new_mimobuf-%s\n", __func__, new_ofdmabuf, new_mimobuf);
-	/*same value, not operation*/
-	if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
-		&& (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
-		wifi_debug(DEBUG_ERROR, "%s:Reduntant value\n", __func__);
-
-		return RETURN_OK;
-	}
-	/*modify dat file to new file*/
-	params[0].name="MuOfdmaDlEnable";
-	params[0].value=new_ofdmabuf;
-	params[1].name="MuMimoDlEnable";
-	params[1].value=new_mimobuf;
-	wifi_datfileWrite(dat_file, params, 2);
-	/*hostapd control restarp ap to take effect on these new value*/
-	wifi_reloadAp(radio_index);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getDownlinkMuType(INT radio_index, wifi_dl_mu_type_t *mu_type)
-{
-	CHAR dat_file[64] = {0};
-	wifi_band band = band_invalid;
-	char ofdmabuf[32] = {'\0'};
-	char mimobuf[32] = {'\0'};
-	char *token = NULL;
-	long int ofdma = 0;
-	long int mimo = 0;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (mu_type == NULL)
-		return RETURN_ERR;
-	band = radio_index_to_band(radio_index);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "%s:Band Error\n", __func__);
-		return RETURN_ERR;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	/*get current value in dat file*/
-	wifi_datfileRead(dat_file, "MuOfdmaDlEnable", ofdmabuf, sizeof(ofdmabuf));
-	wifi_datfileRead(dat_file, "MuMimoDlEnable", mimobuf, sizeof(mimobuf));
-
-	token = strtok(ofdmabuf, ";");
-	if (token == NULL) {
-		wifi_debug(DEBUG_ERROR, "strtok fail\n");
-		return RETURN_ERR;
-	}
-	if (hal_strtol(token, 10, &ofdma) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	token = strtok(mimobuf, ";");
-	if (token == NULL) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtok fail\n");
-		return RETURN_ERR;
-	}
-
-	if (hal_strtol(token, 10, &mimo) < 0) {
-		wifi_debug(DEBUG_ERROR, "strtol fail\n");
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%ld,mimo=%ld\n", __func__, ofdma, mimo);
-	if ((ofdma == 1) && (mimo == 1))
-		*mu_type = WIFI_DL_MU_TYPE_OFDMA_MIMO;
-	else if ((ofdma == 0) && (mimo == 1))
-		*mu_type = WIFI_DL_MU_TYPE_MIMO;
-	else if ((ofdma == 1) && (mimo == 0))
-		*mu_type = WIFI_DL_MU_TYPE_OFDMA;
-	else
-		*mu_type = WIFI_DL_MU_TYPE_NONE;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setUplinkMuType(INT radio_index, wifi_ul_mu_type_t mu_type)
-{
-	// hemu onoff=<val> (bitmap- UL MU-MIMO(bit3), DL MU-MIMO(bit2), UL OFDMA(bit1), DL OFDMA(bit0))
-	CHAR dat_file[64] = {0};
-	wifi_band band = band_invalid;
-	char ofdmabuf[32] = {'\0'};
-	char mimobuf[32] = {'\0'};
-	char new_ofdmabuf[32] = {'\0'};
-	char new_mimobuf[32] = {'\0'};
-	struct params params[2];
-	char *str_zero = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 15bss per band.*/
-	char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
-	UCHAR bss_cnt = 0;
-	UCHAR val_cnt = 0;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	band = radio_index_to_band(radio_index);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "%s:Band Error\n", __func__);
-		return RETURN_ERR;
-	}
-	if ((mu_type < WIFI_UL_MU_TYPE_NONE)
-		|| (mu_type > WIFI_UL_MU_TYPE_OFDMA)) {
-		wifi_debug(DEBUG_ERROR, "%s:mu_type input Error\n", __func__);
-		return RETURN_ERR;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	/*get current value in dat file*/
-	wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
-	wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
-	WIFI_ENTRY_EXIT_DEBUG("%s:ofdma-%s, mimo-%s\n", __func__, ofdmabuf, mimobuf);
-	get_bssnum_byindex(radio_index, &bss_cnt);
-	val_cnt = 2*bss_cnt - 1;
-	wifi_debug(DEBUG_INFO, "bssNumber:%d,ValCnt:%d\n", bss_cnt, val_cnt);
-	if ((val_cnt >= sizeof(new_ofdmabuf))
-		|| (val_cnt >= sizeof(new_mimobuf))) {
-		wifi_debug(DEBUG_ERROR, "bss cnt Error\n");
-		return RETURN_ERR;
-	}
-	/*translate set value*/
-	if (mu_type == WIFI_UL_MU_TYPE_NONE) {
-		strncpy(new_ofdmabuf, str_zero, val_cnt);
-		strncpy(new_mimobuf, str_zero, val_cnt);
-	}
-	if (mu_type == WIFI_UL_MU_TYPE_OFDMA) {
-		strncpy(new_ofdmabuf, str_one, val_cnt);
-		strncpy(new_mimobuf, str_zero, val_cnt);
-	}
-	wifi_debug(DEBUG_INFO, "new_ofdmabuf-%s, new_mimobuf-%s\n", new_ofdmabuf, new_mimobuf);
-	/*same value, not operation*/
-	if ((strncmp(new_mimobuf, mimobuf, 1) ==0)
-		&& (strncmp(new_ofdmabuf, ofdmabuf, 1) ==0)) {
-		wifi_debug(DEBUG_ERROR, "Reduntant value\n");
-		return RETURN_OK;
-	}
-	/*modify dat file to new file*/
-	params[0].name="MuOfdmaUlEnable";
-	params[0].value=new_ofdmabuf;
-	params[1].name="MuMimoUlEnable";
-	params[1].value=new_mimobuf;
-	wifi_datfileWrite(dat_file, params, 2);
-	wifi_reloadAp(radio_index);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getUplinkMuType(INT radio_index, wifi_ul_mu_type_t *mu_type)
-{
-	CHAR dat_file[64] = {0};
-	wifi_band band = band_invalid;
-	char ofdmabuf[32] = {'\0'};
-	char mimobuf[32] = {'\0'};
-	char *token = NULL;
-	UCHAR ofdma = 0;
-	UCHAR mimo = 0;
-	int res;
-	unsigned long tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (mu_type == NULL)
-	return RETURN_ERR;
-	band = radio_index_to_band(radio_index);
-	if (band == band_invalid) {
-		wifi_debug(DEBUG_ERROR, "%s:Band Error", __func__);
-		return RETURN_ERR;
-	}
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	/*get current value in dat file*/
-	wifi_datfileRead(dat_file, "MuOfdmaUlEnable", ofdmabuf, sizeof(ofdmabuf));
-	wifi_datfileRead(dat_file, "MuMimoUlEnable", mimobuf, sizeof(mimobuf));
-
-	token = strtok(ofdmabuf, ";");
-	if (token == NULL) {
-		wifi_debug(DEBUG_ERROR, "strtok fail\n");
-		return RETURN_ERR;
-	}
-
-	if (hal_strtoul(token, 10, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-	}
-	ofdma = tmp;
-	token = strtok(mimobuf, ";");
-	if (token == NULL) {
-		wifi_debug(DEBUG_ERROR, "strtok fail\n");
-		return RETURN_ERR;
-	}
-
-	if (hal_strtoul(token, 10, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-	}
-	mimo = tmp;
-
-	WIFI_ENTRY_EXIT_DEBUG("%s:ofdma=%d, mimo=%d\n", __func__, ofdma, mimo);
-	if ((ofdma == 1) && (mimo == 0))
-		*mu_type = WIFI_UL_MU_TYPE_OFDMA;
-	else
-		*mu_type = WIFI_UL_MU_TYPE_NONE;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-
-INT wifi_setGuardInterval(INT radio_index, wifi_guard_interval_t guard_interval)
-{
-
-	char buf[256] = {0};
-	char config_file[64] = {0};
-	char GI[8] = {0};
-	UINT mode_map = 0;
-	FILE *f = NULL;
-	wifi_band band = band_invalid;
-	char dat_file[64] = {'\0'};
-	struct params params[3];
-	int res;
-	char *str_zro = "0;0;0;0;0;0;0;0;0;0;0;0;0;0;0;0";/*default 16bss per band.*/
-	char *str_one = "1;1;1;1;1;1;1;1;1;1;1;1;1;1;1;1";
-	UCHAR bss_cnt = 0;
-	UCHAR val_cnt = 0;
-	char valbuf[64] = {0};
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (wifi_getRadioMode(radio_index, buf, &mode_map) == RETURN_ERR) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error\n");
-		return RETURN_ERR;
-	}
-	/*sanity check*/
-	if (((guard_interval == wifi_guard_interval_1600)
-		|| (guard_interval == wifi_guard_interval_3200))
-		&& ((mode_map & (WIFI_MODE_BE | WIFI_MODE_AX)) == 0)) {
-		wifi_debug(DEBUG_ERROR, "N/AC Mode not support 1600/3200ns GI\n");
-		return RETURN_ERR;
-	}
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	band = radio_index_to_band(radio_index);
-
-	// Hostapd are not supported HE mode GI 1600, 3200 ns.
-	if (guard_interval == wifi_guard_interval_800) {	// remove all capab about short GI
-		res = _syscmd_secure(buf, sizeof(buf), "sed -r -i 's/\\[SHORT-GI-(.){1,2}0\\]//g' %s", config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-		}
-
-	} else if (guard_interval == wifi_guard_interval_400 || guard_interval == wifi_guard_interval_auto){
-		wifi_hostapdRead(config_file, "ht_capab", buf, sizeof(buf));
-		if (strstr(buf, "[SHORT-GI-") == NULL) {
-			res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^ht_capab=.*/s/$/[SHORT-GI-20][SHORT-GI-40]/' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-			}
-
-		}
-		if (band == band_5) {
-			wifi_hostapdRead(config_file, "vht_capab", buf, sizeof(buf));
-			if (strstr(buf, "[SHORT-GI-") == NULL) {
-				res = _syscmd_secure(buf, sizeof(buf), "sed -r -i '/^vht_capab=.*/s/$/[SHORT-GI-80][SHORT-GI-160]/' %s", config_file);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-				}
-
-			}
-		}
-	}
-	/*wifi_reloadAp(radio_index);
-		caller "wifi_setRadioOperatingParameters" have done this step.
-	*/
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, band);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	get_bssnum_byindex(radio_index, &bss_cnt);
-	if (bss_cnt <= 0)
-	{
-		wifi_debug(DEBUG_ERROR, "Unexpected bss_cnt\n");
-		return RETURN_ERR;
-	}
-	if (bss_cnt > LOGAN_MAX_NUM_VAP_PER_RADIO)
-		bss_cnt = LOGAN_MAX_NUM_VAP_PER_RADIO;
-	val_cnt = 2*bss_cnt - 1;
-	if (guard_interval == wifi_guard_interval_400) {
-		strncpy(valbuf, str_one, val_cnt);
-		params[0].name = "HT_GI";
-		params[0].value = valbuf;
-		params[1].name = "VHT_SGI";
-		params[1].value = valbuf;
-		wifi_datfileWrite(dat_file, params, 2);
-		memcpy(GI, "0.4", 3);
-	} else {
-		strncpy(valbuf, str_zro, val_cnt);
-		params[0].name = "HT_GI";
-		params[0].value = valbuf;
-		params[1].name = "VHT_SGI";
-		params[1].value = valbuf;
-		/*should enable FIXED_HE_GI_SUPPORT in driver*/
-		params[2].name = "FgiFltf";
-		if (guard_interval == wifi_guard_interval_800) {
-			params[2].value = "800";
-			memcpy(GI, "0.8", 3);
-		} else if (guard_interval == wifi_guard_interval_1600) {
-			params[2].value = "1600";
-			memcpy(GI, "1.6", 3);
-		} else if (guard_interval == wifi_guard_interval_3200) {
-			params[2].value = "3200";
-			memcpy(GI, "3.2", 3);
-		} else if (guard_interval == wifi_guard_interval_auto) {
-			params[2].value = "0";
-			memcpy(GI, "auto", 4);
-		}
-		wifi_datfileWrite(dat_file, params, 3);
-	}
-	// Record GI for get GI function
-	res = snprintf(buf, sizeof(buf), "%s%d.txt", GUARD_INTERVAL_FILE, radio_index);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	f = fopen(buf, "w");
-	if (f == NULL)
-		return RETURN_ERR;
-	fprintf(f, "%s", GI);
-	if (fclose(f) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getGuardInterval(INT radio_index, wifi_guard_interval_t *guard_interval)
-{
-	char buf[32] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (guard_interval == NULL)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s%d.txt 2> /dev/null", GUARD_INTERVAL_FILE, radio_index);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	if (strncmp(buf, "0.4", 3) == 0)
-		*guard_interval = wifi_guard_interval_400;
-	else if (strncmp(buf, "0.8", 3) == 0)
-		*guard_interval = wifi_guard_interval_800;
-	else if (strncmp(buf, "1.6", 3) == 0)
-		*guard_interval = wifi_guard_interval_1600;
-	else if (strncmp(buf, "3.2", 3) == 0)
-		*guard_interval = wifi_guard_interval_3200;
-	else
-		*guard_interval = wifi_guard_interval_auto;
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setBSSColor(INT radio_index, UCHAR color)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	struct params params = {0};
-	char config_file[128] = {0};
-	char bss_color[4] ={0};
-	int res;
-
-	if (color < 1 || color > 63) {
-		wifi_debug(DEBUG_ERROR, "color value is err:%d.\n", color);
-		return RETURN_ERR;
-	}
-	params.name = "he_bss_color";
-	res = snprintf(bss_color, sizeof(bss_color), "%hhu", color);
-	if (os_snprintf_error(sizeof(bss_color), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.value = bss_color;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &params, 1);
-	//wifi_hostapdProcessUpdate(radio_index, &params, 1);
-	wifi_reloadAp(radio_index);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_getBSSColor(INT radio_index, UCHAR *color)
-{
-	char config_file[128] = {0};
-	char buf[64] = {0};
-	char temp_output[128] = {'\0'};
-	int res;
-	unsigned long tmp;
-
-	if (NULL == color)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, radio_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "he_bss_color", buf, sizeof(buf));
-
-	if(strlen(buf) > 0) {
-		res = snprintf(temp_output, sizeof(temp_output), "%s", buf);
-	} else {
-		res = snprintf(temp_output, sizeof(temp_output), "1");   // default value
-	}
-	if (os_snprintf_error(sizeof(temp_output), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	if (hal_strtoul(temp_output, 10, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-	}
-	*color = tmp;
-	wifi_debug(DEBUG_INFO, "output_string=%s\n", color);
-
-	return RETURN_OK;
-}
-
-/* multi-psk support */
-INT wifi_getMultiPskClientKey(INT apIndex, mac_address_t mac, wifi_key_multi_psk_t *key)
-{
-	char cmd[256];
-	char interface_name[16] = {0};
-	int res;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = snprintf(cmd, sizeof(cmd), "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",
-		interface_name,
-		mac[0],
-		mac[1],
-		mac[2],
-		mac[3],
-		mac[4],
-		mac[5]
-	);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_INFO, "DEBUG LOG wifi_getMultiPskClientKey(%s)\n",cmd);
-
-	res = _syscmd_secure(key->wifi_keyId, 64, "hostapd_cli -i %s sta %x:%x:%x:%x:%x:%x |grep '^keyid' | cut -f 2 -d = | tr -d '\n'",interface_name,mac[0],mac[1],mac[2], mac[3], mac[4], mac[5]);
-	if(res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-
-	return RETURN_OK;
-}
-
-INT wifi_pushMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
-{
-	char interface_name[16] = {0};
-	FILE *fd	  = NULL;
-	char fname[100];
-
-	char out[64] = {0};
-	wifi_key_multi_psk_t * key = NULL;
-	int res, ret;
-
-	if(keysNumber < 0)
-			return RETURN_ERR;
-
-	res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
-	if (os_snprintf_error(sizeof(fname), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	fd = fopen(fname, "w");
-	if (!fd) {
-			return RETURN_ERR;
-	}
-	key= (wifi_key_multi_psk_t *) keys;
-	for(int i=0; i<keysNumber; ++i, key++) {
-		ret = fprintf(fd, "keyid=%s 00:00:00:00:00:00 %s\n", key->wifi_keyId, key->wifi_psk);
-		if (ret < 0)
-			wifi_debug(DEBUG_ERROR, "fprintf fail\n");
-	}
-	if (fclose(fd) != 0) {
-		wifi_debug(DEBUG_ERROR, "fclose fail\n");
-		return RETURN_ERR;
-	}
-
-	//reload file
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-	res = _syscmd_secure(out, 64, "hostapd_cli -i%s raw RELOAD_WPA_PSK", interface_name);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_getMultiPskKeys(INT apIndex, wifi_key_multi_psk_t *keys, INT keysNumber)
-{
-	FILE *fd	  = NULL;
-	char fname[100];
-	char * line = NULL;
-	char * pos = NULL;
-	size_t len = 0;
-	ssize_t read = 0;
-	INT ret = RETURN_OK;
-	wifi_key_multi_psk_t *keys_it = NULL;
-	int res;
-
-	if (keysNumber < 1) {
-		return RETURN_ERR;
-	}
-
-	res = snprintf(fname, sizeof(fname), "%s%d.psk", PSK_FILE, apIndex);
-	if (os_snprintf_error(sizeof(fname), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	fd = fopen(fname, "r");
-	if (!fd) {
-		return RETURN_ERR;
-	}
-
-	if (keys == NULL) {
-		ret = RETURN_ERR;
-		goto close;
-	}
-
-	keys_it = keys;
-	while ((read = getline(&line, &len, fd)) != -1) {
-		//Strip trailing new line if present
-		if (read > 0 && line[read-1] == '\n') {
-			line[read-1] = '\0';
-		}
-
-		if(strcmp(line,"keyid=")) {
-			if (sscanf(line, "keyid=%63s", keys_it->wifi_keyId) == EOF)
-				continue;
-			if (!(pos = index(line, ' '))) {
-				ret = RETURN_ERR;
-				goto close;
-			}
-			pos++;
-			//Here should be 00:00:00:00:00:00
-			if (!(strcmp(pos,"00:00:00:00:00:00"))) {
-				 wifi_debug(DEBUG_ERROR, "Not supported MAC: %s\n", pos);
-			}
-			if (!(pos = index(pos, ' '))) {
-				ret = RETURN_ERR;
-				goto close;
-			}
-			pos++;
-
-			//The rest is PSK
-			res = snprintf(&keys_it->wifi_psk[0], sizeof(keys_it->wifi_psk), "%s", pos);
-			if (os_snprintf_error(sizeof(keys_it->wifi_psk), res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				if (fclose(fd) == EOF)
-					wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-
-				return RETURN_ERR;
-			}
-
-			keys_it++;
-
-			if(--keysNumber <= 0)
-		break;
-		}
-	}
-
-close:
-	free(line);
-	if (fclose(fd) == EOF)
-		wifi_debug(DEBUG_ERROR, "Unexpected fclose fail\n");
-	return ret;
-}
-/* end of multi-psk support */
-
-INT wifi_setNeighborReports(UINT apIndex,
-							 UINT numNeighborReports,
-							 wifi_NeighborReport_t *neighborReports)
-{
-	char hex_bssid[13] = { 0 };
-	char bssid[18] = { 0 };
-	char nr[100] = { 0 };
-	char ssid[MAX_SSID_NAME_LEN];
-	char hex_ssid[MAX_SSID_NAME_LEN];
-	char interface_name[16] = {0};
-	INT ret;
-	int res;
-	unsigned char hex_ssid_len;
-
-	/*rmeove all neighbors*/
-	wifi_debug(DEBUG_INFO, "removing all neighbors from %s\n", interface_name);
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	res = v_secure_system("hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
-		interface_name, interface_name);
-
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-		return RETURN_ERR;
-	}
-
-	for(unsigned int i = 0; i < numNeighborReports; i++)
-	{
-		memset(ssid, 0, sizeof(ssid));
-		ret = wifi_getSSIDName(apIndex, ssid);
-		if (ret != RETURN_OK)
-			return RETURN_ERR;
-
-		memset(hex_ssid, 0, sizeof(hex_ssid));
-		hex_ssid_len = sizeof(hex_ssid);
-		for(size_t j = 0,k = 0; ssid[j] != '\0' && k < sizeof(hex_ssid); j++,k+=2 ) {
-			res = snprintf(hex_ssid + k, hex_ssid_len, "%02x", ssid[j]);
-
-			if (os_snprintf_error(hex_ssid_len, res)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-				return RETURN_ERR;
-			}
-			hex_ssid_len = sizeof(hex_ssid) - strlen(hex_ssid);
-		}
-
-		res = snprintf(hex_bssid, sizeof(hex_bssid),
-				"%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx",
-				neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
-		if (os_snprintf_error(sizeof(hex_bssid), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-		res = snprintf(bssid, sizeof(bssid),
-				"%02hhx:%02hhx:%02hhx:%02hhx:%02hhx:%02hhx",
-				neighborReports[i].bssid[0], neighborReports[i].bssid[1], neighborReports[i].bssid[2], neighborReports[i].bssid[3], neighborReports[i].bssid[4], neighborReports[i].bssid[5]);
-		if (os_snprintf_error(sizeof(bssid), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		res = snprintf(nr, sizeof(nr),
-				"%s"									// bssid
-				"%02hhx%02hhx%02hhx%02hhx"			  // bssid_info
-				"%02hhx"								// operclass
-				"%02hhx"								// channel
-				"%02hhx",							   // phy_mode
-				hex_bssid,
-				neighborReports[i].info & 0xff, (neighborReports[i].info >> 8) & 0xff,
-				(neighborReports[i].info >> 16) & 0xff, (neighborReports[i].info >> 24) & 0xff,
-				neighborReports[i].opClass,
-				neighborReports[i].channel,
-				neighborReports[i].phyTable);
-		if (os_snprintf_error(sizeof(nr), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		res = v_secure_system("hostapd_cli set_neighbor %s ssid=%s nr=%s -i %s",
-				bssid, hex_ssid, nr, interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "v_secure_system fail\n");
-			return RETURN_ERR;
-		}
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_getApInterworkingElement(INT apIndex, wifi_InterworkingElement_t *output_struct)
-{
-	return RETURN_OK;
-}
-
-INT mtk_wifi_set_get_mru_info(
-	INT radioIndex, INT vendor_data_attr, USHORT punct_bitmap, mtk_nl80211_cb call_back, void *output)
-{
-	int ret = -1;
-	struct unl unl_ins;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-
-	/*init mtk nl80211 vendor cmd*/
-	param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_AP_RADIO;
-	param.if_type = NL80211_ATTR_WIPHY;
-	param.if_idx = radio_index_to_phy(radioIndex);
-
-	ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-		return RETURN_ERR;
-	}
-	/*add mtk vendor cmd data*/
-
-	if (nla_put_u16(msg, vendor_data_attr, punct_bitmap)) {
-		wifi_debug(DEBUG_ERROR, "Nla put vendor_data_attr(%d) attribute error\n", vendor_data_attr);
-		nlmsg_free(msg);
-		goto err;
-	}
-
-	/*send mtk nl80211 vendor msg*/
-	ret = mtk_nl80211_send(&unl_ins, msg, msg_data, call_back, output);
-	if (ret) {
-		wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-		goto err;
-	}
-	/*deinit mtk nl80211 vendor msg*/
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_INFO, "send cmd success.\n");
-
-	return RETURN_OK;
-err:
-	mtk_nl80211_deint(&unl_ins);
-	wifi_debug(DEBUG_ERROR,"send cmd fails\n");
-	return RETURN_ERR;
-}
-
-int get_mru_info_handler(struct nl_msg *msg, void *data)
-{
-	struct nlattr *tb[NL80211_ATTR_MAX + 1];
-	struct nlattr *vndr_tb[MTK_NL80211_VENDOR_AP_RADIO_ATTR_MAX + 1];
-	struct genlmsghdr *gnlh = nlmsg_data(nlmsg_hdr(msg));
-	USHORT *punct_bitmap = (USHORT *)data;
-	int err = 0;
-
-	err = nla_parse(tb, NL80211_ATTR_MAX, genlmsg_attrdata(gnlh, 0),
-			  genlmsg_attrlen(gnlh, 0), NULL);
-	if (err < 0)
-		return err;
-
-	if (tb[NL80211_ATTR_VENDOR_DATA]) {
-		err = nla_parse_nested(vndr_tb, MTK_NL80211_VENDOR_AP_RADIO_ATTR_MAX,
-			tb[NL80211_ATTR_VENDOR_DATA], NULL);
-		if (err < 0)
-			return err;
-
-		if (vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO]) {
-			*punct_bitmap = nla_get_u16(vndr_tb[MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO]);
-		}
-	}
-
-	return 0;
-}
-
-
-INT wifi_setRadioPreamblePuncture(INT radioIndex, USHORT punct_bitmap)
-{
-	if (mtk_wifi_set_get_mru_info(radioIndex, MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO, punct_bitmap,
-		NULL, NULL)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-INT wifi_getRadioPreamblePuncture(INT radioIndex, USHORT *output)
-{
-	USHORT punct_bitmap;
-
-	if (mtk_wifi_set_get_mru_info(radioIndex, MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO, 0xffff,
-		get_mru_info_handler, &punct_bitmap)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "send MTK_NL80211_VENDOR_ATTR_AP_MRU_INFO cmd fails\n");
-		return RETURN_ERR;
-	}
-
-	*output = punct_bitmap;
-
-	return RETURN_OK;
-}
-
-
-INT wifi_getApWpsLastConnectionStatus(INT apIndex, CHAR *output_string);
-
-#ifdef _WIFI_HAL_TEST_
-int main(int argc,char **argv)
-{
-	int index;
-	INT ret=0;
-	char buf[1024]="";
-	wifi_ParseProfile();
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if(argc<3)
-	{
-		if(argc==2)
-		{
-			if(!strcmp(argv[1], "init"))
-				return wifi_init();
-			if(!strcmp(argv[1], "reset"))
-				return wifi_reset();
-			if(!strcmp(argv[1], "wifi_getHalVersion"))
-			{
-				char buffer[64];
-				if(wifi_getHalVersion(buffer)==RETURN_OK)
-					printf("Version: %s\n", buffer);
-				else
-					printf("Error in wifi_getHalVersion\n");
-				return RETURN_OK;
-			}
-		}
-		printf("wifihal <API> <radioIndex> <arg1> <arg2> ...\n");
-		exit(-1);
-	}
-
-	index = atoi(argv[2]);
-	if (strstr(argv[1], "test_system")!=NULL) {
-		ret = v_secure_system("iw phy | grep 'MHz \\[' | cut -d' ' -f2,4 > /tmp/freq-channel-map.txt");
-		printf("ret = %d\n", ret);
-
-		ret = v_secure_system("hostapd_cli show_neighbor -i %s | awk '{print $1 \" \" $2}' | xargs -n2 -r hostapd_cli remove_neighbor -i %s",
-			"ra0", "ra0");
-		printf("ret = %d\n", ret);
-
-		ret = v_secure_system("echo %s > /var/prevchanval2G_AutoChannelEnable", "1,2,3");
-		printf("ret = %d\n", ret);
-
-		ret = v_secure_system("ifconfig -a %s > /tmp/Radio_Stats.txt", "rai0");
-		printf("ret = %d\n", ret);
-
-		ret = v_secure_system("ifconfig %s > /tmp/SSID_Stats.txt", "rax0");
-		printf("ret = %d\n", ret);
-
-		ret = v_secure_system("iw dev %s station dump > /tmp/AssociatedDevice_Stats.txt", "ra0");
-		printf("ret = %d\n", ret);
-		ret = v_secure_system("iw dev %s station dump | grep Station >> /tmp/AllAssociated_Devices_5G.txt", "ra0");
-		printf("ret = %d\n", ret);
-		ret = v_secure_system("ping -q -c 1 -W 1  \"%s\"  > /dev/console 2>&1", "20.1.1.101");
-		printf("ret = %d\n", ret);
-
-		return 0;
-	}
-
-	if (strstr(argv[1], "test_popen")!=NULL) {
-		FILE *fp = v_secure_popen("w", "cat");
-		fprintf(fp, "popen write success\n");
-		fclose(fp);
-
-		char buf[1024];
-		memset(buf, 0, sizeof(buf));
-		fp = v_secure_popen("r", "echo popen read success");
-		if (fp == NULL) {
-			printf("v_secure_popen failed\n");
-		} else {
-			if (fgets(buf, sizeof(buf), fp) == NULL) {
-				printf("v_secure_popen read error\n");
-			} else {
-				printf("%s\n", buf);
-			}
-			v_secure_pclose(fp);
-		}
-
-#if 0
-		fp = v_secure_popen("r", "hostapd_cli -i %s reload", "ra0");
-		if (fp == NULL) {
-			printf("v_secure_popen failed\n");
-		} else {
-			if (fgets(buf, sizeof(buf), fp) == NULL) {
-				printf("v_secure_popen read error\n");
-			} else {
-				printf("%s", buf);
-			}
-			v_secure_pclose(fp);
-		}
-#endif
-
-		long int band;
-		memset(buf, 0, sizeof(buf));
-		ret = _syscmd_secure(buf, sizeof(buf),
-			"iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", 0);
-		if (hal_strtol(buf, 16, &band) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		printf("ret = %d, band0=%ld\n", ret, band);
-
-		memset(buf, 0, sizeof(buf));
-		ret = _syscmd_secure(buf, sizeof(buf),
-			"iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", 1);
-		if (hal_strtol(buf, 16, &band) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		printf("ret = %d, band1=%ld\n", ret, band);
-
-		memset(buf, 0, sizeof(buf));
-		ret = _syscmd_secure(buf, sizeof(buf),
-			"iw phy%d info | grep 'Band .:' | tail -n 1 | tr -d ':\\n' | awk '{print $2}'", 2);
-		if (hal_strtol(buf, 16, &band) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-		}
-		printf("ret = %d, band2=%ld\n", ret, band);
-	}
-
-	if(strstr(argv[1], "wifi_getApName")!=NULL)
-	{
-		wifi_getApName(index,buf);
-		printf("Ap name is %s \n",buf);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_getRadioExtChannel")!=NULL)
-	{
-		wifi_getRadioExtChannel(index,buf);
-		printf("extchannel is %s \n",buf);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_getApWpsLastConnectionStatus")!=NULL) {
-		char buf[32] = {0};
-		int res;
-
-		res = wifi_getApWpsLastConnectionStatus(index, buf);
-		if (res == RETURN_OK)
-			printf("ap_index=%d, wifi_getApWpsLastConnectionStatus=%s\n", index, buf);
-		else
-			printf("fail to get AP wps last connection status for ap_index=%d\n", index);
-	}
-
-#ifndef WIFI_7992
-	/*it is only suitable for eagle*/
-	if (strstr(argv[1], "mlo_test")) {
-		wifi_vap_info_map_t vap[3];
-		int i;
-		unsigned char mld_mac[6] = {0x00, 0x0c, 0x43, 0x11, 0x22, 0x33};
-		unsigned char mld_mac2[6] = {0x00, 0x0c, 0x43, 0x44, 0x55, 0x66};
-		radio_band[0] = band_2_4;
-		radio_band[1] = band_5;
-		radio_band[2] = band_6;
-
-		if (eht_mld_config_init() != RETURN_OK)
-			printf("eht_mld_config_init() fail!\n");
-
-		memset(vap, 0, sizeof(vap));
-		for (i = 0; i < 3; i++) {
-			if (wifi_getRadioVapInfoMap(i, &vap[i]) != RETURN_OK)
-				printf("wifi_getRadioVapInfoMap fail[%d]", i);
-		}
-
-		/*case 1-create mld[5], transfer ra0 mld[1]->mld[5]*/
-		vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_enable = 1;
-		vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_id = 5;	
-		memcpy(vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac, 6);
-
-		/*case 2-create mld[6], transfer ra1 mld[2]->mld[6]*/
-		vap[0].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 1;
-		vap[0].vap_array[1].u.bss_info.mld_info.common_info.mld_id = 6;	
-		memcpy(vap[0].vap_array[1].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
-		if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-
-		/*case 3-rai0 keep in mld[1]*/
-		vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_enable = 1;
-		vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_id = 1;	
-		memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac, 6);
-
-		/*case 4-rai1 leave mld[2]*/
-		vap[1].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 0;
-		vap[1].vap_array[1].u.bss_info.mld_info.common_info.mld_id = 2;	
-		memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
-
-		if (wifi_createVAP(1, &vap[1]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-
-		/*case 5-rax1 leave mld[2]->null*/
-		vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 0;
-		vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_id = 2;	
-		memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
-
-		if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-
-		/*case 6-rax1 null->join mld[7]*/
-		vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_enable = 1;
-		vap[2].vap_array[1].u.bss_info.mld_info.common_info.mld_id = 7;	
-		memcpy(vap[1].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac2, 6);
-
-		if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-
-		/*case 7-ra0 leve mld[5]->null, mld[5] destroy*/
-		vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_enable = 0;
-		vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_id = 5;	
-		memcpy(vap[0].vap_array[0].u.bss_info.mld_info.common_info.mld_addr, mld_mac, 6);
-		if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-
-		mld_info_display();
-	}
-
-	if (strstr(argv[1], "dynamic_vap_test")) {
-		wifi_vap_info_map_t vap[3];
-		int i;
-		radio_band[0] = band_2_4;
-		radio_band[1] = band_5;
-		radio_band[2] = band_6;
-
-		if (eht_mld_config_init() != RETURN_OK)
-			printf("eht_mld_config_init() fail!\n");
-
-		memset(vap, 0, sizeof(vap));
-		for (i = 0; i < 3; i++) {
-			if (wifi_getRadioVapInfoMap(i, &vap[i]) != RETURN_OK)
-				printf("wifi_getRadioVapInfoMap fail[%d]", i);
-		}
-
-		/*case 1-enable vap[4/6/8/10/12/14] ra2/ra3/ra4/ra5/ra6/ra7*/
-		for (i = 2; i < 8; i++)
-			vap[0].vap_array[i].u.bss_info.enabled = 1;
-		if (wifi_createVAP(0, &vap[0]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-
-		/*case 2-disable vap[1/3] rai0/rai1*/
-		for (i = 0; i < 2; i++)
-			vap[1].vap_array[i].u.bss_info.enabled = 0;
-		if (wifi_createVAP(1, &vap[1]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-	
-		/*case 3-disable vap[16/17] rax0/rax1, enable vap[18/19/20/21/22/23] rax2,rax3,rax4,rax5,rax6,rax7*/
-		for (i = 0; i < 2; i++)
-			vap[2].vap_array[i].u.bss_info.enabled = 0;
-		if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");		
-
-		for (i = 2; i < 8; i++)
-			vap[2].vap_array[i].u.bss_info.enabled = 1;
-		if (wifi_createVAP(2, &vap[2]) != RETURN_OK)
-			printf("wifi_createVAP[0] fail\n");
-	}
-#endif
-
-	if(strstr(argv[1], "wifi_getApAssociatedDeviceDiagnosticResult3")!=NULL)
-	{
-		wifi_associated_dev3_t *associated_dev_array = NULL, *dev3;
-		INT sta_count, i, j;
-		wifi_getApAssociatedDeviceDiagnosticResult3(index, &associated_dev_array, (unsigned int *)(&sta_count));
-		printf("wifi_getApAssociatedDeviceDiagnosticResult3\n");
-		if (associated_dev_array == NULL) {
-			printf("wifi_getApAssociatedDeviceDiagnosticResult3 fail\n");
-			return 0;
-		}
-		for (i = 0; i < sta_count; i++) {
-			dev3 = (wifi_associated_dev3_t *)(associated_dev_array + i);
-			printf("mac(%02x:%02x:%02x:%02x:%02x:%02x:)\n", dev3->cli_MACAddress[0], dev3->cli_MACAddress[1],
-				dev3->cli_MACAddress[2], dev3->cli_MACAddress[3], dev3->cli_MACAddress[4], dev3->cli_MACAddress[5]);
-			printf("\t tx_rate=%u, rx_rate=%u, snr=%u, rx_bytes=%lu, tx_bytes=%lu, rssi=%hhd, tx_pkts=%lu, rx_pkts=%lu\n"
-				"mlo_enable=%u\n", dev3->cli_LastDataUplinkRate , dev3->cli_LastDataDownlinkRate,
-				dev3->cli_SNR, dev3->cli_BytesReceived, dev3->cli_BytesSent, dev3->cli_RSSI, dev3->cli_PacketsReceived,
-				dev3->cli_BytesSent, dev3->mld_enable);
-
-			if (dev3->mld_enable) {
-				printf("\tmld mac(%02x:%02x:%02x:%02x:%02x:%02x:)\n", dev3->mld_addr[0], dev3->mld_addr[1],
-					dev3->mld_addr[2], dev3->mld_addr[3], dev3->mld_addr[4], dev3->mld_addr[5]);
-				
-				for (j = 0; j < 3; j++) {
-					if (!dev3->mld_link_info[j].valid)
-						continue;
-					printf("\tlink mac(%02x:%02x:%02x:%02x:%02x:%02x:)\n", dev3->mld_link_info[j].link_addr[0],
-						dev3->mld_link_info[j].link_addr[1],
-						dev3->mld_link_info[j].link_addr[2], dev3->mld_link_info[j].link_addr[3], dev3->mld_link_info[j].link_addr[4],
-						dev3->mld_link_info[j].link_addr[5]);
-					printf("\trssi=%hhd, tx_rate=%lu, rx_rate=%lu, tx_bytes=%llu, rx_bytes=%llu\n",
-						dev3->mld_link_info[j].rssi, dev3->mld_link_info[j].tx_rate, dev3->mld_link_info[j].rx_rate,
-						dev3->mld_link_info[j].tx_bytes, dev3->mld_link_info[j].rx_bytes);
-				}
-				
-			}
-		}
-		return 0;
-	}
-	if (strstr(argv[1], "wifi_setRadioAMSDUEnable")!=NULL) {
-		unsigned char enable = atoi(argv[3]);
-		BOOL out_put;
-		if (enable)
-			wifi_setRadioAMSDUEnable(index, TRUE);
-		else
-			wifi_setRadioAMSDUEnable(index, FALSE);
-		wifi_getRadioAMSDUEnable(index, &out_put);
-		printf("amsdu = %d\n", out_put);
-	}
-	if (strstr(argv[1], "wifi_setApIsolationEnable")!=NULL) {
-		unsigned char enable = atoi(argv[3]);
-		BOOL out_put;
-		if (enable)
-			wifi_setApIsolationEnable(index, TRUE);
-		else
-			wifi_setApIsolationEnable(index, FALSE);
-		wifi_getApIsolationEnable(index, &out_put);
-		printf("isolation input=%d, output=%d\n", enable, out_put);
-	}
-	if(strstr(argv[1], "wifi_setRadioMode")!=NULL)
-	{
-		UINT pureMode;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-
-		pureMode = atoi(argv[3]);
-		wifi_setRadioMode(index, NULL, pureMode);
-		printf("Ap SET Radio mode 0x%x\n", pureMode);
-		return 0;
-	}
-	if (strstr(argv[1], "wifi_setRadioAutoBlockAckEnable") != NULL) {
-		unsigned char enable;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		if (enable)
-			wifi_setRadioAutoBlockAckEnable(index, TRUE);
-		else
-			wifi_setRadioAutoBlockAckEnable(index, FALSE);
-		printf("%s handle wifi_setRadioAutoBlockAckEnable\n", __FUNCTION__);
-	}
-	if(strstr(argv[1], "wifi_setRadioTrafficStatsRadioStatisticsEnable")!=NULL)
-	{
-		wifi_setRadioTrafficStatsRadioStatisticsEnable(index, TRUE);
-		printf("Ap SET wifi_setRadioTrafficStatsRadioStatisticsEnable\n");
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_setRadioTrafficStatsMeasure")!=NULL)
-	{
-		wifi_radioTrafficStatsMeasure_t input = {30, 200};
-
-		wifi_setRadioTrafficStatsMeasure(index, &input);
-		printf("Ap SET wifi_setRadioTrafficStatsMeasure\n");
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_setRadioTransmitPower")!=NULL)
-	{
-		ULONG TransmitPower;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		TransmitPower = atoi(argv[3]);
-		wifi_setRadioTransmitPower(index, TransmitPower);
-		printf("Ap SET TransmitPower %lu\n", TransmitPower);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_setApManagementFramePowerControl")!=NULL)
-	{
-		INT TransmitPower;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		TransmitPower = atoi(argv[3]);
-		wifi_setApManagementFramePowerControl(index, TransmitPower);
-		printf("Ap SET Mgnt TransmitPower %d\n", TransmitPower);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_setRadioBW") != NULL)
-	{
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-
-		wifi_setRadioOperatingChannelBandwidth(index, argv[3]);
-		printf("Ap SET bw %s\n", argv[3]);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_setCountryCode") != NULL)
-	{
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-
-		wifi_setRadioCountryCode(index, argv[3]);
-		printf("Ap SET CountryCode %s\n", argv[3]);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_setChannel") != NULL)
-	{
-		UINT channel;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		channel = atoi(argv[3]);
-
-		wifi_setRadioChannel(index, channel);
-		printf("Ap SET channel %d\n", channel);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_setACSPeriod") != NULL)
-	{
-		ULONG seconds;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		seconds = atoi(argv[3]);
-
-		wifi_setRadioAutoChannelRefreshPeriod(index, seconds);
-		printf("Ap SET ACSPeriod %ld\n", seconds);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_setExtCh") != NULL)
-	{
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-
-		wifi_setRadioExtChannel(index, argv[3]);
-		printf("Ap SET ExtChannel %s\n", argv[3]);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_setHtCoex") != NULL)
-	{
-		UINT ht_coex;
-		BOOL enable = FALSE;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		ht_coex = atoi(argv[3]);
-
-		if (ht_coex == 1)
-			enable = TRUE;
-		wifi_setRadioObssCoexistenceEnable(index, enable);
-		printf("Ap SET ht_coex %d\n", enable);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_setChMode") != NULL)
-	{
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-
-		wifi_setRadioChannelMode(index, argv[3], FALSE, FALSE, FALSE);
-		printf("Ap SET ChannelMode %s\n", argv[3]);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_set80211h") != NULL)
-	{
-		UINT en_11h;
-		BOOL enable = FALSE;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		en_11h = atoi(argv[3]);
-
-		if (en_11h == 1)
-			enable = TRUE;
-		wifi_setRadioIEEE80211hEnabled(index, enable);
-		printf("Ap SET 80211h %d\n", enable);
-		return 0;
-	}
-
-	if(strstr(argv[1], "wifi_factoryResetRadio")!=NULL)
-	{
-		wifi_factoryResetRadio(index);
-		printf("wifi_factoryResetRadio ok!\n");
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_getRadioResetCount")!=NULL)
-	{
-		ULONG rst_cnt;
-		wifi_getRadioResetCount(index, &rst_cnt);
-		printf("wifi_factoryResetRadio rst_cnt = %lu\n", rst_cnt);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_addApAclDevice", strlen(argv[1])) == 0) {
-		if(argc <= 3 )
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		wifi_addApAclDevice(index, argv[3]);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getApAclDevices", strlen(argv[1])) == 0) {
-		wifi_getApAclDevices(index, buf, 1024);
-		wifi_debug(DEBUG_NOTICE, "Ap acl Devices: %s\n", buf);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_delApAclDevice", strlen(argv[1])) == 0) {
-		if(argc <= 3 )
-		{
-		   wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		wifi_delApAclDevice(index, argv[3]);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_delApAclDevices", strlen(argv[1])) == 0) {
-		wifi_delApAclDevices(index);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getApAclDeviceNum", strlen(argv[1])) == 0) {
-		UINT acl_num = 0;
-		wifi_getApAclDeviceNum(index, &acl_num);
-		wifi_debug(DEBUG_NOTICE, "Ap acl numbers: %d\n", acl_num);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getApDenyAclDevices", strlen(argv[1])) == 0) {
-		wifi_getApDenyAclDevices(index, buf, 1024);
-		wifi_debug(DEBUG_NOTICE, "Ap Deny Acl Devices: %s\n", buf);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_setApMacAddressControlMode", strlen(argv[1])) == 0) {
-		int filter_mode = 0;
-		if(argc <= 3 )
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		filter_mode = atoi(argv[3]);
-		wifi_setApMacAddressControlMode(index,filter_mode);
-		return 0;
-	}
-		if (strncmp(argv[1], "wifi_getRadioDeclineBARequestEnable", strlen(argv[1])) == 0) {
-		BOOL output_bool = 0;
-		wifi_getRadioDeclineBARequestEnable(index, &output_bool);
-		wifi_debug(DEBUG_NOTICE, "Ap get radio ba decline enable: %d\n", output_bool);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getRadioAutoBlockAckEnable", strlen(argv[1])) == 0) {
-		BOOL output_bool = 0;
-		wifi_getRadioAutoBlockAckEnable(index, &output_bool);
-		wifi_debug(DEBUG_NOTICE, "Ap get radio auto_ba enable: %d\n", output_bool);
-		return 0;
-	}
-
-	if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
-		int filter_mode = 0;
-		wifi_getApMacAddressControlMode(index, &filter_mode);
-		wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_setRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
-		int enable = 0;
-		if(argc <= 3 )
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = (BOOL)atoi(argv[3]);
-		wifi_setRadioIGMPSnoopingEnable(index, enable);
-		wifi_debug(DEBUG_NOTICE, "Ap set IGMP Snooping Enable: %d\n", enable);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_setRadioDCSEnable", strlen(argv[1])) == 0) {
-		int enable = 0;
-		if(argc <= 3 )
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = (BOOL)atoi(argv[3]);
-		wifi_setRadioDCSEnable(index, enable);
-		wifi_debug(DEBUG_NOTICE, "Ap set DCS Enable: %d\n", enable);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getRadioAutoChannelRefreshPeriod", strlen(argv[1])) == 0) {
-		ULONG period = 0;
-
-		wifi_getRadioAutoChannelRefreshPeriod(index, &period);
-		wifi_debug(DEBUG_NOTICE, "Get RefreshPeriod: %ld\n", period);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_setRadioDfsRefreshPeriod", strlen(argv[1])) == 0) {
-		ULONG period = 0;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		period = (ULONG)atoi(argv[3]);
-		wifi_setRadioDfsRefreshPeriod(index, period);
-		wifi_debug(DEBUG_NOTICE, "Set RefreshPeriod: %ld\n", period);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_setRadioDCSChannelPool", strlen(argv[1])) == 0) {
-		char pool[256] = {'\0'};
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		strncpy(pool, argv[3], strlen(argv[3]));
-		wifi_setRadioDCSChannelPool(index, pool);
-		wifi_debug(DEBUG_NOTICE, "Set DCSChannelPool: %s\n", pool);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getRadioDCSChannelPool", strlen(argv[1])) == 0) {
-		char pool[256] = {'\0'};
-
-		wifi_getRadioDCSChannelPool(index, pool);
-		wifi_debug(DEBUG_NOTICE, "Get DCSChannelPool: %s\n", pool);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getRadioIGMPSnoopingEnable", strlen(argv[1])) == 0) {
-		BOOL out_status = 0;
-		wifi_getRadioIGMPSnoopingEnable(index, &out_status);
-		wifi_debug(DEBUG_NOTICE, "Ap get IGMP Snooping Enable: %d\n", out_status);
-		return 0;
-	}
-
-	if (strncmp(argv[1], "wifi_setApWmmEnable", strlen(argv[1])) == 0) {
-		int enable = 0;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		wifi_setApWmmEnable(index,enable);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_pushSsidAdvertisementEnable", strlen(argv[1])) == 0) {
-		int enable = 0;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		wifi_pushSsidAdvertisementEnable(index,enable);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_down", strlen(argv[1])) == 0) {
-		wifi_down();
-		return 0;
-	}
-
-	if (strncmp(argv[1], "wifi_getRadioStatus", strlen(argv[1])) == 0) {
-		BOOL enable = 0;
-
-		wifi_getRadioStatus(index, &enable);
-		wifi_debug(DEBUG_NOTICE, "wifi_getRadioStatus enable: %d\n", (int)enable);
-		return 0;
-	}
-
-	if (strncmp(argv[1], "wifi_getApWMMCapability", strlen(argv[1])) == 0) {
-		BOOL enable = 0;
-
-		wifi_getApWMMCapability(index, &enable);
-		wifi_debug(DEBUG_NOTICE, "wifi_getApWMMCapability enable: %d\n", (int)enable);
-		return 0;
-	}
-
-	if (strncmp(argv[1], "wifi_getApWmmEnable", strlen(argv[1])) == 0) {
-		BOOL enable = 0;
-
-		wifi_getApWmmEnable(index, &enable);
-		wifi_debug(DEBUG_NOTICE, "wifi_getApWmmEnable enable: %d\n", (int)enable);
-		return 0;
-	}
-
-	if (strncmp(argv[1], "wifi_getApMacAddressControlMode", strlen(argv[1])) == 0) {
-		int filter_mode = 0;
-		wifi_getApMacAddressControlMode(index, &filter_mode);
-		wifi_debug(DEBUG_NOTICE, "Ap MacAddress Control Mode: %d\n", filter_mode);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_getRadioMode")!=NULL)
-	{
-		UINT mode = 0;
-
-		wifi_getRadioMode(index, buf, &mode);
-		printf("Ap Radio mode is %s , mode = 0x%x\n", buf, mode);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_getRadioAutoChannelEnable")!=NULL)
-	{
-		BOOL b = FALSE;
-		BOOL *output_bool = &b;
-		wifi_getRadioAutoChannelEnable(index,output_bool);
-		printf("Channel enabled = %d \n",b);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_getApWpaEncryptionMode")!=NULL)
-	{
-		wifi_getApWpaEncryptionMode(index,buf);
-		printf("encryption enabled = %s\n",buf);
-		return 0;
-	}
-	if(strstr(argv[1], "wifi_getApSsidAdvertisementEnable")!=NULL)
-	{
-		BOOL b = FALSE;
-		BOOL *output_bool = &b;
-		wifi_getApSsidAdvertisementEnable(index,output_bool);
-		printf("advertisment enabled =  %d\n",b);
-		return 0;
-	}
-	if(strstr(argv[1],"wifi_getApAssociatedDeviceTidStatsResult")!=NULL)
-	{
-		if(argc <= 3 )
-		{
-			printf("Insufficient arguments \n");
-			exit(-1);
-		}
-
-		char sta[20] = {'\0'};
-		ULLONG handle= 0;
-		strncpy(sta,argv[3], strlen(argv[3]));
-		mac_address_t st;
-	mac_addr_aton(st,sta);
-
-		wifi_associated_dev_tid_stats_t tid_stats;
-		wifi_getApAssociatedDeviceTidStatsResult(index,&st,&tid_stats,&handle);
-		for(int tid_index=0; tid_index<PS_MAX_TID; tid_index++) //print tid stats
-			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);
-	}
-
-	if(strstr(argv[1], "getApEnable")!=NULL) {
-		BOOL enable;
-		ret=wifi_getApEnable(index, &enable);
-		printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
-	}
-	else if(strstr(argv[1], "setApEnable")!=NULL) {
-		BOOL enable;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		ret=wifi_setApEnable(index, enable);
-		printf("%s %d: %d, returns %d\n", argv[1], index, enable, ret);
-	}
-	else if(strstr(argv[1], "getApStatus")!=NULL) {
-		char status[64];
-		ret=wifi_getApStatus(index, status);
-		printf("%s %d: %s, returns %d\n", argv[1], index, status, ret);
-	}
-	else if(strstr(argv[1], "wifi_getSSIDNameStatus")!=NULL)
-	{
-		wifi_getSSIDNameStatus(index,buf);
-		printf("%s %d: active ssid : %s\n",argv[1], index,buf);
-		return 0;
-	} else if(strstr(argv[1], "wifi_resetApVlanCfg")!=NULL) {
-		wifi_resetApVlanCfg(index);
-		printf("%s %d: wifi_resetApVlanCfg : %s\n",argv[1], index,buf);
-		return 0;
-	}
-	else if(strstr(argv[1], "getSSIDTrafficStats2")!=NULL) {
-		wifi_ssidTrafficStats2_t stats={0};
-		ret=wifi_getSSIDTrafficStats2(index, &stats); //Tr181
-		printf("%s %d: returns %d\n", argv[1], index, ret);
-		printf("	 ssid_BytesSent			 =%lu\n", stats.ssid_BytesSent);
-		printf("	 ssid_BytesReceived		 =%lu\n", stats.ssid_BytesReceived);
-		printf("	 ssid_PacketsSent		   =%lu\n", stats.ssid_PacketsSent);
-		printf("	 ssid_PacketsReceived	   =%lu\n", stats.ssid_PacketsReceived);
-		printf("	 ssid_RetransCount		  =%lu\n", stats.ssid_RetransCount);
-		printf("	 ssid_FailedRetransCount	=%lu\n", stats.ssid_FailedRetransCount);
-		printf("	 ssid_RetryCount			=%lu\n", stats.ssid_RetryCount);
-		printf("	 ssid_MultipleRetryCount	=%lu\n", stats.ssid_MultipleRetryCount);
-		printf("	 ssid_ACKFailureCount	   =%lu\n", stats.ssid_ACKFailureCount);
-		printf("	 ssid_AggregatedPacketCount =%lu\n", stats.ssid_AggregatedPacketCount);
-		printf("	 ssid_ErrorsSent			=%lu\n", stats.ssid_ErrorsSent);
-		printf("	 ssid_ErrorsReceived		=%lu\n", stats.ssid_ErrorsReceived);
-		printf("	 ssid_UnicastPacketsSent	=%lu\n", stats.ssid_UnicastPacketsSent);
-		printf("	 ssid_UnicastPacketsReceived	=%lu\n", stats.ssid_UnicastPacketsReceived);
-		printf("	 ssid_DiscardedPacketsSent	  =%lu\n", stats.ssid_DiscardedPacketsSent);
-		printf("	 ssid_DiscardedPacketsReceived  =%lu\n", stats.ssid_DiscardedPacketsReceived);
-		printf("	 ssid_MulticastPacketsSent	  =%lu\n", stats.ssid_MulticastPacketsSent);
-		printf("	 ssid_MulticastPacketsReceived  =%lu\n", stats.ssid_MulticastPacketsReceived);
-		printf("	 ssid_BroadcastPacketsSent	  =%lu\n", stats.ssid_BroadcastPacketsSent);
-		printf("	 ssid_BroadcastPacketsRecevied  =%lu\n", stats.ssid_BroadcastPacketsRecevied);
-		printf("	 ssid_UnknownPacketsReceived	=%lu\n", stats.ssid_UnknownPacketsReceived);
-	}
-	else if(strstr(argv[1], "getNeighboringWiFiDiagnosticResult2")!=NULL) {
-		wifi_neighbor_ap2_t *neighbor_ap_array=NULL, *pt=NULL;
-		UINT array_size=0;
-		UINT i=0;
-		ret=wifi_getNeighboringWiFiDiagnosticResult2(index, &neighbor_ap_array, &array_size);
-		printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
-		for(i=0, pt=neighbor_ap_array; i<array_size; i++, pt++) {
-			printf("  neighbor %d:\n", i);
-			printf("	 ap_SSID				=%s\n", pt->ap_SSID);
-			printf("	 ap_BSSID			   =%s\n", pt->ap_BSSID);
-			printf("	 ap_Mode				=%s\n", pt->ap_Mode);
-			printf("	 ap_Channel			 =%d\n", pt->ap_Channel);
-			printf("	 ap_SignalStrength	  =%d\n", pt->ap_SignalStrength);
-			printf("	 ap_SecurityModeEnabled =%s\n", pt->ap_SecurityModeEnabled);
-			printf("	 ap_EncryptionMode	  =%s\n", pt->ap_EncryptionMode);
-			printf("	 ap_SupportedStandards  =%s\n", pt->ap_SupportedStandards);
-			printf("	 ap_OperatingStandards  =%s\n", pt->ap_OperatingStandards);
-			printf("	 ap_OperatingChannelBandwidth   =%s\n", pt->ap_OperatingChannelBandwidth);
-			printf("	 ap_SecurityModeEnabled		 =%s\n", pt->ap_SecurityModeEnabled);
-			printf("	 ap_BeaconPeriod				=%d\n", pt->ap_BeaconPeriod);
-			printf("	 ap_Noise					   =%d\n", pt->ap_Noise);
-			printf("	 ap_BasicDataTransferRates	  =%s\n", pt->ap_BasicDataTransferRates);
-			printf("	 ap_SupportedDataTransferRates  =%s\n", pt->ap_SupportedDataTransferRates);
-			printf("	 ap_DTIMPeriod				  =%d\n", pt->ap_DTIMPeriod);
-			printf("	 ap_ChannelUtilization		  =%d\n", pt->ap_ChannelUtilization);
-		}
-		if(neighbor_ap_array)
-			free(neighbor_ap_array); //make sure to free the list
-	}
-	else if(strstr(argv[1], "getApAssociatedDeviceDiagnosticResult")!=NULL) {
-		wifi_associated_dev_t *associated_dev_array=NULL, *pt=NULL;
-		UINT array_size=0;
-		UINT i=0;
-		ret=wifi_getApAssociatedDeviceDiagnosticResult(index, &associated_dev_array, &array_size);
-		printf("%s %d: array_size=%d, returns %d\n", argv[1], index, array_size, ret);
-		for(i=0, pt=associated_dev_array; i<array_size; i++, pt++) {
-			printf("  associated_dev %d:\n", i);
-			printf("	 cli_OperatingStandard	  =%s\n", pt->cli_OperatingStandard);
-			printf("	 cli_OperatingChannelBandwidth  =%s\n", pt->cli_OperatingChannelBandwidth);
-			printf("	 cli_SNR					=%d\n", pt->cli_SNR);
-			printf("	 cli_InterferenceSources	=%s\n", pt->cli_InterferenceSources);
-			printf("	 cli_DataFramesSentAck	  =%lu\n", pt->cli_DataFramesSentAck);
-			printf("	 cli_DataFramesSentNoAck	=%lu\n", pt->cli_DataFramesSentNoAck);
-			printf("	 cli_BytesSent			  =%lu\n", pt->cli_BytesSent);
-			printf("	 cli_BytesReceived		  =%lu\n", pt->cli_BytesReceived);
-			printf("	 cli_RSSI				   =%d\n", pt->cli_RSSI);
-			printf("	 cli_MinRSSI				=%d\n", pt->cli_MinRSSI);
-			printf("	 cli_MaxRSSI				=%d\n", pt->cli_MaxRSSI);
-			printf("	 cli_Disassociations		=%d\n", pt->cli_Disassociations);
-			printf("	 cli_AuthenticationFailures =%d\n", pt->cli_AuthenticationFailures);
-		}
-		if(associated_dev_array)
-			free(associated_dev_array); //make sure to free the list
-	}
-
-	if(strstr(argv[1],"wifi_getRadioChannelStats")!=NULL)
-	{
-#define MAX_ARRAY_SIZE 64
-		int i, array_size;
-		char *p, *ch_str;
-		wifi_channelStats_t input_output_channelStats_array[MAX_ARRAY_SIZE];
-
-		if(argc != 5)
-		{
-			printf("Insufficient arguments, Usage: wifihal wifi_getRadioChannelStats <AP-Index> <Array-Size> <Comma-seperated-channel-numbers>\n");
-			exit(-1);
-		}
-		memset(input_output_channelStats_array, 0, sizeof(input_output_channelStats_array));
-
-		for (i=0, array_size=atoi(argv[3]), ch_str=argv[4]; i<array_size; i++, ch_str=p)
-		{
-			strtok_r(ch_str, ",", &p);
-			input_output_channelStats_array[i].ch_number = atoi(ch_str);
-		}
-		wifi_getRadioChannelStats(atoi(argv[2]), input_output_channelStats_array, array_size);
-		if(!array_size)
-			array_size=1;//Need to print current channel statistics
-		for(i=0; i<array_size; i++)
-			printf("chan num = %d \t, noise =%d\t ch_utilization_busy_rx = %lld \t,\
-					ch_utilization_busy_tx = %lld \t,ch_utilization_busy = %lld \t,\
-					ch_utilization_busy_ext = %lld \t, ch_utilization_total = %lld \t \n",\
-					input_output_channelStats_array[i].ch_number,\
-					input_output_channelStats_array[i].ch_noise,\
-					input_output_channelStats_array[i].ch_utilization_busy_rx,\
-					input_output_channelStats_array[i].ch_utilization_busy_tx,\
-					input_output_channelStats_array[i].ch_utilization_busy,\
-					input_output_channelStats_array[i].ch_utilization_busy_ext,\
-					input_output_channelStats_array[i].ch_utilization_total);
-	}
-
-	if(strstr(argv[1],"wifi_getAssociatedDeviceDetail")!=NULL)
-	{
-		if(argc <= 3 )
-		{
-			printf("Insufficient arguments \n");
-			exit(-1);
-		}
-		char mac_addr[20] = {'\0'};
-		wifi_device_t output_struct;
-		int dev_index = atoi(argv[3]);
-
-		wifi_getAssociatedDeviceDetail(index,dev_index,&output_struct);
-		mac_addr_ntoa(mac_addr,output_struct.wifi_devMacAddress);
-		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);
-	}
-
-	if(strstr(argv[1],"wifi_setNeighborReports")!=NULL)
-	{
-		if (argc <= 3)
-		{
-			printf("Insufficient arguments\n");
-			exit(-1);
-		}
-		char args[256];
-		wifi_NeighborReport_t *neighborReports;
-
-		neighborReports = calloc(argc - 2, sizeof(neighborReports));
-		if (!neighborReports)
-		{
-			printf("Failed to allocate memory");
-			exit(-1);
-		}
-
-		for (int i = 3; i < argc; ++i)
-		{
-			char *val;
-			int j = 0;
-			unsigned long tmp;
-			memset(args, 0, sizeof(args));
-			strncpy(args, argv[i], sizeof(args));
-			val = strtok(args, ";");
-			while (val != NULL)
-			{
-				if (j == 0)
-				{
-					mac_addr_aton(neighborReports[i - 3].bssid, val);
-				} else if (j == 1)
-				{
-					if (hal_strtoul(val, 16, &tmp) < 0) {
-						wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-					}
-					neighborReports[i - 3].info = tmp;
-				} else if (j == 2)
-				{
-					if (hal_strtoul(val, 16, &tmp) < 0) {
-						wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-					}
-					neighborReports[i - 3].opClass = tmp;
-
-				} else if (j == 3)
-				{
-					if (hal_strtoul(val, 16, &tmp) < 0) {
-						wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-					}
-					neighborReports[i - 3].channel = tmp;
-				} else if (j == 4)
-				{
-					if (hal_strtoul(val, 16, &tmp) < 0) {
-						wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-					}
-					neighborReports[i - 3].phyTable = tmp;
-				} else {
-					printf("Insufficient arguments]n\n");
-					exit(-1);
-				}
-				val = strtok(NULL, ";");
-				j++;
-			}
-		}
-
-		INT ret = wifi_setNeighborReports(index, argc - 3, neighborReports);
-		if (ret != RETURN_OK)
-		{
-			printf("wifi_setNeighborReports ret = %d", ret);
-			exit(-1);
-		}
-	}
-	if(strstr(argv[1],"wifi_getRadioIfName")!=NULL)
-	{
-		if((ret=wifi_getRadioIfName(index, buf))==RETURN_OK)
-			printf("%s.\n", buf);
-		else
-			printf("Error returned\n");
-	}
-	if(strstr(argv[1],"wifi_getApSecurityModesSupported")!=NULL)
-	{
-		if((ret=wifi_getApSecurityModesSupported(index, buf))==RETURN_OK)
-			printf("%s.\n", buf);
-		else
-			printf("Error returned\n");
-	}
-	if(strstr(argv[1],"wifi_getRadioOperatingChannelBandwidth")!=NULL)
-	{
-		if (argc <= 2)
-		{
-			printf("Insufficient arguments\n");
-			exit(-1);
-		}
-		char buf[64]= {'\0'};
-		wifi_getRadioOperatingChannelBandwidth(index,buf);
-		printf("Current operating bandwidth is %s \n",buf);
-		return 0;
-	}
-	if(strstr(argv[1],"wifi_getCountryCode") != NULL)
-	{
-		if (argc <= 2)
-		{
-			printf("Insufficient arguments\n");
-			exit(-1);
-		}
-		char country[64]= {'\0'};
-		wifi_getRadioCountryCode(index, country);
-		printf("Current country code is %s \n", country);
-		return 0;
-	}
-	if(strstr(argv[1],"wifi_getRadioConfiguredChannelBandwidth") != NULL)
-	{
-		if (argc <= 2)
-		{
-			printf("Insufficient arguments\n");
-			exit(-1);
-		}
-		char buf[64]= {'\0'};
-		wifi_getRadioConfiguredChannelBandwidth(index, buf);
-		printf("Current config bandwidth is %s \n",buf);
-		return 0;
-	}
-	if(strstr(argv[1],"wifi_getRadioChannelsInUse") != NULL)
-	{
-		if (argc <= 2)
-		{
-			printf("Insufficient arguments\n");
-			exit(-1);
-		}
-		char buf[256]= {'\0'};
-		wifi_getRadioChannelsInUse(index, buf);
-		printf("RadioChannelsInUse is %s \n",buf);
-		return 0;
-	}
-	if(strstr(argv[1],"pushRadioChannel2")!=NULL)
-	{
-		if (argc <= 5)
-		{
-			printf("Insufficient arguments\n");
-			exit(-1);
-		}
-		UINT channel = atoi(argv[3]);
-		UINT width = atoi(argv[4]);
-		UINT beacon = atoi(argv[5]);
-		INT ret = wifi_pushRadioChannel2(index,channel,width,beacon);
-		printf("Result = %d", ret);
-	}
-	if(strstr(argv[1],"wifi_getRadioChannel")!=NULL)
-	{
-		ULONG channel = 0;
-		wifi_getRadioChannel(index, &channel);
-		printf("channel is %ld \n",channel);
-		return 0;
-	}
-	if(strstr(argv[1],"wifi_getACSPeriod") != NULL)
-	{
-		ULONG ACS_Period = 0;
-		wifi_getRadioAutoChannelRefreshPeriod(index, &ACS_Period);
-		printf("ACS_Period is %ld \n", ACS_Period);
-		return 0;
-	}
-	if(strstr(argv[1],"wifi_getApBridgeInfo")!=NULL)
-	{
-		char br_name[64], ip[64], subset[64] = {0};
-		wifi_getApBridgeInfo(0, br_name, ip, subset);
-		printf("wifi_getApBridgeInfo br_name = %s, ip = %s, subset = %s\n", br_name, ip, subset);
-	}
-	if(strstr(argv[1],"wifi_enableGreylistAccessControl")!=NULL)
-	{
-		int enable;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		wifi_enableGreylistAccessControl(enable == 0 ? FALSE : TRUE);
-		printf("wifi_enableGreylistAccessControl enable=%d\n", enable);
-	}
-	if(strstr(argv[1],"wifi_setApBridgeInfo")!=NULL)
-	{
-		if(argc <= 5)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		wifi_setApBridgeInfo(0, argv[3], argv[4], argv[5]);
-		printf("wifi_setApBridgeInfo br_name = %s, ip = %s, subset = %s\n", argv[3], argv[4], argv[5]);
-	}
-
-	if(strstr(argv[1], "wifi_getATMCapable")!=NULL)
-    {
-        BOOL b = FALSE;
-        BOOL *output_bool = &b;
-        wifi_getATMCapable(output_bool);
-        printf("ATM capable = %d \n",b);
-        return 0;
-    }
-	if (strncmp(argv[1], "wifi_setATMEnable", strlen(argv[1])) == 0) {
-		int enable = 0;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		wifi_setATMEnable(enable);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getATMEnable", strlen(argv[1])) == 0) {
-		BOOL b = FALSE;
-        BOOL *output_bool = &b;
-		wifi_getATMEnable(output_bool);
-		printf("ATM enable = %d \n", b);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_setApATMAirTimePercent", strlen(argv[1])) == 0) {
-		unsigned int percent = 0;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		percent = atoi(argv[3]);
-		wifi_setApATMAirTimePercent(index, percent);
-		return 0;
-	}
-	if (strncmp(argv[1], "wifi_getApATMAirTimePercent", strlen(argv[1])) == 0) {
-		unsigned int percent = 0;
-		unsigned int *output = &percent;
-
-		wifi_getApATMAirTimePercent(index, output);
-		printf("ATM percent = %d \n", percent);
-		return 0;
-	}
-	if (strstr(argv[1],"setGF")!=NULL)
-	{
-		BOOL enable;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		enable = atoi(argv[3]);
-		if((ret=wifi_setRadio11nGreenfieldEnable(index, enable))==RETURN_OK)
-			printf("wifi_setRadio11nGreenfieldEnable success\n");
-		else
-			printf("wifi_setRadio11nGreenfieldEnable Error\n");
-	}
-	if (strstr(argv[1],"setVID")!=NULL)
-	{
-		INT vid;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		vid = atoi(argv[3]);
-		if((ret=wifi_setApVlanID(index, vid))==RETURN_OK)
-			printf("wifi_setApVlanID success.\n");
-		else
-			printf("wifi_setApVlanID Error\n");
-	}
-	if (strncmp(argv[1], "wifi_getApATMSta", strlen(argv[1])) == 0) {
-		UCHAR outbuf[256]={0};
-
-		wifi_getApATMSta(index, outbuf, sizeof(outbuf));
-		printf("sta air time percent is %s \n", outbuf);
-		return 0;
-	}
-	if (strstr(argv[1], "wifi_setRadioPreamblePuncture") != NULL) {
-		USHORT punct_bitmap;
-		if(argc <= 3)
-		{
-			wifi_debug(DEBUG_ERROR, "Insufficient arguments \n");
-			exit(-1);
-		}
-		punct_bitmap = atoi(argv[3]);
-		wifi_setRadioPreamblePuncture(index, punct_bitmap);
-		printf("%s handle punct_bitmap\n", __FUNCTION__);
-	}
-	if (strstr(argv[1], "wifi_getRadioPreamblePuncture") != NULL) {
-		USHORT punct_bitmap = 0;
-
-		wifi_getRadioPreamblePuncture(index, &punct_bitmap);
-		printf("wifi_getRadioPreamblePuncture = %d\n", punct_bitmap);
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return 0;
-}
-
-#endif
-
-#ifdef WIFI_HAL_VERSION_3
-
-INT BitMapToTransmitRates(UINT bitMap, char *BasicRate, unsigned long size)
-{
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	if (bitMap & WIFI_BITRATE_1MBPS) {
-		if ((size - strlen(BasicRate)) <= 2)
-			return RETURN_ERR;
-		strncat(BasicRate, "1,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_2MBPS) {
-		if ((size - strlen(BasicRate)) <= 2)
-			return RETURN_ERR;
-		strncat(BasicRate, "2,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_5_5MBPS) {
-		if ((size - strlen(BasicRate)) <= 4)
-			return RETURN_ERR;
-		strncat(BasicRate, "5.5,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_6MBPS) {
-		if ((size - strlen(BasicRate)) <= 2)
-			return RETURN_ERR;
-		strncat(BasicRate, "6,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_9MBPS) {
-		if ((size - strlen(BasicRate)) <= 2)
-			return RETURN_ERR;
-		strncat(BasicRate, "9,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_11MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "11,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_12MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "12,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_18MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "18,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_24MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "24,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_36MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "36,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_48MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "48,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (bitMap & WIFI_BITRATE_54MBPS) {
-		if ((size - strlen(BasicRate)) <= 3)
-			return RETURN_ERR;
-		strncat(BasicRate, "54,", sizeof(BasicRate) - strlen(BasicRate) - 1);
-	}
-	if (strlen(BasicRate) != 0)	 // remove last comma
-		BasicRate[strlen(BasicRate) - 1] = '\0';
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT TransmitRatesToBitMap (char *BasicRatesList, UINT *basicRateBitMap)
-{
-	UINT BitMap = 0;
-	char *rate;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	rate = strtok(BasicRatesList, ",");
-	while(rate != NULL)
-	{
-		if (strcmp(rate, "1") == 0)
-			BitMap |= WIFI_BITRATE_1MBPS;
-		else if (strcmp(rate, "2") == 0)
-			BitMap |= WIFI_BITRATE_2MBPS;
-		else if (strcmp(rate, "5.5") == 0)
-			BitMap |= WIFI_BITRATE_5_5MBPS;
-		else if (strcmp(rate, "6") == 0)
-			BitMap |= WIFI_BITRATE_6MBPS;
-		else if (strcmp(rate, "9") == 0)
-			BitMap |= WIFI_BITRATE_9MBPS;
-		else if (strcmp(rate, "11") == 0)
-			BitMap |= WIFI_BITRATE_11MBPS;
-		else if (strcmp(rate, "12") == 0)
-			BitMap |= WIFI_BITRATE_12MBPS;
-		else if (strcmp(rate, "18") == 0)
-			BitMap |= WIFI_BITRATE_18MBPS;
-		else if (strcmp(rate, "24") == 0)
-			BitMap |= WIFI_BITRATE_24MBPS;
-		else if (strcmp(rate, "36") == 0)
-			BitMap |= WIFI_BITRATE_36MBPS;
-		else if (strcmp(rate, "48") == 0)
-			BitMap |= WIFI_BITRATE_48MBPS;
-		else if (strcmp(rate, "54") == 0)
-			BitMap |= WIFI_BITRATE_54MBPS;
-		rate = strtok(NULL, ",");
-	}
-	*basicRateBitMap = BitMap;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-// This API is used to configured all radio operation parameter in a single set. it includes channel number, channelWidth, mode and auto chammel configuration.
-INT wifi_setRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
-{
-	char buf[128] = {0};
-	int bandwidth = 20;
-	int set_mode = 0;
-	BOOL drv_dat_change = 0, hapd_conf_change = 0;
-	wifi_radio_operationParam_t current_param;
-	int ApIndex;
-	int ret, bss_num, i;
-	char ret_buf[MAX_BUF_SIZE] = {0};
-	BOOL enabled = FALSE;
-	int bss_idx;
-
-	ret = wifi_BandProfileRead(0, index, "BssidNum", ret_buf, sizeof(ret_buf), "1");
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
-		return RETURN_ERR;
-	}
-	bss_num = atoi(ret_buf);
-	if (bss_num <= 0)  {
-		wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", ret_buf);
-		return RETURN_ERR;
-	}
-	if (bss_num > LOGAN_MAX_NUM_VAP_PER_RADIO) {
-		wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
-		bss_num = LOGAN_MAX_NUM_VAP_PER_RADIO;
-	}
-	wifi_debug(DEBUG_OFF, "band %d BssidNum %d\n", index, bss_num);
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	multiple_set = TRUE;
-	if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
-	{
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
-		return RETURN_ERR;
-	}
-	if (operationParam->enable == TRUE) {
-		if (enabled == FALSE) {
-			wifi_setRadioEnable(index, TRUE);
-			radio_start_uptime[index] = wifi_getSystemUpSecs();
-		} else {
-			for (bss_idx = 0; bss_idx < bss_num; bss_idx++) {
-				if (array_index_to_vap_index(index, bss_idx, &ApIndex) != RETURN_OK) {
-					wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, bss_idx %d\n", index, bss_idx);
-					continue;
-				}
-				if (getVapEnableConfig(ApIndex) == TRUE)
-					wifi_setApEnable(ApIndex, TRUE);
-			}
-		}
-	} else if (enabled == TRUE && operationParam->enable == FALSE) {
-		wifi_setRadioEnable(index, FALSE);
-		return RETURN_OK;
-	}
-	if (wifi_getRadioOperatingParameters(index, &current_param) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingParameters return error.\n");
-		goto err;
-	}
-	if (current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
-		if (wifi_setRadioAutoChannelEnable(index, operationParam->autoChannelEnabled) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioAutoChannelEnable return error.\n");
-			goto err;
-		}
-		drv_dat_change = TRUE;
-	}
-
-	if (current_param.autoChanRefreshPeriod != operationParam->autoChanRefreshPeriod) {
-		if (wifi_setRadioAutoChannelRefreshPeriod(index, operationParam->autoChanRefreshPeriod) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioAutoChannelRefreshPeriod return error.\n");
-			goto err;
-		}
-	}
-
-	if (current_param.channelWidth != operationParam->channelWidth ||
-		current_param.channel != operationParam->channel ||
-		current_param.autoChannelEnabled != operationParam->autoChannelEnabled) {
-		if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_20MHZ)
-			bandwidth = 20;
-		else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_40MHZ)
-			bandwidth = 40;
-		else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80MHZ)
-			bandwidth = 80;
-		else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_160MHZ || operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_80_80MHZ)
-			bandwidth = 160;
-		else if (operationParam->channelWidth == WIFI_CHANNELBANDWIDTH_320MHZ)
-			bandwidth = 320;
-
-		if (operationParam->autoChannelEnabled) {
-			if (wifi_pushRadioChannel2(index, 0, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
-				goto err;
-			}
-		} else {
-			if (wifi_pushRadioChannel2(index, operationParam->channel, bandwidth, operationParam->csa_beacon_count) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_pushRadioChannel2 return error.\n");
-				goto err;
-			}
-		}
-	}
-	if (current_param.variant != operationParam->variant) {
-		// Two different definition bit map, so need to check every bit.
-		if (operationParam->variant & WIFI_80211_VARIANT_A)
-			set_mode |= WIFI_MODE_A;
-		if (operationParam->variant & WIFI_80211_VARIANT_B)
-			set_mode |= WIFI_MODE_B;
-		if (operationParam->variant & WIFI_80211_VARIANT_G)
-			set_mode |= WIFI_MODE_G;
-		if (operationParam->variant & WIFI_80211_VARIANT_N)
-			set_mode |= WIFI_MODE_N;
-		if (operationParam->variant & WIFI_80211_VARIANT_AC)
-			set_mode |= WIFI_MODE_AC;
-		if (operationParam->variant & WIFI_80211_VARIANT_AX)
-			set_mode |= WIFI_MODE_AX;
-		if (operationParam->variant & WIFI_80211_VARIANT_BE)
-			set_mode |= WIFI_MODE_BE;
-		// Second parameter is to set channel band width, it is done by wifi_pushRadioChannel2 if changed.
-		memset(buf, 0, sizeof(buf));
-
-		if (wifi_setRadioMode(index, NULL, set_mode) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioMode return error.\n");
-			goto err;
-		}
-	}
-	
-	if (current_param.dtimPeriod != operationParam->dtimPeriod) {
-		for (i = 0; i < bss_num; i++) {
-			if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-				continue;
-			}
-			if (wifi_setApDTIMInterval(ApIndex, operationParam->dtimPeriod) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_setApDTIMInterval return error.\n");
-				goto err;
-			}
-			hapd_conf_change = TRUE;
-		}
-	}
-	if (current_param.beaconInterval != operationParam->beaconInterval) {
-		for (i = 0; i < bss_num; i++) {
-			if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-				continue;
-			}
-
-			if (wifi_setRadioBeaconPeriod(ApIndex, operationParam->beaconInterval) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_setRadioBeaconPeriod return error.\n");
-				goto err;
-			}
-			hapd_conf_change = TRUE;
-		}
-	}
-	if (current_param.operationalDataTransmitRates != operationParam->operationalDataTransmitRates) {
-		BitMapToTransmitRates(operationParam->operationalDataTransmitRates, buf, sizeof(buf));
-		for (i = 0; i < bss_num; i++) {
-			if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-				continue;
-			}
-			if (wifi_setRadioBasicDataTransmitRates(ApIndex, buf) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_setRadioBasicDataTransmitRates return error.\n");
-				goto err;
-			}
-			hapd_conf_change = TRUE;
-		}
-	}
-	if (current_param.fragmentationThreshold != operationParam->fragmentationThreshold) {
-		for (i = 0; i < bss_num; i++) {
-			if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-				continue;
-			}
-			if (wifi_setRadioFragmentationThreshold(ApIndex, operationParam->fragmentationThreshold) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_setRadioFragmentationThreshold return error.\n");
-				goto err;
-			}
-			hapd_conf_change = TRUE;
-		}
-	}
-
-	if (current_param.rtsThreshold != operationParam->rtsThreshold) {
-		for (i = 0; i < bss_num; i++) {
-			if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-				continue;
-			}
-			if (wifi_setApRtsThreshold(ApIndex, operationParam->rtsThreshold) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_setApRtsThreshold return error.\n");
-				goto err;
-			}
-			hapd_conf_change = TRUE;
-		}
-	}
-
-	if (current_param.stbcEnable != operationParam->stbcEnable) {
-		if (wifi_setRadioSTBCEnable(index, operationParam->stbcEnable) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioSTBCEnable return error.\n");
-			goto err;
-		}
-		hapd_conf_change = TRUE;
-		drv_dat_change = TRUE;
-	}
-
-	if (current_param.guardInterval != operationParam->guardInterval) {	
-		if (wifi_setGuardInterval(index, operationParam->guardInterval) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setGuardInterval return error.\n");
-			goto err;
-		}
-		hapd_conf_change = TRUE;
-		drv_dat_change = TRUE;
-	}
-	if (current_param.transmitPower != operationParam->transmitPower) {
-		drv_dat_change = TRUE;
-		if (wifi_setRadioTransmitPower(index, operationParam->transmitPower) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioTransmitPower return error.\n");
-			goto err;
-		}
-	}
-	
-	if (current_param.obssCoex != operationParam->obssCoex) {
-		if (wifi_setRadioObssCoexistenceEnable(index, operationParam->obssCoex) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioObssCoexistenceEnable return error.\n");
-			goto err;
-		}
-	}
-	
-	if (current_param.greenFieldEnable != operationParam->greenFieldEnable) {
-		if (wifi_setRadio11nGreenfieldEnable(index, operationParam->greenFieldEnable) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadio11nGreenfieldEnable return error.\n");
-			goto err;
-		}
-	}
-
-	if (current_param.puncturingInfo.punct_bitmap != operationParam->puncturingInfo.punct_bitmap) {
-		if (wifi_setRadioPreamblePuncture(index, operationParam->puncturingInfo.punct_bitmap) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioPreamblePuncture return error.\n");
-			goto err;
-		}
-	}
-
-	if (current_param.countryCode != operationParam->countryCode) {
-		USHORT country_idx;
-		UCHAR country_find = FALSE;
-
-		for (country_idx = 0; country_idx < ARRAY_SIZE(all_country_code); country_idx++) {
-			if (operationParam->countryCode == all_country_code[country_idx].wifi_countrycode) {
-				country_find = TRUE;
-				break;
-			}
-		}
-
-		if (country_find) {
-			if (wifi_setRadioCountryCode(index, all_country_code[country_idx].CountryName) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "wifi_setRadioCountryCode return error.\n");
-				goto err;
-			}
-		} else
-			wifi_debug(DEBUG_ERROR, "the new countrycode: %d is not supported\n", operationParam->countryCode);
-	}
-
-	/* only down/up interface when dat file has been changed,
-	 * if enable is true, then restart the radio.
-	 */
-	multiple_set = false;
-	if (drv_dat_change == TRUE) {
-		wifi_setRadioEnable(index, FALSE);
-		if (operationParam->enable == TRUE) {
-			wifi_setRadioEnable(index, TRUE);
-			eht_mld_config_init();
-			mld_info_display();
-		}
-	} else if (hapd_conf_change == TRUE) {
-		for (i = 0; i < bss_num; i++) {
-			if (array_index_to_vap_index(index, i, &ApIndex) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-				continue;
-			}
-			wifi_quick_reload_ap(ApIndex);
-		}
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-err:
-	multiple_set = false;
-	return RETURN_ERR;
-}
-
-INT wifi_getRadioOperatingParameters(wifi_radio_index_t index, wifi_radio_operationParam_t *operationParam)
-{
-	char band[64] = {0};
-	char buf[256] = {0};
-	char dat_file[128] = {0};
-
-	UINT mode = 0;
-	BOOL enabled = FALSE;
-	int dtimPeriod;
-	UINT beaconInterval;
-	UINT basicDataTransmitRates;
-	UINT operationalDataTransmitRates;
-	wifi_guard_interval_t guardInterval;
-	UINT transmitPower;
-	int res;
-	unsigned long tmp;
-	unsigned long channel = 0;
-	BOOL auto_ch_en = FALSE;
-	wifi_band band_idx;
-	USHORT punct_bitmap;
-	CHAR country_string[64] = {0};
-	USHORT country_idx;
-	UCHAR country_find = FALSE;
-	ULONG ACS_period = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_debug(DEBUG_OFF, "Entering %s index = %d\n", __func__, (int)index);
-
-	memset(operationParam, 0, sizeof(wifi_radio_operationParam_t));
-	res = snprintf(dat_file, sizeof(dat_file), "%s%d.dat", LOGAN_DAT_FILE, index);
-	if (os_snprintf_error(sizeof(dat_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (wifi_getRadioEnable(index, &enabled) != RETURN_OK)
-	{
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioEnable return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->enable = enabled;
-
-	memset(band, 0, sizeof(band));
-	if (wifi_getRadioOperatingFrequencyBand(index, band) != RETURN_OK)
-	{
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingFrequencyBand return error.\n");
-		return RETURN_ERR;
-	}
-
-	if (!strcmp(band, "2.4GHz"))
-		operationParam->band = WIFI_FREQUENCY_2_4_BAND;
-	else if (!strcmp(band, "5GHz"))
-		operationParam->band = WIFI_FREQUENCY_5_BAND;
-	else if (!strcmp(band, "6GHz"))
-		operationParam->band = WIFI_FREQUENCY_6_BAND;
-	else
-	{
-		wifi_debug(DEBUG_ERROR, "cannot decode band for radio index %d ('%s')\n", index, band);
-	}
-
-	if (wifi_getRadioChannel(index, &channel) != RETURN_OK)
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioChannel return error.\n");
-	operationParam->channel = channel;
-	if (operationParam->channel == 0)
-		wifi_debug(DEBUG_ERROR, "operationParam->channel is 0\n");
-
-	if (wifi_getRadioAutoChannelEnable(index, &auto_ch_en) != RETURN_OK)
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioAutoChannelEnable return error.\n");
-	if (auto_ch_en)
-		operationParam->autoChannelEnabled = TRUE;
-	else
-		operationParam->autoChannelEnabled = FALSE;
-
-	if (wifi_getRadioAutoChannelRefreshPeriod(index, &ACS_period) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioAutoChannelRefreshPeriod return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->autoChanRefreshPeriod = ACS_period;
-
-	memset(buf, 0, sizeof(buf));
-	if (wifi_getRadioOperatingChannelBandwidth(index, buf) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioOperatingChannelBandwidth return error.\n");
-		return RETURN_ERR;
-	}
-	if (!strcmp(buf, "20MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_20MHZ;
-	else if (!strcmp(buf, "40MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_40MHZ;
-	else if (!strcmp(buf, "80MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_80MHZ;
-	else if (!strcmp(buf, "160MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_160MHZ;
-	else if (!strcmp(buf, "320MHz")) operationParam->channelWidth = WIFI_CHANNELBANDWIDTH_320MHZ;
-	else
-	{
-		wifi_debug(DEBUG_ERROR, "Unknown channel bandwidth: %s\n", buf);
-		return false;
-	}
-
-	if (wifi_getRadioMode(index, buf, &mode) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioMode return error.\n");
-		return RETURN_ERR;
-	}
-	// Two different definition bit map, so need to check every bit.
-	if (mode & WIFI_MODE_A)
-		operationParam->variant |= WIFI_80211_VARIANT_A;
-	if (mode & WIFI_MODE_B)
-		operationParam->variant |= WIFI_80211_VARIANT_B;
-	if (mode & WIFI_MODE_G)
-		operationParam->variant |= WIFI_80211_VARIANT_G;
-	if (mode & WIFI_MODE_N)
-		operationParam->variant |= WIFI_80211_VARIANT_N;
-	if (mode & WIFI_MODE_AC)
-		operationParam->variant |= WIFI_80211_VARIANT_AC;
-	if (mode & WIFI_MODE_AX)
-		operationParam->variant |= WIFI_80211_VARIANT_AX;
-	if (mode & WIFI_MODE_BE)
-		operationParam->variant |= WIFI_80211_VARIANT_BE;
-
-	if (wifi_getRadioDCSEnable(index, &operationParam->DCSEnabled) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioDCSEnable return error.\n");
-		return RETURN_ERR;
-	}
-	if (wifi_getApDTIMInterval(index, &dtimPeriod) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getApDTIMInterval return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->dtimPeriod = dtimPeriod;
-	if (wifi_getRadioBeaconPeriod(index, &beaconInterval) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioBeaconPeriod return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->beaconInterval = beaconInterval;
-
-	memset(buf, 0, sizeof(buf));
-	if (wifi_getRadioSupportedDataTransmitRates(index, buf) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioSupportedDataTransmitRates return error.\n");
-		return RETURN_ERR;
-	}
-	TransmitRatesToBitMap(buf, &basicDataTransmitRates);
-	operationParam->basicDataTransmitRates = basicDataTransmitRates;
-
-	memset(buf, 0, sizeof(buf));
-	if (wifi_getRadioBasicDataTransmitRates(index, buf) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioBasicDataTransmitRates return error.\n");
-		return RETURN_ERR;
-	}
-	TransmitRatesToBitMap(buf, &operationalDataTransmitRates);
-	operationParam->operationalDataTransmitRates = operationalDataTransmitRates;
-
-	memset(buf, 0, sizeof(buf));
-	wifi_datfileRead(dat_file, "FragThreshold", buf, sizeof(buf));
-	if (hal_strtoul(buf, 10, &tmp) < 0) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-	}
-	operationParam->fragmentationThreshold = tmp;
-
-	if (wifi_getGuardInterval(index, &guardInterval) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getGuardInterval return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->guardInterval = guardInterval;
-
-	if (wifi_getRadioPercentageTransmitPower(index, (ULONG *)&transmitPower) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioPercentageTransmitPower return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->transmitPower = transmitPower;
-
-	memset(buf, 0, sizeof(buf));
-	wifi_datfileRead(dat_file, "RTSThreshold", buf, sizeof(buf));
-	if (strcmp(buf, "-1") == 0) {
-		operationParam->rtsThreshold = (UINT)-1;	// maxuimum unsigned integer value
-		operationParam->ctsProtection = FALSE;
-	} else {
-		if (hal_strtoul(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-		}
-		operationParam->rtsThreshold = tmp;
-		operationParam->ctsProtection = TRUE;
-	}
-
-	memset(buf, 0, sizeof(buf));
-	wifi_datfileRead(dat_file, "HT_BSSCoexistence", buf, sizeof(buf));
-	if (strcmp(buf, "0") == 0)
-		operationParam->obssCoex = FALSE;
-	else
-		operationParam->obssCoex = TRUE;
-
-	band_idx = radio_index_to_band(index);
-	memset(buf, 0, sizeof(buf));
-	if (band_idx == band_2_4)
-		wifi_datfileRead(dat_file, "HT_STBC", buf, sizeof(buf));
-	else
-		wifi_datfileRead(dat_file, "VHT_STBC", buf, sizeof(buf));
-
-	if (strncmp(buf, "1", 1) == 0)
-		operationParam->stbcEnable = TRUE;
-	else
-		operationParam->stbcEnable = FALSE;
-
-	if (wifi_getRadio11nGreenfieldEnable(index, &operationParam->greenFieldEnable) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadio11nGreenfieldEnable return error.\n");
-		return RETURN_ERR;
-	}
-
-	if (wifi_getRadioPreamblePuncture(index, &punct_bitmap) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioPreamblePuncture return error.\n");
-		return RETURN_ERR;
-	}
-	operationParam->puncturingInfo.punct_bitmap = punct_bitmap;
-
-	// Below value is hardcoded
-
-	operationParam->numSecondaryChannels = 0;
-	for (int i = 0; i < MAXNUMSECONDARYCHANNELS; i++) {
-		operationParam->channelSecondary[i] = 0;
-	}
-	operationParam->csa_beacon_count = 15;
-
-	/* get current Country code*/
-	if (wifi_getRadioCountryCode(index, country_string) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_getRadioCountryCode return error.\n");
-		return RETURN_ERR;
-	}
-
-	for (country_idx = 0; country_idx < ARRAY_SIZE(all_country_code); country_idx++) {
-		if (!strcmp(country_string, all_country_code[country_idx].CountryName)) {
-			country_find = TRUE;
-			break;
-		}
-	}
-
-	if (country_find)
-		operationParam->countryCode = all_country_code[country_idx].wifi_countrycode;
-	else {
-		wifi_debug(DEBUG_ERROR, "current Country Code:%s not supported, use US as default\n", country_string);
-		operationParam->countryCode = wifi_countrycode_US;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-static BOOL is_main_vap_index(int vap_index)
-{
-	int radio, main_vap_index;
-
-	for (radio = 0; radio < get_runtime_max_radio(); radio++) {
-		if (array_index_to_vap_index(radio, 0, &main_vap_index) == RETURN_OK) {
-			if (vap_index == main_vap_index)
-				return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-static int array_index_to_vap_index(UINT radioIndex, int arrayIndex, int *vap_index)
-{
-	if (radioIndex > 2 || arrayIndex < 0 || arrayIndex >= LOGAN_MAX_NUM_VAP_PER_RADIO)
-		return RETURN_ERR;
-
-	if (radioIndex < 2)
-		*vap_index = arrayIndex * 2 + radioIndex;
-	else if (radioIndex == 2)
-		*vap_index = (2 * LOGAN_MAX_NUM_VAP_PER_RADIO) + arrayIndex;
-
-	return RETURN_OK;
-}
-
-/*
- * 2.4G vap index: 0 2 4 6 8 10 12 14 ... (2*bss_idx)
- * 5G vap index:   1 3 5 7 9 11 13 15 ... (2*bss_idx + 1)
- * 6G vap index:   16 17 18 19 20 21 22 23 ... (2*LOGAN_MAX_NUM_VAP_PER_RADIO + bss_idx)
- */
-
-//static int vap_index_to_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
-static int vap_index_to_radio_array_index(int vapIndex, int *radioIndex, int *arrayIndex)
-{
-	if (vapIndex >= MAX_APS || vapIndex < 0)
-		return RETURN_ERR;
-
-	if (vapIndex >= 0 && vapIndex < (2 * LOGAN_MAX_NUM_VAP_PER_RADIO)) {
-		*radioIndex = vapIndex % 2;
-		*arrayIndex = vapIndex / 2;
-	} else if (vapIndex >= (2 * LOGAN_MAX_NUM_VAP_PER_RADIO) && vapIndex < (3 * LOGAN_MAX_NUM_VAP_PER_RADIO)) {
-		*radioIndex = 2;
-		*arrayIndex = vapIndex - (2 * LOGAN_MAX_NUM_VAP_PER_RADIO);
-	}
-
-	return RETURN_OK;
-}
-
-
-wifi_bitrate_t beaconRate_string_to_enum(char *beaconRate) {
-	if (strncmp(beaconRate, "1Mbps", 5) == 0)
-		return WIFI_BITRATE_1MBPS;
-	else if (strncmp(beaconRate, "2Mbps", 5) == 0)
-		return WIFI_BITRATE_2MBPS;
-	else if (strncmp(beaconRate, "5.5Mbps", 7) == 0)
-		return WIFI_BITRATE_5_5MBPS;
-	else if (strncmp(beaconRate, "6Mbps", 5) == 0)
-		return WIFI_BITRATE_6MBPS;
-	else if (strncmp(beaconRate, "9Mbps", 5) == 0)
-		return WIFI_BITRATE_9MBPS;
-	else if (strncmp(beaconRate, "11Mbps", 6) == 0)
-		return WIFI_BITRATE_11MBPS;
-	else if (strncmp(beaconRate, "12Mbps", 6) == 0)
-		return WIFI_BITRATE_12MBPS;
-	else if (strncmp(beaconRate, "18Mbps", 6) == 0)
-		return WIFI_BITRATE_18MBPS;
-	else if (strncmp(beaconRate, "24Mbps", 6) == 0)
-		return WIFI_BITRATE_24MBPS;
-	else if (strncmp(beaconRate, "36Mbps", 6) == 0)
-		return WIFI_BITRATE_36MBPS;
-	else if (strncmp(beaconRate, "48Mbps", 6) == 0)
-		return WIFI_BITRATE_48MBPS;
-	else if (strncmp(beaconRate, "54Mbps", 6) == 0)
-		return WIFI_BITRATE_54MBPS;
-	return WIFI_BITRATE_DEFAULT;
-}
-
-struct beacon_rate_2_string {
-	wifi_bitrate_t beacon;
-	char beacon_str[8];
-};
-
-struct beacon_rate_2_string br2str[12] = {
-	{WIFI_BITRATE_1MBPS, "1Mbps"},
-	{WIFI_BITRATE_2MBPS, "2Mbps"},
-	{WIFI_BITRATE_5_5MBPS, "5.5Mbps"},
-	{WIFI_BITRATE_6MBPS, "6Mbps"},
-	{WIFI_BITRATE_9MBPS, "9Mbps"},
-	{WIFI_BITRATE_11MBPS, "11Mbps"},
-	{WIFI_BITRATE_12MBPS, "12Mbps"},
-	{WIFI_BITRATE_18MBPS, "18Mbps"},
-	{WIFI_BITRATE_24MBPS, "24Mbps"},
-	{WIFI_BITRATE_36MBPS, "36Mbps"},
-	{WIFI_BITRATE_48MBPS, "48Mbps"},
-	{WIFI_BITRATE_54MBPS, "54Mbps"}
-};
-
-INT beaconRate_enum_to_string(wifi_bitrate_t beacon, char *beacon_str, unsigned long str_size)
-{
-	int i;
-	unsigned long len;
-
-	for (i = 0; i < (sizeof(br2str)/sizeof(br2str[0])); i++) {
-		if (beacon == br2str[i].beacon) {
-			len = strlen(br2str[i].beacon_str);
-			if (len >= str_size)
-				return RETURN_ERR;
-			memcpy(beacon_str, br2str[i].beacon_str, len);
-			beacon_str[len] = '\0';
-			break;
-		}
-	}
-	return RETURN_OK;
-}
-
-INT wifi_getRadioVapInfoMap(wifi_radio_index_t index, wifi_vap_info_map_t *map)
-{
-	INT mode = 0;
-	INT ret = -1;
-	UINT output = 0;
-	int i = 0;
-	int vap_index = 0;
-	BOOL enabled = FALSE;
-	char buf[MAX_SSID_NAME_LEN] = {0};
-	wifi_vap_security_t security = {0};
-	int res = RETURN_OK;
-	wifi_vap_info_t *vap;
-	wifi_mld_info_ap_t *mld_info;
-	unsigned char mld_index;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_debug(DEBUG_OFF, "Entering %s index = %d\n", __func__, (int)index);
-
-	memset((void *)map, 0, sizeof(*map));
-	ret = wifi_BandProfileRead(0, index, "BssidNum", buf, sizeof(buf), "0");
-	if (ret != 0) {
-		wifi_debug(DEBUG_ERROR, "wifi_BandProfileRead BssidNum failed\n");
-		return RETURN_ERR;
-	}
-
-	map->num_vaps = atoi(buf);
-	if (map->num_vaps <= 0)  {
-		wifi_debug(DEBUG_ERROR, "invalid BssidNum %s\n", buf);
-		return RETURN_ERR;
-	}
-	if (map->num_vaps > LOGAN_MAX_NUM_VAP_PER_RADIO) {
-		wifi_debug(DEBUG_ERROR, "bss_num is larger than %d, use %d\n", LOGAN_MAX_NUM_VAP_PER_RADIO, LOGAN_MAX_NUM_VAP_PER_RADIO);
-		map->num_vaps = LOGAN_MAX_NUM_VAP_PER_RADIO;
-	}
-
-	for (i = 0; i < map->num_vaps; i++)
-	{
-		map->vap_array[i].radio_index = index;
-
-		if (array_index_to_vap_index(index, i, &vap_index) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid index %d, i %d\n", index, i);
-			continue;
-		}
-
-		map->vap_array[i].vap_index = vap_index;
-		map->vap_array[i].u.bss_info.enabled = getVapEnableConfig(vap_index);
-		
-		memset(buf, 0, sizeof(buf));
-		ret = wifi_getApName(vap_index, buf);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR,"wifi_getApName return error\n");
-		} else {
-			ret = snprintf(map->vap_array[i].vap_name, sizeof(map->vap_array[i].vap_name), "%s", buf);
-			if (os_snprintf_error(sizeof(map->vap_array[i].vap_name), ret)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			}
-		}
-
-		memset(buf, 0, sizeof(buf));
-		ret = wifi_getSSIDName(vap_index, buf);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_getSSIDName return error\n");
-		} else {
-			ret = snprintf(map->vap_array[i].u.bss_info.ssid, sizeof(map->vap_array[i].u.bss_info.ssid), "%s", buf);
-			if (os_snprintf_error(sizeof(map->vap_array[i].u.bss_info.ssid), ret)) {
-				wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			}
-		}
-
-		ret = wifi_getApSsidAdvertisementEnable(vap_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR,"wifi_getApSsidAdvertisementEnable return error\n");
-		}
-		map->vap_array[i].u.bss_info.showSsid = enabled;
-
-		ret = wifi_getApMaxAssociatedDevices(vap_index, &output);
-		if (ret != RETURN_OK) {
-			output = 30;
-			wifi_debug(DEBUG_ERROR, "wifi_getApMaxAssociatedDevices return error\n");
-		}
-		map->vap_array[i].u.bss_info.bssMaxSta = output;
-
-		ret = wifi_getBSSTransitionActivation(vap_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR, "wifi_getBSSTransitionActivation return error\n");
-		}
-		map->vap_array[i].u.bss_info.bssTransitionActivated = enabled;
-
-		ret = wifi_getNeighborReportActivation(vap_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR, "wifi_getNeighborReportActivation return error\n");
-		}
-		map->vap_array[i].u.bss_info.nbrReportActivated = enabled;
-
-		ret = wifi_getApSecurity(vap_index, &security);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_getApSecurity return error\n");
-		} else
-			map->vap_array[i].u.bss_info.security = security;
-
-		ret = wifi_getApMacAddressControlMode(vap_index, &mode);
-		if (ret != RETURN_OK) {
-			mode = 0;
-			wifi_debug(DEBUG_ERROR, "wifi_getApMacAddressControlMode return error\n");
-		}
-
-		if (mode == 0)
-			map->vap_array[i].u.bss_info.mac_filter_enable = FALSE;
-		else
-			map->vap_array[i].u.bss_info.mac_filter_enable = TRUE;
-		if (mode == 1)
-			map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_white_list;
-		else if (mode == 2)
-			map->vap_array[i].u.bss_info.mac_filter_mode = wifi_mac_filter_mode_black_list;
-		
-		ret = wifi_getApWmmEnable(vap_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR, "wifi_getApWmmEnable return error\n");
-		}
-		map->vap_array[i].u.bss_info.wmm_enabled = enabled;
-
-		ret = wifi_getApUAPSDCapability(vap_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR, "wifi_getApUAPSDCapability return error\n");
-		} 
-		map->vap_array[i].u.bss_info.UAPSDEnabled = enabled;
-
-		memset(buf, 0, sizeof(buf));
-		ret = wifi_getApBeaconRate(map->vap_array[i].radio_index, buf);
-		if (ret != RETURN_OK) {
-			map->vap_array[i].u.bss_info.beaconRate = WIFI_BITRATE_1MBPS;
-			wifi_debug(DEBUG_ERROR, "wifi_getApBeaconRate return error\n");
-		} else 
-			map->vap_array[i].u.bss_info.beaconRate = beaconRate_string_to_enum(buf);
-
-		memset(buf, 0, sizeof(buf));
-		ret = wifi_getBaseBSSID(vap_index, buf);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_getBaseBSSID return error\n");
-		} else {
-			if (hwaddr_aton2(buf, map->vap_array[i].u.bss_info.bssid) < 0) {
-				wifi_debug(DEBUG_ERROR, "hwaddr_aton2 fail\n");
-			}
-		}
-		ret = wifi_getRadioIGMPSnoopingEnable(map->vap_array[i].radio_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR, "%s: wifi_getRadioIGMPSnoopingEnable\n", __func__);
-		}
-		map->vap_array[i].u.bss_info.mcast2ucast = enabled;
-
-		ret = wifi_getApIsolationEnable(vap_index, &enabled);
-		if (ret != RETURN_OK) {
-			enabled = FALSE;
-			wifi_debug(DEBUG_ERROR, "wifi_getApIsolationEnable return error\n");
-		}
-
-		map->vap_array[i].u.bss_info.isolation = enabled;
-
-		wifi_getApWpsEnable(vap_index, &enabled);
-		if (enabled) {
-			map->vap_array[i].u.bss_info.wps.enable = enabled;
-		}
-	}
-
-	for (i = 0; i < map->num_vaps; i++)
-	{
-		map->vap_array[i].radio_index = index;
-		vap = &(map->vap_array[i]);
-
-		mld_info = &(vap->u.bss_info.mld_info);
-		memset(mld_info, 0, sizeof(*mld_info));
-
-		mld_index = mld_ap_test_all_mlds(vap->vap_index);
-		if (mld_index) {
-			memcpy(mld_info->common_info.mld_addr, mld_config.mld[mld_index].mld_mac, 6);
-			mld_info->common_info.mld_enable = TRUE;
-			mld_info->common_info.mld_id = mld_index;
-		}
-		wifi_debug(DEBUG_OFF,
-				"vap_index[%d], mld_enable=%d, mld_id[%d]\n",
-				vap->vap_index, mld_info->common_info.mld_enable, mld_info->common_info.mld_id);
-	}
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return res;
-}
-
-void checkVapStatus(int apIndex, BOOL *enable)
-{
-	char if_name[16] = {0};
-	char buf[128] = {0};
-	int res;
-
-	*enable = FALSE;
-	if (wifi_GetInterfaceName(apIndex, if_name) != RETURN_OK)
-		return;
-
-	res = _syscmd_secure(buf, sizeof(buf), "cat %s | grep ^%s=1", VAP_STATUS_FILE, if_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-	}
-
-	if (strlen(buf) > 0)
-		*enable = TRUE;
-	return;
-}
-
-int hostapd_manage_bss(INT apIndex, BOOL enable)
-{
-	char interface_name[16] = {0};
-	char config_file[MAX_SUB_CMD_SIZE] = {0};
-
-	char buf[MAX_BUF_SIZE] = {0};
-	BOOL status = FALSE;
-	int phyId = 0;
-	int radioIndex, bss_idx;
-	int res;
-
-	wifi_getApEnable(apIndex, &status);
-
-	if (enable == status)
-		return RETURN_OK;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (enable == TRUE) {
-		if (vap_index_to_radio_array_index(apIndex, &radioIndex, &bss_idx) != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "invalid apIndex[%d]\n", apIndex);
-			return RETURN_ERR;
-		}
-		phyId = radio_index_to_phy(radioIndex);
-		res = snprintf(config_file, MAX_BUF_SIZE, "%s%d.conf", CONFIG_PREFIX, apIndex);
-		if (os_snprintf_error(MAX_CMD_SIZE, res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		wifi_debug(DEBUG_OFF, "raw ADD bss_config config_file=%s\n", config_file);
-
-		res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw ADD bss_config=phy%d:%s", phyId, config_file);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-		}
-
-	} else {
-		wifi_debug(DEBUG_ERROR, "global raw REMOVE %s\n", interface_name);
-		res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i global raw REMOVE %s", interface_name);
-		if (res) {
-			wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-		}
-	}
-	res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^%s=/!p' -e '$a%s=%d' %s",
-				interface_name, interface_name, enable, VAP_STATUS_FILE);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-	}
-	//Wait for wifi up/down to apply
-	return RETURN_OK;
-}
-
-int hostapd_raw_add_bss(int apIndex)
-{
-	return hostapd_manage_bss(apIndex, TRUE);
-}
-
-int hostapd_raw_remove_bss(int apIndex)
-{
-	return hostapd_manage_bss(apIndex, FALSE);
-}
-
-int hostapd_raw_restart_bss(int apIndex)
-{
-	int ret = 0;
-
-	ret = hostapd_raw_remove_bss(apIndex);
-	if(ret != RETURN_OK)
-		return RETURN_ERR;
-
-	ret = hostapd_raw_add_bss(apIndex);
-	if(ret != RETURN_OK)
-		return RETURN_ERR;
-
-	return RETURN_OK;
-}
-
-static INT getVapBridge(int ap_index, char *bridge_name_buf, int buf_size)
-{
-	int res;
-	char config_file[128] = {0};
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (wifi_hostapdRead(config_file, "bridge", bridge_name_buf, buf_size) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "get bridge fail from %s\n", config_file);
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-static INT setVapBridge(int ap_index, char *bridge_name)
-{
-	int res;
-	char config_file[128] = {0};
-	struct params param = {.name = "bridge"};
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_debug(DEBUG_OFF, "set bridge to %s in %s\n", bridge_name, config_file);
-
-	param.name = "bridge";
-	param.value = bridge_name;
-	if (wifi_hostapdWrite(config_file, &param, 1) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "set bridge fail to %s\n", config_file);
-		return RETURN_ERR;
-	}
-
-	return RETURN_OK;
-}
-
-static int wifi_get_bridge_name(char *vap_name, char *bridge_name, unsigned int bridge_buf_size)
-{
-	int ret = RETURN_ERR;
-	char brname[64] = {0}, brifnames[64] = {0};
-	char brname_str[64] = {0}, brifnames_str[64] = {0};
-	int res;
-
-	for (int i = 0; i <= MAX_NUM_VAP_PER_RADIO; i++) {
-		memset(brname_str, 0, sizeof(brname_str));
-		memset(brifnames_str, 0, sizeof(brifnames_str));		
-       /**  Read bridge interface names
-        * Ex:
-        * Lan_ifname=brlan0 Lan_ifnames=ra0;rai0;rax0
-        * Lan1_ifname=brlan1 Lan1_ifnames=ra1;rai1;rax1
-        */
-		res = snprintf(brname, sizeof(brname), "Lan%d_ifname", i);
-		if (os_snprintf_error(sizeof(brname), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		res = snprintf(brifnames, sizeof(brifnames), "Lan%d_ifnames", i);
-		if (os_snprintf_error(sizeof(brifnames), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			return RETURN_ERR;
-		}
-
-		// read bridge name
-		if(get_value(WIFI_BRLAN_CONFIG, brname, brname_str, sizeof(brname_str)) < 0)
-			continue;
-
-		// read bridge ifnames
-		if(get_value(WIFI_BRLAN_CONFIG, brifnames, brifnames_str, sizeof(brifnames_str)) < 0)
-			continue;
-
-		if (strlen(brifnames_str) && strstr(brifnames_str, vap_name)){
-			if(strlen(brname_str)) {
-				strncpy(bridge_name, brname_str, bridge_buf_size - 1);
-				bridge_name[bridge_buf_size - 1] = '\0';
-			}
-			ret = RETURN_OK;
-			break;
-		}
-	}
-	return ret;
-}
-
-INT wifi_createVAP(wifi_radio_index_t index, wifi_vap_info_map_t *map)
-{
-	unsigned int i;
-	wifi_vap_info_t *vap_info = NULL;
-	int acl_mode;
-	int ret = 0;
-	char buf[256] = {0};
-	char config_file[64] = {0};
-	BOOL apEnable;
-	int band_idx;
-	int res;
-	wifi_mld_common_info_t *mld_info;
-	unsigned char mld_index;
-	unsigned char ap_index_array[MAX_APS] = {0};
-	unsigned char ap_array_num;
-	char interface_name[IF_NAME_SIZE] = {0};
-	char bridge_name[WIFI_BRIDGE_NAME_LEN] = {0};
-	unsigned char hostapd_if_restart = 0, hostapd_allif_restart = 0;
-	struct params params[1];
-	BOOL enableWps = FALSE;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	wifi_debug(DEBUG_OFF, "Entering %s radio[%d], map->num_vaps = %d\n", __func__, (int)index, map->num_vaps);
-	for (i = 0; i < map->num_vaps; i++) {
-		hostapd_if_restart = 0;
-		multiple_set = TRUE;
-
-		vap_info = &map->vap_array[i];
-
-		setVapEnableConfig(vap_info->vap_index, vap_info->u.bss_info.enabled);
-
-		if (vap_info->u.bss_info.enabled == FALSE) {
-			wifi_getApEnable(vap_info->vap_index, &apEnable);
-            if (apEnable) {
-				wifi_setApEnable(vap_info->vap_index, FALSE);
-            }
-			continue;
-		}
-
-		wifi_debug(DEBUG_OFF, "\nCreate VAP for vap_info->vap_index=%d\n", vap_info->vap_index);
-
-		band_idx = radio_index_to_band(index);
-		res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, vap_info->vap_index);
-		if (os_snprintf_error(sizeof(config_file), res)) {
-			wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-			goto err;
-		}
-
-		/*check if hostapd conf file exist or not, if not exist, create an new one*/
-		if (access(config_file, F_OK) != 0) {
-			if(band_idx >= 0 && band_idx < sizeof(wifi_band_str)/sizeof(wifi_band_str[0])) {
-				wifi_debug(DEBUG_ERROR, "\n%s not exist, create an new one\n", config_file);
-				res = _syscmd_secure(buf, sizeof(buf), "cp /etc/hostapd-%s.conf %s", wifi_band_str[band_idx], config_file);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-				}
-			}
-		}
-
-		params[0].name = "interface";
-		params[0].value = vap_info->vap_name;
-		wifi_hostapdWrite(config_file, params, 1);
-
-		ret = wifi_setSSIDName(vap_info->vap_index, vap_info->u.bss_info.ssid);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR,"wifi_setSSIDName return error\n");
-		}
-
-		ret = wifi_setApSsidAdvertisementEnable(vap_info->vap_index, vap_info->u.bss_info.showSsid);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApSsidAdvertisementEnable return error\n");
-		}
-
-		ret = wifi_setApMaxAssociatedDevices(vap_info->vap_index, vap_info->u.bss_info.bssMaxSta);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApMaxAssociatedDevices return error\n");
-		}
-
-		ret = wifi_setBSSTransitionActivation(vap_info->vap_index, vap_info->u.bss_info.bssTransitionActivated);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setBSSTransitionActivation return error\n");
-		}
-
-		ret = wifi_setNeighborReportActivation(vap_info->vap_index, vap_info->u.bss_info.nbrReportActivated);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setNeighborReportActivation return error\n");
-		}
-
-		ret = wifi_setApWmmUapsdEnable(vap_info->vap_index, vap_info->u.bss_info.UAPSDEnabled);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApWmmUapsdEnable return error\n");
-		}
-
-		memset(buf, 0, sizeof(buf));
-		beaconRate_enum_to_string(vap_info->u.bss_info.beaconRate, buf, sizeof(buf));
-		ret = wifi_setApBeaconRate(vap_info->radio_index, buf);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApBeaconRate return error\n");
-		}
-
-		ret = wifi_setApSecurity(vap_info->vap_index, &vap_info->u.bss_info.security);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApSecurity return error\n");
-		}
-
-		wifi_getApWpsEnable(vap_info->vap_index, &enableWps);
-		if (enableWps != vap_info->u.bss_info.wps.enable) {
-			if (wifi_setApWpsEnable(vap_info->vap_index, vap_info->u.bss_info.wps.enable) == RETURN_OK) {
-				if (!is_main_vap_index(vap_info->vap_index))
-					hostapd_if_restart = 1;
-				else
-					hostapd_allif_restart = 1;
-			} else
-				wifi_debug(DEBUG_ERROR, "wifi_setApWpsEnable return error\n");
-		}
-
-		if (vap_info->u.bss_info.enabled == TRUE) {
-			wifi_getApEnable(vap_info->vap_index, &apEnable);
-			if (!apEnable)
-				wifi_setApEnable(vap_info->vap_index, TRUE);
-		}
-
-		memset(buf, 0, sizeof(buf));
-		/*get bridge name from /etc/wireless/hal/wifi_config*/
-		if (wifi_get_bridge_name(vap_info->vap_name, buf, sizeof(buf)) != RETURN_OK)
-			strncpy(buf, DEFAULT_BRIDGE_NAME, sizeof(buf) - 1);
-		/*update bridge name to hostapd.conf from /etc/wireless/hal/wifi_config by requirement from customer*/
-		if (getVapBridge(vap_info->vap_index, bridge_name, sizeof(bridge_name)) == RETURN_OK) {
-			if ((strlen(buf) > 0) &&
-				strncmp(bridge_name, buf, strlen(bridge_name))) {
-					/*if not main interace, just do hostapd if restart for it*/
-					if (!is_main_vap_index(vap_info->vap_index))
-						hostapd_if_restart = 1;
-					else
-						hostapd_allif_restart = 1;
-					setVapBridge(vap_info->vap_index, buf);
-			}
-		}
-
-		multiple_set = FALSE;
-		if (!hostapd_allif_restart) {
-			if (hostapd_if_restart)
-				hostapd_raw_restart_bss(vap_info->vap_index);
-			else
-				wifi_quick_reload_ap(vap_info->vap_index);
-		}
-	}
-
-	/*restart all interface of this radio if needed*/
-	if (hostapd_allif_restart) {
-		wifi_setRadioEnable(index, FALSE);
-		wifi_setRadioEnable(index, TRUE);
-	}
-
-	/*do quick setting for wifi driver*/
-	for (i = 0; i < map->num_vaps; i++) {
-		vap_info = &map->vap_array[i];
-		if (vap_info->u.bss_info.enabled == FALSE)
-			continue;
-
-		if (vap_info->u.bss_info.mac_filter_enable == false){
-			acl_mode = 0;
-		}else {
-			if (vap_info->u.bss_info.mac_filter_mode == wifi_mac_filter_mode_black_list){
-				acl_mode = 2;
-				res = _syscmd_secure(buf, sizeof(buf), "touch %s%d", DENY_PREFIX, vap_info->vap_index);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-				}
-			}else{
-				acl_mode = 1;
-			}
-		}
-
-		// If config use hostapd_cli to set, we calling these type of functions after enable the ap.
-		ret = wifi_setRadioIGMPSnoopingEnable(vap_info->radio_index, vap_info->u.bss_info.mcast2ucast);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setRadioIGMPSnoopingEnable\n");
-		}
-
-		ret = wifi_setApMacAddressControlMode(vap_info->vap_index, acl_mode);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApMacAddressControlMode return error\n");
-		}
-
-		ret = wifi_setApWmmEnable(vap_info->vap_index, vap_info->u.bss_info.wmm_enabled);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApWmmEnable return error\n");
-		}
-
-		ret = wifi_setApIsolationEnable(vap_info->vap_index, vap_info->u.bss_info.isolation);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApIsolationEnable return error\n");
-		}
-		ret = wifi_setApManagementFramePowerControl(vap_info->vap_index, vap_info->u.bss_info.mgmtPowerControl);
-		if (ret != RETURN_OK) {
-			wifi_debug(DEBUG_ERROR, "wifi_setApManagementFramePowerControl return error\n");
-		}
-		// TODO mgmtPowerControl, interworking, wps
-	}
-
-
-	/*process mlo operation*/
-	for (i = 0; i < map->num_vaps; i++) {
-		vap_info = &map->vap_array[i];
-		mld_info = &vap_info->u.bss_info.mld_info.common_info;
-
-		wifi_debug(DEBUG_INFO, "process mlo operation\n");
-		if (!mld_info->mld_enable) {
-			wifi_debug(DEBUG_ERROR, "disable mlo on vap[%d], vap->enabled=%d\n",
-				(int)vap_info->vap_index, vap_info->u.bss_info.enabled);
-			mld_index = mld_ap_test_all_mlds((int)vap_info->vap_index);
-			if (mld_index) {
-				wifi_debug(DEBUG_ERROR, "mlo disabled, remove ap(%d) from mld group(%d)\n",
-					(int)vap_info->vap_index, (int)mld_index);
-				if (wifi_eht_remove_from_ap_mld(mld_index, vap_info->vap_index) != RETURN_OK) {
-					wifi_debug(DEBUG_ERROR, "fail to remove ap(%d) from mld(%d)\n",
-						(int)vap_info->vap_index, (int)mld_index);
-					continue;
-				}
-
-				if (wifi_GetInterfaceName(vap_info->vap_index, interface_name) == RETURN_OK &&
-					wifi_getApEnable(vap_info->vap_index, &apEnable) == RETURN_OK) {
-					/*if ap is enabled, bring it down and up to make it init single link mld*/
-					if (apEnable) {
-						res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s down", interface_name);
-						if (res) {
-							wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-						}
-						res = _syscmd_secure(buf, sizeof(buf), "ifconfig %s up", interface_name);
-						if (res) {
-							wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-						}
-					}
-				}
-
-				if (wifi_eht_get_ap_from_mld(mld_index, ap_index_array, &ap_array_num) != RETURN_OK) {
-					wifi_debug(DEBUG_ERROR,
-						"fail to get all aps from mld(%d).\n", mld_index);
-					continue;
-				}
-
-				if (ap_array_num == 0) {
-					wifi_debug(DEBUG_ERROR,
-						"there's no affiliated ap in mld(%d), destroy it.\n", mld_index);
-					wifi_eht_destroy_ap_mld(mld_index);
-				}
-			}
-		} else {
-			if (mld_info->mld_id == 0 || mld_info->mld_id > MAX_ML_MLD_CNT) {
-				wifi_debug(DEBUG_ERROR, "invalid mld_id %d, ignore it.\n",
-					(int)mld_info->mld_id);
-				continue;
-			}
-
-			if (!vap_info->u.bss_info.enabled) {
-				wifi_debug(DEBUG_ERROR, "vap %d is disabled, not do mlo process.\n",
-					(int)vap_info->vap_index);
-				continue;
-			}
-			
-			if (!mld_test(mld_info->mld_id)) {
-				if (wifi_eht_create_ap_mld(mld_info->mld_id, mld_info->mld_addr) != RETURN_OK) {
-					wifi_debug(DEBUG_ERROR,
-						"fail to create ap mld(%d)\n", mld_info->mld_id);
-					continue;
-				}
-			} else {
-				if(mld_ap_test(&(mld_config.mld[mld_info->mld_id]), vap_info->vap_index)) {
-					wifi_debug(DEBUG_ERROR,
-						"current vap(%d) is already the affiliated ap of mld(%d)\n",
-						vap_info->vap_index, mld_info->mld_id);
-					continue;
-				}
-			}
-			mld_index = mld_ap_test_all_mlds(vap_info->vap_index);
-
-			if (mld_index != 0) {
-				/*transfer*/
-				wifi_eht_mld_ap_transfer(mld_index, mld_info->mld_id, vap_info->vap_index);
-
-				if (wifi_eht_get_ap_from_mld(mld_index, ap_index_array, &ap_array_num) != RETURN_OK) {
-					wifi_debug(DEBUG_ERROR,
-						"fail to get all aps from mld(%d), destroy it.\n", mld_index);
-					continue;
-				}
-				if (ap_array_num == 0) {
-					wifi_debug(DEBUG_ERROR,
-						"there's no affiliated ap in mld(%d), destroy it.\n", mld_index);
-					wifi_eht_destroy_ap_mld(mld_index);
-				}
-			} else {
-				/*join*/
-				wifi_eht_add_to_ap_mld(mld_info->mld_id, vap_info->vap_index);
-			}
-		}
-	}
-	mld_info_display();
-	wifi_eht_config_sync2_dat_by_radio(index);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-err:
-	multiple_set = FALSE;
-	return RETURN_ERR;
-}
-
-int parse_channel_list_int_arr(char *pchannels, wifi_channels_list_t* chlistptr)
-{
-	char *token, *next;
-	const char s[2] = ",";
-	int count =0;
-
-	/* get the first token */
-	token = strtok_r(pchannels, s, &next);
-
-	/* walk through other tokens */
-	while( token != NULL && count < MAX_CHANNELS) {
-		chlistptr->channels_list[count++] = atoi(token);
-		token = strtok_r(NULL, s, &next);
-	}
-
-	return count;
-}
-
-static int getRadioCapabilities(int radioIndex, wifi_radio_capabilities_t *rcap)
-{
-	INT status;
-	wifi_channels_list_t *chlistp;
-	CHAR output_string[64];
-	CHAR pchannels[512];
-	CHAR interface_name[16] = {0};
-	wifi_band band;
-	int res;
-	int main_vap_idx;
-	USHORT country_idx;
-	UCHAR country_find = FALSE;
-
-	if(rcap == NULL)
-	{
-		return RETURN_ERR;
-	}
-
-	rcap->numSupportedFreqBand = 1;
-	band = radio_index_to_band(radioIndex);
-
-	if (band == band_2_4)
-		rcap->band[0] = WIFI_FREQUENCY_2_4_BAND;
-	else if (band == band_5)
-		rcap->band[0] = WIFI_FREQUENCY_5_BAND;
-	else if (band == band_6)
-		rcap->band[0] = WIFI_FREQUENCY_6_BAND;
-
-	chlistp = &(rcap->channel_list[0]);
-	memset(pchannels, 0, sizeof(pchannels));
-
-	/* get radio channels cabability */
-	status = wifi_getRadioCapChannels(radioIndex, pchannels);
-	{
-		 wifi_debug(DEBUG_OFF, "[wifi_hal dbg] : error_ret[%d] radio_index[%d] output[%s]\n", 
-		 	status, radioIndex, pchannels);
-	}
-	/* Number of channels and list*/
-	chlistp->num_channels = parse_channel_list_int_arr(pchannels, chlistp);
-
-	/* autoChannelSupported */
-	/* always ON with wifi_getRadioAutoChannelSupported */
-	rcap->autoChannelSupported = TRUE;
-
-	/* DCSSupported */
-	/* always ON with wifi_getRadioDCSSupported */
-	rcap->DCSSupported = TRUE;
-
-	/* zeroDFSSupported - TBD */
-	rcap->zeroDFSSupported = FALSE;
-
-	/* Supported Country List*/
-	memset(output_string, 0, sizeof(output_string));
-	status = wifi_getRadioCountryCode(radioIndex, output_string);
-	if (status != 0) {
-		wifi_debug(DEBUG_ERROR, "[wifi_hal dbg] : error_ret[%d] radio_index[%d] output[%s]\n",
-			status, radioIndex, output_string);
-		return RETURN_ERR;
-	} else
-		wifi_debug(DEBUG_OFF, "[wifi_hal dbg] : output [%s]\n", output_string);
-
-	rcap->numcountrySupported = ARRAY_SIZE(all_country_code);
-
-	for (country_idx = 0; (country_idx < rcap->numcountrySupported) && (rcap->numcountrySupported <= wifi_countrycode_max); country_idx++)
-		rcap->countrySupported[country_idx] = all_country_code[country_idx].wifi_countrycode;
-
-	for (country_idx = 0; country_idx < rcap->numcountrySupported; country_idx++) {
-		if (!strcmp(output_string, all_country_code[country_idx].CountryName)) {
-			country_find = TRUE;
-			break;
-		}
-	}
-
-	if (country_find && (country_idx != 0) && (country_idx < wifi_countrycode_max)) {
-		wifi_countrycode_type_t tmp;
-
-		tmp = rcap->countrySupported[0];
-		rcap->countrySupported[0] = rcap->countrySupported[country_idx];
-		rcap->countrySupported[country_idx] = tmp;
-	}
-	/* csi */
-	rcap->csi.maxDevices = 8;
-	rcap->csi.soudingFrameSupported = TRUE;
-
-	if (array_index_to_vap_index(radioIndex, 0, &main_vap_idx) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid radio_index[%d]\n", radioIndex);
-		return RETURN_ERR;
-	}
-
-	if (wifi_GetInterfaceName(main_vap_idx, interface_name) != RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "wifi_GetInterfaceName fail\n");
-	}
-	res = snprintf(rcap->ifaceName, sizeof(interface_name), "%s",interface_name);
-	if (os_snprintf_error(sizeof(interface_name), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	/* channelWidth - all supported bandwidths */
-	int i=0;
-	rcap->channelWidth[i] = 0;
-	if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
-		rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
-								WIFI_CHANNELBANDWIDTH_40MHZ);
-
-	} else if (rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) {
-		rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
-								WIFI_CHANNELBANDWIDTH_40MHZ |
-								WIFI_CHANNELBANDWIDTH_80MHZ | WIFI_CHANNELBANDWIDTH_160MHZ);
-	} else if (rcap->band[i] & (WIFI_FREQUENCY_6_BAND)) {
-		rcap->channelWidth[i] |= (WIFI_CHANNELBANDWIDTH_20MHZ |
-								WIFI_CHANNELBANDWIDTH_40MHZ |
-								WIFI_CHANNELBANDWIDTH_80MHZ | 
-								WIFI_CHANNELBANDWIDTH_160MHZ | 
-								WIFI_CHANNELBANDWIDTH_320MHZ);
-	}
-
-
-	/* mode - all supported variants */
-	// rcap->mode[i] = WIFI_80211_VARIANT_H;
-	if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) {
-		rcap->mode[i] = ( WIFI_80211_VARIANT_B | WIFI_80211_VARIANT_G | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AX | WIFI_80211_VARIANT_BE);
-	}
-	else if (rcap->band[i] & WIFI_FREQUENCY_5_BAND ) {
-		rcap->mode[i] = ( WIFI_80211_VARIANT_A | WIFI_80211_VARIANT_N | WIFI_80211_VARIANT_AC | WIFI_80211_VARIANT_AX | WIFI_80211_VARIANT_BE);
-	}
-	else if (rcap->band[i] & WIFI_FREQUENCY_6_BAND) {
-		rcap->mode[i] = ( WIFI_80211_VARIANT_AX | WIFI_80211_VARIANT_BE);
-	}
-	rcap->maxBitRate[i] = ( rcap->band[i] & WIFI_FREQUENCY_2_4_BAND ) ? 300 :
-		((rcap->band[i] & WIFI_FREQUENCY_5_BAND) ? 1734 : 0);
-
-	/* supportedBitRate - all supported bitrates */
-	rcap->supportedBitRate[i] = 0;
-	if (rcap->band[i] & WIFI_FREQUENCY_2_4_BAND) {
-		rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
-									WIFI_BITRATE_11MBPS | WIFI_BITRATE_12MBPS);
-	}
-	else if ((rcap->band[i] & (WIFI_FREQUENCY_5_BAND )) || (rcap->band[i] & (WIFI_FREQUENCY_6_BAND))) {
-		rcap->supportedBitRate[i] |= (WIFI_BITRATE_6MBPS | WIFI_BITRATE_9MBPS |
-									WIFI_BITRATE_12MBPS | WIFI_BITRATE_18MBPS | WIFI_BITRATE_24MBPS |
-									WIFI_BITRATE_36MBPS | WIFI_BITRATE_48MBPS | WIFI_BITRATE_54MBPS);
-	}
-
-
-	rcap->transmitPowerSupported_list[i].numberOfElements = 5;
-	rcap->transmitPowerSupported_list[i].transmitPowerSupported[0]=12;
-	rcap->transmitPowerSupported_list[i].transmitPowerSupported[1]=25;
-	rcap->transmitPowerSupported_list[i].transmitPowerSupported[2]=50;
-	rcap->transmitPowerSupported_list[i].transmitPowerSupported[3]=75;
-	rcap->transmitPowerSupported_list[i].transmitPowerSupported[4]=100;
-	rcap->cipherSupported = 0;
-	rcap->cipherSupported |= WIFI_CIPHER_CAPA_ENC_TKIP | WIFI_CIPHER_CAPA_ENC_CCMP;
-	rcap->maxNumberVAPs = LOGAN_MAX_NUM_VAP_PER_RADIO;
-
-	return RETURN_OK;
-}
-
-
-INT wifi_getHalCapability(wifi_hal_capability_t *cap)
-{
-	INT status = 0, radioIndex = 0, vap_idx;
-	char output[MAX_BUF_SIZE] = {0};
-	int iter = 0;
-	unsigned int j = 0;
-	int max_num_radios = 0;
-	wifi_interface_name_idex_map_t *iface_info = NULL;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	memset(cap, 0, sizeof(wifi_hal_capability_t));
-
-	/* version */
-	cap->version.major = WIFI_HAL_MAJOR_VERSION;
-	cap->version.minor = WIFI_HAL_MINOR_VERSION;
-
-	/* number of radios platform property */
-	wifi_getMaxRadioNumber(&max_num_radios);
-	cap->wifi_prop.numRadios = max_num_radios;
-
-	for(radioIndex=0; radioIndex < cap->wifi_prop.numRadios; radioIndex++)
-	{
-		status = getRadioCapabilities(radioIndex, &(cap->wifi_prop.radiocap[radioIndex]));
-		if (status != 0) {
-			wifi_debug(DEBUG_ERROR, "getRadioCapabilities idx = %d\n", radioIndex);
-			return RETURN_ERR;
-		}
-
-		for (j = 0; j < cap->wifi_prop.radiocap[radioIndex].maxNumberVAPs; j++)
-		{
-			if (iter >= (get_runtime_max_radio() * MAX_NUM_VAP_PER_RADIO))
-			{
-				 wifi_debug(DEBUG_ERROR, "to many vaps for index map (%d)\n", iter);
-				 return RETURN_ERR;
-			}
-			iface_info = &cap->wifi_prop.interface_map[iter];
-			iface_info->phy_index = radioIndex; // XXX: parse phyX index instead
-			iface_info->rdk_radio_index = radioIndex;
-
-			if (array_index_to_vap_index(radioIndex, j, &vap_idx) != RETURN_OK) {
-				wifi_debug(DEBUG_ERROR, "invalid radioIndex %d, j %d\n", radioIndex, j);
-				continue;
-			}
-
-			iface_info->index = vap_idx;
-
-			if (wifi_GetInterfaceName(iface_info->index, output))
-				strncpy(iface_info->interface_name, output, sizeof(iface_info->interface_name) - 1);
-
-			memset(iface_info->bridge_name, 0, sizeof(iface_info->bridge_name));
-			wifi_get_bridge_name(iface_info->interface_name, iface_info->bridge_name,
-				sizeof(iface_info->bridge_name));
-
-			if (strlen(iface_info->bridge_name) == 0) {
-				strncpy(iface_info->bridge_name, DEFAULT_BRIDGE_NAME, sizeof(iface_info->bridge_name) - 1);
-				iface_info->bridge_name[sizeof(iface_info->bridge_name) - 1] = '\0';
-			}
-			// TODO: vlan id
-			// TODO: primary
-			if (wifi_getApName(iface_info->index, output) == RETURN_OK)
-				 strncpy(iface_info->vap_name, output, sizeof(iface_info->vap_name) - 1);
-
-			iter++;
-		}
-	}
-
-	cap->BandSteeringSupported = TRUE;
-#ifdef WIFI_7992
-	cap->wifi_prop.mu_bands = WIFI_BAND_2_5;
-#else
-	cap->wifi_prop.mu_bands = WIFI_BAND_2_5_6;
-#endif
-	memcpy(&g_hal_cap, cap, sizeof(g_hal_cap));
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setOpportunisticKeyCaching(int ap_index, BOOL okc_enable)
-{
-	struct params h_config={0};
-	char config_file[64] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	h_config.name = "okc";
-	h_config.value = okc_enable?"1":"0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &h_config, 1);
-	wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setSAEMFP(int ap_index, BOOL enable)
-{
-	struct params h_config={0};
-	char config_file[64] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	h_config.name = "sae_require_mfp";
-	h_config.value = enable?"1":"0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &h_config, 1);
-	wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setSAEpwe(int ap_index, int sae_pwe)
-{
-	struct params h_config={0};
-	char config_file[64] = {0};
-	char buf[128] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	h_config.name = "sae_pwe";
-	res = snprintf(buf, sizeof(buf), "%d", sae_pwe);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	h_config.value = buf;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &h_config, 1);
-	wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setDisable_EAPOL_retries(int ap_index, BOOL disable_EAPOL_retries)
-{
-	// wpa3 use SAE instead of PSK, so we need to disable this feature when using wpa3.
-	struct params h_config={0};
-	char config_file[64] = {0};
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n", __func__, __LINE__);
-
-	h_config.name = "wpa_disable_eapol_key_retries";
-	h_config.value = disable_EAPOL_retries?"1":"0";
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdWrite(config_file, &h_config, 1);
-	wifi_hostapdProcessUpdate(ap_index, &h_config, 1);
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n", __func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_setApSecurity(INT ap_index, wifi_vap_security_t *security)
-{
-	char buf[128] = {0};
-	char config_file[128] = {0};
-
-	char password[65] = {0};
-	char mfp[32] = {0};
-	char wpa_mode[32] = {0};
-	BOOL okc_enable = FALSE;
-	BOOL sae_MFP = FALSE;
-	BOOL disable_EAPOL_retries = FALSE;
-	int sae_pwe = 0;
-	struct params params = {0};
-	wifi_band band = band_invalid;
-	int res;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	if (security->mode == wifi_security_mode_none) {
-		strncpy(wpa_mode, "None",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa_personal) {
-		strncpy(wpa_mode, "WPA-Personal",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa2_personal){
-		strncpy(wpa_mode, "WPA2-Personal",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa_wpa2_personal){
-		strncpy(wpa_mode, "WPA-WPA2-Personal",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa_enterprise){
-		strncpy(wpa_mode, "WPA-Enterprise",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa2_enterprise){
-		strncpy(wpa_mode, "WPA2-Enterprise",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa_wpa2_enterprise){
-		strncpy(wpa_mode, "WPA-WAP2-Enterprise",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-	} else if (security->mode == wifi_security_mode_wpa3_personal) {
-		strncpy(wpa_mode, "WPA3-Personal",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-		okc_enable = TRUE;
-		sae_MFP = TRUE;
-		sae_pwe = 2;
-		disable_EAPOL_retries = FALSE;
-	} else if (security->mode == wifi_security_mode_wpa3_transition) {
-		strncpy(wpa_mode, "WPA3-Personal-Transition",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-		okc_enable = TRUE;
-		sae_MFP = TRUE;
-		sae_pwe = 2;
-		disable_EAPOL_retries = FALSE;
-	} else if (security->mode == wifi_security_mode_wpa3_enterprise) {
-		strncpy(wpa_mode, "WPA3-Enterprise",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-		sae_MFP = TRUE;
-		sae_pwe = 2;
-		disable_EAPOL_retries = FALSE;
-	} else if (security->mode == wifi_security_mode_enhanced_open) {
-		strncpy(wpa_mode, "OWE",sizeof(wpa_mode) - 1);
-		wpa_mode[sizeof(wpa_mode) - 1] = '\0';
-		sae_MFP = TRUE;
-		sae_pwe = 2;
-		disable_EAPOL_retries = FALSE;
-	}
-
-	band = wifi_index_to_band(ap_index);
-	if (band == band_6 && strstr(wpa_mode, "WPA3") == NULL) {
-		wifi_debug(DEBUG_ERROR, "%s: 6G band must set with wpa3.\n", __func__);
-		return RETURN_ERR;
-	}
-
-	wifi_setApSecurityModeEnabled(ap_index, wpa_mode);
-	wifi_setOpportunisticKeyCaching(ap_index, okc_enable);
-	wifi_setSAEMFP(ap_index, sae_MFP);
-	wifi_setSAEpwe(ap_index, sae_pwe);
-	wifi_setDisable_EAPOL_retries(ap_index, disable_EAPOL_retries);
-
-	if (security->mode != wifi_security_mode_none && security->mode != wifi_security_mode_enhanced_open) {
-		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_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
-			int key_len = strlen(security->u.key.key);
-			// wpa_psk and wpa_passphrase cann;t use at the same time, the command replace one with the other.
-			if (key_len == 64) {	// set wpa_psk
-				strncpy(password, security->u.key.key, 64);	 // 64 characters
-				password[64] = '\0';
-				wifi_setApSecurityPreSharedKey(ap_index, password);
-				res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^wpa_passphrase=/!p' %s", config_file);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-				}
-			} else if (key_len >= 8 && key_len < 64) {  // set wpa_passphrase
-				strncpy(password, security->u.key.key, 63);
-				password[63] = '\0';
-				wifi_delete_pmkid_cache(ap_index);
-				wifi_setApSecurityKeyPassphrase(ap_index, password);
-				res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^wpa_psk=/!p' %s", config_file);
-				if (res) {
-					wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-				}
-			} else
-				return RETURN_ERR;
-
-		}
-		if (security->u.key.type == wifi_security_key_type_sae || security->u.key.type == wifi_security_key_type_psk_sae) {
-			params.name = "sae_password";
-			params.value = security->u.key.key;
-			wifi_delete_pmkid_cache(ap_index);
-			wifi_hostapdWrite(config_file, &params, 1);
-			wifi_hostapdProcessUpdate(ap_index, &params, 1);
-		} else {	// remove sae_password
-			res = _syscmd_secure(buf, sizeof(buf), "sed -i -n -e '/^sae_password=/!p' %s", config_file);
-			if (res) {
-				wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-			}
-		}
-	}
-
-	if (security->mode != wifi_security_mode_none) {
-		memset(&params, 0, sizeof(params));
-		params.name = "wpa_pairwise";
-		if (security->encr == wifi_encryption_tkip)
-			params.value = "TKIP";
-		else if (security->encr == wifi_encryption_aes)
-			params.value = "CCMP";
-		else if (security->encr == wifi_encryption_aes_tkip)
-			params.value = "TKIP CCMP";
-		wifi_hostapdWrite(config_file, &params, 1);
-		wifi_hostapdProcessUpdate(ap_index, &params, 1);
-
-		/* rsn_pairwise need to be updated too */
-		params.name = "rsn_pairwise";
-		wifi_hostapdWrite(config_file, &params, 1);
-		wifi_hostapdProcessUpdate(ap_index, &params, 1);
-	}
-
-	if (security->mfp == wifi_mfp_cfg_disabled){
-		strncpy(mfp,"Disabled",sizeof(mfp)-1);
-		mfp[sizeof(mfp)-1] = '\0';
-	} else if (security->mfp == wifi_mfp_cfg_optional){
-		strncpy(mfp,"Optional",sizeof(mfp)-1);
-		mfp[sizeof(mfp)-1] = '\0';
-	} else if (security->mfp == wifi_mfp_cfg_required){
-		strncpy(mfp,"Required",sizeof(mfp)-1);
-		mfp[sizeof(mfp)-1] = '\0';
-	}
-	wifi_setApSecurityMFPConfig(ap_index, mfp);
-
-	memset(&params, 0, sizeof(params));
-	params.name = "transition_disable";
-	if (security->wpa3_transition_disable == TRUE)
-		params.value = "0x01";
-	else
-		params.value = "0x00";
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(ap_index, &params, 1);
-
-	memset(&params, 0, sizeof(params));
-	params.name = "wpa_group_rekey";
-	res = snprintf(buf, sizeof(buf), "%d", security->rekey_interval);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.value = buf;
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(ap_index, &params, 1);
-
-	memset(&params, 0, sizeof(params));
-	params.name = "wpa_strict_rekey";
-	params.value = security->strict_rekey?"1":"0";
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(ap_index, &params, 1);
-
-	memset(&params, 0, sizeof(params));
-	params.name = "wpa_pairwise_update_count";
-	if (security->eapol_key_retries == 0)
-		security->eapol_key_retries = 4;	// 0 is invalid, set to default value.
-	res = snprintf(buf, sizeof(buf), "%u", security->eapol_key_retries);
-	if (os_snprintf_error(sizeof(buf), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	params.value = buf;
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(ap_index, &params, 1);
-
-	memset(&params, 0, sizeof(params));
-	params.name = "disable_pmksa_caching";
-	params.value = security->disable_pmksa_caching?"1":"0";
-	wifi_hostapdWrite(config_file, &params, 1);
-	wifi_hostapdProcessUpdate(ap_index, &params, 1);
-
-	if (multiple_set == FALSE) {
-		wifi_setApEnable(ap_index, FALSE);
-		wifi_setApEnable(ap_index, TRUE);
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-
-	return RETURN_OK;
-}
-
-INT wifi_getApSecurity(INT ap_index, wifi_vap_security_t *security)
-{
-	char buf[256] = {0};
-	char config_file[128] = {0};
-	long int disable = 0;
-	long int tmp;
-	bool set_sae = FALSE;
-	int res;
-	wifi_encryption_method_t wpa_pairwise = 0, rsn_pairwise = 0;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, ap_index);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_getApSecurityModeEnabled(ap_index, buf);   // Get wpa config
-	security->mode = wifi_security_mode_none;
-	if (strlen(buf) != 0) {
-		if (!strcmp(buf, "WPA-Personal"))
-			security->mode = wifi_security_mode_wpa_personal;
-		else if (!strcmp(buf, "WPA2-Personal"))
-			security->mode = wifi_security_mode_wpa2_personal;
-		else if (!strcmp(buf, "WPA-WPA2-Personal"))
-			security->mode = wifi_security_mode_wpa_wpa2_personal;
-		else if (!strcmp(buf, "WPA-Enterprise"))
-			security->mode = wifi_security_mode_wpa_enterprise;
-		else if (!strcmp(buf, "WPA2-Enterprise"))
-			security->mode = wifi_security_mode_wpa2_enterprise;
-		else if (!strcmp(buf, "WPA-WPA2-Enterprise"))
-			security->mode = wifi_security_mode_wpa_wpa2_enterprise;
-		else if (!strcmp(buf, "WPA3-Personal"))
-			security->mode = wifi_security_mode_wpa3_personal;
-		else if (!strcmp(buf, "WPA3-Personal-Transition"))
-			security->mode = wifi_security_mode_wpa3_transition;
-		else if (!strcmp(buf, "WPA3-Enterprise"))
-			security->mode = wifi_security_mode_wpa3_enterprise;
-		else if (!strcmp(buf, "OWE"))
-			security->mode = wifi_security_mode_enhanced_open;
-	}
-
-	if (security->mode == wifi_security_mode_none)
-		security->encr = wifi_encryption_none;
-	else {
-		wifi_hostapdRead(config_file,"wpa_pairwise",buf,sizeof(buf));
-		if (strlen(buf) > 0) {
-			if (strcmp(buf, "TKIP") == 0)
-				wpa_pairwise = wifi_encryption_tkip;
-			else if (strcmp(buf, "CCMP") == 0)
-				wpa_pairwise = wifi_encryption_aes;
-			else
-				wpa_pairwise = wifi_encryption_aes_tkip;
-		}
-
-		wifi_hostapdRead(config_file,"rsn_pairwise",buf,sizeof(buf));
-		if (strlen(buf) > 0) {
-			if (strcmp(buf, "TKIP") == 0)
-				rsn_pairwise = wifi_encryption_tkip;
-			else if (strcmp(buf, "CCMP") == 0)
-				rsn_pairwise = wifi_encryption_aes;
-			else
-				rsn_pairwise = wifi_encryption_aes_tkip;
-		}
-
-		security->encr = wpa_pairwise | rsn_pairwise;
-	}
-
-	if (security->mode != wifi_security_mode_none) {
-		memset(buf, 0, sizeof(buf));
-		// wpa3 can use one or both configs as password, so we check sae_password first.
-		wifi_hostapdRead(config_file, "sae_password", buf, sizeof(buf));
-		if (strlen(buf) != 0) {
-			if (security->mode == wifi_security_mode_wpa3_personal || security->mode == wifi_security_mode_wpa3_transition)
-				security->u.key.type = wifi_security_key_type_sae;
-			set_sae = TRUE;
-			strncpy(security->u.key.key, buf, sizeof(buf));
-		}
-		wifi_hostapdRead(config_file, "wpa_passphrase", buf, sizeof(buf));
-		if (strlen(buf) != 0){
-			if (set_sae == TRUE)
-				security->u.key.type = wifi_security_key_type_psk_sae;
-			else if (strlen(buf) == 64)
-				security->u.key.type = wifi_security_key_type_psk;
-			else
-				security->u.key.type = wifi_security_key_type_pass;
-			strncpy(security->u.key.key, buf, sizeof(security->u.key.key));
-		}
-		security->u.key.key[255] = '\0';
-	}
-
-	memset(buf, 0, sizeof(buf));
-	wifi_getApSecurityMFPConfig(ap_index, buf);
-	if (strcmp(buf, "Disabled") == 0)
-		security->mfp = wifi_mfp_cfg_disabled;
-	else if (strcmp(buf, "Optional") == 0)
-		security->mfp = wifi_mfp_cfg_optional;
-	else if (strcmp(buf, "Required") == 0)
-		security->mfp = wifi_mfp_cfg_required;
-
-	memset(buf, 0, sizeof(buf));
-	security->wpa3_transition_disable = FALSE;
-	wifi_hostapdRead(config_file, "transition_disable", buf, sizeof(buf));
-	if (strlen(buf) == 0)
-		disable = 0;
-	else {
-		if (hal_strtol(buf, 16, &disable) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			return RETURN_ERR;
-		}
-	}
-	if (disable != 0)
-		security->wpa3_transition_disable = TRUE;
-
-	memset(buf, 0, sizeof(buf));
-	wifi_hostapdRead(config_file, "wpa_group_rekey", buf, sizeof(buf));
-	if (strlen(buf) == 0)
-		security->rekey_interval = 86400;
-	else {
-		if (hal_strtol(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			return RETURN_ERR;
-		}
-		security->rekey_interval = tmp;
-	}
-
-	memset(buf, 0, sizeof(buf));
-	wifi_hostapdRead(config_file, "wpa_strict_rekey", buf, sizeof(buf));
-	if (strlen(buf) == 0)
-		security->strict_rekey = 1;
-	else {
-		if (hal_strtol(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			return RETURN_ERR;
-		}
-		security->strict_rekey = tmp;
-	}
-
-	memset(buf, 0, sizeof(buf));
-	wifi_hostapdRead(config_file, "wpa_pairwise_update_count", buf, sizeof(buf));
-	if (strlen(buf) == 0)
-		security->eapol_key_retries = 4;
-	else {
-		if (hal_strtol(buf, 10, &tmp) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			return RETURN_ERR;
-		}
-		security->eapol_key_retries = tmp;
-	}
-
-	memset(buf, 0, sizeof(buf));
-	wifi_hostapdRead(config_file, "disable_pmksa_caching", buf, sizeof(buf));
-	if (strlen(buf) == 0)
-		security->disable_pmksa_caching = FALSE;
-	else {
-		if (hal_strtol(buf, 10, &(tmp)) < 0) {
-			wifi_debug(DEBUG_ERROR, "strtol fail\n");
-			return RETURN_ERR;
-		}
-		security->disable_pmksa_caching = tmp ? TRUE : FALSE;
-	}
-	/* TODO
-	eapol_key_timeout, eap_identity_req_timeout, eap_identity_req_retries, eap_req_timeout, eap_req_retries
-	*/
-	security->eapol_key_timeout = 1000; // Unit is ms. The default value in protocol.
-	security->eap_identity_req_timeout = 0;
-	security->eap_identity_req_retries = 0;
-	security->eap_req_timeout = 0;
-	security->eap_req_retries = 0;
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-#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)
-{
-	char interface_name[16] = {0};
-
-	char buf[128] = {0};
-	char *mac_addr = NULL;
-	BOOL status = FALSE;
-	size_t len = 0;
-	int res;
-
-	if(ap_index > MAX_APS)
-		return RETURN_ERR;
-
-	*output_numDevices = 0;
-	wifi_getApEnable(ap_index, &status);
-	if (status == FALSE)
-		return RETURN_OK;
-
-	if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	_syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s list_sta", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-	}
-
-	mac_addr = strtok(buf, "\n");
-	for (int i = 0; i < maxNumDevices && mac_addr != NULL; i++) {
-		*output_numDevices = i + 1;
-		wifi_debug(DEBUG_ERROR,, "mac_addr: %s\n", mac_addr);
-		addr_ptr = output_deviceMacAddressArray[i];
-		mac_addr_aton(addr_ptr, mac_addr);
-		mac_addr = strtok(NULL, "\n");
-	}
-
-	return RETURN_OK;
-}
-#else
-INT wifi_getApAssociatedDevice(INT ap_index, CHAR *output_buf, INT output_buf_size)
-{
-	char interface_name[16] = {0};
-
-	BOOL status = false;
-	//int res;
-
-	if(ap_index > MAX_APS || output_buf == NULL || output_buf_size <= 0)
-		return RETURN_ERR;
-
-	output_buf[0] = '\0';
-
-	wifi_getApEnable(ap_index,&status);
-	if (!status)
-		return RETURN_OK;
-
-	if (wifi_GetInterfaceName(ap_index, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	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
-
-INT wifi_getProxyArp(INT apIndex, BOOL *enable)
-{
-	char output[16]={'\0'};
-	char config_file[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if (!enable)
-		return RETURN_ERR;
-
-	res = snprintf(config_file, sizeof(config_file), "%s%d.conf", CONFIG_PREFIX, apIndex);
-	if (os_snprintf_error(sizeof(config_file), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	wifi_hostapdRead(config_file, "proxy_arp", output, sizeof(output));
-
-	if (strlen(output) == 0)
-		*enable = FALSE;
-	else if (strncmp(output, "1", 1) == 0)
-		*enable = TRUE;
-	else
-		*enable = FALSE;
-
-	wifi_debug(DEBUG_INFO, "proxy_arp is : %s\n", output);
-	return RETURN_OK;
-}
-
-INT wifi_getRadioStatsEnable(INT radioIndex, BOOL *output_enable)
-{
-	if (NULL == output_enable || radioIndex >= get_runtime_max_radio())
-		return RETURN_ERR;
-	*output_enable=TRUE;
-	return RETURN_OK;
-}
-
-INT wifi_getTWTsessions(INT ap_index, UINT maxNumberSessions, wifi_twt_sessions_t *twtSessions, UINT *numSessionReturned)
-{
-	char cmd[128] = {0};
-	char buf[128] = {0};
-	char line[128] = {0};
-	FILE *f = NULL;
-	int index = 0, bss_idx;
-	int exp = 0;
-	int mantissa = 0;
-	int duration = 0;
-	int radio_index = 0;
-	uint twt_wake_interval = 0;
-	int phyId = 0;
-	int res;
-	unsigned long tmp_u, tmp_l;
-
-	WIFI_ENTRY_EXIT_DEBUG("Inside %s:%d\n",__func__, __LINE__);
-
-	if (vap_index_to_radio_array_index(ap_index, &radio_index, &bss_idx)!= RETURN_OK) {
-		wifi_debug(DEBUG_ERROR, "invalid ap_index[%d]\n", ap_index);
-		return RETURN_ERR;
-	}
-	phyId = radio_index_to_phy(radio_index);
-
-	res = _syscmd_secure(buf, sizeof(buf),"cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | wc -l", phyId);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-
-	}
-
-	if (hal_strtoul(buf, 10, &tmp_u) < 0) {
-		wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-	}
-	*numSessionReturned = tmp_u - 1;
-
-	if (*numSessionReturned > maxNumberSessions)
-		*numSessionReturned = maxNumberSessions;
-	else if (*numSessionReturned < 1) {
-		*numSessionReturned = 0;
-		return RETURN_OK;
-	}
-
-	res = snprintf(cmd, sizeof(cmd), "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
-	if (os_snprintf_error(sizeof(cmd), res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-	f = v_secure_popen("r", "cat /sys/kernel/debug/ieee80211/phy%d/mt76/twt_stats | tail -n %d | tr '|' ' ' | tr -s ' '", phyId, *numSessionReturned);
-	if (f == NULL) {
-		wifi_debug(DEBUG_ERROR, "v_secure_popen %s error\n", cmd);
-		return RETURN_ERR;
-	}
-
-	// the format of each line is "[wcid] [id] [flags] [exp] [mantissa] [duration] [tsf]"
-	while((fgets(line, sizeof(line), f)) != NULL) {
-		char *tmp = NULL;
-		size_t len = strlen(line);
-		strncpy(buf, line,len);
-		buf[len] = '\0';
-		tmp = strtok(buf, " ");
-		if (tmp == NULL)
-			break;
-
-		if (hal_strtoul(tmp, 10, &tmp_u) < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-		}
-		twtSessions[index].numDevicesInSession = tmp_u;
-		tmp = strtok(NULL, " ");
-		if (tmp == NULL)
-			break;
-
-		if (hal_strtoul(tmp, 10, &tmp_u) < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-		}
-		twtSessions[index].twtParameters.operation.flowID = tmp_u;
-		tmp = strtok(NULL, " ");
-		if (strstr(tmp, "t")) {
-			twtSessions[index].twtParameters.operation.trigger_enabled = TRUE;
-		}
-		if (strstr(tmp, "a")) {
-			twtSessions[index].twtParameters.operation.announced = TRUE;
-		}
-		tmp = strtok(NULL, " ");
-		if (tmp == NULL)
-			continue;
-
-		if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-		}
-		exp = tmp_l;
-
-		tmp = strtok(NULL, " ");
-		if (tmp == NULL)
-			continue;
-		if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-		}
-		mantissa = tmp_l;
-
-		tmp = strtok(NULL, " ");
-
-		if (hal_strtoul(tmp, 10, &tmp_l) < 0) {
-			wifi_debug(DEBUG_ERROR, "Unexpected strtoul fail\n");
-		}
-		duration = tmp_l;
-
-		// only implicit supported
-		twtSessions[index].twtParameters.operation.implicit = TRUE;
-		// only individual agreement supported
-		twtSessions[index].twtParameters.agreement = wifi_twt_agreement_type_individual;
-
-		// wakeInterval_uSec is a unsigned integer, but the maximum TWT wake interval could be 2^15 (mantissa) * 2^32 = 2^47.
-		twt_wake_interval = mantissa * (1 << exp);
-		if (mantissa == 0 || twt_wake_interval/mantissa != (1 << exp)) {
-			// Overflow handling
-			twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = -1;   // max unsigned int
-		} else {
-			twtSessions[index].twtParameters.params.individual.wakeInterval_uSec = twt_wake_interval;
-		}
-		twtSessions[index].twtParameters.params.individual.minWakeDuration_uSec = duration * 256;
-		index++;
-	}
-
-	v_secure_pclose(f);
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-	return RETURN_OK;
-}
-
-INT wifi_enableGreylistAccessControl(BOOL enable)
-{
-	char inf_name[IFNAMSIZ] = {0};
-	int if_idx, ret = 0;
-	struct nl_msg *msg	= NULL;
-	struct nlattr * msg_data = NULL;
-	struct mtk_nl80211_param param;
-	struct unl unl_ins;
-	unsigned short apIndex = 0;
-
-	for (apIndex = 0; apIndex < MAX_APS; apIndex++) {
-		if (wifi_GetInterfaceName(apIndex, inf_name) != RETURN_OK)
-			continue;
-
-		if_idx = if_nametoindex(inf_name);
-		if (!if_idx) {
-			wifi_debug(DEBUG_ERROR, "can't finde ifname(%s) index,ERROR\n", inf_name);
-			continue;
-		}
-
-		/*init mtk nl80211 vendor cmd*/
-		param.sub_cmd = MTK_NL80211_VENDOR_SUBCMD_SET_ACL;
-		param.if_type = NL80211_ATTR_IFINDEX;
-		param.if_idx = if_idx;
-		ret = mtk_nl80211_init(&unl_ins, &msg, &msg_data, &param);
-		if (ret) {
-			wifi_debug(DEBUG_ERROR, "init mtk 80211 netlink and msg fails\n");
-			return RETURN_ERR;
-		}
-
-		if (nla_put_u8(msg, MTK_NL80211_VENDOR_ATTR_ACL_POLICY, enable == FALSE ? 0 : 1)) {
-			wifi_debug(DEBUG_ERROR, "Nla put attribute error\n");
-			nlmsg_free(msg);
-			mtk_nl80211_deint(&unl_ins);
-			continue;
-		}
-
-		/*send mtk nl80211 vendor msg*/
-		ret = mtk_nl80211_send(&unl_ins, msg, msg_data, NULL, NULL);
-		if (ret) {
-			wifi_debug(DEBUG_ERROR, "send mtk nl80211 vender msg fails\n");
-			mtk_nl80211_deint(&unl_ins);
-			continue;
-		}
-		/*deinit mtk nl80211 vendor msg*/
-		mtk_nl80211_deint(&unl_ins);
-		wifi_debug(DEBUG_INFO, " %s cmd success.\n", inf_name);
-	}
-
-	return RETURN_OK;
-}
-
-// Output string is Disabled, Requested, Failed or Success. max 32 characters
-INT wifi_getApWpsLastConnectionStatus(INT apIndex, CHAR *output_string)
-{
-	char interface_name[IF_NAME_SIZE] = {0};
-	char buf[MAX_BUF_SIZE] = {0};
-	int res;
-
-	if ((!output_string) || (apIndex < 0) || (apIndex >= MAX_APS))
-		return RETURN_ERR;
-
-	if ((apIndex < 0) && (apIndex >= MAX_APS))
-		return RETURN_ERR;
-
-	if (wifi_GetInterfaceName(apIndex, interface_name) != RETURN_OK)
-		return RETURN_ERR;
-
-	if (strlen(interface_name) == 0)
-		return RETURN_ERR;
-
-	res = _syscmd_secure(buf, sizeof(buf), "hostapd_cli -i %s wps_get_status", interface_name);
-	if (res) {
-		wifi_debug(DEBUG_ERROR, "_syscmd_secure fail\n");
-		return RETURN_ERR;
-	}
-
-    if (strstr(buf, "PBC Status: Active")) {
-		res = snprintf(output_string, 32, "%s", "Requested");
-    } else if(strstr(buf, "PBC Status: Disabled")) {
-		res = snprintf(output_string, 32, "%s", "Success");
-    } else
-		res = snprintf(output_string, 32, "%s", "Failed");
-
-	if (os_snprintf_error(32, res)) {
-		wifi_debug(DEBUG_ERROR, "Unexpected snprintf fail\n");
-		return RETURN_ERR;
-	}
-
-	WIFI_ENTRY_EXIT_DEBUG("Exiting %s:%d\n",__func__, __LINE__);
-    return RETURN_OK;
-}
-
