[Bugfix][API-1040] reselect when status is DISCONNECTED
[Bugfix][API-1051] fix can't get password when save_list is too long
[Bugfix] add lock when invoke callback

Change-Id: Ieaca5cdc9473fe826cf12aead9b87047d21dd2e8
diff --git a/lib/liblynq-wifi6/libwifi6.c b/lib/liblynq-wifi6/libwifi6.c
index 4a3c6c9..839f835 100755
--- a/lib/liblynq-wifi6/libwifi6.c
+++ b/lib/liblynq-wifi6/libwifi6.c
@@ -65,6 +65,7 @@
 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";
@@ -86,6 +87,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;
 
 static struct local_wpa_ctrl * g_lynq_wpa_ctrl[2] = {0};
 
@@ -401,6 +404,14 @@
     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];
@@ -430,8 +441,7 @@
             //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));
@@ -443,8 +453,7 @@
             }
             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));
@@ -625,12 +634,14 @@
 
 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() {
@@ -762,10 +773,9 @@
             sleep(1);
             RLOGE("wpa service is abnormal info app to exit");
             notify_connect_status(LYNQ_WIFI_STA_SERVICE_ABNORMAL, -1);
-            if (g_ap_callback_func != NULL)
-            {
-                g_ap_callback_func(g_ap_callback_priv, LYNQ_WIFI_SERVICE_ABNORMAL);
-            }
+
+            inner_notify_ap_msg(LYNQ_WIFI_SERVICE_ABNORMAL);
+
             sleep(FAKE_MAX_INT_VALUE); // wait process to exit
         }
 
@@ -1953,8 +1963,11 @@
         }
         else
         {
-            sprintf(LYNQ_WIFI_CMD,"SELECT_NETWORK %d",AP_NETWORK_0);
-            DO_REQUEST(LYNQ_WIFI_CMD);
+            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);
         }
     }
@@ -2333,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);
 
@@ -2353,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)
                 {
@@ -2411,6 +2441,10 @@
 
     if (index >= len || NULL == p || network_len <= 0)
     {
+        if (buff != NULL)
+        {
+            free(buff);
+        }
         return -1;
     }
 
@@ -2421,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;
         }
 
@@ -2447,9 +2481,9 @@
 
         p = password;
         while(password - p < 64 && *password != '\0')
-	{
+        {
             if (*password == '\"')
-	    {
+            {
                 *password = '\0';
                 break;
             }
@@ -2459,6 +2493,11 @@
         break;
     } //end for(index=0; index < count; index++)
 
+    if (buff != NULL)
+    {
+        free(buff);
+    }
+
     return ret;
 }
 
@@ -2949,17 +2988,27 @@
     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);
 
-    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");
@@ -2969,6 +3018,21 @@
         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");
 }
@@ -3282,10 +3346,12 @@
         return -1;
     }
 
-    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    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)
@@ -3304,12 +3370,15 @@
 }
 
 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;
 }
 
@@ -3320,10 +3389,12 @@
         return -1;
     }
 
-    pthread_mutex_lock(&s_check_wpa_ctrl_mutex);
+    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)
         {
@@ -3340,23 +3411,18 @@
 }
 
 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];