[Bugfix][API-867][wifi] add heart beat for callback threads

Change-Id: I65f5f20369817cc2b48feea9e33dedac02181ccd
diff --git a/lib/liblynq-wifi6/libwifi6.c b/lib/liblynq-wifi6/libwifi6.c
index 45a957d..3f684f1 100755
--- a/lib/liblynq-wifi6/libwifi6.c
+++ b/lib/liblynq-wifi6/libwifi6.c
@@ -63,6 +63,11 @@
 const char * state_scan_result = "CTRL-EVENT-SCAN-RESULTS";
 const char * STATE_COMPLETED = "COMPLETED";
 
+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
+
 struct local_wpa_ctrl{
     struct wpa_ctrl *ctrl;
     pthread_mutex_t mutex;
@@ -180,67 +185,139 @@
 
 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);
+        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
+        {
+            wpa_ctrl_close(*pp_lynq_wpa_ctrl);
+            *pp_lynq_wpa_ctrl = NULL;
+            *idle_count = 0;
+            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;
+        return -1;
+    }
+
+    *idle_count = 0;
+    return 1;
+}
+
 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;
-            }
-
-            wpa_ctrl_attach(lynq_wpa_ctrl);
-            g_ap_watcher_started_flag = 1;
-        }
-
-        if ( 0 == wpa_ctrl_pending(lynq_wpa_ctrl))
-	{
-            usleep(100*1000);
+        if (check_pending_msg(&lynq_wpa_ctrl, CTRL_AP, &idle_count, &g_ap_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("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);
                 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);
                 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)
@@ -372,30 +449,18 @@
     char msg_notify[MAX_RET];
     error_number_s error;
     lynq_wifi_sta_status_s state;
+    int idle_count = 0;
 
     struct wpa_ctrl *lynq_wpa_ctrl = NULL;
     g_sta_watcher_stop_flag = 0;
 
     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 +477,9 @@
                 continue;
             }
             get_state_error(msg_notify,&state,&error);
+            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);
         }
     }
     if (lynq_wpa_ctrl != NULL)