[Feature][T8TSK-202][wifi] wifi6.so add support for with/without connman

Change-Id: Ie737adb2d4a0ca567b149d36184d7b3786b60aaf
diff --git a/src/lynq/lib/liblynq-wifi6/include/libwifi6.h b/src/lynq/lib/liblynq-wifi6/include/libwifi6.h
index dc1751c..34a6ec8 100755
--- a/src/lynq/lib/liblynq-wifi6/include/libwifi6.h
+++ b/src/lynq/lib/liblynq-wifi6/include/libwifi6.h
@@ -49,6 +49,7 @@
 typedef enum {
     LYNQ_WIFI_STATUS_DISCONNECT = 0,
     LYNQ_WIFI_STATUS_CONNECT,
+    LYNQ_WIFI_SERVICE_ABNORMAL,
 }lynq_wifi_ap_status_s;
 
 typedef struct ap_info
@@ -153,6 +154,7 @@
 
 //sta start connect to dest_ap
 int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw);
+int lynq_wifi_sta_connect_timeout(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw, int timeout);
 //disconnect 
 int lynq_wifi_sta_disconnect(lynq_wifi_index_e idx,char *ssid);
 
@@ -186,6 +188,9 @@
     LYNQ_WIFI_STA_STATUS_DISCONNECT = 0,
     LYNQ_WIFI_STA_STATUS_CONNECT,
     LYNQ_WIFI_STA_STATUS_SCAN_RESULT,    //finish sta scan 
+    LYNQ_WIFI_STA_STATUS_CONNECT_FAIL,
+    LYNQ_WIFI_STA_SERVICE_ABNORMAL,
+    LYNQ_WIFI_STATUS_EGNORE,
 }lynq_wifi_sta_status_s;
 typedef enum
 {
diff --git a/src/lynq/lib/liblynq-wifi6/libwifi6.c b/src/lynq/lib/liblynq-wifi6/libwifi6.c
index 39314d2..b9658b9 100755
--- a/src/lynq/lib/liblynq-wifi6/libwifi6.c
+++ b/src/lynq/lib/liblynq-wifi6/libwifi6.c
@@ -22,6 +22,8 @@
 #include <netdb.h>
 #include <ifaddrs.h>
 #include "log/log.h"
+#include <sys/time.h>
+#include <asm/errno.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -38,6 +40,7 @@
 #define CTRL_STA 0
 #define CTRL_AP 1
 #define AP_NETWORK_0 0
+#define STA_MAX_SAVED_AP_NUM 50
 
 pthread_t g_ap_watcher_pid = 0;
 volatile int g_ap_watcher_stop_flag = 0;
@@ -62,13 +65,30 @@
 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_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;
 };
 
+
 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;
 
 static struct local_wpa_ctrl * g_lynq_wpa_ctrl[2] = {0};
 
@@ -86,6 +106,117 @@
     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;
+static 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 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))
@@ -98,6 +229,10 @@
     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;
 }
 
@@ -178,69 +313,157 @@
     }while (0)
 
 
-static int exec_cmd(const char *str_cmd, char * str_cmd_ret, size_t max_len);
+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;
 
     struct wpa_ctrl *lynq_wpa_ctrl = NULL;
     g_ap_watcher_stop_flag = 0;
 
     while (g_ap_watcher_stop_flag == 0)
     {
-        if (lynq_wpa_ctrl == NULL)
-	{
-            lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[CTRL_AP]); //@todo temp change
-            if (lynq_wpa_ctrl == NULL)
-	    {
-                usleep(100*1000);
-                continue;
+        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();
             }
 
-            wpa_ctrl_attach(lynq_wpa_ctrl);
-            g_ap_watcher_started_flag = 1;
-        }
-
-        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl))
-	{
-            usleep(100*1000);
             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
+            //you.chen change for tv-box start
             if (strstr(msg_notify, "AP-STA-DISCONNECTED") != NULL)
-	    {
-                if (g_ap_callback_func != NULL)
-                    g_ap_callback_func(g_ap_callback_priv, LYNQ_WIFI_STATUS_DISCONNECT);
+            {
+                inner_notify_ap_msg(LYNQ_WIFI_STATUS_DISCONNECT);
                 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)
-	    {
-                if (g_ap_callback_func != NULL)
-                    g_ap_callback_func(g_ap_callback_priv, LYNQ_WIFI_STATUS_CONNECT);
+            {
+                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();
                     }
                 }
             }
-//you.chen add for tv-box end
+            //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)
@@ -250,6 +473,47 @@
     }
 }
 
+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;
+    }
+
+    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;
+            pthread_cond_signal(&s_global_check_cond);
+        }
+    }
+    else if (state == LYNQ_WIFI_STA_STATUS_CONNECT)
+    {
+        s_sta_status = INNER_STA_STATUS_CONNECTED;
+        pthread_cond_signal(&s_global_check_cond);
+    }
+    pthread_mutex_unlock(&s_global_check_mutex);
+}
+
 void get_state_error(const char* modify, lynq_wifi_sta_status_s* state, error_number_s* error)
 {
     char *pReason;
@@ -360,42 +624,44 @@
         return;
     }
 
+    RLOGD("EVENT : %s\n", modify);
     *error = LYNQ_UNSPECIFIED_REASON;
-    *state = LYNQ_WIFI_STA_STATUS_DISCONNECT;
+    *state = LYNQ_WIFI_STATUS_EGNORE;
     RLOGD("LAST : STA state:%d,error:%d\n",*state,*error);
     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 STAWatcherThreadProc() {
     size_t len = MAX_RET;
     char msg_notify[MAX_RET];
     error_number_s error;
-    lynq_wifi_sta_status_s state;
+    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 (lynq_wpa_ctrl == NULL)
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_STA, &idle_count, &g_sta_watcher_started_flag) != 1)
         {
-            lynq_wpa_ctrl = wpa_ctrl_open(CTRL_PATH[CTRL_STA]);
-            if (lynq_wpa_ctrl == NULL)
-            {
-                usleep(100*1000);
-                continue;
-            }
-
-            wpa_ctrl_attach(lynq_wpa_ctrl);
-            g_sta_watcher_started_flag = 1;
-        }
-
-        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl))
-        {
-            usleep(100*1000);
             continue;
         }
+
         memset(msg_notify, 0, MAX_RET);
         len = MAX_RET;
         if (!wpa_ctrl_recv(lynq_wpa_ctrl, msg_notify, &len))
@@ -412,8 +678,25 @@
                 continue;
             }
             get_state_error(msg_notify,&state,&error);
-            g_sta_callback_func(g_sta_callback_priv, state, error);
+            notify_connect_status(state, error);
 
+            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 (lynq_wpa_ctrl != NULL)
@@ -423,6 +706,127 @@
     }
 }
 
+// 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;
@@ -435,15 +839,7 @@
         goto out_enable;
     }
 
-    const char * cmd_check_service =
-            "state=`systemctl is-active wg870_drv_insmod.service`\n"
-            "[ \"\"$state == \"active\" ] && exit 0\n"
-            "[ \"\"$state == \"inactive\" ] && systemctl start wg870_drv_insmod.service\n";
-//    if (g_lynq_wpa_ctrl[0] != NULL && g_lynq_wpa_ctrl[1] != NULL) {
-//        return 0;
-//    }
-
-    ret = system(cmd_check_service);
+    ret = system(start_wg870_service_script);
     if (ret != 0)
     {
         //printf("service state %d\n", ret);
@@ -452,80 +848,16 @@
         goto out_enable;
     }
 
-    RLOGD("check service state is OK");
-    for (i=0; i<10; i++)
+    if (g_global_watcher_pid == 0 ) // this thread will not exit when lynq_wifi_disable called,to avoid dead lock,take care
     {
-        if (system("connmanctl technologies | grep -q \"/net/connman/technology/wifi\"") == 0) {
-            break;
-        }
-        usleep(300*1000);
-    }
-
-    if (i >= 10)
-    {
-	RLOGE("[wifi error] check connman technologies no wifi");
-        ret = -1;
-        goto out_enable;
-    }
-
-    //@todo delete add temp check for socket avilable start (20220606)
-    for (i=0; i<60; i++)
-    {
-        if (system("netstat -an | grep -q DGRAM") == 0) {
-            break;
-        }
-        sleep(1);
-    }
-
-    if (i >= 60)
-    {
-        ret  = -1;
-        goto out_enable;
-    }
-    //@todo delete add temp check for socket avilable end (20220606)
-
-    if (0 != system("ifconfig | grep -q ap0"))
-    {
-        system("connmanctl enable wifi");
-        usleep(300*1000);
-        system("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect");
-        system("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0");
-        usleep(300*1000);
-        system("connmanctl tether wifi on lynq 1qaz@WSX#$%^");
-        usleep(300*1000);
-        system("wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 disconnect");
-    }
-    if (g_ap_watcher_pid == 0 )
-    {
-        ret=pthread_create(&g_ap_watcher_pid,NULL,APWatcherThreadProc,NULL);
+        ret=pthread_create(&g_global_watcher_pid,NULL,GlobalWatcherThreadProc,NULL);
         if(ret<0)
-	{
-            RLOGE("[wifi error]creat APWatcherThreadProc fail");
+        {
+            RLOGE("[wifi error]creat GlobalWatcherThreadProc fail");
             ret = -1;
             goto out_enable;
         }
     }
-    
-    RLOGD("creat APWatcherTheradProc susccs");
-    if (g_sta_watcher_pid == 0 ) {
-        ret=pthread_create(&g_sta_watcher_pid,NULL,STAWatcherThreadProc,NULL);
-        if(ret<0)
-	{
-            RLOGE("[wifi error]creat STAWatcherThreadProc fail");
-            ret = -1;
-            goto out_enable;
-        }
-    }
-
-    RLOGD("creat STAWatcherTheradProc susccs");
-    for (i=0; i<10; i++)
-    {
-        usleep(300*1000);
-        if (g_ap_watcher_started_flag == 1 && g_sta_watcher_started_flag == 1)
-	{
-            break;
-        }
-    }
 
     g_lynq_wpa_ctrl[0] = malloc(sizeof (struct local_wpa_ctrl));
     g_lynq_wpa_ctrl[1] = malloc(sizeof (struct local_wpa_ctrl));
@@ -726,6 +1058,8 @@
         *str = '\0';
     }
 
+    results[ret] = NULL;
+
     return ret;
 }
 
@@ -751,6 +1085,9 @@
 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)
     {
@@ -769,6 +1106,19 @@
 
     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;
@@ -972,6 +1322,7 @@
     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;
@@ -1002,24 +1353,24 @@
     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;
@@ -1027,24 +1378,24 @@
             }
             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;
@@ -1052,17 +1403,21 @@
 
         } //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");
@@ -1575,6 +1930,49 @@
     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(500*1000);
+    if (0 == inner_get_status_info(idx, &curr_state))
+    {
+        if (strcmp(status, STATE_COMPLETED) == 0)
+        {
+            return 0;
+        }
+        else if (retry_count == 4) //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)
 {
@@ -1586,11 +1984,11 @@
 
     CHECK_WPA_CTRL(CTRL_AP);
 
-//    system("connmanctl enable wifi");
-//    system("connmanctl tether wifi on cy-test 12345678");
-//    system("ifconfig wlan0 down");
-//    system("ifconfig wlan0 up");
-//    system("ifconfig wlan0 up");
+    if (inner_get_ap_interface_name() == NULL)
+    {
+        RLOGE("lynq_wifi_ap_start get ap name fail");
+        return -1;
+    }
 
     //DO_OK_FAIL_REQUEST(lynq_remove_all_cmd);
     //DO_OK_FAIL_REQUEST(lynq_reconfig_cmd);
@@ -1598,6 +1996,20 @@
     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();
+
     return 0;
 }
 
@@ -1619,7 +2031,14 @@
     DO_OK_FAIL_REQUEST(LYNQ_WIFI_CMD);
 
 //    system("connmanctl tether wifi off");
-	
+
+    ret = system_call_v("%s %s", start_stop_ap_script, "stop");
+    if (ret != 0)
+    {
+        RLOGE("lynq_wifi_ap_start excute script fail");
+        return -1;
+    }
+
     return 0;
 }
 
@@ -1834,24 +2253,33 @@
     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");
+        RLOGE("check ieee80211w error\n");
         return -1;
     }
     if ( strncmp(lynq_auth_str,"1",1) == 0 )
     {
 
-       *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
-       return 0;
+        *auth = LYNQ_WIFI_AUTH_WPA2_WPA3_PSK;
+        return 0;
     }else if( strncmp(lynq_auth_str,"2",1) == 0 )
     {
 
@@ -1859,6 +2287,7 @@
         return 0;
     }else
     {
+        RLOGE("check ieee80211w error, not 1 or 2\n");
         *auth = -1;
         return -1;
     }
@@ -1917,10 +2346,11 @@
     char *split_lines[128] = {0};
     char *buff, *p, *ssid, *ssid_end_flag;
     char tmp_ssid[128]={0};
-	RLOGD("enter lynq_sta_ssid_password_get");
+    RLOGD("enter lynq_sta_ssid_password_get");
 
     network_len = 0;
     p = NULL;
+    buff = NULL;
 
     CHECK_IDX(idx, CTRL_STA);
 
@@ -1937,46 +2367,62 @@
         return  -1;
     }
 
-    buff = alloca(MAX_RET);
+    fseek(fp, 0, SEEK_END);
+    len = ftell(fp);
+    buff = malloc(len + 1);
+
+    if (buff == NULL)
+    {
+        RLOGE("[lynq_sta_ssid_password_get] malloc memory [%d] fail\n", len);
+        return  -1;
+    }
+
     fseek(fp, 0, SEEK_SET);
-    len = fread(buff, 1, MAX_RET, fp);
+    len = fread(buff, 1, len, fp);
     fclose(fp);
 
     for(index=0; index < len; index ++)
     {
         for(; 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;
-             }
-             network_len = buff + index - p;
-             break;
+            p = buff + index + 9;
+            for (; index < len; index ++ )
+            {
+                if (buff[index] != '}')
+                {
+                    continue;
+                }
+                buff[index] = '\0';
+                break;
+            }
+            network_len = buff + index - p;
+            break;
         }
 
         if (p == NULL)
+        {
+            if (buff != NULL)
+            {
+                free(buff);
+            }
+
             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)
                 {
@@ -1995,6 +2441,10 @@
 
     if (index >= len || NULL == p || network_len <= 0)
     {
+        if (buff != NULL)
+        {
+            free(buff);
+        }
         return -1;
     }
 
@@ -2005,23 +2455,23 @@
     {
         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;
         }
 
@@ -2031,9 +2481,9 @@
 
         p = password;
         while(password - p < 64 && *password != '\0')
-	{
+        {
             if (*password == '\"')
-	    {
+            {
                 *password = '\0';
                 break;
             }
@@ -2043,6 +2493,11 @@
         break;
     } //end for(index=0; index < count; index++)
 
+    if (buff != NULL)
+    {
+        free(buff);
+    }
+
     return ret;
 }
 
@@ -2162,6 +2617,7 @@
         {
             info->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);
         return 0;
@@ -2300,14 +2756,12 @@
 	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_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);
-	    RLOGD("inner_set_sta_auth_psw before set SAE CMD");
             DO_OK_FAIL_REQUEST(lynq_ket_mgmt_cmd);
-	    RLOGD("inner_set_sta_auth_psw after set SAE CMD");
             DO_OK_FAIL_REQUEST(lynq_pairwise_cmd);
             DO_OK_FAIL_REQUEST(lynq_psk_cmd);
 
@@ -2348,11 +2802,15 @@
     return inner_get_network_auth(CTRL_STA, net_no, auth);
 }
 
-int lynq_wifi_sta_connect(lynq_wifi_index_e idx, char *ssid, lynq_wifi_auth_s auth, char *psw)
+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')
     {
@@ -2363,39 +2821,84 @@
     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;
-    count = lynq_get_network_number_list(idx, CTRL_STA, net_no_list, ssid);
+    memset(&ap_info, 0, sizeof (ap_info));
+    memset(status, 0, sizeof (status));
 
-    for (index=0; index < count; index++)
+    curr_state.ap = &ap_info;
+    curr_state.state = status;
+
+    if (0 == inner_get_status_info(CTRL_STA, &curr_state) && curr_state.net_no >= 0)
     {
-        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 (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;
+                pthread_cond_signal(&s_global_check_cond);
+                pthread_mutex_unlock(&s_global_check_mutex);
+                return 0;
+            }
         }
     }
 
-    if (net_no < 0)
+    if (net_no == -1)
     {
-        net_no = lynq_add_network(CTRL_STA);
-        if (net_no == -1)
-	{
-            return -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;
+            }
         }
 
-        RLOGD("net no is %d\n", net_no);
-        if (0 != inner_set_sta_ssid(net_no, ssid))
-	{
-            return -1;
+        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;
+            }
         }
     }
 
@@ -2404,7 +2907,28 @@
         return -1;
     }
 
-    return inner_sta_start_stop(net_no, 1, 1);
+
+    DO_OK_FAIL_REQUEST(cmd_disconnect);
+    system("echo \"\" > /tmp/wlan0_dhcpcd_router");
+    usleep(200*1000);
+
+    ret = inner_sta_start_stop(net_no, 1, 1);
+
+    pthread_mutex_lock(&s_global_check_mutex);
+    s_sta_status = INNER_STA_STATUS_CONNECTING;
+    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)
@@ -2434,6 +2958,9 @@
         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);
 }
 
@@ -2448,45 +2975,64 @@
     CHECK_IDX(idx, CTRL_STA);
     CHECK_WPA_CTRL(CTRL_STA);
 
-    system("connmanctl enable wifi");
-
-    if (system("ifconfig | grep -q wlan0") != 0)
+    ret = system_call_v("%s %s", start_stop_sta_script, "start");
+    if (ret != 0)
     {
+        RLOGE("lynq_wifi_ap_start excute script fail");
         return -1;
     }
 
-//    DO_OK_FAIL_REQUEST(cmd_remove_all);
-//    system(lynq_first_sta_cmd);
-//    system(lynq_reconfigure_cmd);
-//    DO_OK_FAIL_REQUEST(lynq_reconnect_cmd);
     system(lynq_enable_sta_cmd);
     system(lynq_reconnect_cmd);
 //    DO_OK_FAIL_REQUEST(lynq_reconnect_cmd);
     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_stop(lynq_wifi_index_e idx)
 {
 //    char lynq_disable_network_cmd[MAX_CMD];
 //    curr_status_info curr_state;
 //    ap_info_s ap_info;
+    int i=0;
+    char state[MAX_CMD];
 
-    const char * lynq_disable_sta_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disable_net all";
+//    const char * lynq_disable_sta_cmd = "wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disable_net all";
     CHECK_IDX(idx, CTRL_STA);
     CHECK_WPA_CTRL(CTRL_STA);
 
-//    curr_state.ap = &ap_info;
-//    curr_state.state = NULL;
-
-//    if (0 != inner_get_status_info(CTRL_STA, &curr_state) || curr_state.net_no < 0) {
-//        return 0;
-//    }
-
-//    sprintf(lynq_disable_network_cmd, "DISABLE_NETWORK %d", curr_state.net_no);
-//    DO_OK_FAIL_REQUEST(lynq_disable_network_cmd);
-    system(lynq_disable_sta_cmd);
+//    system(lynq_disable_sta_cmd);
+    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_ap_start excute script fail");
+        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_ap_start curr state %s", state);
+        usleep(SLEEP_TIME_ON_IDLE);
+    }
+
     return 0;
 //    return system("connmanctl disable wifi");
 }
@@ -2543,21 +3089,22 @@
 
     CHECK_WPA_CTRL(CTRL_AP);
 
-//    ap_info_s * tmp_ap;
-//    device_info_s * tmp_list;
+    //    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 = &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)
+    if (inner_get_status_info_ap (CTRL_AP, *ap) != 0 || (*ap)->ap_ssid[0] == '\0')
     {
-	RLOGE("inner_get_status_info_ap !=0\n");
+        RLOGE("inner_get_status_info_ap !=0 or ap_ssid is empty\n");
         return -1;
     }
 
@@ -2570,7 +3117,7 @@
     while (reply_len > 0)
     {
         if (memcmp(cmd_reply, "FAIL", 4) == 0)
-	{
+        {
             break;
         }
         line_count = lynq_split(cmd_reply, reply_len, '\n', split_lines);
@@ -2582,7 +3129,7 @@
         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;
         }
@@ -2642,6 +3189,7 @@
     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;
@@ -2652,7 +3200,14 @@
         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]);
-        inner_copy_ssid(p->ssid, split_words[4], sizeof (p->ssid));
+        if (count_words == 4) // ssid hided
+        {
+            p->ssid[0] = '\0';
+        }
+        else
+        {
+            inner_copy_ssid(p->ssid, split_words[4], sizeof (p->ssid));
+        }
     }
 
     return 0;
@@ -2720,29 +3275,36 @@
     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++)
     {
-	RLOGD("[lynq_get_sta_saved_ap]to get ssid %d", index);
-	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get ssid");
         inner_get_param(CTRL_STA, net_no_list[index], "ssid", (*list)[index].base_info.ap_ssid);
-	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get mac");
         inner_get_param(CTRL_STA, net_no_list[index], "bssid", (*list)[index].base_info.ap_mac);
-	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get auth");
         inner_get_network_auth(CTRL_STA, net_no_list[index], &(*list)[index].base_info.auth);
-	RLOGD("[lynq_get_sta_saved_ap][inner_get_param]to get band");
         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");
+        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");
@@ -2758,7 +3320,11 @@
 
     CHECK_WPA_CTRL(CTRL_STA);
 
-    system(clean_last_re);
+    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 )
@@ -2780,19 +3346,39 @@
         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 susccs");
 
     return 0;
 }
 
 int lynq_unreg_ap_event_callback(void * priv) {
+    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);
         return 0;
     }
+    pthread_mutex_unlock(&s_ap_callback_mutex);
     return -1;
 }
 
@@ -2803,30 +3389,40 @@
         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 susccs");
     return 0;
 }
 
 int lynq_unreg_sta_event_callback(void * priv) {
+    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);
         return 0;
     }
+    pthread_mutex_unlock(&s_sta_callback_mutex);
     return -1;
 }
 
-
-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_get_ap_status(lynq_wifi_index_e idx, lynq_wifi_ap_run_status_s * ap_status)
 {
     char state[MAX_CMD];
@@ -2942,28 +3538,111 @@
     return 0;
 }
 
-int lynq_set_country_code(lynq_wifi_index_e idx, char * country_code) {
-//    const char * cmd_str = "GET country";
-//    CHECK_IDX(idx, CTRL_AP);
-//    CHECK_WPA_CTRL(CTRL_STA);
+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};
 
-//    DO_REQUEST(cmd_str);
-//    printf("result %s\n", cmd_reply);
+    sprintf(set_country_cmd, "uci set lynq_uci.lynq_wifi_country_code.code='%s'",country_code);
 
-    if (country_code == NULL || *country_code == '\0')
+    if (0 != system(check_uci_cmd))
     {
-        RLOGD("bad country code\n");
+        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;
     }
 
-    char lynq_country_cmd[MAX_CMD];
-    sprintf(lynq_country_cmd, "wl country %s", country_code);
-    if (system(lynq_country_cmd) == 0)
+    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0 )
     {
-        return 0;
+        RLOGE("fread fail!");
+        fclose(fp);
+        return -1;
     }
 
-    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)
@@ -3002,7 +3681,12 @@
 
     if (idx == 1)
     {
-       ifaName = "tether";
+       ifaName = inner_get_ap_interface_name();
+       if (ifaName == NULL)
+       {
+           RLOGE("[lynq_get_interface_ip] ap name get fail");
+           return -1;
+       }
     }
     else if (idx != 0)
     {
@@ -3106,24 +3790,16 @@
 
 //    *rssi = atoi(split_words[1]) * -1;
 
-    FILE *fp;
-    size_t i = 0;
     char lynq_cmd_ret[MAX_RET]={0};
 
-//    CHECK_IDX(idx, CTRL_AP);
 /*******change other cmd to get rssi*******
  *
  *wl rssi ---> wl -i wlan0 rssi
  *
  ***** change by qs.xiong 20221011*******/
-    if((fp=popen("wl -i wlan0 rssi","r"))==NULL)
+    if (0 !=  exec_cmd("wl -i wlan0 rssi", lynq_cmd_ret, MAX_RET))
     {
-        perror("popen error!");
-        return -1;
-    }
-    if((fread(lynq_cmd_ret,sizeof(lynq_cmd_ret),1,fp))<0)
-    {
-        perror("fread fail!");
+        RLOGE("[lynq_get_connect_ap_rssi] exec cmd [ wl -i wlan0 rssi ] fail");
         return -1;
     }
     *rssi = atoi(lynq_cmd_ret) * -1;
@@ -3131,7 +3807,7 @@
     if(*rssi == 0)
     {
         RLOGE("[lynq_get_connect_ap_rssi]sta didn't connected any ap device,please check connection\n");
-	return -1;
+        return -1;
     }
 
     return 0;
@@ -3160,6 +3836,8 @@
 
 int lynq_get_connect_ap_ip(lynq_wifi_index_e idx, char *ip)
 {
+    int ret;
+    char *p;
     char bssid[1024] = {0};
 
     if (ip == NULL)
@@ -3175,7 +3853,33 @@
         return -1;
     }
 
-    return inner_get_ip_by_mac(bssid, ip, 32); //better input by user
+    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");
+        return -1;
+    }
+
+    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_ap_connect_num(int sta_number)
@@ -3281,7 +3985,8 @@
     int mask_len;
     char *p;
     char tmp[64] = {0};
-    if (exec_cmd("ifconfig tether | grep Mask", str_cmd_ret, max_len) != 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)
@@ -3318,6 +4023,12 @@
     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') {
@@ -3336,28 +4047,27 @@
         }
     }
 
-    system("tc qdisc del dev tether root > /dev/null 2>&1");
-    system("tc qdisc add dev tether root handle 1: htb r2q 1");
-    system("tc class add dev tether parent 1:  classid 1:1  htb rate 50Mbit ceil 70Mbit prio 2 quantum 3000");
+    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;
     }
-    sprintf(str_cmd, "tc filter add dev tether parent 1: protocol ip prio 16 u32 match ip dst %s flowid 1:1", str_cmd_ret);
-    system(str_cmd);
-    system("tc class add dev tether parent 1:  classid 1:2  htb rate 80Mbit ceil 100Mbit prio 0 quantum 3000000");
-    sprintf(str_cmd, "tc filter add dev tether parent 1: protocol ip prio 1 u32 match ip dst %s flowid 1:2", dest_ip);
-    //printf("----cmd:%s\n", str_cmd);
-    system(str_cmd);
+    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));
-        if (0 != exec_cmd("tc -s class show dev tether classid 1:1 | grep Sent", str_cmd, 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, strlen(str_cmd), ' ', results);
+        n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
         if (n > 9) {
             if (strcmp(results[1], "Sent") == 0) {
                 currAP1Bytes = atoll(results[2]);
@@ -3368,10 +4078,12 @@
         }
 
         memset(str_cmd, 0, sizeof(str_cmd));
-        if (0 != exec_cmd("tc -s class show dev tether classid 1:2 | grep Sent", str_cmd, 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, strlen(str_cmd), ' ', results);
+        n = lynq_split(str_cmd_ret, strlen(str_cmd_ret), ' ', results);
         if (n > 9) {
             if (strcmp(results[1], "Sent") == 0) {
                 currAP2Bytes = atoll(results[2]);
@@ -3419,9 +4131,8 @@
 
         if (currSetAP1Speed != setAP1Speed) {
             setAP1Speed = currSetAP1Speed;
-            sprintf(str_cmd, "tc class replace dev tether parent 1:  classid 1:1  htb rate %dMbit ceil %dMbit prio 2 quantum 3000", setAP1Speed, (int)(setAP1Speed*1.4));
-            //printf("------***change speed: %s\n", str_cmd);
-            system(str_cmd);
+            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));
         }
     }
 }
@@ -3480,9 +4191,15 @@
 
 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;
-    system("tc qdisc del dev tether root");
+    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
diff --git a/src/lynq/lib/liblynq-wifi6/scripts/get_interface_name.sh b/src/lynq/lib/liblynq-wifi6/scripts/get_interface_name.sh
new file mode 100755
index 0000000..4dc8717
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts/get_interface_name.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "$1" == "0" ]; then
+	echo "wlan0"
+elif [ "$1" == "1" ]; then
+	echo "ap0"
+else
+	exit 1
+fi
+
diff --git a/src/lynq/lib/liblynq-wifi6/scripts/sta_status_change.sh b/src/lynq/lib/liblynq-wifi6/scripts/sta_status_change.sh
new file mode 100755
index 0000000..829303e
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts/sta_status_change.sh
@@ -0,0 +1,3 @@
+#!/bin/sh
+
+
diff --git a/src/lynq/lib/liblynq-wifi6/scripts/start_stop_ap.sh b/src/lynq/lib/liblynq-wifi6/scripts/start_stop_ap.sh
new file mode 100755
index 0000000..25dd644
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts/start_stop_ap.sh
@@ -0,0 +1,36 @@
+#!/bin/sh
+
+if [ "$1" == "start" ]; then
+	ifconfig ap0 192.168.15.1 netmask 255.255.255.240
+
+	if [ $? != 0 ]; then
+		exit 1
+	fi
+	mkdir -p /run/wg870/dnsmasq.d
+	conf_file="/run/wg870/dnsmasq.conf"
+	echo "port=0" > $conf_file
+	echo "interface=ap0" >> $conf_file
+	echo "listen-address=192.168.15.1" >> $conf_file
+	echo "bind-interfaces"  >> $conf_file
+	echo "localise-queries" >> $conf_file
+	echo "dhcp-range=192.168.15.2,192.168.15.14,255.255.255.240,1h"  >> $conf_file
+	echo "dhcp-option=3,192.168.15.1"  >> $conf_file
+	echo "dhcp-option=6,192.168.15.1"  >> $conf_file
+	echo "dhcp-range=192.168.15.2,192.168.15.14,255.255.255.240,1h"  >> $conf_file
+	echo "dhcp-leasefile=/run/wg870/ap0.lease" >> $conf_file
+	ps -eo "%p %a" | grep "/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid" | grep -v grep 
+	if [ $? != 0 ]; then
+		/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid -7 /run/wg870/dnsmasq.d --local-service -C $conf_file -r /run/wg870
+	fi
+
+elif [ "$1" == "stop" ]; then
+	ps -eo "%p %a" | grep "/usr/bin/dnsmasq -x /run/wg870/dnsmasq.pid" | grep -v grep | awk '{print "kill "$1}' | sh
+	ifconfig ap0 down
+	if [ $? != 0 ]; then
+		exit 1
+	fi
+else
+	exit 2
+fi
+
+exit 0
diff --git a/src/lynq/lib/liblynq-wifi6/scripts/start_stop_sta.sh b/src/lynq/lib/liblynq-wifi6/scripts/start_stop_sta.sh
new file mode 100755
index 0000000..25ab126
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts/start_stop_sta.sh
@@ -0,0 +1,35 @@
+#!/bin/sh
+
+if [ "$1" == "start" ]; then
+        ifconfig wlan0 up
+        if [ $? != 0 ]; then
+                exit 1
+        fi
+		ps -eo "%p %a" | grep "dhcpcd wlan0" | grep -v grep
+		if [ $? != 0 ];	then
+			echo "" > /tmp/wlan0_dhcpcd_router
+			mkdir -p /run/wg870/
+			hook_script="/run/wg870/wlan0_dhcpcd_run_hooks.sh"
+			echo "#!/bin/sh" > $hook_script
+			echo "if [ \"\$reason\" == \"BOUND\" -o \"\$reason\" == \"RENEW\" -o \"\$reason\" == \"REBIND\" ]; then" >> $hook_script
+			echo "    if [ \"\$new_routers\" != \"\" ]; then" >> $hook_script
+			echo "        for x in \$new_routers; do" >> $hook_script
+			echo "            echo \"new_router \$x\" > /tmp/wlan0_dhcpcd_router" >> $hook_script
+			echo "            ping -c2 \$x &" >> $hook_script
+			echo "        done" >> $hook_script
+			echo "    fi" >> $hook_script
+			echo "fi" >> $hook_script
+			chmod +x $hook_script
+			dhcpcd wlan0 -t 0 -o domain_name_servers --noipv4ll -4 -B -G -c $hook_script &
+		fi
+elif [ "$1" == "stop" ]; then
+        ps -eo "%p %a" | grep "dhcpcd wlan0" | grep -v grep | awk '{print "kill "$1}' | sh
+        ifconfig wlan0 0.0.0.0
+        if [ $? != 0 ]; then
+                exit 1
+        fi
+else
+        exit 2
+fi
+
+exit 0
diff --git a/src/lynq/lib/liblynq-wifi6/scripts/start_wg870_service.sh b/src/lynq/lib/liblynq-wifi6/scripts/start_wg870_service.sh
new file mode 100755
index 0000000..fae9b34
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts/start_wg870_service.sh
@@ -0,0 +1,58 @@
+#!/bin/sh
+for ((i=0; i < 10; i++)); do
+        state=`systemctl is-active wg870_drv_insmod.service`
+        if [ "$state" == "active" ]; then
+                break
+        elif [ "$state" != "activating" ]; then
+                echo "to start now"
+                systemctl start wg870_drv_insmod.service
+        fi
+        usleep 100000
+done
+
+if [ "$state" != "active" ]; then
+        exit 1
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ ping`
+if  [ "$state" != "PONG" ]; then
+    for ((i=0; i < 50; i++)); do
+        usleep 100000
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ ping`
+        echo "$state"
+        if [ "$state" == "PONG" ]; then
+            service_started=1
+            break
+        fi
+    done
+else
+        service_started=1
+fi
+
+if [ "$service_started" != "1" ];then
+        exit 1
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface | grep -vE "Available|p2p-dev" | grep wlan0`
+if [ $? != 0 ]; then
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface_add wlan0 /data/wifi/wg870/wpa_supplicant.conf nl80211`
+        if [ "$state" != "OK" ]; then
+                exit 2
+        fi
+		wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect
+fi
+
+state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface | grep -vE "Available|p2p-dev" | grep ap0`
+if [ $? != 0 ]; then
+		wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0
+        state=`wpa_cli -iwpa_wlan0_cmd -p/var/run/ interface_add ap0 /data/wifi/wg870/wpa_supplicant_ap.conf nl80211`
+
+        if [ "$state" != "OK" ]; then
+                exit 3
+        fi
+        ifconfig ap0 down
+fi
+
+
+exit 0
+
diff --git a/src/lynq/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh b/src/lynq/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh
new file mode 100755
index 0000000..61b44d9
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts_connman/get_interface_name.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+
+if [ "$1" == "0" ]; then
+	echo "wlan0"
+elif [ "$1" == "1" ]; then
+	echo "tether"
+else
+	exit 1
+fi
+
diff --git a/src/lynq/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh b/src/lynq/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts_connman/sta_status_change.sh
diff --git a/src/lynq/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh b/src/lynq/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts_connman/start_stop_ap.sh
diff --git a/src/lynq/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh b/src/lynq/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh
new file mode 100755
index 0000000..e69de29
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts_connman/start_stop_sta.sh
diff --git a/src/lynq/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh b/src/lynq/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh
new file mode 100755
index 0000000..303a075
--- /dev/null
+++ b/src/lynq/lib/liblynq-wifi6/scripts_connman/start_wg870_service.sh
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+for ((i=0; i < 10; i++)); do
+	state=`systemctl is-active wg870_drv_insmod.service`
+	if [ "$state" == "active" ]; then
+		break	
+	elif [ "$state" != "activating" ]; then
+
+		systemctl start wg870_drv_insmod.service
+	fi
+	usleep 100000 
+done
+
+if [ "$state" != "active" ]; then
+	exit 1
+fi
+
+for ((i=0; i < 10; i++)); do
+	connmanctl technologies | grep -q "/net/connman/technology/wifi"
+	if [ $? == 0 ]; then
+		connman_started=1
+		break
+	fi
+done
+
+if [ "$connman_started" == ""]; then
+	exit 2
+fi
+
+ifconfig | grep -q wlan0
+
+if [ $? != 0 ]; then
+	connmanctl enable wifi
+
+	for ((i=0; i < 5; i++)); do
+		usleep 100000 
+		ifconfig | grep -q wlan0
+		if [ $? == 0 ]; then
+			wlan0_started=1
+			wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 disconnect
+			break
+		fi
+	done
+else
+	wlan0_started=1
+fi
+
+
+if [ "$wlan0_started" == ""]; then
+    exit 3
+fi
+
+ifconfig | grep -q ap0
+
+if [ $? != 0 ]; then
+	wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=wlan0 DRIVER interface_create ap0
+	connmanctl tether wifi on lynq 1qaz@WSX#$%^
+
+	for ((i=0; i < 5; i++)); do
+		usleep 100000 
+		ifconfig | grep -q ap0
+		if [ $? == 0 ]; then
+			ap0_started=1
+			wpa_cli -iwpa_wlan0_cmd -p/var/run/ IFNAME=ap0 disconnect
+			break
+		fi
+	done
+else
+	ap0_started=1
+fi
+
+
+if [ "$ap0_started" == ""]; then
+    exit 4
+fi
+