[Featrue][API-1062][wifi]add auto connect contrl api,add func & callback

Change-Id: I6e49f5a28a03a690889faab5856cb87bb5f8b7f1
diff --git a/lib/liblynq-wifi6/libwifi6.c b/lib/liblynq-wifi6/libwifi6.c
index d15072d..ed38fbf 100755
--- a/lib/liblynq-wifi6/libwifi6.c
+++ b/lib/liblynq-wifi6/libwifi6.c
@@ -51,10 +51,16 @@
 volatile int g_sta_scan_finish_flag = 1;
 volatile int g_sta_watcher_started_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"};
@@ -89,6 +95,8 @@
 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};
 
@@ -662,6 +670,142 @@
 
 }
 
+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);
@@ -673,6 +817,17 @@
     }
     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;
@@ -735,6 +890,62 @@
         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, last_state = -1;
+    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 (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)
+    {
+        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()
@@ -904,16 +1115,20 @@
     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;
     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]);
     g_ap_watcher_pid = 0;
     g_sta_watcher_pid = 0;
+    g_sta_auto_watcher_pid = 0;
     g_lynq_wpa_ctrl[0] = NULL;
     g_lynq_wpa_ctrl[1] = NULL;
     system("systemctl stop wg870_drv_insmod.service");
@@ -3065,6 +3280,16 @@
     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;
@@ -3452,6 +3677,48 @@
     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 susccs");
+    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];