diff --git a/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c b/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c
new file mode 100755
index 0000000..60c4224
--- /dev/null
+++ b/IC_src/mtk/lib/liblynq-wifi6/libwifi6.c
@@ -0,0 +1,5221 @@
+/**@File lib_wifi6.c
+*  @Brief :about function test
+*  @details :
+*  @Author : you.chen
+*  @Date : 2022-4-6
+*  @Version : V1.0
+*  @copy ritght : Copyright (c) MobileTek
+*/
+#include <log/log.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <stdlib.h>
+#include <string.h>
+#include "libwifi6.h"
+#include <wpa_ctrl.h>
+#include <string.h>
+#include <time.h>
+#include <pthread.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <ifaddrs.h>
+#include "log/log.h"
+#include <sys/time.h>
+#include <asm/errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+#ifdef __cplusplus
+}
+#endif
+#undef LOG_TAG
+#define LOG_TAG "LYNQ_WIFI"
+#define MAX_CMD 128
+#define MAX_RET 4096
+#define MODE_LEN 10
+#define CTRL_STA 0
+#define CTRL_AP 1
+#define AP_NETWORK_0 0
+#define STA_MAX_SAVED_AP_NUM 50
+#define MAC_LEN 17
+
+pthread_t g_ap_watcher_pid = 0;
+volatile int g_ap_watcher_stop_flag = 0;
+volatile int g_ap_watcher_started_flag = 0;
+
+pthread_t g_ap_tmp_watcher_pid = 0;
+volatile int g_ap_tmp_watcher_stop_flag = 0;
+
+pthread_t g_sta_watcher_pid = 0;
+volatile int g_sta_watcher_stop_flag = 0;
+volatile int g_sta_scan_finish_flag = 1;
+volatile int g_sta_watcher_started_flag = 0;
+volatile int g_sta_conncet_status_flag = 0;
+volatile int g_sta_fake_scan_finish_flag = 0;
+
+pthread_t g_sta_auto_watcher_pid = 0;
+volatile int g_sta_auto_watcher_stop_flag = 0;
+volatile int g_sta_auto_scan_finish_flag = 1;
+volatile int g_sta_auto_watcher_started_flag = 0;
+void * g_ap_callback_priv = NULL;
+AP_CALLBACK_FUNC_PTR g_ap_callback_func = NULL;
+void * g_sta_callback_priv = NULL;
+STA_CALLBACK_FUNC_PTR g_sta_callback_func = NULL;
+void * g_sta_auto_callback_priv = NULL;
+STA_AUTO_CALLBACK_FUNC_PTR g_sta_auto_callback_func = NULL;
+
+
+//const char * CTRL_PATH="/var/run/wpa_supplicant";
+const char * CTRL_PATH[2] = {"/var/run/wpa_supplicant/wlan0", "/var/run/wpa_supplicant/ap0"};
+//const char * CTRL_PATH[2] = {"/var/run/wpa_supplicant/wlan0", "/var/run/wpa_supplicant/wlan0"};
+const char * cmd_list_networks = "LIST_NETWORKS";
+const char * cmd_save_config = "SAVE_CONFIG";
+const char * cmd_disconnect = "DISCONNECT";
+const char * cmd_remove_all = "REMOVE_NETWORK all";
+const char * state_scan_result = "CTRL-EVENT-SCAN-RESULTS";
+const char * STATE_COMPLETED = "COMPLETED";
+const char * STATE_SCANNING = "SCANNING";
+const char * STATE_DISCONNECTED = "DISCONNECTED";
+
+const char * cmd_ping = "PING";
+const char * rsp_pong = "PONG";
+const int SLEEP_TIME_ON_IDLE = 100 * 1000; // usecond
+const int MAX_IDLE_COUNT = 600; // 60s
+
+const char * start_wg870_service_script = "/etc/wg870/scripts/start_wg870_service.sh";
+const char * get_interface_name_script = "/etc/wg870/scripts/get_interface_name.sh";
+const char * start_stop_sta_script = "/etc/wg870/scripts/start_stop_sta.sh";
+const char * start_stop_ap_script = "/etc/wg870/scripts/start_stop_ap.sh";
+const char * sta_status_change_script = "/etc/wg870/scripts/sta_status_change.sh";
+
+static char s_ap_iterface_name[64] = {0};
+
+struct local_wpa_ctrl{
+    struct wpa_ctrl *ctrl;
+    pthread_mutex_t mutex;
+};
+
+volatile int g_history_disconnect_valid_num = 0;
+int g_history_disconnect_net[128];
+
+static pthread_mutex_t s_check_wpa_ctrl_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_sta_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+static pthread_mutex_t s_ap_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+// add for auto connect
+static pthread_mutex_t s_sta_auto_callback_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static struct local_wpa_ctrl * g_lynq_wpa_ctrl[2] = {0};
+
+//you.chen add for tv-box start
+volatile int g_gbw_enabled = 0;
+char * g_gbw_mac = NULL;
+pthread_t g_gbw_watcher_pid = 0;
+static int startGBW();
+static int stopGBW();
+//you.chen add for tv-box end
+
+typedef struct __curr_status_info {
+    ap_info_s *ap;
+    char * state;
+    int net_no;
+}curr_status_info;
+
+typedef enum {
+    INNER_STA_STATUS_INIT = 0,
+    INNER_STA_STATUS_CONNECTING,
+    INNER_STA_STATUS_ASSOCIATING,
+    INNER_STA_STATUS_ASSOCIATED,
+    INNER_STA_STATUS_CONNECTED,
+    INNER_STA_STATUS_DISCONNECTING,
+    INNER_STA_STATUS_DISCONNECTED,
+    INNER_STA_STATUS_CANCEL,
+}inner_sta_status_s;
+
+static pthread_cond_t s_global_check_cond = PTHREAD_COND_INITIALIZER;
+static pthread_mutex_t s_global_check_mutex = PTHREAD_MUTEX_INITIALIZER;
+volatile inner_sta_status_s s_sta_status = INNER_STA_STATUS_INIT;
+static error_number_s s_sta_error_number = -1;
+static char s_sta_current_connecting_ssid[64] = {0};
+static struct timespec s_sta_connect_timeout;
+const int MAX_CONNNECT_TIME = 15; // second
+pthread_t g_global_watcher_pid = 0;
+static int s_service_invoke_timeout_cnt=0;
+const int FAKE_MAX_INT_VALUE = 99999;
+
+static void print_disconnect_list()
+{
+    int i;
+    for( i = 0; i < g_history_disconnect_valid_num; i++ )
+    {
+        RLOGD(" list of g_history_disconnect_valid_num is  %d histroy_list[%d]:%d --------- %d",g_history_disconnect_valid_num,i,g_history_disconnect_net[i],__LINE__);
+    }
+
+    return;
+}
+
+// idex  ----> history_disconnect_list[x]  index
+static int removeElement(int idex)
+{
+    RLOGD("into removeElement");
+    if( index < 0 )
+    {
+        RLOGD("WIFI [removeElement] input idex < 0,idex is %d: ",idex);
+        return -1;
+    }
+    RLOGD("%s line: %d  g_history_disconnect_net[%d]: %d  end g_history_disconnect_net[%d]:%d",__func__,__LINE__,idex,g_history_disconnect_net[idex],g_history_disconnect_valid_num-1, g_history_disconnect_net[g_history_disconnect_valid_num-1]);
+    g_history_disconnect_net[idex] = g_history_disconnect_net[g_history_disconnect_valid_num-1];    //g_history_disconnect_vaild_num  -1 for get last index
+    g_history_disconnect_valid_num --;
+    RLOGD("end removeElement");
+    return 0;
+}
+static int check_history_disconenct_ap_list(int val)
+{
+    print_disconnect_list();
+    RLOGD("WIFI[check_history_disconenct_ap_list]into check_history_disconenct_ap_list && input val is %d g_history_disconnect_valid_num is %d line",val,g_history_disconnect_valid_num,__LINE__);
+    int i;
+    for( i = 0; i < g_history_disconnect_valid_num; i++)
+    {
+        if( val == g_history_disconnect_net[i] )
+        {
+             RLOGD("[wifi]-----input val is %d,g_history_disconnect_net[%d]:%d",val,i,g_history_disconnect_net[i]);
+             RLOGD("end check_history_disconenct_ap_list && return network index");
+             return i;
+        }
+    }
+    RLOGD("end check_history_disconenct_ap_list && return fail,didn't need remove networkid %d from list  g_history_disconnect_valid_num is %d line %d",val,g_history_disconnect_valid_num,__LINE__);
+    return -1;
+}
+
+
+static void lynq_sta_removeElement(int net_no)
+{
+    int ret;
+
+    ret = check_history_disconenct_ap_list(net_no);
+    if( ret == -1 )
+    {
+        RLOGD("curr_net_no not in history_disconenct_lsit,return 0 %s %d",__func__,__LINE__);
+        return;
+    }else
+    {
+        ret = removeElement(ret);
+        if( ret == 0 )
+        {
+            RLOGD("removeElement pass %s %d",__func__,__LINE__);
+            return;
+        }
+    }
+
+    return;
+}
+
+static void notify_service_invoke_fail(int error)
+{
+    struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
+    pthread_mutex_lock(&s_global_check_mutex);
+    if (error == -2) //timeout
+    {
+        s_service_invoke_timeout_cnt++;
+        if (s_service_invoke_timeout_cnt > 10)
+        {
+            pthread_cond_signal(&s_global_check_cond);
+        }
+    }
+    else if (error == -1)
+    {
+        // check if can connect wpa service
+        lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[0]);
+        if (lynq_wpa_ctrl == NULL)
+        {
+            s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+            pthread_cond_signal(&s_global_check_cond);
+        }
+        wpa_ctrl_close(lynq_wpa_ctrl);
+        lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[1]);
+        if (lynq_wpa_ctrl == NULL)
+        {
+            s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+            pthread_cond_signal(&s_global_check_cond);
+        }
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int system_call_v(const char * fmt, ...)
+{
+    char str_cmd[256] = {0};
+    va_list args;
+    va_start(args, fmt);
+    vsprintf(str_cmd, fmt, args);
+    va_end(args);
+    printf("system call----------%s\n", str_cmd);
+    return system(str_cmd);
+}
+
+static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len);
+
+static const char * inner_get_ap_interface_name()
+{
+    char * p;
+    char cmd[128]={0};
+
+    sprintf(cmd, "%s %d", get_interface_name_script, LYNQ_WIFI_INTERFACE_1);
+    if (0 != exec_cmd(cmd, s_ap_iterface_name, sizeof(s_ap_iterface_name)) || s_ap_iterface_name[0] == '\0')
+    {
+        memset(s_ap_iterface_name, 0, sizeof (s_ap_iterface_name));
+        return NULL;
+    }
+    p = strchr(s_ap_iterface_name, ' ');
+    if (NULL != p)
+    {
+        *p = '\0';
+    }
+    p = strchr(s_ap_iterface_name, '\n');
+    if (NULL != p)
+    {
+        *p = '\0';
+    }
+    if (s_ap_iterface_name[0] == '\0')
+    {
+        return NULL;
+    }
+
+    return s_ap_iterface_name;
+}
+
+static void check_tether_and_notify()
+{
+    RLOGD("check_tether_and_notify called");
+    if (inner_get_ap_interface_name() == NULL || 0 == system_call_v("ifconfig | grep %s", s_ap_iterface_name))
+    {
+        return;
+    }
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_service_invoke_timeout_cnt = FAKE_MAX_INT_VALUE;
+    pthread_cond_signal(&s_global_check_cond);
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int local_wpa_ctrl_request(struct local_wpa_ctrl *ctrl, const char *cmd, size_t cmd_len,
+                            char *reply, size_t *reply_len,
+                                  void (*msg_cb)(char *msg, size_t len))
+{
+    int ret;
+    if (ctrl->ctrl == NULL) {
+        RLOGE("local_wpa_ctrl_request ctrl is null\n");
+        return -1;
+    }
+    pthread_mutex_lock(&ctrl->mutex);
+    ret = wpa_ctrl_request(ctrl->ctrl, cmd, cmd_len, reply, reply_len, msg_cb);
+    pthread_mutex_unlock(&ctrl->mutex);
+    if (ret != 0)
+    {
+        notify_service_invoke_fail(ret);
+    }
+    return ret;
+}
+
+static struct local_wpa_ctrl * inner_get_wpa_ctrl(int index) {
+    int repeat_cnt;
+    struct local_wpa_ctrl *lynq_wpa_ctrl = NULL;
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    RLOGD("inner_get_wpa_ctrl\n");
+    for (repeat_cnt = 0; repeat_cnt < 5 && NULL == g_lynq_wpa_ctrl[index]; repeat_cnt++) {
+        pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+//        printf("wait enable finish\n");
+        usleep(500 * 1000);
+        pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    }
+    if (NULL == g_lynq_wpa_ctrl[index]) {
+        RLOGE("NULL == g_lynq_wpa_ctrl[index]");
+        goto out_addr;
+    }
+    if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
+        g_lynq_wpa_ctrl[index]->ctrl = wpa_ctrl_open(CTRL_PATH[index]);
+        if (NULL == g_lynq_wpa_ctrl[index]->ctrl) {
+            RLOGE("wpa_ctrl_open fail\n");
+            goto out_addr;
+        }
+        pthread_mutex_init(&g_lynq_wpa_ctrl[index]->mutex, NULL);
+    }
+    lynq_wpa_ctrl = g_lynq_wpa_ctrl[index];
+out_addr:
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    return lynq_wpa_ctrl;
+}
+
+#define PRINT_AND_RETURN_VALUE(str,value) \
+{\
+    perror((str));\
+    return (value);\
+}
+
+#define CHECK_IDX(idx, type) do { \
+        if ( (idx == LYNQ_WIFI_INTERFACE_0 && type != CTRL_STA) || (idx == LYNQ_WIFI_INTERFACE_1 && type != CTRL_AP) \
+                || idx < LYNQ_WIFI_INTERFACE_0 || idx > LYNQ_WIFI_INTERFACE_1 ) { \
+            RLOGE("not support create [%s] on interface [%d]\n", (type == CTRL_STA ? "station" : "ap"), idx); \
+            return -1; \
+        } \
+    }while (0)
+
+#define CHECK_WPA_CTRL(index) int ret = 0;\
+    size_t reply_len = MAX_RET; \
+    char cmd_reply[MAX_RET]={0}; \
+    struct local_wpa_ctrl *lynq_wpa_ctrl = NULL; \
+    do{ \
+        lynq_wpa_ctrl = inner_get_wpa_ctrl(index); \
+        if (NULL == lynq_wpa_ctrl) return -1; \
+    }while(0)
+
+#define DO_REQUEST(cmd_str) do { \
+        reply_len = MAX_RET;\
+        cmd_reply[0] = '\0'; \
+        RLOGD("to call [%s]\n", cmd_str);  \
+        ret = local_wpa_ctrl_request(lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL); \
+        if (ret != 0) { \
+            RLOGE("call "#cmd_str" fail %d\n", ret); \
+            return ret; \
+        } \
+        cmd_reply[reply_len+1] = '\0'; \
+        RLOGD("cmd replay [ %s ]\n", cmd_reply); \
+    }while(0)
+
+#define DO_OK_FAIL_REQUEST(cmd_str) do { \
+        DO_REQUEST(cmd_str); \
+        if (reply_len >=4 && memcmp(cmd_reply, "FAIL", 4) == 0 ) {\
+            RLOGE("cmd "#cmd_str" return FAIL\n"); \
+            return -1; \
+        } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0) { \
+            RLOGE("cmd "#cmd_str" return not OK|FAIL\n"); \
+            return -1; \
+        } \
+    }while (0)
+
+
+static int check_connection(struct wpa_ctrl * wpa_ctrl)
+{
+    size_t reply_len = MAX_RET;
+    char cmd_reply[MAX_RET]={0};
+    int ret;
+
+    RLOGD("check_connection [%p]", wpa_ctrl);
+    ret = wpa_ctrl_request(wpa_ctrl, cmd_ping, strlen(cmd_ping), cmd_reply, &reply_len, NULL);
+
+    if (ret != 0 || reply_len < 4 || memcmp(cmd_reply, rsp_pong, 4) != 0)
+    {
+        RLOGE("check_connection error: ctrl [%p], ret [%d], reply_len [%d], rsp [%s]", wpa_ctrl, ret, reply_len, cmd_reply);
+        if (ret != 0)
+        {
+            notify_service_invoke_fail(ret);
+        }
+        return -1;
+    }
+
+    return 0;
+}
+
+/**
+ * @brief check_pending_msg
+ * @param lynq_wpa_ctrl
+ * @return 1 has msg, 0 no msg, -1 error
+ */
+static int check_pending_msg(struct wpa_ctrl ** pp_lynq_wpa_ctrl, int type, int* idle_count, int *started_flag)
+{
+    int ret;
+
+    if (*pp_lynq_wpa_ctrl == NULL) // need connect
+    {
+        *pp_lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[type]); //@todo temp change
+        if (*pp_lynq_wpa_ctrl == NULL)
+        {
+            usleep(SLEEP_TIME_ON_IDLE);
+            return -1;
+        }
+
+        ret = wpa_ctrl_attach(*pp_lynq_wpa_ctrl);
+        if (ret == 0) // attach success
+        {
+            *started_flag = 1;
+        }
+        else
+        {
+            RLOGE("[wifi error]sta watch thread wpa_ctrl_attach fail");
+            wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+            *pp_lynq_wpa_ctrl = NULL;
+            *idle_count = 0;
+            notify_service_invoke_fail(-2);
+            usleep(SLEEP_TIME_ON_IDLE);
+            return -1;
+        }
+    }
+
+    ret = wpa_ctrl_pending(*pp_lynq_wpa_ctrl);
+    if ( ret == 0) // no pending messages
+    {
+        usleep(SLEEP_TIME_ON_IDLE);
+        *idle_count += 1;
+        if (*idle_count > MAX_IDLE_COUNT)
+        {
+            if (check_connection(*pp_lynq_wpa_ctrl) != 0)
+            {
+                wpa_ctrl_detach(*pp_lynq_wpa_ctrl);
+                wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+                *pp_lynq_wpa_ctrl = NULL;
+                *idle_count = 0;
+                return -1;
+            }
+            *idle_count = 0;
+        }
+        return 0;
+    }
+    else if ( ret == -1) // on error
+    {
+        RLOGE("[wifi error]sta wpa_ctrl_pending");
+        wpa_ctrl_detach(*pp_lynq_wpa_ctrl);
+        wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+        *pp_lynq_wpa_ctrl = NULL;
+        *idle_count = 0;
+        notify_service_invoke_fail(ret);
+        return -1;
+    }
+
+    *idle_count = 0;
+    return 1;
+}
+
+static inline void inner_notify_ap_msg(lynq_wifi_ap_status_s status)
+{
+    pthread_mutex_lock(&s_ap_callback_mutex);
+    if (g_ap_callback_func != NULL)
+        g_ap_callback_func(g_ap_callback_priv, status);
+    pthread_mutex_unlock(&s_ap_callback_mutex);
+}
+
+static void APWatcherThreadProc() {
+    size_t len = MAX_RET;
+    char msg_notify[MAX_RET];
+    int idle_count = 0;
+    char *ptr = NULL;
+    char mac[32] = {0};
+    char cmd[256] = {0};
+
+    struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+    g_ap_watcher_stop_flag = 0;
+
+    while (g_ap_watcher_stop_flag == 0)
+    {
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_AP, &idle_count, &g_ap_watcher_started_flag) != 1)
+        {
+            if (g_ap_callback_func != NULL && idle_count == MAX_IDLE_COUNT - 100 )
+            {
+                check_tether_and_notify();
+            }
+
+            continue;
+        }
+
+        memset(msg_notify, 0, MAX_RET);
+        len = MAX_RET;
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+        {
+            msg_notify[len+1] = '\0';
+            RLOGD("APWatcherThreadProc ap------> %s\n", msg_notify);
+            //you.chen change for tv-box start
+            if (strstr(msg_notify, "AP-STA-DISCONNECTED") != NULL)
+            {
+                inner_notify_ap_msg(LYNQ_WIFI_STATUS_DISCONNECT);
+                ptr = strstr(msg_notify, "AP-STA-DISCONNECTED");
+                if( ptr != NULL)
+                {
+                    ptr += strlen("AP-STA-DISCONNECTED ");
+                    memcpy(mac,ptr,17);
+                    sprintf(cmd,"cat /run/wg870/ap0.lease | grep \"%s\" | awk '{print \"dhcp_release ap0 \"$3\" \"$2\}' | sh",mac);
+                    RLOGD("%s %d cmd is %s",__func__,__LINE__,cmd);
+                    system(cmd);
+                }
+
+                if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+                {
+                    RLOGD("disconect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+                    {
+                        stopGBW();
+                    }
+                }
+            }
+            else if (strstr(msg_notify, "AP-STA-CONNECTED") != NULL)
+            {
+                inner_notify_ap_msg(LYNQ_WIFI_STATUS_CONNECT);
+                if (g_gbw_enabled == 1 && g_gbw_mac != NULL)
+                {
+                    RLOGD("conect %d, %s ,%s\n", g_gbw_enabled, g_gbw_mac, strstr(msg_notify, (const char*)g_gbw_mac));
+                    if (strstr(msg_notify, (const char*)g_gbw_mac) != NULL)
+                    {
+                        startGBW();
+                    }
+                }
+            }
+            else if ( strstr(msg_notify, "Failed to start AP functionality") != NULL )
+            {
+                RLOGD("APWatcherThreadProc ap------> service error");
+                inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+            }
+            else
+            {
+                RLOGD("APWatcherThreadProc ap------> going on check next msg");
+            }
+            //you.chen add for tv-box end
+        } // end if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+    } // end while (g_ap_watcher_stop_flag == 0)
+    if (lynq_wpa_ctrl != NULL)
+    {
+        wpa_ctrl_detach(lynq_wpa_ctrl);
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+}
+
+static void inner_check_connect_error(const char * event_msg, lynq_wifi_sta_status_s state, error_number_s error_num)
+{
+    char * p;
+    const char * try_associat_flag = "Trying to associate";
+    const char * associated_flag = "Associated with ";
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    if (s_sta_status < INNER_STA_STATUS_CONNECTING || s_sta_status >= INNER_STA_STATUS_CONNECTED) //not in connecting stage, egnore
+    {
+        pthread_mutex_unlock(&s_global_check_mutex);
+        return;
+    }
+
+    // youchen@2023-10-17 add for "not notify connect fail directly" begin
+    if (state == LYNQ_WIFI_STA_STATUS_CONNECT_FAIL)
+    {
+        s_sta_error_number = error_num;
+        s_sta_status = INNER_STA_STATUS_DISCONNECTED;
+        RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+        pthread_cond_signal(&s_global_check_cond);
+        pthread_mutex_unlock(&s_global_check_mutex);
+        return;
+    }
+    // youchen@2023-10-17 add for "not notify connect fail directly" end
+
+    if (state == LYNQ_WIFI_STATUS_EGNORE)
+    {
+        if (strstr(event_msg, try_associat_flag) != NULL && strstr(event_msg, s_sta_current_connecting_ssid) != NULL) //associating request ssid
+        {
+            s_sta_status = INNER_STA_STATUS_ASSOCIATING;
+        }
+        else if (s_sta_status == INNER_STA_STATUS_ASSOCIATING && (p=strstr(event_msg, associated_flag)) != NULL)
+        {
+            s_sta_status = INNER_STA_STATUS_ASSOCIATED;
+        }
+    }
+    else if (state == LYNQ_WIFI_STA_STATUS_DISCONNECT)
+    {
+        s_sta_error_number = error_num;
+        if (s_sta_status >= INNER_STA_STATUS_ASSOCIATING && strstr(event_msg, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL && error_num != LYNQ_WAIT_CONNECT_ACTIVE)
+        {
+            s_sta_status = INNER_STA_STATUS_DISCONNECTED;
+            RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+            pthread_cond_signal(&s_global_check_cond);
+        }
+    }
+    else if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+    {
+        s_sta_status = INNER_STA_STATUS_CONNECTED;
+        RLOGD("inner_check_connect_error line: %d, curr state %d, %d %d ------",__LINE__, state, s_sta_status, s_sta_error_number);
+        pthread_cond_signal(&s_global_check_cond);
+    }
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
+static int lynq_split(char * str, int len, char delimiter, char * results[]);
+static inline char inner_convert_char(char in);
+static inline void inner_copy_ssid(char * out_ssid, const char * ssid,  size_t out_ssid_len);
+static int lynq_get_network_number_list(lynq_wifi_index_e idx, int ap_sta, int net_no_list[], char * ssid);
+
+
+
+/*
+just tmp add for fix sta connect ap fail check ap connect info
+return 0 --->Current no sta device connect this AP
+*/
+static int lynq_connected_ap_sta_status() {
+
+    FILE *fp;
+    size_t i = 0;
+    int ret;
+    char lynq_cmd_ret[MAX_RET]={0};
+
+    if((fp=popen("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 list_sta","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+    {
+        perror("fread fail!");
+        ret=pclose(fp);
+        if(ret == -1)
+            perror("close file faild");
+        return -1;
+    }
+    if( strlen(lynq_cmd_ret) < MAC_LEN)
+    {
+        RLOGD("---Current no sta device connect this AP %s  %d\n", lynq_cmd_ret,strlen(lynq_cmd_ret));
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+            perror("close file faild");
+        }
+        return 0;
+    }else{
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+            perror("close file faild");
+        }
+        RLOGD("---Current has sta device connect this AP--- %s\n", lynq_cmd_ret);
+        return 1;
+     }
+}
+
+/*
+    just tmp add for fix sta connect ap fail; check fw status
+    return 1 ----> fw status error; need wl down/up
+*/
+static int check_current_fw_status() {
+
+    FILE *fp;
+    FILE *fp1;
+    size_t i = 0;
+    int ret;
+    char lynq_cmd_ret_2g[MAX_RET]={0};
+    char lynq_cmd_ret_5g[MAX_RET]={0};
+
+    const char * fw_status = "0x0096";    //0x0096 is normal fw status
+
+    if((fp=popen("wl shmem  0x15ee a","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret_5g,sizeof(lynq_cmd_ret_2g),1,fp))<0)
+    {
+        perror("fread fail!");
+        if(pclose(fp) == -1)
+            perror("close fp file faild");
+        return -1;
+    }
+
+    if((fp1=popen("wl shmem  0x15ee b","r"))==NULL)
+    {
+        perror("popen error!");
+        if(pclose(fp) == -1)
+            perror("clsoe fp file faild");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret_2g,sizeof(lynq_cmd_ret_5g),1,fp1))<0)
+    {
+        perror("fread fail!");
+        if(pclose(fp1) == -1)
+            perror("clsoe fp1 file faild");
+        if(pclose(fp) == -1)
+            perror("clsoe fp file faild");
+        return -1;
+    }
+
+    if ( strncmp(fw_status,lynq_cmd_ret_2g,6) == 0 || strncmp(fw_status,lynq_cmd_ret_5g,6) == 0 )
+    {
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+            perror("close fp file faild");
+        }
+        ret=pclose(fp1);
+        if(ret==-1)
+        {
+            perror("close fp1 file faild");
+        }
+        return 0;
+    }else
+    {
+        ret=pclose(fp);
+        if(ret==-1)
+        {
+           perror("close file faild");
+        }
+        if(pclose(fp1) == -1)
+        {
+            perror("clsoe file fp1 faild");
+        }
+        RLOGD("current fw status --error--");
+        return 1;
+    }
+}
+
+/*
+eg: wl counters info
+sh-3.2# wl counters
+counters_version 30
+datalen 1648
+Slice_index: 0
+reinitreason_counts: 0(0) 1(0) 2(3) 3(0) 4(0) 5(0) 6(0) 7(0) 8(0) 9(0) 10(0) 11(0) 12(0) 13(0) 14(2) 15(0) 16(0) 17(0) 18(0) 19(0) 20(0) 21(0) 22(0) 23(0) 24(0) 25(0) 26(0) 27(0) 28(0) 29(0) 30(0) 31(0) 32(0) 33(0) 34(0) 35(0) 36(0) 37(0) 38(0) 39(0) 40(0) 41(0) 42(0) 43(0) 44(0) 45(0) 46(0) 47(0) 48(0) 49(0) 50(0) 51(0) 52(0) 53(0) 54(0)
+reinit 0 reset 2 pciereset 0 cfgrestore 0 dma_hang 0 ampdu_wds 0
+
+check reinit status
+return 0 ===> fw did wl reinit cmd
+*/
+static int check_current_reinit_info()
+{
+    FILE *fp;
+    int ret;
+    char lynq_cmd_ret[MAX_RET]={0};
+    char * dest;
+    char destid[3]={0};
+    if((fp=popen("wl counters","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+    {
+        perror("fread fail!");
+        if(pclose(fp) == -1)
+        {
+           perror("close fp file faild");
+        }
+        return -1;
+    }
+    dest = strstr(lynq_cmd_ret,"reinit ");
+    if(dest != NULL)
+    {
+        dest +=strlen("reinit ");
+        RLOGD("current get dest str is %s",dest);
+        memcpy(destid,dest,2);
+        ret = atoi(destid);
+        RLOGD("get current wl counters cmd return counts is %d",ret);
+        if( ret != 0 )
+        {
+            RLOGD("current fw did run cmd wl reinit");
+            if( pclose(fp) == -1 )
+            {
+                perror("close fp file faild");
+            }
+            return 0;
+        }
+    }
+    if( pclose(fp) == -1 )
+    {
+       perror("close fp file faild");
+    }
+    RLOGD("current fw didn't run cmd wl reinit,dest ptr is NULL");
+    return -1;
+}
+
+static void APTmpWatcherThreadProc() {
+
+    int i = 0;
+    int delytime = 300;
+    g_ap_tmp_watcher_stop_flag = 0;
+
+    RLOGD("APTmpWatcherThreadProc ----> ThreadProc start");
+    while(1)
+    {
+        sleep(1);
+        i++;
+        if ( (i % 30) == 0 )
+        {
+            if ( check_current_reinit_info() == 0 )
+            {
+                system("wl reset_cnts");
+                system("wl down");
+                system("wl up");
+                RLOGD("APTmpWatcherThreadProc:check fw did reinit cmd,do down/up reset");
+            }
+        }
+        if ( (i % 10) == 0 )
+        {
+            if( lynq_connected_ap_sta_status() == 0 )      //0 --->no sta device connect this ap
+            {
+                if(check_current_fw_status() == 1)        //1 --->current fw status not 0x0096
+                {
+                    system("wl down");
+                    system("wl up");
+                }
+            }
+        }
+        if ( i == delytime )
+        {
+            i = 0;
+        }
+        if( g_ap_tmp_watcher_stop_flag == 1 )       //quit proc
+        {
+           RLOGD("APTmpWatcherThreadProc ----- > ap closed or wifi disabled");
+           return;
+        }
+
+    }
+
+}
+
+static int lynq_wifi_sta_stop_network(lynq_wifi_index_e idx,int networkid)
+{
+    char LYNQ_DISABLE_CMD[128]={0};
+    
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+    
+    sprintf(LYNQ_DISABLE_CMD,"DISABLE_NETWORK %d",networkid);
+    RLOGD("LYNQ_DISABLE_CMD is:%s\n",LYNQ_DISABLE_CMD);
+    DO_OK_FAIL_REQUEST(LYNQ_DISABLE_CMD);
+
+    return 0;
+
+}
+
+static int lynq_wifi_sta_enable_network(lynq_wifi_index_e idx,int networkid)
+{
+    char LYNQ_ENABLE_CMD[128]={0};
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+
+    sprintf(LYNQ_ENABLE_CMD,"ENABLE_NETWORK %d",networkid);
+    RLOGD("LYNQ_ENABLE_CMD is:%s\n",LYNQ_ENABLE_CMD);
+    DO_OK_FAIL_REQUEST(LYNQ_ENABLE_CMD);
+
+    return 0;
+
+}
+
+static int lynq_tmp_enable_network(lynq_wifi_index_e idx,int net_no_list[],int len)
+{
+
+    int index,networkid;
+
+    for ( index = 0; index < len ;index++)
+    {
+        networkid = net_no_list[index];
+        if( lynq_wifi_sta_enable_network(idx,networkid) != 0 )
+        {
+            RLOGE("[wifi]lynq_tmp_enable_network  id is %d fail",networkid);
+        }
+        RLOGD("[wifi]lynq_tmp_enable_network  id is %d",networkid);
+     }
+    return 0;
+
+}
+
+
+/*
+    dis_net_list   user disconnect list
+*/
+static void lynq_two_arr_merge(int dis_net_list[],int valid_num,int out[],int * outlen)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    print_disconnect_list();
+    int count,ncount,index;
+    int flag = 0;
+    int merge_index = 0;
+    int net_no_list[128];
+
+    for(ncount = 0;ncount < valid_num; ncount++ )
+    {
+        RLOGD("input history disconenct_list[%d] %d %d",ncount,dis_net_list[ncount],__LINE__);
+    }
+
+    index =lynq_get_network_number_list(0, 0, net_no_list,NULL);
+    for( count = 0; count < index; count++)
+    {
+        for(ncount = 0; ncount < valid_num; ncount++)
+        {
+            RLOGD(" %s dis_net_list[%d]->%d %d",__func__,ncount,dis_net_list[ncount],__LINE__);
+            if(net_no_list[count] == dis_net_list[ncount])
+            {
+                RLOGD("[wifi]this is history disconnect idx ----> %d %d",net_no_list[count],__LINE__);
+                flag = 1;
+                break;
+            }
+        }
+        if( flag != 1 )
+        {
+            out[merge_index] = net_no_list[count];
+            RLOGD("out[%d]: %d    net_no_list[%d]: %d %d",merge_index,out[merge_index],count,net_no_list[count],__LINE__);
+            merge_index ++;
+        }
+        flag = 0;
+    }
+    * outlen =merge_index;
+    RLOGD("[wifi]lynq_two_arr_merge get len is -----> %d",* outlen);
+    return;
+}
+
+void get_state_error(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error)
+{
+    char *pReason;
+    char *wpanetid;
+    char destid[3] = {0};
+    int tmpdisid = -1;
+    *error = LYNQ_WAIT_CONNECT_ACTIVE;
+    if (strstr(modify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_SCAN_RESULT;
+        RLOGD("CTRL-EVENT-SCAN-RESULTS state:%d,error:%d\n",*state,*error);
+        return;
+    }
+
+    if (strstr(modify, "Trying to associate") != NULL)
+    {
+        RLOGD("Current sta is Trying to associate");
+        *state = LYNQ_WIFI_STATUS_EGNORE;
+        g_sta_conncet_status_flag = 1;
+	return;
+    }
+
+    if (strstr(modify, "CTRL-EVENT-CONNECTED") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_CONNECT;
+        RLOGD("CTRL-EVENT-CONNECTED state:%d,error:%d",*state,*error);
+        g_sta_conncet_status_flag = 0;
+        return;
+    }
+
+    if (strstr(modify,"CTRL-EVENT-AUTH-REJECT") != NULL)
+    {
+        *error = LYNQ_PSW_ERROR;
+        *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+        RLOGD("CTRL-EVENT-AUTH-REJECT state:%d,error:%d\n",*state,*error);
+        g_sta_conncet_status_flag = 0;
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            memcpy(destid,wpanetid,2);
+            tmpdisid = atoi(destid);
+
+        }
+        pReason = strstr(modify, "reason=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("reason=");
+            if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+            {
+                *error = LYNQ_TIME_OUT;
+            }
+            else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+            {
+                *error = LYNQ_PSW_ERROR;
+                *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+                // tmp fix sta autoconnect connect and disconnect
+                // you.chen@2023-10-17 only disable network during autoconnect
+                if(tmpdisid != -1 && s_sta_status == INNER_STA_STATUS_INIT && lynq_wifi_sta_stop_network(0,tmpdisid) != 0)
+                {
+                    RLOGE("stop wlan0 network %d fail",tmpdisid);
+                }
+            }
+            else 
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+        }
+        else
+        {
+            *error = LYNQ_UNSPECIFIED_REASON;
+        }
+        RLOGD("CTRL-EVENT-SSID-TEMP-DISABLED state:%d,error:%d,tmpnetid:%d",*state,*error,tmpdisid);
+        g_sta_conncet_status_flag = 0;
+        return;
+
+    }
+
+    if (strstr(modify, "CTRL-EVENT-NETWORK-NOT-FOUND") != NULL)
+    {
+        *error = LYNQ_NOT_FIND_AP;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-NETWORK-NOT-FOUND state:%d,error:%d\n",*state,*error);
+        g_sta_conncet_status_flag = 0;
+        return;
+    }
+
+
+    if (strstr(modify, "CTRL-EVENT-ASSOC-REJECT") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT\n");
+        pReason = strstr(modify, "status_code=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("status_code=");
+            if (memcmp(pReason, "17", 2) == 0)
+            {
+                *error = LYNQ_AP_UNABLE_HANDLE;
+            }
+            else if (memcmp(pReason, "1",1) == 0)
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+            else
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+
+             *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+             RLOGD("CTRL-EVENT-ASSOC-REJECT BUT NOT STATUS_CODE NOT 1 or 17 state:%d,error:%d\n",*state,*error);
+             g_sta_conncet_status_flag = 0;
+             return;
+        }
+        else
+        {
+            RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT BUT NOT FOUND STATUS_CODE\n");
+            *error = LYNQ_UNSPECIFIED_REASON;
+            *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+            RLOGD("CTRL-EVENT-ASSOC-REJECT state:%d,error:%d\n",*state,*error);
+            return;
+        }
+    }
+
+    if (strstr(modify, "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER\n");
+        *error = LYNQ_AUTHENTICATION_NO_LONGER_VALID;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER state:%d,error:%d\n",*state,*error);
+        return;
+    }
+
+    if (strstr(modify, "CTRL-EVENT-DISCONNECTED") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-DISCONNECTED\n");
+        *error = LYNQ_WAIT_CONNECT_ACTIVE;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d\n",*state,*error);
+        return;
+    }
+
+    // add by qs.xiong 20231026   tmp fix sta association request to the driver failed
+    if (strstr(modify, "Association request to the driver failed") != NULL)
+    {
+        RLOGD("Association request to the driver failed --- recover");
+        system("wl down");
+        system("wl up");
+        *error = LYNQ_UNSPECIFIED_REASON;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d\n",*state,*error);
+        return;
+    }
+    // add by qs.xiong 20231026   tmp fix sta association request to the driver failed end
+
+
+    RLOGD("EVENT : %s\n", modify);
+    *error = LYNQ_UNSPECIFIED_REASON;
+    *state = LYNQ_WIFI_STATUS_EGNORE;
+    RLOGD("LAST : STA state:%d,error:%d\n",*state,*error);
+    return;
+
+}
+
+void get_state_error_networkid(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error,int *networkid)
+{
+    char *pReason;
+    char *wpanetid;
+    char destid[3];
+    *error = LYNQ_WAIT_CONNECT_ACTIVE;
+    *networkid = -1;
+    if (strstr(modify, "CTRL-EVENT-SCAN-RESULTS") != NULL)
+    {
+        *state = LYNQ_WIFI_STA_STATUS_SCAN_RESULT;
+        RLOGD("CTRL-EVENT-SCAN-RESULTS state:%d,error:%d,,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-CONNECTED") != NULL)
+    {
+        RLOGD("[xiong]:wpanetid = strstrmodify;\n");
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            RLOGD("[xiong]:memcpy(destid,wpanetid,0\n");
+            if (memcpy(destid,wpanetid,2) != NULL)
+            {
+                 RLOGD("[xiong]:memcpy(destid,wpanetid,1\n");
+                *networkid = atoi(destid);
+                RLOGD("get networkid is %d\n",*networkid);
+            }
+             RLOGD("[xiong]:memcpy(destid,wpanetid,2\n");
+        }
+        *state = LYNQ_WIFI_STA_STATUS_CONNECT;
+        RLOGD("CTRL-EVENT-CONNECTED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-SSID-TEMP-DISABLED") != NULL)
+    {
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            if (memcpy(destid,wpanetid,2) != NULL)
+            {
+                *networkid = atoi(destid);
+                RLOGD("get networkid is %d\n",*networkid);
+            }
+        }
+        pReason = strstr(modify, "reason=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("reason=");
+            if (memcmp(pReason, "CONN_FAILED", 11) == 0)
+            {
+                *error = LYNQ_TIME_OUT;
+            }
+            else if (memcmp(pReason, "WRONG_KEY", 9) == 0)
+            {
+                *error = LYNQ_PSW_ERROR;
+            }
+            else 
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+            *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+            RLOGD("CTRL-EVENT-SSID-TEMP-DISABLED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+            return;
+        }
+        else
+        {
+            *error = LYNQ_UNSPECIFIED_REASON;
+            *state = LYNQ_WIFI_STA_STATUS_CONNECT_FAIL;
+            return;
+        }
+    }
+    if (strstr(modify, "CTRL-EVENT-ASSOC-REJECT") != NULL)
+    {
+        wpanetid = strstr(modify,"id=");
+        if ( wpanetid != NULL )
+        {
+            wpanetid +=strlen("id=");
+            if (memcpy(destid,wpanetid,2) != NULL)
+            {
+                *networkid = atoi(destid);
+                RLOGD("get networkid is %d\n",*networkid);
+            }
+        }
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT\n");
+        pReason = strstr(modify, "status_code=");
+        if (pReason != NULL)
+        {
+            pReason += strlen("status_code=");
+            if (memcmp(pReason, "17", 2) == 0)
+            {
+                *error = LYNQ_AP_UNABLE_HANDLE;
+            }
+            else if (memcmp(pReason, "1",1) == 0)
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+            else
+            {
+                *error = LYNQ_UNSPECIFIED_REASON;
+            }
+             *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+             RLOGD("CTRL-EVENT-ASSOC-REJECT BUT NOT STATUS_CODE NOT 1 or 17 state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+             return;
+        }
+        else
+        {
+            RLOGD("FIND CTRL EVENT : CTRL-EVENT-ASSOC-REJECT BUT NOT FOUND STATUS_CODE\n");
+            *error = LYNQ_UNSPECIFIED_REASON;
+            *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+            RLOGD("CTRL-EVENT-ASSOC-REJECT state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+            return;
+        }
+    }
+    if (strstr(modify, "CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER\n");
+        *error = LYNQ_AUTHENTICATION_NO_LONGER_VALID;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-SAE-UNKNOWN-PASSWORD-IDENTIFIER state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    if (strstr(modify, "CTRL-EVENT-DISCONNECTED") != NULL)
+    {
+        RLOGD("FIND CTRL EVENT : CTRL-EVENT-DISCONNECTED\n");
+        *error = LYNQ_WAIT_CONNECT_ACTIVE;
+        *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+        RLOGD("CTRL-EVENT-DISCONNECTED state:%d,error:%d,networkid:%d\n",*state,*error,*networkid);
+        return;
+    }
+    RLOGD("EVENT : %s\n", modify);
+    *error = LYNQ_UNSPECIFIED_REASON;
+    *state = LYNQ_WIFI_STATUS_EGNORE;
+    RLOGD("LAST : STA state:%d,error:%d,network:%d\n",*state,*error,*networkid);
+    return;
+}
+static void notify_connect_status(lynq_wifi_sta_status_s state, error_number_s error)
+{
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    if (g_sta_callback_func != NULL && state != LYNQ_WIFI_STATUS_EGNORE)
+    {
+        RLOGD("STAWatcherThreadProc callback begin ------> %d %d\n", state, error);
+        g_sta_callback_func(g_sta_callback_priv, state, error);
+        RLOGD("STAWatcherThreadProc callback end ------> %d %d\n", state, error);
+    }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+}
+static void notify_auto_connect_status(lynq_wifi_sta_status_s state, error_number_s error,int networkid)
+{
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    if (g_sta_callback_func != NULL && state != LYNQ_WIFI_STATUS_EGNORE)
+    {
+        RLOGD("STAWatcherThreadProc callback begin ------> %d %d %d\n", state, error,networkid);
+        g_sta_auto_callback_func(g_sta_auto_callback_priv, state, error,networkid);
+        RLOGD("STAAutoWatcherThreadProc callback end ------> %d %d %d\n", state, error,networkid);
+    }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+}
+
+static void STAWatcherThreadProc() {
+    size_t len = MAX_RET;
+    char msg_notify[MAX_RET];
+    error_number_s error;
+    lynq_wifi_sta_status_s state, last_state = -1;
+    int idle_count = 0;
+
+    struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+    g_sta_watcher_stop_flag = 0;
+
+    RLOGD("STAWatcherThreadProc thread started ------");
+    while (g_sta_watcher_stop_flag == 0)
+    {
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_watcher_started_flag) != 1)
+        {
+            continue;
+        }
+
+        memset(msg_notify, 0, MAX_RET);
+        len = MAX_RET;
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+        {
+            msg_notify[len+1] = '\0';
+            RLOGD("STAWatcherThreadProc sta ------> %s\n", msg_notify);
+            if (strstr(msg_notify, state_scan_result) != NULL)
+            {
+                g_sta_scan_finish_flag = 1;
+            }
+
+            if (g_sta_callback_func == NULL)
+            {
+                continue;
+            }
+            get_state_error(msg_notify,&state,&error);
+            // youchen@2023-10-17 add for "not notify connect fail directly" begin
+            if (state == LYNQ_WIFI_STA_STATUS_CONNECT_FAIL)
+            {
+                notify_connect_status(LYNQ_WIFI_STA_STATUS_DISCONNECT, error);
+            }
+            else if (state == LYNQ_WIFI_STA_STATUS_SCAN_RESULT &&
+                     s_sta_status != INNER_STA_STATUS_INIT && g_sta_conncet_status_flag != 0)
+            {
+                RLOGD("donot report scan result during in call connect manual");
+            }
+            else
+            {
+                notify_connect_status(state, error);
+            }
+            // youchen@2023-10-17 add for "not notify connect fail directly" end
+
+            if (state != LYNQ_WIFI_STA_STATUS_SCAN_RESULT)
+            {
+                inner_check_connect_error(msg_notify, state, error);
+                if (last_state != state)
+                {
+                    if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+                    {
+                        system_call_v("%s %s", sta_status_change_script, "connect");
+                    }
+                    else if (state == LYNQ_WIFI_STA_STATUS_DISCONNECT)
+                    {
+                        system_call_v("%s %s", sta_status_change_script, "disconnect");
+                    }
+                }
+
+                last_state = state;
+                if (g_sta_fake_scan_finish_flag == 1)
+                {
+                    g_sta_fake_scan_finish_flag = 0;
+                    notify_connect_status(LYNQ_WIFI_STA_STATUS_SCAN_RESULT, 0);
+                }
+            }
+        }
+    }
+    if (lynq_wpa_ctrl != NULL)
+    {
+        wpa_ctrl_detach(lynq_wpa_ctrl);
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+}
+static void STAAutoWatcherThreadProc() {
+    size_t len = MAX_RET;
+    char msg_notify[MAX_RET];
+    error_number_s error;
+    lynq_wifi_sta_status_s state;
+    int idle_count = 0;
+    int networkid;
+    struct wpa_ctrl *lynq_wpa_ctrl = NULL;
+    g_sta_auto_watcher_stop_flag = 0;
+    RLOGD("STAAutoWatcherThreadProc thread started ------");
+    while (g_sta_auto_watcher_stop_flag == 0)
+    {
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_auto_watcher_started_flag) != 1)
+        {
+            continue;
+        }
+        memset(msg_notify, 0, MAX_RET);
+        len = MAX_RET;
+        if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
+        {
+            msg_notify[len+1] = '\0';
+            RLOGD("STAAutoWatcherThreadProc sta ------> %s\n", msg_notify);
+            if (strstr(msg_notify, state_scan_result) != NULL)
+            {
+                g_sta_auto_scan_finish_flag = 1;
+            }
+            if (g_sta_auto_callback_func == NULL)
+            {
+                continue;
+            }
+            get_state_error_networkid(msg_notify,&state,&error,&networkid); // add net state error network function
+            notify_auto_connect_status(state, error,networkid);
+        }
+    }
+    if (lynq_wpa_ctrl != NULL)
+    {
+        wpa_ctrl_detach(lynq_wpa_ctrl);
+        wpa_ctrl_close(lynq_wpa_ctrl);
+    }
+}
+
+// this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
+static void GlobalWatcherThreadProc()
+{
+    int ret, connect_timeout, service_abnormal;
+    error_number_s error_num = -1;
+    inner_sta_status_s sta_status;
+    scan_info_s *scan_list = NULL;
+    int i, scan_len=0;
+    char connecting_ssid[64];
+    struct timeval now;
+
+    RLOGD("GlobalWatcherThreadProc start to run");
+
+    while (1)
+    {
+        pthread_mutex_lock(&s_global_check_mutex);
+        pthread_cond_wait(&s_global_check_cond,&s_global_check_mutex);
+        if (s_sta_status == INNER_STA_STATUS_CONNECTED)
+        {
+            pthread_mutex_unlock(&s_global_check_mutex);
+            usleep(50*1000);
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+            continue;
+        }
+
+        connect_timeout = 0;
+        service_abnormal = 0;
+        if (s_sta_status >= INNER_STA_STATUS_CONNECTING && s_sta_status < INNER_STA_STATUS_CONNECTED)
+        {
+            while (1)
+            {
+                ret = pthread_cond_timedwait(&s_global_check_cond, &s_global_check_mutex, &s_sta_connect_timeout);
+                if (ret == ETIME)
+                {
+                    connect_timeout = 1;
+                }
+                else if (ret != 0)
+                {
+                    gettimeofday(&now,NULL);
+                    if (now.tv_sec < s_sta_connect_timeout.tv_sec) //time not arrive
+                    {
+                        usleep(SLEEP_TIME_ON_IDLE);
+                        continue;
+                    }
+                    connect_timeout = 1;
+                }
+                sta_status = s_sta_status;
+                error_num = s_sta_error_number;
+                s_sta_status = INNER_STA_STATUS_INIT;
+                strcpy(connecting_ssid, s_sta_current_connecting_ssid);
+                memset(&s_sta_connect_timeout, 0, sizeof (s_sta_connect_timeout));
+                memset(&s_sta_current_connecting_ssid, 0, sizeof (s_sta_current_connecting_ssid));
+                break;
+            }
+        }
+        if (s_service_invoke_timeout_cnt > 10)
+        {
+            service_abnormal = 1;
+            s_service_invoke_timeout_cnt = 0;
+        }
+        pthread_mutex_unlock(&s_global_check_mutex);
+
+        if (service_abnormal == 1)
+        {
+            sleep(1);
+            RLOGE("wpa service is abnormal info app to exit");
+            notify_connect_status(LYNQ_WIFI_STA_SERVICE_ABNORMAL, -1);
+
+            inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+
+            sleep(FAKE_MAX_INT_VALUE); // wait process to exit
+        }
+
+        if (sta_status == INNER_STA_STATUS_CANCEL)
+        {
+            continue;
+        }
+        else if (sta_status == INNER_STA_STATUS_CONNECTED)
+        {
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+        }
+        else if (connect_timeout == 0 && error_num == LYNQ_NOT_FIND_AP) // not found ap maybe mismatch auth
+        {
+            if (0 == lynq_get_scan_list(0, &scan_list, &scan_len) && NULL != scan_list) // if not found, but scan result exist, maybe auth error
+            {
+                for(i=0; i < scan_len;i++)
+                {
+                    if (strcmp(scan_list[i].ssid, connecting_ssid) == 0)
+                    {
+                        error_num = LYNQ_AUTH_ERROR;
+                        break;
+                    }
+                }
+                free(scan_list);
+            }
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, error_num);
+        }
+        else if (connect_timeout == 0)
+        {
+            notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, error_num);
+        }
+        else // wait timeout
+        {
+            if (0 != lynq_get_sta_status(LYNQ_WIFI_INTERFACE_0, &sta_status)) // get status fail
+            {
+                ; // wpa service abnormal
+            }
+            else if (sta_status == LYNQ_WIFI_STA_STATUS_ENABLE) // connect ok
+            {
+                RLOGD("GlobalWatcherThreadProc notify connected");
+                notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT, 0);
+            }
+            else
+            {
+                RLOGD("GlobalWatcherThreadProc notify timeout");
+                notify_connect_status(LYNQ_WIFI_STA_STATUS_CONNECT_FAIL, LYNQ_TIME_OUT);
+            }
+        }
+    } // while (1)
+}
+
+int lynq_wifi_enable(void)
+{
+    int ret = 0;
+    int i;
+    RLOGD("enter lynq_wifi_enable");
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+
+    if (g_lynq_wpa_ctrl[0] != NULL && g_lynq_wpa_ctrl[1] != NULL)
+    {
+        goto out_enable;
+    }
+
+    ret = system(start_wg870_service_script);
+    if (ret != 0)
+    {
+        //printf("service state %d\n", ret);
+        RLOGE("[wifi error]service state %d",ret);
+        ret = -1;
+        goto out_enable;
+    }
+
+    if (g_global_watcher_pid == 0 ) // this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
+    {
+        ret=pthread_create(&g_global_watcher_pid,NULL,GlobalWatcherThreadProc,NULL);
+        if(ret<0)
+        {
+            RLOGE("[wifi error]creat GlobalWatcherThreadProc fail");
+            ret = -1;
+            goto out_enable;
+        }
+    }
+
+    g_lynq_wpa_ctrl[0] = malloc(sizeof (struct local_wpa_ctrl));
+    g_lynq_wpa_ctrl[1] = malloc(sizeof (struct local_wpa_ctrl));
+    memset(g_lynq_wpa_ctrl[0], 0 , sizeof(struct local_wpa_ctrl));
+    memset(g_lynq_wpa_ctrl[1], 0 , sizeof(struct local_wpa_ctrl));
+out_enable:
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    return ret;
+}
+
+int lynq_wifi_disable(void)
+{
+    RLOGD("enter lynq_wifi_disable");
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    g_ap_watcher_stop_flag = 1;
+    g_sta_watcher_stop_flag = 1;
+    g_sta_auto_watcher_stop_flag = 1;
+/*  g_ap_tmp_watcher_stop_flag = 1;
+    if (g_ap_watcher_pid != 0)
+        pthread_join(g_ap_watcher_pid, NULL);
+*/
+    if (g_sta_watcher_pid != 0)
+        pthread_join(g_sta_watcher_pid, NULL);
+    if (g_sta_auto_watcher_pid != 0)
+        pthread_join(g_sta_auto_watcher_pid, NULL);
+    if (g_lynq_wpa_ctrl[0] != NULL)
+        wpa_ctrl_close(g_lynq_wpa_ctrl[0]);
+    if (g_lynq_wpa_ctrl[1] != NULL)
+        wpa_ctrl_close(g_lynq_wpa_ctrl[1]);
+    if (g_ap_tmp_watcher_pid != 0)
+        pthread_join(g_ap_tmp_watcher_pid, NULL);
+    g_ap_watcher_pid = 0;
+    g_sta_watcher_pid = 0;
+    g_sta_auto_watcher_pid = 0;
+//    g_ap_tmp_watcher_pid = 0;
+    g_lynq_wpa_ctrl[0] = NULL;
+    g_lynq_wpa_ctrl[1] = NULL;
+    g_history_disconnect_valid_num = 0;   //clean history_disconenct_list info
+    system("systemctl stop wg870_drv_insmod.service");
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    return 0;
+}
+
+static inline char inner_convert_char(char in)
+{
+    if (in >= '0' && in <= '9')
+    {
+        return in - '0';
+    }
+    else if (in >= 'a' && in <= 'f')
+    {
+        return in - 'a' + 10;
+    }
+    else if (in >= 'A' && in <= 'F')
+    {
+        return in - 'A' + 10;
+    }
+    else
+    {
+        return '\xff';
+    }
+}
+
+static inline void inner_copy_ssid(char * out_ssid, const char * ssid,  size_t out_ssid_len)
+{
+    char *p;
+    size_t pos = 0;
+    if (NULL == out_ssid)
+        return;
+    //printf("input ssid=[%s]\n", ssid);
+    memset(out_ssid, 0, out_ssid_len);
+    if (NULL == ssid)
+        return;
+    p = strchr(ssid, '\\');
+    if (NULL == p)
+    {
+        strncpy(out_ssid, ssid, out_ssid_len);
+        //printf(" first %s\n", out_ssid);
+    }
+    else
+    {
+        pos = p - ssid;
+        memcpy(out_ssid, ssid, pos);
+        //printf("pos %lu -- %s\n", pos, out_ssid);
+        for(; pos < out_ssid_len; pos ++)
+        {
+            if (p[0] == '\0')
+            {
+                //printf(" out %s\n", out_ssid);
+                return;
+            }
+            else if (p[0] != '\\')
+            {
+                out_ssid[pos] = p[0];
+                p += 1;
+            }
+            else if (p[1] == 'x' || p[1] == 'X')
+            {
+                out_ssid[pos] = inner_convert_char(p[2]) << 4 | inner_convert_char(p[3]);
+                p += 4;
+            }
+            else if (p[1] == '\\')
+            {
+                out_ssid[pos] = '\\';
+                p += 2;
+            }
+            else if (p[1] == 't')
+            {
+                out_ssid[pos] = '\t';
+                p += 2;
+            }
+            else if (p[1] == 'r')
+            {
+                out_ssid[pos] = '\r';
+                p += 2;
+            }
+            else if (p[1] == 'n')
+            {
+                out_ssid[pos] = '\n';
+                p += 2;
+            }
+            else
+            {
+                out_ssid[pos] = p[1];
+                p += 2;
+            }//todo find a better way to convert?
+        }
+    }
+    //printf(" out %s\n", out_ssid);
+}
+
+static int inner_get_param(int interface, int net_no, char* param_name, char * out_put) {
+    int i, ssid_len;
+    char lynq_cmd_get[128]={0};
+    RLOGD("enter inner_get_param");
+    if (out_put == NULL)
+    {
+        RLOGE("output ptr is null");
+        return -1;
+    }
+    if (param_name == NULL)
+    {
+        RLOGE("param ptr is null");
+        return -1;
+    }
+    if (param_name[0] == '\0')
+    {
+        RLOGE("param is empty");
+        return -1;
+    }
+
+    sprintf(lynq_cmd_get, "GET_NETWORK %d %s", net_no, param_name);
+
+    CHECK_WPA_CTRL(interface);
+
+    DO_REQUEST(lynq_cmd_get);
+
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("wpa_supplicant return cmd_reply is FAIL");
+        return -1;
+    }
+
+//    printf("reply len %d, %08x\n", reply_len, (int)out_put);
+    if (strcmp(param_name, "ssid") == 0)
+    {
+        if (cmd_reply[0] == '\"')
+	{
+            ssid_len = reply_len - 1;
+            memcpy(out_put, cmd_reply + 1, ssid_len);
+            if (out_put[ssid_len-1] == '\"')
+            {
+                out_put[ssid_len-1] = '\0';
+            }
+            else
+            {
+                out_put[ssid_len] = '\0';
+            }
+        }
+        else
+	{
+            ssid_len = reply_len / 2;
+            for(i=0; i<ssid_len; i++)
+            {
+                out_put[i] = inner_convert_char(cmd_reply[i*2]) << 4 | inner_convert_char(cmd_reply[i*2 + 1]);
+            }
+            out_put[ssid_len] = '\0';
+        }
+    }
+    else
+    {
+        memcpy(out_put, cmd_reply, reply_len + 1);
+    }
+    return 0;
+}
+
+static int lynq_split(char * str, int len, char delimiter, char * results[]) {
+    int ret = 0;
+    char * end = str + len - 1;
+    results[ret++] = str;
+    while(str < end)
+    {
+        if (*str == delimiter)
+	{
+            *str++ = '\0';
+            results[ret++] = str;
+            continue;
+        }
+        str++;
+    }
+    if (*str == delimiter)
+    {
+        *str = '\0';
+    }
+
+    results[ret] = NULL;
+
+    return ret;
+}
+/*
+ *add func to get conencted STA device ip from dnsmasq ap0.lease
+ *return 0 means get ip success
+ */
+static int inner_get_ip_by_mac_lease(const char * mac, char * ip,int ip_len)
+{
+    char * p;
+    int ret;
+    char cmd[256]={0};
+    if (NULL == mac || NULL == ip)
+        return -1;
+    memset(ip, 0, ip_len);
+    sprintf(cmd, "cat /run/wg870/ap0.lease | grep \"%s\" | awk '{print $3}'", mac);
+    ret = exec_cmd(cmd, ip, ip_len);
+    if( ret == 0 )
+    {
+        p = strchr(ip, '\n');
+        if (NULL != p)
+        {
+            *p = '\0';
+            RLOGD("inner_get_ip_by_mac_lease %s function return is:%d", ip,ret);
+            return ret;
+        }else
+        {
+            ret = -1;
+        }
+    }
+    RLOGD("%s %d function return is:%d",__func__,__LINE__,ret);
+    return ret;
+
+}
+
+static int inner_get_ip_by_mac(const char * mac, char * ip, int ip_len)
+{
+    char * p;
+    int ret = 0;
+    char cmd[256]={0};
+    if (NULL == mac || NULL == ip)
+        return -1;
+    memset(ip, 0, ip_len);
+    sprintf(cmd, "ip n s | grep \"lladdr\" | grep \"%s\" | awk '{print $1}' | grep -v \":\" | head -1", mac);
+    ret = exec_cmd(cmd, ip, ip_len);
+    p = strchr(ip, '\n');
+    if (NULL != p)
+    {
+        *p = '\0';
+    }else
+    {
+	ret = inner_get_ip_by_mac_lease(mac,ip,ip_len);
+    }
+    RLOGD("inner_get_ip_by_mac %s\n", ip);
+    return ret;
+}
+
+static int inner_get_hostname_by_ip(char *ip, char *hostname) {
+    struct in_addr addr ={0};
+    struct hostent *ht;
+    char cmd[64] = {0};
+    char * p;
+    int ret;
+
+    if (ip == NULL || *ip == '\0' || hostname == NULL)
+    {
+        RLOGE("ip == NULL or hostname == NULL");
+	return -1;
+    }
+
+    *hostname = '\0';
+    if (inet_aton(ip, &addr) == 0)
+    {
+        printf("---inet_aton fail\n");
+        return -1;
+    }
+
+    ht = gethostbyaddr(&addr, sizeof(struct in_addr), AF_INET);
+
+    if (ht == NULL)
+    {
+        hostname[0] = '\0';
+        sprintf(cmd, "grep -F '%s' /run/wg870/ap0.lease | awk '{print $4}' | tail -1", ip);
+        ret = exec_cmd(cmd, hostname, 32);
+        if (ret == 0)
+        {
+            p = strchr(hostname, '\n');
+            if (p != NULL)
+            {
+                *p = '\0';
+            }
+            return 0;
+        }
+        hostname[0] = '\0';
+        RLOGE("---gethostbyaddr fail\n");
+        herror(NULL);
+        return -1;
+    }
+
+    strcpy(hostname, ht->h_name);
+
+    return 0;
+}
+
+static int lynq_get_network_number_list(lynq_wifi_index_e idx, int ap_sta, int net_no_list[], char * ssid)
+{
+    int count, index, words_count;
+    char * split_lines[128]= {0};
+    char * split_words[128] = {0};
+    char local_ssid[128] = {0};
+    const char *lynq_wifi_list_networks = "LIST_NETWORKS";
+    RLOGD("[lynq_get_network_number_list] enter lynq_get_network_number_list api");
+
+    CHECK_WPA_CTRL(ap_sta);
+
+    DO_REQUEST(lynq_wifi_list_networks);
+
+    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+    //@todo check ssid field to compatible
+
+    ret = 0;
+    for(index=1; index < count; index++)
+    {
+        words_count = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
+        if (words_count > 2)
+	{
+            inner_copy_ssid(local_ssid, split_words[1], sizeof (local_ssid));
+            if (ssid == NULL || strcmp(local_ssid, ssid) == 0)
+	    {
+                net_no_list[ret++] = atoi(split_words[0]);
+            }
+        }
+    }
+    RLOGD("[lynq_get_network_number_list] lynq_get_network_number_list return ok");
+    return ret;
+}
+
+static int lynq_add_network(int ap_sta) {
+    size_t i=0;
+    CHECK_WPA_CTRL(ap_sta);
+    const char *lynq_wifi_add_network = "ADD_NETWORK";
+
+    RLOGD("[lynq_add_network] enter lynq_add_network");
+    DO_REQUEST(lynq_wifi_add_network);
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("[wifi error]lynq_add_network  cmd_reply FAIL");
+        return -1;
+    }
+
+    for(i=0;i<reply_len;i++)
+    {
+        if(cmd_reply[i] == '\n')
+	{
+            cmd_reply[i] = '\0';
+            break;
+        }
+    }
+    return atoi(cmd_reply);
+}
+
+static int lynq_check_network_number(lynq_wifi_index_e idx, int ap_sta, int net_no)
+{
+    int count, index;
+    int net_no_list[128];
+
+    RLOGD("[lynq_check_network_number] enter lynq_check_network_number api");
+    count = lynq_get_network_number_list(idx, ap_sta, net_no_list, NULL);
+    for (index=0; index < count; index++)
+    {
+        if (net_no_list[index] == net_no)
+	{
+            return 0;
+        }
+    }
+
+    if (count >= 1)
+        index = net_no_list[count - 1];
+    else
+        index = -1;
+
+    while (index < net_no )
+    {
+        index = lynq_add_network(ap_sta);
+        if (index >= net_no)
+	{ // required network no created
+            RLOGD("required network no created\n");;
+            return 0;
+        }
+        else if( index < 0)
+	{
+            RLOGE("[lynq_check_network_number] add network fail");
+            return -1;
+        }
+    }
+
+    if (index < 0)
+    {
+        RLOGE("[lynq_check_network_number] network index < 0");
+	return -1;
+    }
+    RLOGD("[lynq_check_network_number] work finished &state is ok");
+    return 0;
+}
+
+static lynq_wifi_band_m convert_band_from_freq(int freq) { //@todo
+    if (freq > 5000 && freq < 6000)
+    {
+        return LYNQ_WIFI_5G_band;
+    }
+    else if (freq > 2000 && freq <  3000)
+    {
+        return LYNQ_WIFI_2G_band;
+    }
+    return LYNQ_WIFI_2_and_5G_band;
+}
+
+static lynq_wifi_auth_s convert_auth_from_key_mgmt(char * key_mgmt) {
+    if (key_mgmt != NULL)
+    {
+        if (memcmp( key_mgmt, "NONE", 4) == 0)
+	{
+            return LYNQ_WIFI_AUTH_OPEN;
+        }
+        else if (memcmp( key_mgmt, "WEP", 3) == 0)
+	{
+            return LYNQ_WIFI_AUTH_WEP;
+        }
+        else if (memcmp( key_mgmt, "WPA-PSK", 7) == 0)
+	{
+            return LYNQ_WIFI_AUTH_WPA_PSK;
+        }
+        else if (memcmp( key_mgmt, "WPA2-PSK", 8) == 0)
+	{
+            return LYNQ_WIFI_AUTH_WPA2_PSK;
+        }
+    }
+
+    return -1;
+}
+
+static lynq_wifi_auth_s convert_max_auth_from_flag(char * flag) {
+    if (flag != NULL)
+    {
+        if ( strstr(flag,"WPA2-PSK+SAE-CCMP") != NULL || strstr(flag, "SHA256") != NULL || strstr(flag,"WPA2-SAE") != NULL || ( strstr(flag,"SAE-H2E") != NULL &&  strstr(flag,"WPS") == NULL ) )
+        {
+            return LYNQ_WIFI_AUTH_WPA3_PSK;
+        }else if ( strstr( flag,"SAE-CCMP") != NULL || strstr(flag,"SAE-H2E") != NULL )
+        {
+            return LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        }else if (strstr( flag, "WPA2-PSK") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WPA2_PSK;
+        }
+        else if (strstr( flag, "WPA-PSK") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WPA_PSK;
+        }
+        else if (strstr( flag, "WEP") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_WEP;
+        }
+        else if (strstr( flag, "NONE") != NULL)
+        {
+            return LYNQ_WIFI_AUTH_OPEN;
+        }
+        else if (strcmp( flag, "[ESS]") == 0 || strcmp( flag,"[WPS][ESS]") == 0)
+        {
+            return LYNQ_WIFI_AUTH_OPEN;
+        }
+        else
+        {
+            RLOGD("convert_max_auth_from_flag not-found auth mode");
+        }
+    }
+
+    return -1;
+}
+
+static lynq_wifi_bandwidth_type_m convert_bandwidth_from_bw(int bw) {
+    switch (bw) {
+    case 10:
+        return LYNQ_WIFI_BANDWIDTH_HT10;
+        break;
+    case 20:
+        return LYNQ_WIFI_BANDWIDTH_HT20;
+        break;
+    case 40:
+        return LYNQ_WIFI_BANDWIDTH_HT40;
+        break;
+    case 80:
+        return LYNQ_WIFI_BANDWIDTH_HT80;
+        break;
+    default:
+        break;
+    }
+
+    return -1;
+}
+
+static int inner_get_network_auth(int interface, int net_no, lynq_wifi_auth_s *auth);
+static int inner_get_status_info(int interface, curr_status_info *curr_state) {
+    int i, count;
+    char *p;
+    const char *lynq_status_cmd = "STATUS";
+    const char * FLAG_SSID = "ssid=";
+    const char * FLAG_SBSID = "bssid=";
+    const char * FLAG_KEY_MGMT = "key_mgmt=";
+    const char * FLAG_FREQ = "freq=";
+    const char * FLAG_STATE = "wpa_state=";
+    const char * FLAG_ID = "id=";
+    const char * FLAG_IPADDR = "ip_address=";
+    char *split_lines[128] = {0};
+
+    CHECK_WPA_CTRL(interface);
+
+    if (curr_state == NULL)
+    {
+        RLOGE("[wifi error][inner_get_status_info]curr_state is NULL");
+        return -1;
+    }
+
+    DO_REQUEST(lynq_status_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+    curr_state->net_no = -1;
+    ret = -1;
+    for(i=0; i < count; i++)
+    {
+        if (curr_state->ap != NULL)
+        {
+            p = strstr(split_lines[i], FLAG_SBSID);
+            if (p != NULL)
+            {
+                strncpy(curr_state->ap->ap_mac, p + strlen(FLAG_SBSID), sizeof(curr_state->ap->ap_mac));
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_SSID);
+            if (p != NULL)
+            {
+                inner_copy_ssid(curr_state->ap->ap_ssid, p + strlen(FLAG_SSID), sizeof (curr_state->ap->ap_ssid));
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_KEY_MGMT);
+            if (p != NULL)
+            {
+                curr_state->ap->auth = convert_auth_from_key_mgmt(p + strlen(FLAG_KEY_MGMT));
+                RLOGD("inner_get_status_info: key_mgmt %d, -- %s\n", curr_state->ap->auth, p);
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_FREQ);
+            if (p != NULL)
+            {
+                curr_state->ap->band = convert_band_from_freq(atoi( p + strlen(FLAG_FREQ)));
+                ret = 0;
+                continue;
+            }
+            p = strstr(split_lines[i], FLAG_IPADDR);
+            if (p != NULL)
+            {
+                strncpy(curr_state->ap->ap_ip, p + strlen(FLAG_IPADDR), sizeof(curr_state->ap->ap_ip));
+                ret = 0;
+                continue;
+            }
+        } // end  if (ap != NULL)
+        if (curr_state->state != NULL)
+        {
+            p = strstr(split_lines[i], FLAG_STATE);
+            if (p != NULL)
+            {
+                strcpy(curr_state->state, p + strlen(FLAG_STATE));
+                ret = 0;
+                continue;
+            }
+
+        } //end else if (state != NULL)
+        if ((p = strstr(split_lines[i], FLAG_ID)) == split_lines[i])
+        {
+            ret = 0;
+            curr_state->net_no = atoi(p + strlen(FLAG_ID));
+            RLOGD("inner_get_status_info:net_no %d, -- %s\n", curr_state->net_no, p);
+        }
+    }
+
+    if (ret == 0 && curr_state->ap != NULL && curr_state->net_no >= 0) // auth may not right when add wpa3
+    {
+        inner_get_network_auth(interface, curr_state->net_no, &curr_state->ap->auth);
+    }
+
+    return ret;
+}
+
+int lynq_wifi_ap_ssid_set(lynq_wifi_index_e idx,char *ap_ssid)
+{
+    RLOGD("enter lynq_wifi_ap_ssid_set");
+    char lynq_wifi_ssid_cmd[80]={0};
+
+    if (ap_ssid == NULL)
+    {
+        RLOGE("Input ap_ssid is NULL");
+        return -1;
+    }
+    else
+    {
+        RLOGD("[lynq_wifi_ap_ssid_set]idx:%d ap_ssid : %s\n", idx, ap_ssid);
+    }
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        RLOGE("Do check ap network_number fail");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", AP_NETWORK_0, ap_ssid);
+
+    DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    RLOGD("[lynq_wifi_ap_ssid_set] set ssid succeed %d",__LINE__);
+    return 0;
+
+}
+
+int lynq_wifi_ap_ssid_get(lynq_wifi_index_e idx, char* ap_ssid)
+{
+    RLOGD("enter lynq_wifi_ap_ssid_get");
+    CHECK_IDX(idx, CTRL_AP);
+    return inner_get_param(CTRL_AP, AP_NETWORK_0, "ssid", ap_ssid);
+}
+
+/*****
+ *frequency  <------>channel
+ *
+ *frequency   1    2    3    4    5    6    7    8    9   10   11   12   13   36   40   44   48   149  153  157  161  165
+ *
+ *
+ *channel     2412,2417,2422,2427,2532,2437,2442,2447,2452,2457,2462,2467,2472,5180,5200,5220,5240,5745,5765,5785,5805,5825
+ *
+ *
+ * */ 
+static int lynq_check_set_frequency(int input_frequency){
+    int legitimate_frequency[]={2412,2417,2422,2427,2432,2437,2442,2447,2452,2457,2462,2467,2472,5180,5200,5220,5240,5745,5765,5785,5805,5825};
+    int i;
+    int arr_len = sizeof(legitimate_frequency) / sizeof(int);
+
+    for(i = 0; i < arr_len; i++)
+    {
+        if(input_frequency == legitimate_frequency[i])
+            break;
+    }
+
+    if(i == arr_len)
+    {
+        RLOGE("[lynq_check_set_frequency]input frequency is --->%d,please check it\n", input_frequency);
+        return -1;
+    }
+
+    return 0;
+}
+
+static int lynq_check_frequencyby_country_code(int input_frequency)
+{
+    char str_cnc[]="CN";
+    char str_dest[20]="";
+
+    if( lynq_get_country_code(1,str_dest) != 0 )
+    {
+        RLOGE("get country_code error\n");
+	return -1;
+    }
+    if( strncmp(str_dest,str_cnc,2) != 0 )
+    {
+        return 0;
+    }else if( 2473 < input_frequency && input_frequency < 5744)
+    {
+        RLOGE("input frequency is bad\n");
+	return -1;
+    } 
+    return 0;
+}
+int lynq_wifi_ap_frequency_set(lynq_wifi_index_e idx,int lynq_wifi_frequency)
+{
+    int check;
+    char lynq_wifi_frequency_cmd[128]={0};
+    char lynq_cmd_mode[128]={0};
+    char lynq_cmd_slect[128]={0};
+    RLOGD("enter %s %d input frequency:%d",__func__,__LINE__,lynq_wifi_frequency);
+    //@do check input frequency
+    check = lynq_check_set_frequency(lynq_wifi_frequency);
+    if(check != 0)
+    {
+        RLOGE("do check frequency error");
+        return -1;
+    }
+    check = lynq_check_frequencyby_country_code(lynq_wifi_frequency);
+    if(check != 0)
+    {
+        RLOGE("do check frequency error");
+        return -1;
+    }
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        RLOGE("[set ap frequecny][lynq_check_network_number] error");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_wifi_frequency_cmd,"SET_NETWORK %d frequency %d", AP_NETWORK_0, lynq_wifi_frequency);
+    sprintf(lynq_cmd_mode, "SET_NETWORK %d mode 2", AP_NETWORK_0);
+    sprintf(lynq_cmd_slect, "SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    DO_OK_FAIL_REQUEST(lynq_wifi_frequency_cmd);
+    DO_OK_FAIL_REQUEST(lynq_cmd_mode);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_wifi_ap_frequency_get(lynq_wifi_index_e idx,int *lynq_wifi_frequency)
+{
+    char lynq_frequency_str[MAX_RET] = {0};
+    RLOGD("enter lynq_wifi_ap_frequency_get and input idx is %d",idx);
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "frequency", lynq_frequency_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_frequency_get]get frequency from device fail");
+        return -1;
+    }
+    *lynq_wifi_frequency = atoi(lynq_frequency_str);
+
+    return 0;
+}
+
+int lynq_wifi_ap_bandwidth_set(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m bandwidth)
+{
+    RLOGD("enter lynq_wifi_ap_bandwidth_set");
+    CHECK_IDX(idx, CTRL_AP);
+    switch(bandwidth){
+        case LYNQ_WIFI_BANDWIDTH_HT10:
+	{
+            RLOGE("bandwith  [%d] not support now\n", bandwidth);
+	    return -1;
+	}
+        case LYNQ_WIFI_BANDWIDTH_HT20:
+        {
+            char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 6";
+            system("wl down");
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
+                return -1;
+            }
+            system("wl up");
+            break;
+        }
+        case LYNQ_WIFI_BANDWIDTH_HT40:
+        {
+            char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/40";
+            sprintf(lynq_cmd_bandwith, "wl chanspec ");
+            system("wl down");
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
+                return -1;
+            }
+            system("wl up");
+            break;
+        }
+        case LYNQ_WIFI_BANDWIDTH_HT80:
+        {
+            char lynq_cmd_bandwith[MAX_CMD]="wl chanspec 149/80";
+            system("wl down");
+            if (system(lynq_cmd_bandwith) != 0 )
+	    {
+                RLOGE("lynq_wifi_ap_bandwidth_set erro");
+                return -1;
+            }
+            system("wl up");
+            break;
+        }				
+        default:
+        {
+            RLOGE("auth type [%d] not support now\n", bandwidth);
+            return -1;
+        }
+    }
+
+
+    return 0;
+}
+
+int lynq_wifi_ap_bandwidth_get(lynq_wifi_index_e idx,lynq_wifi_bandwidth_type_m* bandwidth)
+{
+    int count = 0;
+    int index = 0;
+    char *split_words[128] = {0};
+    const char *lynq_chanspec_cmd = "DRIVER chanspec\n";
+    RLOGD("enter lynq_wifi_ap_bandwidth_get");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    DO_REQUEST(lynq_chanspec_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+    for(;index < count; index++) {
+        if (strncmp(split_words[index], "bw", 2) != 0) {
+            continue;
+        }
+
+        index++;
+        if (index >= count) {
+            return -1;
+        }
+
+        RLOGD("bw %s\n", split_words[index]);
+        *bandwidth = convert_bandwidth_from_bw(atoi(split_words[index]));
+        return 0;
+    }
+    RLOGE("[wifi error]lynq_wifi_ap_bandwidth_get");
+    return -1;
+}
+
+int lynq_wifi_ap_channel_set( lynq_wifi_index_e idx,int channel)
+{
+    char lynq_cmd_channel[MAX_CMD]={0};
+    RLOGD("enter lynq_wifi_ap_channel_set and input channel is %d",channel);
+    CHECK_IDX(idx, CTRL_AP);
+
+    sprintf(lynq_cmd_channel, "wl channel %d", channel);
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0) 
+    {
+        return -1;
+    }
+
+    system("wl down");
+    if (system(lynq_cmd_channel) != 0 ){
+        RLOGE("lynq_wifi_ap_channel_set erro");
+        return -1;
+    }
+    system("wl up");
+    return 0;
+}
+
+int lynq_wifi_ap_channel_get( lynq_wifi_index_e idx,int* channel)
+{
+    int count = 0;
+    int index = 0;
+    char *split_words[128] = {0};
+    char lynq_chanspec_cmd[]="DRIVER chanspec\n";
+    RLOGD("enter lynq_wifi_ap_channel_get");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    DO_REQUEST(lynq_chanspec_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+    for(;index < count; index++) 
+    {
+        RLOGD("[lynq_wifi_ap_channel_get]---- %s\n",split_words[index]);
+        if (strncmp(split_words[index], "channel", 2) != 0) {
+            continue;
+        }
+
+        index++;
+        if (index >= count) 
+	{
+            return -1;
+        }
+
+        *channel = atoi(split_words[index]);
+        return 0;
+    }
+    RLOGE("[lynq_wifi_ap_channel_get] function fail");
+    return -1;
+}
+
+
+int lynq_wifi_ap_auth_set(lynq_wifi_index_e idx, lynq_wifi_auth_s auth)
+{
+    char ssid[MAX_CMD] = {0};
+    int freq = 0;
+    char lynq_auth_cmd[64]={0};
+    char lynq_auth_alg_cmd[64]={0};
+    char lynq_psk_cmd[64]={0};
+    char lynq_pairwise_cmd[64]={0};
+    char lynq_ieee80211_cmd[64]={0};
+    RLOGD("enter lynq_wifi_ap_auth_set and input idx is:%d,auth is:%d",idx,auth);
+    lynq_wifi_auth_s org_auth;
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != AP_NETWORK_0) 
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_set] check network fail\n");
+        return -1;
+    }
+
+    if (0 == lynq_wifi_ap_auth_get(idx, &org_auth) && org_auth != -1) {
+        if (org_auth == auth) {
+            RLOGD("org_auth --- is %d\n",org_auth);
+            return 0;
+        }
+        else {
+            if (0 != lynq_wifi_ap_ssid_get(idx, ssid)) {
+                ssid[0] = '\0';
+            }
+            lynq_wifi_ap_frequency_get(idx, &freq);
+
+            DO_OK_FAIL_REQUEST(cmd_disconnect);
+            DO_OK_FAIL_REQUEST(cmd_remove_all);
+            if (ssid[0] != '\0') {
+                lynq_wifi_ap_ssid_set(idx, ssid);
+            }
+            if (freq != 0) {
+                lynq_wifi_ap_frequency_set(idx, freq);
+            }
+        }
+    }
+
+    switch(auth){
+	case LYNQ_WIFI_AUTH_OPEN:
+        {
+            RLOGD("auth == is LYNQ_WIFI_AUTH_OPEN\n");
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+	    break;
+	}
+        case LYNQ_WIFI_AUTH_WEP:
+        {
+            RLOGD("auth == is LYNQ_WIFI_AUTH_WEP\n");
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise NONE", AP_NETWORK_0);
+            sprintf(lynq_auth_alg_cmd,"SET_NETWORK %d auth_alg  SHARED", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_auth_alg_cmd);
+            break;
+        }
+	case LYNQ_WIFI_AUTH_WPA_PSK:
+        {
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            break;
+
+	}
+        case LYNQ_WIFI_AUTH_WPA2_PSK:
+	{
+            if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", AP_NETWORK_0);
+                sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            }
+            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", AP_NETWORK_0);
+                sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            }
+//            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+//            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+        case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+            sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 1", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt WPA-PSK SAE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+        case LYNQ_WIFI_AUTH_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA2", AP_NETWORK_0);
+            sprintf(lynq_ieee80211_cmd,"SET_NETWORK %d ieee80211w 2", AP_NETWORK_0);
+            sprintf(lynq_psk_cmd,"SET_NETWORK %d key_mgmt SAE", AP_NETWORK_0);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", AP_NETWORK_0);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ieee80211_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+	    break;
+	}		
+	default:
+        {
+            RLOGE("auth type [%d] not support now\n", auth);
+            return -1;
+        }
+    }
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_wifi_ap_auth_get(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
+{
+    char lynq_auth_str[MAX_RET] = {0};
+    char lynq_auth_alg_str[MAX_RET] = {0};
+    char lynq_proto_str[MAX_RET] = {0};
+    RLOGD("enter lynq_wifi_ap_auth_get");
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "key_mgmt", lynq_auth_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network fail");
+        return -1;
+    }
+
+    if (memcmp( lynq_auth_str, "NONE", 4) == 0)
+    {
+        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "auth_alg", lynq_auth_alg_str) != 0)
+	{
+            RLOGD("---auth is OPEN\n");
+            *auth = LYNQ_WIFI_AUTH_OPEN;
+            return 0;
+        }
+        else if (memcmp(lynq_auth_alg_str, "SHARED", 6) == 0)
+	{
+            RLOGD("---auth is WEP\n");
+            *auth = LYNQ_WIFI_AUTH_WEP;
+            return 0;
+        }
+        else
+	{
+            RLOGD("---auth is OPEN\n");
+            *auth = LYNQ_WIFI_AUTH_OPEN;
+            return 0;
+        }
+    }
+    else if(strcmp( lynq_auth_str, "WPA-PSK") == 0 )
+    {
+        if (inner_get_param(CTRL_AP, AP_NETWORK_0, "proto", lynq_proto_str) != 0)
+	{
+            RLOGE("---auth is -1\n");
+            *auth = -1;
+        }
+        else if (memcmp(lynq_proto_str, "RSN", 3) == 0)
+	{
+            RLOGD("---auth WPA2_PSK\n");
+            *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+            return 0;
+        }
+        else
+	{
+            RLOGD("---auth WPA_PSK\n");
+            *auth = LYNQ_WIFI_AUTH_WPA_PSK;
+	    return 0;
+        }
+    }
+    
+    if (inner_get_param(CTRL_AP, AP_NETWORK_0, "ieee80211w", lynq_auth_str) != 0)
+    {
+        RLOGE("[wifi error][lynq_wifi_ap_auth_get] check network auth ieee80211w fail");
+        return -1;
+    }
+    
+    if (memcmp(lynq_auth_str,"1",1) == 0 )
+    {
+	RLOGD("auth : LYNQ_WIFI_AUTH_WPA2_WPA3_PSK\n");
+        *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        return 0;
+    }else if (memcmp(lynq_auth_str,"2",1) == 0 )
+    {
+	RLOGD("auth : LYNQ_WIFI_AUTH_WPA3_PSK\n");
+        *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+        return 0;
+    }
+    else
+    {
+	RLOGE("---auth -- -1\n");
+        *auth = -1;
+    }
+
+    return 0;
+}
+
+static int inner_check_ap_connected(lynq_wifi_index_e idx, int retry_count)
+{
+    char status[64];
+    char LYNQ_WIFI_CMD[32]={0};
+    curr_status_info curr_state;
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    memset(status, 0, sizeof (status));
+
+    curr_state.ap = NULL;
+    curr_state.state = status;
+
+    printf("inner_check_ap_connected %d\n", retry_count);
+    usleep(250*1000);
+    if (0 == inner_get_status_info(idx, &curr_state))
+    {
+        if ((strcmp(status, STATE_SCANNING) == 0)|| (strcmp(status, STATE_COMPLETED) == 0))
+        {
+            return 0;
+        }
+        else if (retry_count == 8) //not ok in 2s, do reconnect
+        {
+            DO_REQUEST("RECONNECT");
+            return inner_check_ap_connected(idx, retry_count+1);
+        }
+        else if (retry_count > 20)
+        {
+            printf("retry 10 time\n");
+            return -1;
+        }
+        else
+        {
+            if (strcmp(status, STATE_DISCONNECTED) == 0)
+            {
+                sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
+                DO_REQUEST(LYNQ_WIFI_CMD);
+            }
+            return inner_check_ap_connected(idx, retry_count+1);
+        }
+    }
+    return -1;
+}
+
+int lynq_wifi_ap_start(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    char LYNQ_WIFI_CMD[128]={0};
+
+    CHECK_IDX(idx, CTRL_AP);
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    if (inner_get_ap_interface_name() == NULL)
+    {
+        RLOGE("lynq_wifi_ap_start get ap name fail");
+        return -1;
+    }
+
+
+    sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
+    DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
+
+    ret = system_call_v("%s %s", start_stop_ap_script, "start");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_ap_start excute script fail");
+        return -1;
+    }
+
+    if (inner_check_ap_connected(idx, 0) != 0)
+    {
+        return -1;
+    }
+
+    check_tether_and_notify();
+/*
+    if (g_ap_tmp_watcher_pid == 0)
+    {
+        if(pthread_create(&g_ap_tmp_watcher_pid,NULL,APTmpWatcherThreadProc,NULL) < 0)
+        {
+            g_ap_tmp_watcher_pid = 0;
+            RLOGE("[wifi error]create APTmpWatcherThreadProc fail");
+            return -1;
+        }
+        RLOGD("[lynq_wifi_ap_start] creat APTmpWatcherThreadProc ok");
+    }
+*/
+    RLOGD("end %s %d",__func__,__LINE__);
+    return 0;
+}
+
+int lynq_wifi_ap_restart(lynq_wifi_index_e idx)
+{
+    return lynq_wifi_ap_stop(idx) == 0 ? lynq_wifi_ap_start(idx)  : -1;
+}
+
+int lynq_wifi_ap_stop(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    char LYNQ_WIFI_CMD[128]={0};
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(LYNQ_WIFI_CMD,"DISABLE_NETWORK %d",AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
+
+
+    ret = system_call_v("%s %s", start_stop_ap_script, "stop");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_ap_start excute script fail");
+        return -1;
+    }
+/*
+    g_ap_tmp_watcher_stop_flag = 1;
+    if (g_ap_tmp_watcher_pid != 0)
+        pthread_join(g_ap_tmp_watcher_pid, NULL);
+    g_ap_tmp_watcher_pid = 0;
+*/
+    RLOGD("end %s %d",__func__,__LINE__);
+    return 0;
+}
+
+int lynq_wifi_ap_hide_ssid(lynq_wifi_index_e idx)
+{
+    char lynq_disable_cmd[128] = {0};
+    char lynq_select_cmd[128] = {0};
+    const char *lynq_hide_cmd = "SET HIDE_SSID 1";
+    RLOGD("enter lynq_wifi_ap_hide_ssid");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+    sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
+    sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+    DO_OK_FAIL_REQUEST(lynq_hide_cmd);
+    DO_OK_FAIL_REQUEST(lynq_select_cmd);
+
+    return 0;
+}
+
+int lynq_wifi_ap_unhide_ssid(lynq_wifi_index_e idx)
+{
+    char lynq_disable_cmd[128] = {0};
+    char lynq_select_cmd[128] = {0};
+    const char *lynq_unhide_cmd = "SET HIDE_SSID 0";
+    RLOGD("enter lynq_wifi_ap_unhide_ssid");
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_disable_cmd,"DISABLE_NETWORK %d", AP_NETWORK_0);
+    sprintf(lynq_select_cmd,"SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+    DO_OK_FAIL_REQUEST(lynq_unhide_cmd);
+    DO_OK_FAIL_REQUEST(lynq_select_cmd);
+
+    return 0;
+}
+
+int lynq_ap_password_set(lynq_wifi_index_e idx,char *password)
+{
+    int pass_len;
+    char lynq_tmp_cmd[MAX_CMD] = {0};
+    char lynq_wpa2_wpa3[64] = {0};
+    char lynq_wep_tx_keyidx_cmd[MAX_CMD] = {0};
+    RLOGD("enter lynq_ap_password_set");
+    if( password == NULL )
+    {
+        RLOGE("[lynq_ap_password_set]input password is NULL");
+        return -1;
+    }
+    pass_len=strlen(password);
+    lynq_wifi_auth_s auth = -1;
+    if(pass_len < 8 || pass_len >= 64)
+    {
+        RLOGE("[lynq_ap_password_set]input password len not in rage");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (0 != lynq_wifi_ap_auth_get(idx, &auth))
+    {
+        RLOGE("[lynq_ap_password_set] get ap auth info error\n");
+        return -1;
+    }
+    else if (auth == LYNQ_WIFI_AUTH_OPEN)
+    {
+        RLOGD("ap auth :LYNQ_WIFI_AUTH_OPEN\n");
+        return 0;
+    }
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    if (auth == LYNQ_WIFI_AUTH_WEP)
+    {
+        RLOGD("[lynq_ap_password_set]ap auth : LYNQ_WIFI_AUTH_WEP\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d wep_key0 \"%s\"",AP_NETWORK_0, password);
+        sprintf(lynq_wep_tx_keyidx_cmd,"SET_NETWORK %d wep_tx_keyidx 0",AP_NETWORK_0);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+        DO_OK_FAIL_REQUEST(lynq_wep_tx_keyidx_cmd);
+    }
+    else if (auth == LYNQ_WIFI_AUTH_WPA_PSK || auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+    {
+        RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA_PSK  LYNQ_WIFI_AUTH_WPA2_PSK\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+    }
+    else if (auth == LYNQ_WIFI_AUTH_WPA2_WPA3_PSK || auth == LYNQ_WIFI_AUTH_WPA3_PSK)
+    {
+        
+        RLOGD("[lynq_ap_password_set]ap auth :LYNQ_WIFI_AUTH_WPA2_WPA3  LYNQ_WIFI_AUTH_WPA3_PSK\n");
+        sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",AP_NETWORK_0, password);
+        sprintf(lynq_wpa2_wpa3,"SET_NETWORK %d sae_password \"%s\"",AP_NETWORK_0, password);
+        DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+        DO_OK_FAIL_REQUEST(lynq_wpa2_wpa3);
+
+    }
+    else
+    {   
+        RLOGD("[lynq_ap_password_set]ap auth :get ap auth error\n");
+        return -1;
+    }
+
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_ap_password_get(lynq_wifi_index_e idx, char *password)
+{
+    FILE * fp;
+    int len, ret;
+    int count, index;
+    char *split_lines[128] = {0};
+    char *buff, *p;
+    RLOGD("enter lynq_ap_password_get");
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    fp = fopen("/data/wifi/wg870/wpa_supplicant_ap.conf", "rb");
+//    fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
+    if (NULL == fp)
+    {
+        RLOGE("open file fail\n");
+        return  -1;
+    }
+
+    buff = alloca(MAX_RET);
+    fseek(fp, 0, SEEK_SET);
+    len = fread(buff, 1, MAX_RET, fp);
+    fclose(fp);
+
+    for(index=0; index < len; index ++)
+    {
+        if (memcmp(buff + index, "network={", 9) != 0)
+	{
+            continue;
+        }
+         p = buff + index + 9;
+         for (; index < len; index ++ )
+	 {
+             if (buff[index] != '}')
+	     {
+                 continue;
+             }
+             buff[index] = '\0';
+             break;
+         }
+         len = buff + index - p;
+    }
+
+    count = lynq_split(p, len, '\n', split_lines);
+
+    ret = -1;
+    for(index=0; index < count; index++)
+    {
+        p = strstr(split_lines[index], "psk=");
+        if (p != NULL)
+	{
+            p += 4;
+            if (*p == '\"')
+	    {
+                p++;
+            }
+        }
+        else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+	{
+            p += 9;
+            if (*p == '\"')
+	    {
+                p++;
+            }
+        }
+        else
+	{
+            continue;
+        }
+
+        strcpy(password, p);
+
+        while(*password != '\0')
+	{
+            if (*password == '\"')
+	    {
+                *password = '\0';
+                break;
+            }
+            password++;
+        }
+        ret = 0;
+        break;
+    } //end for(index=0; index < count; index++)
+
+    return ret;
+}
+
+static int inner_get_network_auth(int interface, int net_no, lynq_wifi_auth_s *auth) {
+    char lynq_auth_str[MAX_RET] = {0};
+    char lynq_proto_str[MAX_RET] = {0};
+
+    if (inner_get_param(interface, net_no, "key_mgmt", lynq_auth_str) != 0)
+    {
+        return -1;
+    }
+
+    *auth = convert_auth_from_key_mgmt(lynq_auth_str);
+
+    if (*auth == LYNQ_WIFI_AUTH_WPA_PSK)
+    {
+        if (inner_get_param(interface, net_no, "proto", lynq_proto_str) == 0)
+        {
+            if (strcmp(lynq_proto_str, "RSN") == 0)
+            {
+                *auth = LYNQ_WIFI_AUTH_WPA2_PSK;
+                return 0;
+            }
+            else if (strcmp(lynq_proto_str, "WPA") == 0) // need compare when wpa3 supported
+            {
+                return 0;
+            }
+        }
+    }
+    else if (*auth == LYNQ_WIFI_AUTH_OPEN || *auth == LYNQ_WIFI_AUTH_WEP)
+    {
+        return 0;
+    }
+
+    if (inner_get_param(interface, net_no,"ieee80211w",lynq_auth_str) !=0)
+    {
+        RLOGE("check ieee80211w error\n");
+        return -1;
+    }
+    if ( strncmp(lynq_auth_str,"1",1) == 0 )
+    {
+
+        *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        return 0;
+    }else if( strncmp(lynq_auth_str,"2",1) == 0 )
+    {
+
+        *auth = LYNQ_WIFI_AUTH_WPA3_PSK;
+        return 0;
+    }else
+    {
+        RLOGE("check ieee80211w error, not 1 or 2\n");
+        *auth = -1;
+        return -1;
+    }
+    return 0;
+}
+
+int lynq_sta_ssid_password_set(lynq_wifi_index_e idx, ap_info_s *ap, char *password)
+{
+    RLOGD("enter lynq_sta_ssid_password_set");
+    int pass_len, net_no, count, index;
+    char lynq_tmp_cmd[300]={0};
+    int net_no_list[128];
+    lynq_wifi_auth_s net_auth;
+    pass_len=strlen(password);
+    if(pass_len < 8 || pass_len >= 64)
+    {
+        RLOGE("[lynq_sta_ssid_password_set]input psw error");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    net_no = -1;
+    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ap->ap_ssid);
+
+    for (index=0; index < count; index++)
+    {
+        net_auth = -1;
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == ap->auth)
+	{
+            net_no = net_no_list[index];
+            break;
+        }
+    }
+
+    if (net_no < 0)
+    {
+        return -1;
+    }
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    sprintf(lynq_tmp_cmd,"SET_NETWORK %d psk \"%s\"",net_no, password);
+
+    DO_OK_FAIL_REQUEST(lynq_tmp_cmd);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+/**
+*   buff  data
+*   buff_len  size of buff
+*   idx  sta
+*   *ap   ap info for find ssid && password
+*   password  return password
+* 
+*/
+static int lynq_sta_ssid_password_auth_get(char * buff,int buff_len,lynq_wifi_index_e idx, ap_info_s *ap,char *password) { // @todo
+
+    int ret, network_len, i, ssid_len,curr_auth;
+    int count, index,org_index;
+    char *split_lines[128] = {0};
+    char *p, *ssid, *ssid_end_flag,*ptr;
+    char tmp_ssid[128]={0};
+    char tmp_auth[24]={0};
+
+    org_index = 0;
+    network_len = 0;
+    p = NULL;
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    while(1){
+        network_len = 0;
+        p == NULL;
+        for(; org_index < buff_len; org_index ++)
+        {
+            for(; org_index < buff_len; org_index ++)
+            {
+                if (memcmp(buff + org_index, "network={", 9) != 0)
+                {
+                    continue;
+                }
+                p = buff + org_index + 9;
+
+                for (; org_index < buff_len; org_index ++ )
+                {
+                    if (buff[org_index] != '}')
+                    {
+                        continue;
+                    }
+                    buff[org_index] = '\0';
+                    break;
+                }
+                network_len = buff + org_index - p;
+                break;
+            }
+
+            if (p == NULL)
+            {
+                RLOGD("not find dest info %s(),line %dERROR",__func__,__LINE__);
+                return -1;
+            }
+
+            ssid = strstr(p, "ssid=");
+            if (ssid != NULL) {
+                ssid += strlen("ssid=");
+                if (ssid[0] == '\"')
+                {
+                    if (memcmp(ssid + 1, ap->ap_ssid, strlen(ap->ap_ssid)) == 0 && ssid[strlen(ap->ap_ssid) + 1] == '\"')
+                    {
+                        break;
+                    }
+                }
+                else
+                {
+                    ssid_end_flag = strstr(ssid, "\n");
+                    if (ssid_end_flag != NULL)
+                    {
+                        ssid_len = (ssid_end_flag - ssid) / 2;
+                        for(i=0; i<ssid_len; i++)
+                        {
+                            tmp_ssid[i] = inner_convert_char(ssid[i*2]) << 4 | inner_convert_char(ssid[i*2 + 1]);
+                        }
+                        if (memcmp(tmp_ssid, ap->ap_ssid, ssid_len) == 0)
+                        {
+                            break;
+                        }
+                    }
+                }
+            }
+
+        }
+
+        if (org_index >= buff_len || NULL == p || network_len <= 0)
+        {
+
+            if (buff != NULL)
+            RLOGD("not find dest ssid %s(),line %dERROR",__func__,__LINE__);
+            return -1;
+        }
+
+        count = lynq_split(p, network_len, '\n', split_lines);
+        ret = -1;
+        for( index=0; index < count; index++ )
+        {
+            p = strstr(split_lines[index], "key_mgmt=");
+            if(p != NULL)
+            {
+                p += 9;
+                if(memcmp(p,"SAE",3) == 0)
+                {
+                    curr_auth = 5;
+                }else if(memcmp(p,"WPA-PSK SAE",11) == 0)
+                {
+                     curr_auth = 4;
+                }else if(memcmp(p,"WPA-PSK",7) == 0 )
+                {
+                      curr_auth = 3;
+                }else if(memcmp(p,"NONE",4) == 0 )
+                {
+                      curr_auth = 0;
+                }else{
+                        curr_auth = 1;
+                    }
+                if( curr_auth < 1 || curr_auth > 6)
+                {
+                    ret = -1;
+                }
+                break;
+            }
+        }
+        if( curr_auth == 0)
+        {
+            return 0;
+        }else if(curr_auth == ap->auth || ap->auth <= 3 && curr_auth <= 3 && curr_auth != -1 )
+        {
+            for(index=0; index < count; index++)
+            {
+                /*get psw info*/
+
+                p = strstr(split_lines[index], "psk=");
+                if (p != NULL)
+                {
+                    p += 4;
+                    if (*p == '\"')
+                    {
+                        p++;
+                    }
+                }
+                else if (NULL != (p = strstr(split_lines[index], "wep_key0=")))
+                {
+                    p += 9;
+                    if (*p == '\"')
+                    {
+                        p++;
+                    }
+                }
+                else
+                {
+                    continue;
+                }
+
+                if (*p == '\"')
+                    p++;
+                strncpy(password, p, 64);
+                p = password;
+                while(password - p < 64 && *password != '\0')
+                {
+                    if (*password == '\"')
+                    {
+                        *password = '\0';
+                        ret = 0;
+                        break;
+                    }
+                    password++;
+                }
+                break;
+            }
+            break;
+        }
+    }
+
+    return ret;
+}
+
+
+
+int lynq_sta_ssid_password_get(lynq_wifi_index_e idx, ap_info_s *ap, char *password) { // @todo
+
+    FILE * fp;
+    int len, ret;
+    char *info_buff;
+    RLOGD("enter lynq_sta_ssid_password_get");
+
+    info_buff = NULL;
+    CHECK_IDX(idx, CTRL_STA);
+
+    if (NULL == password)
+    {
+        RLOGE("bad param\n");
+        return -1;
+    }
+
+    fp = fopen("/data/wifi/wg870/wpa_supplicant.conf", "rb");
+    if (NULL == fp)
+    {
+        RLOGE("[lynq_sta_ssid_password_get] open file fail\n");
+        return  -1;
+    }
+
+    fseek(fp, 0, SEEK_END);
+    len = ftell(fp);
+    info_buff = malloc(len + 1);
+
+    if (info_buff == NULL)
+    {
+        RLOGE("[lynq_sta_ssid_password_get] malloc memory [%d] fail\n", len);
+        return  -1;
+    }
+
+    fseek(fp, 0, SEEK_SET);
+    len = fread(info_buff, 1, len, fp);
+    fclose(fp);
+
+
+    ret= lynq_sta_ssid_password_auth_get(info_buff,len,0, ap,password);
+
+    if(ret == 0)
+    {
+        RLOGD("lynq_sta_ssid_password_auth_get pass return ssid :%s psw is %s",ap->ap_ssid,password);
+        free(info_buff);
+        return 0;
+    }
+    else{
+        free(info_buff);
+        return -1;
+    }
+
+}
+
+
+static int inner_set_sta_ssid(int net_no, char *sta_ssid)
+{
+    char lynq_wifi_ssid_cmd[80]={0};
+
+    if (sta_ssid == NULL)
+    {
+        RLOGE("sta_ssid is null\n");
+        return -1;
+    }
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    sprintf(lynq_wifi_ssid_cmd,"SET_NETWORK %d ssid \"%s\"", net_no, sta_ssid);
+
+    DO_OK_FAIL_REQUEST(lynq_wifi_ssid_cmd);
+//    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+
+}
+
+static int inner_sta_start_stop(int net_no, int start_flag, int save)
+{
+    char lynq_disable_cmd[128]={0};
+    char lynq_select_cmd[128]={0};
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    if (save != 0)
+    {
+        if (start_flag != 0)
+        {
+            sprintf(lynq_select_cmd,"ENABLE_NETWORK %d", net_no);
+            DO_OK_FAIL_REQUEST(lynq_select_cmd);
+        }
+        else
+        {
+            sprintf(lynq_select_cmd,"DISABLE_NETWORK %d", net_no);
+            DO_OK_FAIL_REQUEST(lynq_select_cmd);
+        }
+        DO_OK_FAIL_REQUEST(cmd_save_config);
+    }
+
+    if (start_flag == 0)
+    {
+        sprintf(lynq_disable_cmd,"DISCONNECT");
+        DO_OK_FAIL_REQUEST(lynq_disable_cmd);
+    }
+    else
+    {
+        sprintf(lynq_select_cmd,"SELECT_NETWORK %d", net_no);
+        DO_OK_FAIL_REQUEST(lynq_select_cmd);
+    }
+
+    return 0;
+}
+
+int lynq_wifi_get_sta_ssid(lynq_wifi_index_e idx, char* sta_ssid)
+{
+    RLOGD("enter lynq_sta_ssid_password_set");
+    CHECK_IDX(idx, CTRL_STA);
+
+    curr_status_info curr_state;
+    ap_info_s ap_info;
+    curr_state.ap = &ap_info;
+    curr_state.state = NULL;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state))
+    {
+        strncpy(sta_ssid, ap_info.ap_ssid, sizeof (ap_info.ap_ssid));
+        return 0;
+    }
+
+    return -1;
+}
+
+int lynq_wifi_get_sta_available_ap(lynq_wifi_index_e idx, ap_detail_info_s *info)
+{
+    RLOGD("[wifi] ---ernter lynq_wifi_get_sta_available_ap");
+    scan_info_s *scan_list = NULL;
+    saved_ap_info_s *save_list = NULL;
+    int scan_len=0;
+    int save_len=0;
+    int best_index = -1;
+    int best_scan_index = -1;
+    int best_rssi = 0;
+    int i, j, ret;
+
+    ret = -1;
+
+    CHECK_IDX(idx, CTRL_STA);
+    if (info == NULL)
+    {
+        return -1;
+    }
+
+    curr_status_info curr_state;
+    ap_info_s ap_info;
+    char status[64];
+
+    memset(&ap_info, 0, sizeof (ap_info));
+    memset(status, 0, sizeof (status));
+
+    curr_state.ap = &ap_info;
+    curr_state.state = status;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+    {
+        memcpy(&info->base_info, &ap_info, sizeof (ap_info_s));
+        if (strcmp(status, STATE_COMPLETED) == 0)
+        {
+            info->status = LYNQ_WIFI_AP_STATUS_ENABLE;
+            RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status --> LYNQ_WIFI_AP_STATUS_ENABLE");
+        }
+        else
+        {
+            info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
+            RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status --> LYNQ_WIFI_AP_STATUS_DISABLE");
+        }
+        lynq_get_connect_ap_ip(idx, info->base_info.ap_ip);
+        lynq_get_connect_ap_rssi(idx, &info->rssi);
+        lynq_sta_ssid_password_get(idx, & info->base_info, info->base_info.psw);
+        RLOGD("[wifi] ---ent --lynq_wifi_get_sta_available_ap");
+        return 0;
+    }
+
+    lynq_wifi_sta_start_scan(idx);
+    sleep(2);
+    if (0 != lynq_get_scan_list(0, &scan_list, &scan_len))
+    {
+        if (NULL != scan_list)
+        {
+            free(scan_list);
+        }
+        return -1;
+    }
+
+    if (0 != lynq_get_sta_saved_ap(0, &save_list, &save_len))
+    {
+        if (NULL != scan_list)
+        {
+            free(scan_list);
+        }
+        if (NULL != save_list)
+        {
+            free(save_list);
+        }
+        return -1;
+    }
+
+    for (i=0; i < save_len; i++)
+    {
+        for (j=0; j < scan_len; j++)
+	{
+            if (strcmp(save_list[i].base_info.ap_ssid, scan_list[j].ssid) == 0 //@todo not finished
+                    && save_list[i].base_info.auth == scan_list[j].auth)
+	    {
+                if (best_rssi == 0)
+		{
+                    best_index = i;
+                    best_rssi = scan_list[j].rssi;
+                }
+                else if (best_rssi > scan_list[j].rssi)
+		{
+                    best_index = i;
+                    best_scan_index = j;
+                    best_rssi = scan_list[j].rssi;
+                }
+                strncpy(save_list[i].base_info.ap_mac, scan_list[j].mac, sizeof (save_list[i].base_info.ap_mac));
+                break;
+            }
+        }
+    }
+
+    if (best_index >= 0)
+    {
+        memcpy(&info->base_info, &save_list[best_index].base_info, sizeof (ap_info_s));
+        inner_get_ip_by_mac( info->base_info.ap_mac, info->base_info.ap_ip, sizeof (info->base_info.ap_ip));
+        info->status = LYNQ_WIFI_AP_STATUS_DISABLE;
+        RLOGD("[wifi] ---lynq_wifi_get_sta_available_ap status ---> LYNQ_WIFI_AP_STATUS_ENABLE");
+        info->rssi = best_rssi;
+        ret = 0;
+    }
+
+    if (NULL != scan_list)
+    {
+        free(scan_list);
+    }
+    if (NULL != save_list)
+    {
+        free(save_list);
+    }
+
+    RLOGD("[wifi] ---end -lynq_wifi_get_sta_available_ap");
+    return ret;
+}
+
+static int inner_set_sta_auth_psw(int net_no, lynq_wifi_auth_s auth, char *password)
+{
+    char lynq_auth_cmd[128]={0};
+    char lynq_ket_mgmt_cmd[64]={0};
+    char lynq_pairwise_cmd[64]={0};
+    char lynq_psk_cmd[64]={0};
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    switch(auth)
+    {
+        case LYNQ_WIFI_AUTH_OPEN:
+        {
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d key_mgmt NONE", net_no);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+//          DO_OK_FAIL_REQUEST(cmd_save_config);
+            break;
+        }
+        case LYNQ_WIFI_AUTH_WPA_PSK:
+        case LYNQ_WIFI_AUTH_WPA2_PSK:
+	{
+            if (auth == LYNQ_WIFI_AUTH_WPA_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto WPA", net_no);
+            }
+            else if (auth == LYNQ_WIFI_AUTH_WPA2_PSK)
+	    {
+                sprintf(lynq_auth_cmd,"SET_NETWORK %d proto RSN", net_no);
+            }
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt WPA-PSK", net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+
+            if (password != NULL)
+	    {
+                sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+                DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+                sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            }
+
+//            DO_OK_FAIL_REQUEST(cmd_save_config);
+            break;
+        }	
+	case LYNQ_WIFI_AUTH_WPA2_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 1",net_no);
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE WPA-PSK",net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+            
+	    DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+	    break;
+	}
+	case LYNQ_WIFI_AUTH_WPA3_PSK:
+	{
+            sprintf(lynq_auth_cmd,"SET_NETWORK %d ieee80211w 2",net_no);
+            sprintf(lynq_ket_mgmt_cmd,"SET_NETWORK %d key_mgmt SAE",net_no);
+            sprintf(lynq_pairwise_cmd,"SET_NETWORK %d pairwise CCMP", net_no);
+            sprintf(lynq_psk_cmd, "SET_NETWORK %d psk \"%s\"", net_no, password);
+            
+            DO_OK_FAIL_REQUEST(lynq_auth_cmd);
+            DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
+            DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
+            DO_OK_FAIL_REQUEST(lynq_psk_cmd);
+
+	    break;
+	}
+	default:
+            return -1;
+    }
+
+    return 0;
+}
+
+static int inner_get_curr_net_no(int interface) {
+    curr_status_info curr_state;
+    curr_state.ap = NULL;
+    curr_state.state = NULL;
+
+    if (0 != inner_get_status_info(interface, &curr_state))
+    {
+        return -1;
+    }
+
+    return curr_state.net_no;
+}
+
+int lynq_wifi_get_sta_auth(lynq_wifi_index_e idx, lynq_wifi_auth_s *auth)
+{
+    int net_no;
+    CHECK_IDX(idx, CTRL_STA);
+
+    net_no = inner_get_curr_net_no(CTRL_STA);
+
+    if (net_no < 0)
+    {
+        return -1;
+    }
+
+    return inner_get_network_auth(CTRL_STA, net_no, auth);
+}
+
+int lynq_wifi_sta_connect_timeout(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw, int timeout)
+{
+    int count, net_no, index;
+    int net_no_list[128];
+    char rm_net_cmd[128];
+    lynq_wifi_auth_s net_auth;
+    curr_status_info curr_state;
+    ap_info_s ap_info;
+    char status[64];
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("bad ssid\n");
+        return -1;
+    }
+
+    if (LYNQ_WIFI_AUTH_OPEN != auth)
+    {
+        if (psw == NULL || strlen(psw) < 8 || strlen(psw) >= 64)
+        {
+            RLOGE("bad password\n");
+            return -1;
+        }
+    }
+
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    if (s_sta_status != INNER_STA_STATUS_INIT)
+    {
+        s_sta_status = INNER_STA_STATUS_CANCEL;
+        pthread_cond_signal(&s_global_check_cond);
+    }
+    pthread_mutex_unlock(&s_global_check_mutex);
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    net_no = -1;
+    memset(&ap_info, 0, sizeof (ap_info));
+    memset(status, 0, sizeof (status));
+
+    curr_state.ap = &ap_info;
+    curr_state.state = status;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
+    {
+        if (strcmp(status, STATE_COMPLETED) == 0 && strcmp(ap_info.ap_ssid, ssid) ==0 && ap_info.auth == auth)
+        {
+            net_no = curr_state.net_no;
+            if (0 == lynq_sta_ssid_password_get(idx, &ap_info, ap_info.psw)
+                    && strcmp(ap_info.psw, psw) == 0)
+            {
+                RLOGD("already connected\n");
+
+                pthread_mutex_lock(&s_global_check_mutex);
+                s_sta_status = INNER_STA_STATUS_CONNECTED;
+                lynq_sta_removeElement(net_no);
+                pthread_cond_signal(&s_global_check_cond);
+                pthread_mutex_unlock(&s_global_check_mutex);
+                return 0;
+            }
+        }
+    }
+
+    if (net_no == -1)
+    {
+        count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+
+        for (index=0; index < count; index++)
+        {
+            net_auth = -1;
+            if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+            {
+                net_no = net_no_list[index];
+                break;
+            }
+        }
+
+        if (net_no < 0)
+        {
+            count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
+            for ( index = 0; index < (count - STA_MAX_SAVED_AP_NUM + 1 ) ;index++)       //+1 is for add new network
+            {
+                sprintf(rm_net_cmd,"REMOVE_NETWORK %d",net_no_list[index]);
+                RLOGD("call cmd rm_net_cmd: %s;index is %d\n",rm_net_cmd,index);
+                DO_OK_FAIL_REQUEST(rm_net_cmd);
+            }
+            net_no = lynq_add_network(CTRL_STA);
+            if (net_no == -1)
+            {
+                return -1;
+            }
+
+            RLOGD("net no is %d\n", net_no);
+            if (0 != inner_set_sta_ssid(net_no, ssid))
+            {
+                return -1;
+            }
+        }
+    }
+
+    if (0 != inner_set_sta_auth_psw(net_no, auth, psw))
+    {
+        return -1;
+    }
+
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    system("echo \"\" > /tmp/wlan0_dhcpcd_router");
+    usleep(200*1000);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    lynq_sta_removeElement(net_no);
+    pthread_mutex_unlock(&s_global_check_mutex);
+
+    ret = inner_sta_start_stop(net_no, 1, 1);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_CONNECTING;
+    g_sta_conncet_status_flag = 1;
+    strcpy(s_sta_current_connecting_ssid, ssid);
+    struct timeval now;
+    gettimeofday(&now,NULL);
+    s_sta_connect_timeout.tv_sec = now.tv_sec + timeout;
+    s_sta_connect_timeout.tv_nsec = now.tv_usec*1000;
+    pthread_cond_signal(&s_global_check_cond);
+    pthread_mutex_unlock(&s_global_check_mutex);
+    return ret;
+}
+
+int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw)
+{
+    return lynq_wifi_sta_connect_timeout(idx, ssid, auth, psw, MAX_CONNNECT_TIME);
+}
+
+int lynq_wifi_sta_disconnect(lynq_wifi_index_e idx, char *ssid)
+{
+    ap_info_s ap;
+    curr_status_info curr_state;
+    ap.ap_ssid[0] = '\0';
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("input ssid is NULL\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    curr_state.ap = &ap;
+    curr_state.state = NULL;
+
+    if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+    {
+        return 0;
+    }
+
+    if (strcmp(ap.ap_ssid, ssid) != 0)
+    {
+        return 0;
+    }
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_DISCONNECTING;
+    pthread_mutex_unlock(&s_global_check_mutex);
+    return inner_sta_start_stop(curr_state.net_no, 0, 0);
+}
+
+int lynq_wifi_sta_disconnect_ap(lynq_wifi_index_e idx, char *ssid)
+{
+    int i,check_history_idx_flag;
+    ap_info_s ap;
+    curr_status_info curr_state;
+    ap.ap_ssid[0] = '\0';
+    check_history_idx_flag = 0;
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGE("input ssid is NULL\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+
+    curr_state.ap = &ap;
+    curr_state.state = NULL;
+
+    if (inner_get_status_info(CTRL_STA, &curr_state) != 0)
+    {
+        return 0;
+    }
+
+    if (strcmp(ap.ap_ssid, ssid) != 0)
+    {
+        return 0;
+    }
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_DISCONNECTING;
+    RLOGD("WIFI[lynq_wifi_sta_disconnect_ap]g_history_disconnect_valid_num is %d",g_history_disconnect_valid_num);
+    for( i = 0; i< g_history_disconnect_valid_num ; i++)
+    {
+        RLOGD("WIFI[lynq_wifi_sta_disconnect_ap]g_history_disconnect_net[%d] is %d,current disconnet network is %d",i,g_history_disconnect_net[i],curr_state.net_no);
+        if( g_history_disconnect_net[i] == curr_state.net_no)
+        {
+            RLOGD("current disconenct ap idx is %d && last aready into g_history_disconenct_net",curr_state.net_no);
+            check_history_idx_flag = 1;
+            break;
+        }
+    }
+    if ( check_history_idx_flag == 0)
+    {
+        RLOGD("current need add ap idx is %d ,g_history_disconnect_valid_num is %d line %d",curr_state.net_no,g_history_disconnect_valid_num,__LINE__);
+        g_history_disconnect_net[g_history_disconnect_valid_num] = curr_state.net_no;
+        g_history_disconnect_valid_num++;
+    }
+    RLOGD("%s %d",__func__,__LINE__);
+    print_disconnect_list();
+    pthread_mutex_unlock(&s_global_check_mutex);
+    return lynq_wifi_sta_stop_network(idx, curr_state.net_no);
+
+}
+
+
+int lynq_wifi_sta_start(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d func",__func__,__LINE__);
+    const char *lynq_enable_sta_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 enable_net all";
+    const char *lynq_reconnect_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 reconnect";
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    ret = system_call_v("%s %s", start_stop_sta_script, "start");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_sta_start excute script fail %s %d",__func__,__LINE__);
+        return -1;
+    }
+
+    system(lynq_enable_sta_cmd);
+    system(lynq_reconnect_cmd);
+    pthread_mutex_lock(&s_global_check_mutex);
+    g_history_disconnect_valid_num = 0;   //clean history_disconenct_list info
+    s_sta_status = INNER_STA_STATUS_INIT;
+    pthread_mutex_unlock(&s_global_check_mutex);
+    RLOGD("end %s %d func",__func__,__LINE__);
+    return 0;
+}
+
+static int inner_get_status_info_state (int interface, char *state) {
+    curr_status_info curr_state;
+    curr_state.ap = NULL;
+    curr_state.state = state;
+    return inner_get_status_info(interface, &curr_state);
+}
+
+int lynq_wifi_sta_start_auto(lynq_wifi_index_e idx)
+{
+
+    RLOGD("[wifi]enter lynq_wifi_sta_start_auto start");
+    int tmp_open_idx[128];
+    int len;
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_INIT;
+    lynq_two_arr_merge(g_history_disconnect_net,g_history_disconnect_valid_num,tmp_open_idx,&len);
+    pthread_mutex_unlock(&s_global_check_mutex);
+    if(lynq_tmp_enable_network(idx,tmp_open_idx,len) != 0 )
+    {
+        RLOGD("[wifi]lynq_tmp_enable_network error");
+    }
+
+    RLOGD("[wifi]enter lynq_wifi_sta_start_auto end");
+    return 0;
+}
+
+
+int lynq_wifi_sta_stop(lynq_wifi_index_e idx)
+{
+    RLOGD("enter %s %d",__func__,__LINE__);
+    int i=0;
+    char state[MAX_CMD];
+
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    ret = system_call_v("%s %s", start_stop_sta_script, "stop");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_sta_stop excute script fail %s %d",__func__,__LINE__);
+        return -1;
+    }
+
+    for (i=0; i < 30; i++) // to check if sta is realy stoped
+    {
+        if (inner_get_status_info_state(idx, state) != 0)
+        {
+            break;
+        }
+
+        if (memcmp(state, STATE_DISCONNECTED, strlen (STATE_DISCONNECTED)) == 0)
+        {
+            break;
+        }
+        RLOGD("lynq_wifi_sta_stop curr state %s %s %d", state,__func__,__LINE__);
+        usleep(SLEEP_TIME_ON_IDLE);
+    }
+    pthread_mutex_lock(&s_global_check_mutex);
+    g_history_disconnect_valid_num = 0;   //clean history_disconenct_list info
+    pthread_mutex_unlock(&s_global_check_mutex);
+    RLOGD("end %s %d",__func__,__LINE__);
+    return 0;
+//    return system("connmanctl disable wifi");
+}
+int lynq_wifi_sta_stop_net(lynq_wifi_index_e idx,int networkid)
+{
+    char LYNQ_DISABLE_CMD[128]={0};
+    CHECK_IDX(idx, CTRL_STA);
+    CHECK_WPA_CTRL(CTRL_STA);
+    sprintf(LYNQ_DISABLE_CMD,"DISABLE_NETWORK %d",networkid);
+    RLOGD("LYNQ_DISABLE_CMD is:%d\n",LYNQ_DISABLE_CMD);
+    DO_OK_FAIL_REQUEST(LYNQ_DISABLE_CMD);
+    return 0;
+}
+
+//static int inner_get_sta_info(lynq_wifi_index_e idx, const char * bssid, device_info_s *dev) {
+//    int i, count;
+//    char *p;
+//    const char * FLAG_SSID = "ssid=";
+//    const char * FLAG_SBSID = "bssid=";
+//    const char * FLAG_KEY_MGMT = "key_mgmt=";
+//    const char * FLAG_FREQ = "freq=";
+//    char lynq_sta_cmd[MAX_CMD];
+//    char *split_lines[128] = {0};
+
+//    CHECK_WPA_CTRL(CTRL_AP);
+
+//    sprintf(lynq_sta_cmd, "STA %s", bssid);
+
+//    DO_REQUEST(lynq_sta_cmd);
+
+//    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+
+//    for(i=0; i < count; i++) {
+//        p = strstr(split_lines[i], FLAG_SSID);
+//        if (p != NULL) {
+//            strcpy(ap->ap_ssid, p + strlen(FLAG_SSID));
+//            continue;
+//        }
+//    }
+
+//    lynq_get_interface_ip(idx, ap->ap_ip);
+//    lynq_ap_password_set(idx, ap->psw);
+
+//    return 0;
+//}
+
+static int inner_get_status_info_ap (int interface, ap_info_s *ap) {
+    curr_status_info curr_state;
+    curr_state.ap = ap;
+    curr_state.state = NULL;
+    return inner_get_status_info(interface, &curr_state);
+}
+
+int lynq_get_ap_device_list(lynq_wifi_index_e idx, ap_info_s **ap, device_info_s ** list,int * len)
+{
+    RLOGD("[wifi]-----enter lynq_get_ap_device_list");
+    int index, line_count;
+    device_info_s *dev_info;
+    const char *lynq_first_sta_cmd = "STA-FIRST";
+    char lynq_next_sta_cmd[MAX_CMD];
+    char *bssid[1024] = {0};
+    char *split_lines[128] = {0};
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    //    ap_info_s * tmp_ap;
+    //    device_info_s * tmp_list;
+    if (ap == NULL || list == NULL || len == NULL)
+    {
+        RLOGE("bad input param");
+        return -1;
+    }
+
+    //    ap = &tmp_ap;
+    //    list = &tmp_list;
+    *ap = malloc(sizeof (ap_info_s));
+    memset(*ap, 0, sizeof (ap_info_s));
+
+    if (inner_get_status_info_ap (CTRL_AP, *ap) != 0 || (*ap)->ap_ssid[0] == '\0')
+    {
+        RLOGE("inner_get_status_info_ap !=0 or ap_ssid is empty\n");
+        return -1;
+    }
+
+    lynq_get_interface_ip(idx, (*ap)->ap_ip);
+    lynq_ap_password_get(idx, (*ap)->psw);
+
+    DO_REQUEST(lynq_first_sta_cmd);
+
+    index = 0;
+    while (reply_len > 0)
+    {
+        if (memcmp(cmd_reply, "FAIL", 4) == 0)
+        {
+            break;
+        }
+        line_count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+        bssid[index] = malloc(strlen(split_lines[0]) + 1);
+        strcpy(bssid[index], split_lines[0]);
+        index++;
+        sprintf(lynq_next_sta_cmd, "STA-NEXT %s", split_lines[0]);
+        reply_len = MAX_RET;
+        cmd_reply[0] = '\0';
+        ret = local_wpa_ctrl_request(lynq_wpa_ctrl, lynq_next_sta_cmd, strlen(lynq_next_sta_cmd), cmd_reply, &reply_len, NULL);
+        if (ret != 0 || memcmp(cmd_reply, "FAIL", 4) == 0)
+        {
+            RLOGD("run %s fail \n", lynq_next_sta_cmd);
+            break;
+        }
+    }
+
+    *len = index;
+
+    *list = malloc(sizeof(device_info_s) * (*len));
+    for (index=0; index < *len; index++)
+    {
+        dev_info = &(*list)[index];
+        memset(dev_info, 0, sizeof(device_info_s));
+        strncpy(dev_info->sta_mac, bssid[index], sizeof (dev_info->sta_mac));
+        inner_get_ip_by_mac(dev_info->sta_mac, dev_info->sta_ip, sizeof (dev_info->sta_ip));
+        inner_get_hostname_by_ip(dev_info->sta_ip, dev_info->hostname);
+        dev_info->status = LYNQ_WIFI_STATUS_CONNECT;
+        free(bssid[index]);
+    }
+    RLOGD("[wifi]-----end lynq_get_ap_device_list");
+    return 0;
+}
+
+int lynq_get_scan_list(lynq_wifi_index_e idx, scan_info_s ** list,int * len)
+{
+    int i, count, index, count_words;
+    const char *lynq_scan_result_cmd = "SCAN_RESULTS";
+    char *split_lines[128] = {0};
+    char *split_words[128] = {0};
+    scan_info_s * p;
+
+    if (list == NULL || len == NULL)
+    {
+        return -1;
+    }
+
+    for (i =0; i < 50 && g_sta_scan_finish_flag == 0; i++)
+    {
+        usleep(100 * 1000);
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    DO_REQUEST(lynq_scan_result_cmd);
+
+    count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
+    *len = count - 1;
+    *list = malloc(sizeof (scan_info_s) * *len);
+
+    count_words = lynq_split(split_lines[0], strlen(split_lines[0]), '/', split_words); //@todo get with header
+    for (index=0; index <count_words; index++)
+    {
+        RLOGD("----header: %s\n", split_words[index]);
+    }
+
+    for(index = 1;index < count; index++)
+    {
+        RLOGD("---- %s\n",split_lines[index]);
+        memset(split_words, 0 , sizeof (split_words));
+        count_words = lynq_split(split_lines[index], strlen(split_lines[index]), '\t', split_words);
+        if (count_words < 4)
+            continue;
+        RLOGD("count: %d, %s\n", count_words, split_words[0]);
+        //bssid / frequency / signal level / flags / ssid
+        p = (*list) + index - 1;
+        strcpy(p->mac, split_words[0]);
+        p->band = convert_band_from_freq(atoi(split_words[1]));
+        p->rssi = -1 * atoi( split_words[2]);
+        p->auth = convert_max_auth_from_flag(split_words[3]);
+        if (count_words == 4) // ssid hided
+        {
+            p->ssid[0] = '\0';
+        }
+        else
+        {
+            inner_copy_ssid(p->ssid, split_words[4], sizeof (p->ssid));
+        }
+    }
+
+    return 0;
+}
+
+int lynq_sta_forget_ap(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth)
+{
+    int count, net_no, index;
+    int net_no_list[128];
+    lynq_wifi_auth_s net_auth;
+
+    char lynq_remove_cmd[MAX_CMD];
+
+    if (ssid == NULL || *ssid == '\0')
+    {
+        RLOGD("bad ssid\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    net_no = -1;
+    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+
+    for (index=0; index < count; index++)
+    {
+        net_auth = -1;
+        if (0 == inner_get_network_auth(CTRL_STA, net_no_list[index], &net_auth) && net_auth == auth)
+	{
+            net_no = net_no_list[index];
+            break;
+        }
+    }
+
+    if (net_no < 0)
+    {
+        return 0;
+    }
+
+    sprintf(lynq_remove_cmd, "REMOVE_NETWORK %d", net_no);
+
+    DO_OK_FAIL_REQUEST(lynq_remove_cmd);
+
+    RLOGD("WIFI[lynq_sta_forget_ap][check_history_disconenct_ap_list] input net_no is %d",net_no);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    lynq_sta_removeElement(net_no);
+    pthread_mutex_unlock(&s_global_check_mutex);
+
+    RLOGD("%s %d",__func__,__LINE__);
+    print_disconnect_list();
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+
+    return 0;
+}
+
+int lynq_get_sta_saved_ap(lynq_wifi_index_e idx, saved_ap_info_s ** list, int * len)
+{
+    int count, index;
+    int net_no_list[128];
+    char freq[16];
+    RLOGD("enter lynq_get_sta_saved_ap api\n");
+    if (list == NULL || len == NULL)
+    {
+        RLOGE("bad param,please check!");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+//    CHECK_WPA_CTRL(CTRL_STA);
+
+    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, NULL);
+    RLOGD("[lynq_get_sta_saved_ap]count is %d\n", count);
+
+    if (count < 0)
+    {
+        RLOGE("list network fail");
+        return count;
+    }
+    else if (count == 0)
+    {
+        *list = NULL;
+        *len = 0;
+        return 0;
+    }
+
+    *list = malloc(sizeof (saved_ap_info_s) * count);
+    memset(*list, 0, sizeof (saved_ap_info_s) * count);
+    *len = count;
+
+    for (index=0; index < count; index++)
+    {
+        inner_get_param(CTRL_STA, net_no_list[index], "ssid", (*list)[index].base_info.ap_ssid);
+        inner_get_param(CTRL_STA, net_no_list[index], "bssid", (*list)[index].base_info.ap_mac);
+        inner_get_network_auth(CTRL_STA, net_no_list[index], &(*list)[index].base_info.auth);
+        if (inner_get_param(CTRL_STA, net_no_list[index], "frequency", freq) == 0)
+        {
+            (*list)[index].base_info.band = convert_band_from_freq(atoi(freq));
+        }
+        else
+        {
+            (*list)[index].base_info.band = -1;
+        }
+        RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get psw");
+        lynq_sta_ssid_password_get(idx, & (*list)[index].base_info, (*list)[index].base_info.psw);
+    }
+    RLOGD("[lynq_get_sta_saved_ap] return ok");
+    return 0;
+}
+
+int lynq_wifi_sta_start_scan(lynq_wifi_index_e idx)
+{
+    if ( s_sta_status == INNER_STA_STATUS_INIT && g_sta_conncet_status_flag != 0 )
+    {
+        RLOGD("current sta is autoconnecting dest ap,fake scan result");
+        g_sta_fake_scan_finish_flag = 1;
+        return 0;
+    }
+    else if (g_sta_conncet_status_flag != 0)
+    {
+        RLOGD("current sta is connecting dest ap, don't scan");
+        return 1;
+    }
+
+    const char *clean_last_re ="wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 bss_flush";
+    const char *lynq_scan_cmd = "SCAN";
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    CHECK_WPA_CTRL(CTRL_STA);
+
+    if (g_sta_scan_finish_flag == 1 && s_sta_status == INNER_STA_STATUS_INIT) // temp add
+    {
+        RLOGD("tmp clear scanlist");
+        system(clean_last_re);
+    }
+    g_sta_scan_finish_flag = 0;
+    DO_REQUEST(lynq_scan_cmd);
+    if (reply_len >=9 && memcmp(cmd_reply, "FAIL-BUSY", 9) == 0 )
+    {
+        return 0;
+    } else if (reply_len >=2 && memcmp(cmd_reply, "OK", 2) != 0)
+    {
+        g_sta_scan_finish_flag = 1;
+        return -1;
+    }
+
+    return 0;
+}
+
+int lynq_reg_ap_event_callback(void * priv, AP_CALLBACK_FUNC_PTR cb) {
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_ap_event_callback ptr is NULL,plese check!\n");
+        return -1;
+    }
+
+    pthread_mutex_lock(&s_ap_callback_mutex);
+    g_ap_callback_priv = priv;
+    g_ap_callback_func = cb;
+    pthread_mutex_unlock(&s_ap_callback_mutex);
+
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    if (g_ap_watcher_pid == 0 )
+    {
+        if(pthread_create(&g_ap_watcher_pid,NULL,APWatcherThreadProc,NULL) < 0)
+        {
+            g_ap_watcher_pid = 0;
+            pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+            RLOGE("[wifi error]creat APWatcherThreadProc fail");
+            return -1;
+        }
+    }
+
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    RLOGD("creat APWatcherTheradProc succeed");
+
+    return 0;
+}
+
+int lynq_unreg_ap_event_callback(void * priv) {
+    RLOGD("enter %s %d",__func__,__LINE__);
+    pthread_mutex_lock(&s_ap_callback_mutex);
+    if (g_ap_callback_priv == priv)
+    {
+        g_ap_callback_func = NULL;
+        g_ap_callback_priv = NULL;
+        pthread_mutex_unlock(&s_ap_callback_mutex);
+	RLOGD("unreg ap callback pass %s %d",__func__,__LINE__);
+        return 0;
+    }
+    pthread_mutex_unlock(&s_ap_callback_mutex);
+    RLOGE("unreg ap callback fail %s %d",__func__,__LINE__);
+    return -1;
+}
+
+int lynq_reg_sta_event_callback(void * priv, STA_CALLBACK_FUNC_PTR cb){
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_sta_event_callback ptr is NULL,plese check!\n");
+        return -1;
+    }
+
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    g_sta_callback_priv = priv;
+    g_sta_callback_func = cb;
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    if (g_sta_watcher_pid == 0 ) {
+        if(pthread_create(&g_sta_watcher_pid,NULL,STAWatcherThreadProc,NULL) < 0)
+        {
+            g_sta_watcher_pid = 0;
+            pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+            RLOGE("[wifi error]creat STAWatcherThreadProc fail");
+            return -1;
+        }
+    }
+
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    RLOGD("creat STAWatcherTheradProc succeed");
+    return 0;
+}
+
+int lynq_unreg_sta_event_callback(void * priv) {
+    RLOGD("enter %s %d",__func__,__LINE__);
+    pthread_mutex_lock(&s_sta_callback_mutex);
+    if (g_sta_callback_priv == priv)
+    {
+        g_sta_callback_func = NULL;
+        g_sta_callback_priv = NULL;
+        pthread_mutex_unlock(&s_sta_callback_mutex);
+        RLOGD("unreg sta callback pass  %s %d",__func__,__LINE__);
+        return 0;
+    }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
+    RLOGE("unreg sta callback fail  %s %d",__func__,__LINE__);
+    return -1;
+}
+
+int lynq_reg_sta_auto_event_callback(void * priv, STA_AUTO_CALLBACK_FUNC_PTR cb){
+    if (cb == NULL) 
+    {
+        RLOGE("lynq_reg_sta_auto_event_callback ptr is NULL,plese check!\n");
+        return -1;
+    }
+    pthread_mutex_lock(&s_sta_auto_callback_mutex);
+    g_sta_auto_callback_priv = priv;
+    g_sta_auto_callback_func = cb;
+    pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    if (g_sta_auto_watcher_pid == 0 ) {
+        if(pthread_create(&g_sta_auto_watcher_pid,NULL,STAAutoWatcherThreadProc,NULL) < 0)  //create STAAutoWatcherThreadProc
+        {
+            g_sta_auto_watcher_pid = 0;
+            pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+            RLOGE("[wifi error]creat STAWatcherThreadProc fail");
+            return -1;
+        }
+    }
+    pthread_mutex_unlock(&s_check_wpa_ctrl_mutex);
+    RLOGD("creat STAWatcherTheradProc succeed");
+    return 0;
+}
+int lynq_unreg_sta_auto_event_callback(void * priv) {
+    pthread_mutex_lock(&s_sta_auto_callback_mutex);
+    if (g_sta_auto_callback_priv == priv)
+    {  
+        g_sta_auto_watcher_stop_flag = 1;
+        if (g_sta_auto_watcher_pid != 0)
+        {
+            pthread_join(g_sta_auto_watcher_pid, NULL);
+        }
+    g_sta_auto_watcher_pid = 0;
+        g_sta_auto_callback_func = NULL;
+        g_sta_auto_callback_priv = NULL;
+        pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+        return 0;
+    }
+    pthread_mutex_unlock(&s_sta_auto_callback_mutex);
+    return -1;
+}
+int lynq_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status)
+{
+    char state[MAX_CMD];
+    RLOGD("enter lynq_get_ap_status\n");
+    CHECK_IDX(idx, CTRL_AP);
+
+    if (inner_get_status_info_state(CTRL_AP, state) != 0)
+    {
+        *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
+        return 0;
+    }
+
+    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+    {
+        *ap_status = LYNQ_WIFI_AP_STATUS_ENABLE;
+    }
+    else
+    {
+        *ap_status = LYNQ_WIFI_AP_STATUS_DISABLE;
+    }
+
+    return 0;
+}
+
+int lynq_get_sta_status(lynq_wifi_index_e idx, lynq_wifi_sta_run_status_s * sta_status) {
+    char state[MAX_CMD];
+    RLOGD("enter lynq_get_sta_status\n");
+    CHECK_IDX(idx, CTRL_STA);
+
+    if (inner_get_status_info_state(CTRL_STA, state) != 0)
+    {
+        *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
+        return 0;
+    }
+
+    if (memcmp(state, STATE_COMPLETED, strlen (STATE_COMPLETED)) == 0)
+    {
+        *sta_status = LYNQ_WIFI_STA_STATUS_ENABLE;
+    }
+    else
+    {
+        *sta_status = LYNQ_WIFI_STA_STATUS_DISABLE;
+    }
+
+    return 0;
+}
+
+int lynq_get_country_code(lynq_wifi_index_e idx, char * country_code) {
+//    CHECK_IDX(idx, CTRL_AP);
+//    int ret = 0;
+//    size_t reply_len = MAX_RET;
+//    char cmd_reply[MAX_RET]={0};
+//    const char * cmd_str = "GET country";
+//    struct wpa_ctrl *s_lynq_wpa_ctrl = NULL;
+//    do{
+//        if (NULL == s_lynq_wpa_ctrl) {
+//            s_lynq_wpa_ctrl = wpa_ctrl_open("/var/run/wpa_wlan0_cmd");
+//            if (NULL == s_lynq_wpa_ctrl ) {
+//                printf("wpa_ctrl_open fail\n");
+//                return -1;
+//            }
+//        }
+//    }while(0);
+
+//    do {
+//        reply_len = MAX_RET;
+//        cmd_reply[0] = '\0';
+//        printf("to call [%s]\n", cmd_str);
+//        ret = local_wpa_ctrl_request(s_lynq_wpa_ctrl, cmd_str, strlen(cmd_str), cmd_reply, &reply_len, NULL);
+//        if (ret != 0) {
+//            RLOGE("call ##cmd_str fail %d\n", ret);
+//            return ret;
+//        }
+//        cmd_reply[reply_len+1] = '\0';
+//        RLOGD("cmd replay [ %s ]\n", cmd_reply);
+//    }while(0);
+
+    FILE *fp;
+    size_t i = 0;
+    char lynq_cmd_ret[MAX_RET]={0};
+
+//    CHECK_IDX(idx, CTRL_AP);
+
+    if((fp=popen("wl country","r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
+    {
+        perror("fread fail!");
+        return -1;
+    }
+
+    for(i=0; i < strlen(lynq_cmd_ret); i++)
+    {
+        if (lynq_cmd_ret[i] == ' ')
+	{
+            lynq_cmd_ret[i] = '\0';
+            break;
+        }
+    }
+
+    strcpy(country_code,lynq_cmd_ret);
+    RLOGD("---country code %s\n", country_code);
+
+    int ret=pclose(fp);
+    if(ret==-1)
+    {
+        perror("close file faild");
+    }
+
+    return 0;
+}
+
+
+static int check_and_init_uci_config(char * country_code)
+{
+    FILE * fp;
+    int is_different = 0;
+    const char * check_uci_cmd ="uci show | grep lynq_wifi_country_code";
+    const char * create_uci_cmd ="uci set lynq_uci.lynq_wifi_country_code='lynq_wifi_country_code'";
+    const char * commit_uci_cmd ="uci commit";
+    char set_country_cmd[MAX_CMD];
+    char lynq_cmd_ret[MAX_CMD]={0};
+
+    sprintf(set_country_cmd, "uci set lynq_uci.lynq_wifi_country_code.code='%s'",country_code);
+
+    if (0 != system(check_uci_cmd))
+    {
+        if (0 != system(create_uci_cmd))
+        {
+            RLOGE("creat_uci_cmd fail");
+            return -1;
+        }
+        is_different = 1;
+    }
+
+    if((fp=popen("uci get lynq_uci.lynq_wifi_country_code.code","r"))==NULL)
+    {
+        RLOGE("popen error!");
+        return -1;
+    }
+
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0 )
+    {
+        RLOGE("fread fail!");
+        fclose(fp);
+        return -1;
+    }
+
+    if ( strncmp(lynq_cmd_ret,country_code,2) != 0 )
+    {
+	RLOGE("get country code for uci %s，input cpuntry code is:%s\n",lynq_cmd_ret,country_code);
+        is_different = 1;
+    }
+
+    fclose(fp);
+
+    if (is_different)
+    {
+        if ( 0 != system(set_country_cmd))
+        {
+            RLOGE("set_country_cmd fail");
+            return -1;
+        }
+        if (0 != system(commit_uci_cmd))
+        {
+            RLOGE("commmit fail");
+        }
+    }
+
+    return is_different;
+}
+
+int lynq_set_country_code(lynq_wifi_index_e idx, char * country_code) {
+    char check_current_code[10];
+    const char * support_country[] = {"CN", "EU"};
+
+    int ret,is_different, i, cc_count;
+
+    if (country_code == NULL || country_code[0] == '\0')
+    {
+        RLOGE("bad country code\n");
+        return -1;
+    }
+
+    cc_count = sizeof (support_country) / sizeof (char*);
+    for(i=0; i < cc_count; i++)
+    {
+        if (strcmp(support_country[i], country_code) == 0)
+        {
+            break;
+        }
+    }
+
+    if (i >= cc_count)
+    {
+        RLOGE("unspported country code %s\n", country_code);
+        return -1;
+    }
+
+    is_different = check_and_init_uci_config(country_code);
+    if( is_different < 0 )
+    {
+        RLOGE("init set uci fail\n");
+        return -1;
+    }
+
+    ret = lynq_get_country_code(idx,check_current_code);
+    if( ret == 0 && (is_different == 1 || strcmp(check_current_code, country_code) != 0))
+    {
+        ret = lynq_wifi_disable();
+        if(ret != 0 )
+        {
+            RLOGE("berfore set country,find bcmdhd insmod,remod fail\n");
+            return -1;
+        }
+    }
+
+    return 0;
+}
+
+int lynq_get_connect_ap_mac(lynq_wifi_index_e idx,char *mac)
+{
+    RLOGD("enter lynq_get_connect_ap_mac\n");
+    if (mac == NULL) 
+    {
+        RLOGE("input ptr is NULL,please check\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+    ap_info_s ap;
+    ap.ap_mac[0] = '\0';
+
+    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+    {
+        return -1;
+    }
+    strcpy(mac, ap.ap_mac);
+
+    return 0;
+}
+
+int lynq_get_interface_ip(lynq_wifi_index_e idx, char *ip)
+{
+    RLOGD("enter lynq_get_interface_ip\n");
+    struct ifaddrs *ifaddr_header, *ifaddr;
+    struct in_addr * ifa;
+    const char * ifaName = "wlan0";
+    if (ip == NULL)
+    {
+       RLOGE("[lynq_get_interface_ip]input erro,input is NULL ptr,please check\n");
+       return -1;
+    }
+
+    if (idx == 1)
+    {
+       ifaName = inner_get_ap_interface_name();
+       if (ifaName == NULL)
+       {
+           RLOGE("[lynq_get_interface_ip] ap name get fail");
+           return -1;
+       }
+    }
+    else if (idx != 0)
+    {
+       return -1;
+    }
+
+    if (getifaddrs(&ifaddr_header) == -1)
+    {
+       perror("getifaddrs");
+       return -1;
+       //exit(EXIT_FAILURE);
+    }
+
+
+    for (ifaddr = ifaddr_header; ifaddr != NULL; ifaddr = ifaddr->ifa_next)
+    {
+        if (ifaddr->ifa_addr == NULL)
+           continue;
+        if((strcmp(ifaddr->ifa_name,ifaName)==0))
+        {
+            if (ifaddr->ifa_addr->sa_family==AF_INET) // check it is IP4
+            {
+               // is a valid IP4 Address
+               ifa=&((struct sockaddr_in *)ifaddr->ifa_addr)->sin_addr;
+               inet_ntop(AF_INET, ifa, ip, INET_ADDRSTRLEN);
+               RLOGD("[lynq_get_interface_ip]:%s IP Address %s/n", ifaddr->ifa_name, ip);
+               freeifaddrs(ifaddr_header);
+               RLOGD("ip %s\n", ip);
+               return 0;
+            }
+        }
+    }
+    freeifaddrs(ifaddr_header);
+    RLOGE("[lynq_get_interface_ip] can't find interface | other erro\n");
+    return -1;
+}
+
+int lynq_get_interface_mac(lynq_wifi_index_e idx,char *mac)
+{
+    RLOGD("enter lynq_get_interface_mac\n");
+    int count;
+    size_t i;
+    int WIFI_INTERFACE_MAC_LEN = 17;
+    char *split_words[128] = {0};
+    const char *lynq_get_mac_cmd = "DRIVER MACADDR";
+
+    CHECK_WPA_CTRL(idx);
+
+    DO_REQUEST(lynq_get_mac_cmd);
+
+    if (memcmp(cmd_reply, "FAIL", 4) == 0)
+    {
+        RLOGE("[lynq_get_interface_mac]do request cmd --DRIVER MACADDR-- reply FAIL\n");
+        return -1;
+    }
+
+    count = lynq_split(cmd_reply, reply_len, '=', split_words);
+
+    if (count < 2)
+    {
+        return -1;
+    }
+
+    for (i=0; i < strlen(split_words[1]); i++ )
+    {
+        if (split_words[1][i] != ' ')
+	{
+            break;
+        }
+    }
+
+    strncpy(mac, split_words[1] + i, WIFI_INTERFACE_MAC_LEN);
+
+    return 0;
+}
+
+int lynq_get_connect_ap_rssi(lynq_wifi_index_e idx,int * rssi)
+{
+//    int count;
+//    char *split_words[128] = {0};
+//    const char *lynq_get_rssi_cmd = "DRIVER RSSI";
+
+//    if (rssi == NULL) {
+//        return -1;
+//    }
+
+//    CHECK_IDX(idx, CTRL_STA);
+
+//    CHECK_WPA_CTRL(CTRL_STA);
+
+//    DO_REQUEST(lynq_get_rssi_cmd);
+
+//    if (memcmp(cmd_reply, "FAIL", 4) == 0) {
+//        return -1;
+//    }
+
+//    count = lynq_split(cmd_reply, reply_len, ' ', split_words);
+
+//    if (count < 2) {
+//        return -1;
+//    }
+
+//    *rssi = atoi(split_words[1]) * -1;
+
+    char lynq_cmd_ret[MAX_RET]={0};
+
+/*******change other cmd to get rssi*******
+ *
+ *wl rssi ---> wl -i wlan0 rssi
+ *
+ ***** change by qs.xiong 20221011*******/
+    if (0 !=  exec_cmd("wl -i wlan0 rssi", lynq_cmd_ret, MAX_RET))
+    {
+        RLOGE("[lynq_get_connect_ap_rssi] exec cmd [ wl -i wlan0 rssi ] fail");
+        return -1;
+    }
+    *rssi = atoi(lynq_cmd_ret) * -1;
+/****** if got rssi is 0,means sta didn't connected any device****/
+    if(*rssi == 0)
+    {
+        RLOGE("[lynq_get_connect_ap_rssi]sta didn't connected any ap device,please check connection\n");
+        return -1;
+    }
+
+    return 0;
+}
+
+int lynq_get_connect_ap_band(lynq_wifi_index_e idx, lynq_wifi_band_m * band)
+{
+    RLOGD("enter lynq_get_connect_ap_band\n");
+    if (band == NULL)
+    {
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+    ap_info_s ap;
+    ap.band = -1;
+
+    if (inner_get_status_info_ap(CTRL_STA, &ap) != 0)
+    {
+        return -1;
+    }
+    *band = ap.band;
+
+    return 0;
+}
+
+int lynq_get_connect_ap_ip(lynq_wifi_index_e idx, char *ip)
+{
+    int ret;
+    char *p;
+    char bssid[1024] = {0};
+
+    if (ip == NULL)
+    {
+        RLOGE("[lynq_get_connect_ap_ip]invalid param ptr ip,input ptr is NULL\n");
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_STA);
+
+    if (lynq_get_connect_ap_mac(idx, bssid) != 0)
+    {
+        return -1;
+    }
+
+    ip[0] = '\0';
+    ret = inner_get_ip_by_mac(bssid, ip, 32); //better input by user
+    if (ret != 0)
+    {
+        RLOGE("[lynq_get_connect_ap_ip] inner_get_ip_by_mac return fail");
+    }
+
+    if (ip[0] == '\0' || strchr(ip, ':') != NULL) //temp change, not ok
+    {
+        ip[0] = '\0';
+        ret = exec_cmd("grep \"new_router\" /tmp/wlan0_dhcpcd_router | awk '{print $2}'| tail -1", ip, 32);
+        if (ret != 0)
+        {
+            ip[0] = '\0';
+            return 0;
+        }
+        else
+        {
+            p = strchr(ip, '\n');
+            if (p != NULL)
+            {
+                *p = '\0';
+            }
+        }
+    }
+    return 0;
+}
+
+int lynq_get_sta_connected_dns(lynq_wifi_index_e idx, char *dns)
+{
+    RLOGD("[wifi]--enter--lynq_get_sta_connected_dns");
+    return lynq_get_connect_ap_ip(idx,dns); //> not 100 % get dns info
+}
+
+int lynq_ap_connect_num(int sta_number)
+{
+    char lynq_limit_cmd[32]={0};
+    int ret;
+    if((sta_number < 1 ) && (sta_number > 15))
+    {
+        RLOGE("sta_number: not in range\n",sta_number);
+        return -1;
+    }
+    sprintf(lynq_limit_cmd,"wl maxassoc  %d", sta_number);
+    ret = system(lynq_limit_cmd);
+    if(ret != 0)
+    {
+        RLOGE("cmd of limit ap devices number error\n");
+    }
+    return 0;
+}
+
+int lynq_enable_acs(lynq_wifi_index_e idx,int acs_mode)
+{
+
+    char lynq_wifi_acs_cmd[128]={0};
+    char lynq_cmd_mode[128]={0};
+    char lynq_cmd_slect[128]={0};
+
+    if((acs_mode != 2) && (acs_mode != 5))
+    {
+        PRINT_AND_RETURN_VALUE("set acs_mode is error",-1);
+    }
+
+    if (lynq_check_network_number(idx, CTRL_AP, AP_NETWORK_0) != 0)
+    {
+        return -1;
+    }
+
+    CHECK_IDX(idx, CTRL_AP);
+
+    CHECK_WPA_CTRL(CTRL_AP);
+
+    sprintf(lynq_wifi_acs_cmd,"SET_NETWORK %d frequency %d", AP_NETWORK_0, acs_mode);
+    sprintf(lynq_cmd_mode, "SET_NETWORK %d mode 2", AP_NETWORK_0);
+    sprintf(lynq_cmd_slect, "SELECT_NETWORK %d", AP_NETWORK_0);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    DO_OK_FAIL_REQUEST(lynq_wifi_acs_cmd);
+    DO_OK_FAIL_REQUEST(lynq_cmd_mode);
+    DO_OK_FAIL_REQUEST(cmd_save_config);
+    DO_OK_FAIL_REQUEST(lynq_cmd_slect);
+
+    return 0;
+}
+//you.chen add for tv-box start
+static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len) {
+    FILE *fp;
+    //printf("to exec cmd:%s\n", str_cmd);
+    if((fp=popen(str_cmd,"r"))==NULL)
+    {
+        perror("popen error!");
+        return -1;
+    }
+    if((fread(str_cmd_ret,max_len,1,fp))<0)
+    {
+        perror("fread fail!");
+        fclose(fp);
+        return -1;
+    }
+    fclose(fp);
+    return 0;
+}
+
+static int get_netmask_length(const char* mask)
+{
+    int masklen=0, i=0;
+    int netmask=0;
+
+    if(mask == NULL)
+    {
+        return 0;
+    }
+
+    struct in_addr ip_addr;
+    if( inet_aton(mask, &ip_addr) )
+    {
+        netmask = ntohl(ip_addr.s_addr);
+    }else
+    {
+        netmask = 0;
+        return 0;
+    }
+
+    while(0 == (netmask & 0x01) && i<32)
+    {
+        i++;
+        netmask = netmask>>1;
+    }
+    masklen = 32-i;
+    return masklen;
+}
+
+static int get_tether_route_str(char *str_cmd_ret, size_t max_len) {
+    int mask_len;
+    char *p;
+    char tmp[64] = {0};
+    sprintf(tmp, "ifconfig %s | grep Mask", s_ap_iterface_name);
+    if (exec_cmd(tmp, str_cmd_ret, max_len) != 0)
+        return -1;
+    p = strstr(str_cmd_ret, "Mask:");
+    if (p == NULL)
+        return -1;
+    mask_len = get_netmask_length(p + 5);
+    if (mask_len == 0)
+        return -1;
+    p = strstr(str_cmd_ret, "inet addr:");
+    if (p == NULL)
+        return -1;
+    strcpy(tmp, p + 10);
+    p = strstr(tmp, " ");
+    if (p != NULL)
+        *p = '\0';
+    sprintf(str_cmd_ret, "%s/%d", tmp, mask_len);
+    return 0;
+}
+
+static void GBWWatchThreadProc() {
+    int i,n, nloop, nmax, ncheckcount, nidlecount;
+    unsigned long long lastAP1Bytes, lastAP2Bytes, currAP1Bytes, currAP2Bytes;
+    unsigned int lastAP1Drop,lastAP2Drop, currAP1Drop, currAP2Drop;
+    unsigned int setAP1Speed, setAP2Speed, lastAP1Speed, lastAP2Speed, currAP1Speed, currAP2Speed,currSetAP1Speed;
+    char *results[16] = {0};
+    char str_cmd[256] = {0};
+    char str_cmd_ret[128] = {0};
+    char dest_ip[32] = {0};
+    lastAP1Bytes = lastAP2Bytes = 0;
+    lastAP1Drop = lastAP2Drop = 0;
+    lastAP1Speed = lastAP2Speed = 0;
+    setAP1Speed = 50;
+    setAP2Speed = 80;
+    nloop = 0;
+    nmax = 6;
+    ncheckcount = nidlecount = 0;
+
+    if (inner_get_ap_interface_name() == NULL)
+    {
+        RLOGE("------gbw thread run\n");
+        return;
+    }
+
+    RLOGD("------gbw thread run\n");
+    sprintf(str_cmd, "ip neigh | grep %s | awk '{print $1}'", g_gbw_mac);
+    while (dest_ip[0] == '\0') {
+        sleep(1);
+        str_cmd_ret[0] = '\0';
+        exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret));
+        for(n = 0; n < (int)sizeof(str_cmd_ret) && str_cmd_ret[n] != '\0'; n++) {
+            if (str_cmd_ret[n] == '\n'){
+                str_cmd_ret[n] = '\0';
+                break;
+            }
+        }
+        if (str_cmd_ret[0] != '\0')
+        {
+            strcpy(dest_ip, str_cmd_ret);
+        }
+    }
+
+    system_call_v("tc qdisc del dev %s root > /dev/null 2>&1", s_ap_iterface_name);
+    system_call_v("tc qdisc add dev %s root handle 1: htb r2q 1", s_ap_iterface_name);
+    system_call_v("tc class add dev %s parent 1:  classid 1:1  htb rate 50Mbit ceil 70Mbit prio 2 quantum 3000", s_ap_iterface_name);
+    if (get_tether_route_str(str_cmd_ret, sizeof (str_cmd_ret)) != 0)
+    {
+        RLOGD("not get tether info\n");
+        return;
+    }
+    system_call_v("tc filter add dev %s parent 1: protocol ip prio 16 u32 match ip dst %s flowid 1:1", s_ap_iterface_name, str_cmd_ret);
+    system_call_v("tc class add dev %s parent 1:  classid 1:2  htb rate 80Mbit ceil 100Mbit prio 0 quantum 3000000", s_ap_iterface_name);
+    system_call_v("tc filter add dev %s parent 1: protocol ip prio 1 u32 match ip dst %s flowid 1:2", s_ap_iterface_name, dest_ip);
+
+    while (1) {
+        sleep(1);
+        memset(str_cmd, 0, sizeof(str_cmd));
+        memset(str_cmd_ret, 0, sizeof(str_cmd_ret));
+        sprintf(str_cmd, "tc -s class show dev %s classid 1:1 | grep Sent", s_ap_iterface_name);
+        if (0 != exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret)))
+            continue;
+        //printf("ap1 --- %s\n", str_cmd);
+        n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
+        if (n > 9) {
+            if (strcmp(results[1], "Sent") == 0) {
+                currAP1Bytes = atoll(results[2]);
+            }
+            if (strcmp(results[6], "(dropped") == 0) {
+                currAP1Drop = atoi(results[7]);
+            }
+        }
+
+        memset(str_cmd, 0, sizeof(str_cmd));
+        memset(str_cmd_ret, 0, sizeof(str_cmd_ret));
+        sprintf(str_cmd, "tc -s class show dev %s classid 1:2 | grep Sent", s_ap_iterface_name);
+        if (0 != exec_cmd(str_cmd, str_cmd_ret, sizeof (str_cmd_ret)))
+            continue;
+        //printf("ap2 --- %s\n", str_cmd);
+        n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
+        if (n > 9) {
+            if (strcmp(results[1], "Sent") == 0) {
+                currAP2Bytes = atoll(results[2]);
+            }
+            if (strcmp(results[6], "(dropped") == 0) {
+                currAP2Drop = atoi(results[7]);
+            }
+        }
+
+        //printf("ap1 %llu- %u, ap2 %llu-%u\n", currAP1Bytes, currAP1Drop, currAP2Bytes, currAP2Drop);
+        if (currAP1Bytes < lastAP1Bytes || currAP2Bytes < lastAP2Bytes) {
+            lastAP1Bytes = currAP1Bytes;
+            lastAP2Bytes = currAP2Bytes;
+            continue;
+        }
+
+        currAP1Speed = (currAP1Bytes - lastAP1Bytes) / 128 / 1024;
+        currAP2Speed = (currAP2Bytes - lastAP2Bytes) / 128 / 1024;
+        //printf("ap1 speed %d mb, ap2 speed %d mb\n", currAP1Speed, currAP2Speed);
+        lastAP1Speed = currAP1Speed;
+        lastAP2Speed = currAP2Speed;
+        lastAP1Bytes = currAP1Bytes;
+        lastAP2Bytes = currAP2Bytes;
+
+        currSetAP1Speed = setAP1Speed;
+        if ((currAP2Speed < 30 && currAP2Speed > 5) && currAP1Speed > 5) {
+            ncheckcount++;
+            if (ncheckcount > 3) {
+                ncheckcount = 0;
+                currSetAP1Speed = 5;
+            }
+        }
+        else {
+            ncheckcount = 0;
+            if (currAP1Speed < 5)
+                nidlecount++;
+            else
+                nidlecount = 0;
+
+        }
+
+        if (nidlecount > 60 ){
+            currSetAP1Speed = 50;
+        }
+
+        if (currSetAP1Speed != setAP1Speed) {
+            setAP1Speed = currSetAP1Speed;
+            system_call_v(str_cmd, "tc class replace dev %s parent 1:  classid 1:1  htb rate %dMbit ceil %dMbit prio 2 quantum 3000",
+                         s_ap_iterface_name, setAP1Speed, (int)(setAP1Speed*1.4));
+        }
+    }
+}
+
+int enableGBW(const char* mac) {
+    int i,len;
+    char get_ipaddr_cmd[128]={0};
+    ap_info_s *ap;
+    device_info_s * list;
+
+    if (mac == NULL || g_gbw_enabled == 1)
+        return -1;
+    len = strlen(mac);
+    g_gbw_mac = malloc(len + 1);
+    for(i=0;i<len;i++) {
+        if (mac[i] >= 'A' && mac[i] <= 'Z')
+        {
+            g_gbw_mac[i] = 'a' + (mac[i] - 'A');
+        }
+        else
+            g_gbw_mac[i] = mac[i];
+    }
+    g_gbw_mac[i] = '\0';
+    g_gbw_enabled = 1;
+
+    sprintf(get_ipaddr_cmd, "ip neigh | grep %s", g_gbw_mac);
+    if (system(get_ipaddr_cmd) == 0) {
+        //startGBW();
+        if ( 0 ==lynq_get_ap_device_list(1, &ap, &list,&len) ) {
+            for (i=0;i<len;i++) {
+                //printf("--mac:%s, name:%s\n",list[i].sta_mac, list[i].hostname);
+                if (strcmp(g_gbw_mac, list[i].sta_mac) == 0)
+                    startGBW();
+            }
+            free(ap);
+            free(list);
+        }
+    }
+    return 0;
+}
+
+int disableGBW() {
+    stopGBW();
+    free(g_gbw_mac);
+    g_gbw_mac = NULL;
+    g_gbw_enabled = 1;
+    return 0;
+}
+
+static int startGBW() {
+    if (g_gbw_watcher_pid != 0) {
+        stopGBW();
+    }
+    pthread_create(&g_gbw_watcher_pid,NULL,GBWWatchThreadProc,NULL);
+}
+
+static int stopGBW() {
+    void* retval;
+    char cmd[64] = {0};
+    pthread_cancel(g_gbw_watcher_pid);
+    pthread_join(g_gbw_watcher_pid, &retval);
+    g_gbw_watcher_pid = 0;
+    sprintf(cmd, "%s %d", get_interface_name_script, LYNQ_WIFI_INTERFACE_1);
+    if (s_ap_iterface_name[0] != '\0')
+    {
+        sprintf(cmd, "tc qdisc del dev %s root", s_ap_iterface_name);
+        system(cmd);
+    }
+}
+//you.chen add for tv-box end
