SSB-15430: AP restarts automatically during connection
authorDebasish Das <d.das@samsung.com>
Thu, 14 Apr 2016 14:29:54 +0000 (19:59 +0530)
committerTarun Karela <t.karela@samsung.com>
Mon, 4 Jun 2018 09:40:47 +0000 (10:40 +0100)
HAL cleanup was not proper; so the socket creation was failing subsequently

Change-Id: I9113a0ce61ad5863555cdc83929e8b6fb0a774d8
SCSC-Bug-Id: SSB-15430
Signed-off-by: Debasish Das <d.das@samsung.com>
common.h
wifi_hal.cpp

index 5cfa92a4743f69a900f3eb3ea11793ce6032c1fe..82208c2cd092808cce14dccd9ece7f8d6a9fe5a4 100755 (executable)
--- a/common.h
+++ b/common.h
@@ -111,6 +111,7 @@ typedef struct {
     struct nl_sock *cmd_sock;                       // command socket object\r
     struct nl_sock *event_sock;                     // event socket object\r
     int nl80211_family_id;                          // family id for 80211 driver\r
+    int cleanup_socks[2];                           // sockets used to implement wifi_cleanup\r
 \r
     bool in_event_loop;                             // Indicates that event loop is active\r
     bool clean_up;                                  // Indication to clean up the socket\r
index 837119a8d05dece5820e43b5d1d1e92826d0ce16..51c7d4a3bea9cef5eb11b628faa23b7e89385548 100755 (executable)
@@ -138,9 +138,16 @@ wifi_error wifi_initialize(wifi_handle *handle)
     memset(info, 0, sizeof(*info));\r
 \r
     ALOGI("Creating socket");\r
+    if (socketpair(AF_UNIX, SOCK_STREAM, 0, info->cleanup_socks) == -1) {\r
+        ALOGE("Could not create cleanup sockets");\r
+        free(info);\r
+        return WIFI_ERROR_UNKNOWN;\r
+    }\r
+\r
     struct nl_sock *cmd_sock = wifi_create_nl_socket(WIFI_HAL_CMD_SOCK_PORT);\r
     if (cmd_sock == NULL) {\r
         ALOGE("Could not create handle");\r
+        free(info);\r
         return WIFI_ERROR_UNKNOWN;\r
     }\r
 \r
@@ -148,12 +155,16 @@ wifi_error wifi_initialize(wifi_handle *handle)
     if (event_sock == NULL) {\r
         ALOGE("Could not create handle");\r
         nl_socket_free(cmd_sock);\r
+        free(info);\r
         return WIFI_ERROR_UNKNOWN;\r
     }\r
 \r
     struct nl_cb *cb = nl_socket_get_cb(event_sock);\r
     if (cb == NULL) {\r
         ALOGE("Could not create handle");\r
+        nl_socket_free(cmd_sock);\r
+        nl_socket_free(event_sock);\r
+        free(info);\r
         return WIFI_ERROR_UNKNOWN;\r
     }\r
 \r
@@ -229,6 +240,8 @@ static void internal_cleaned_up_handler(wifi_handle handle)
     wifi_cleaned_up_handler cleaned_up_handler = info->cleaned_up_handler;\r
 \r
     if (info->cmd_sock != 0) {\r
+        close(info->cleanup_socks[0]);\r
+        close(info->cleanup_socks[1]);\r
         nl_socket_free(info->cmd_sock);\r
         nl_socket_free(info->event_sock);\r
         info->cmd_sock = NULL;\r
@@ -245,10 +258,59 @@ static void internal_cleaned_up_handler(wifi_handle handle)
 void wifi_cleanup(wifi_handle handle, wifi_cleaned_up_handler handler)\r
 {\r
     hal_info *info = getHalInfo(handle);\r
+    char buf[64];\r
+\r
     info->cleaned_up_handler = handler;\r
+    if (write(info->cleanup_socks[0], "Exit", 4) < 1) {\r
+        ALOGE("could not write to the cleanup socket");\r
+    } else {\r
+        // Listen to the response\r
+        // Hopefully we dont get errors or get hung up\r
+        // Not much can be done in that case, but assume that\r
+        // it has rx'ed the Exit message to exit the thread.\r
+        // As a fallback set the cleanup flag to TRUE\r
+        memset(buf, 0, sizeof(buf));\r
+        int result = read(info->cleanup_socks[0], buf, sizeof(buf));\r
+        ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result, errno);\r
+        if (strncmp(buf, "Done", 4) == 0) {\r
+            ALOGE("Event processing terminated");\r
+        } else {\r
+            ALOGD("Rx'ed %s", buf);\r
+        }\r
+    }\r
     info->clean_up = true;\r
+    pthread_mutex_lock(&info->cb_lock);\r
 \r
-    ALOGI("Wifi cleanup completed");\r
+    int bad_commands = 0;\r
+\r
+    for (int i = 0; i < info->num_event_cb; i++) {\r
+        cb_info *cbi = &(info->event_cb[i]);\r
+        WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;\r
+    }\r
+\r
+    while (info->num_cmd > bad_commands) {\r
+        int num_cmd = info->num_cmd;\r
+        cmd_info *cmdi = &(info->cmd[bad_commands]);\r
+        WifiCommand *cmd = cmdi->cmd;\r
+        if (cmd != NULL) {\r
+            pthread_mutex_unlock(&info->cb_lock);\r
+            cmd->cancel();\r
+            pthread_mutex_lock(&info->cb_lock);\r
+            /* release reference added when command is saved */\r
+            cmd->releaseRef();\r
+            if (num_cmd == info->num_cmd) {\r
+                bad_commands++;\r
+            }\r
+        }\r
+    }\r
+\r
+    for (int i = 0; i < info->num_event_cb; i++) {\r
+        cb_info *cbi = &(info->event_cb[i]);\r
+        WifiCommand *cmd = (WifiCommand *)cbi->cb_arg;\r
+        ALOGE("Leaked command %p", cmd);\r
+    }\r
+    pthread_mutex_unlock(&info->cb_lock);\r
+    internal_cleaned_up_handler(handle);\r
 }\r
 \r
 static int internal_pollin_handler(wifi_handle handle)\r
@@ -274,40 +336,49 @@ void wifi_event_loop(wifi_handle handle)
         info->in_event_loop = true;\r
     }\r
 \r
-    pollfd pfd;\r
-    memset(&pfd, 0, sizeof(pfd));\r
+    pollfd pfd[2];\r
+    memset(&pfd[0], 0, sizeof(pollfd) * 2);\r
 \r
-    pfd.fd = nl_socket_get_fd(info->event_sock);\r
-    pfd.events = POLLIN;\r
+    pfd[0].fd = nl_socket_get_fd(info->event_sock);\r
+    pfd[0].events = POLLIN;\r
+    pfd[1].fd = info->cleanup_socks[1];\r
+    pfd[1].events = POLLIN;\r
 \r
-    /* TODO: Add support for timeouts */\r
+    char buf[2048];\r
 \r
     do {\r
         int timeout = -1;                   /* Infinite timeout */\r
-        pfd.revents = 0;\r
-         ALOGI("Polling socket");\r
-        int result = poll(&pfd, 1, -1);\r
+        pfd[0].revents = 0;\r
+        pfd[1].revents = 0;\r
+        int result = poll(pfd, 2, timeout);\r
         if (result < 0) {\r
-            ALOGE("Error polling socket");\r
-        } else if (pfd.revents & POLLERR) {\r
+        } else if (pfd[0].revents & POLLERR) {\r
             ALOGE("POLL Error; error no = %d", errno);\r
-            char buf[2048];\r
-            int result2 = read(pfd.fd, buf, sizeof(buf));\r
+            int result2 = read(pfd[0].fd, buf, sizeof(buf));\r
             ALOGE("Read after POLL returned %d, error no = %d", result2, errno);\r
-        } else if (pfd.revents & POLLHUP) {\r
+        } else if (pfd[0].revents & POLLHUP) {\r
             ALOGE("Remote side hung up");\r
             break;\r
-        } else if (pfd.revents & POLLIN) {\r
-             ALOGI("Found some events!!!");\r
+        } else if (pfd[0].revents & POLLIN) {\r
             internal_pollin_handler(handle);\r
+        } else if (pfd[1].revents & POLLIN) {\r
+            memset(buf, 0, sizeof(buf));\r
+            int result2 = read(pfd[1].fd, buf, sizeof(buf));\r
+            ALOGE("%s: Read after POLL returned %d, error no = %d", __FUNCTION__, result2, errno);\r
+            if (strncmp(buf, "Exit", 4) == 0) {\r
+                ALOGD("Got a signal to exit!!!");\r
+                if (write(pfd[1].fd, "Done", 4) < 1) {\r
+                    ALOGE("could not write to the cleanup socket");\r
+                }\r
+                break;\r
+            } else {\r
+                ALOGD("Rx'ed %s on the cleanup socket\n", buf);\r
+            }\r
         } else {\r
-            ALOGE("Unknown event - %0x", pfd.revents);\r
+            ALOGE("Unknown event - %0x, %0x", pfd[0].revents, pfd[1].revents);\r
         }\r
     } while (!info->clean_up);\r
-\r
-\r
-    ALOGI("Cleaning up");\r
-    internal_cleaned_up_handler(handle);\r
+    ALOGI("Exit %s", __FUNCTION__);\r
 }\r
 \r
 ///////////////////////////////////////////////////////////////////////////////////////\r
@@ -372,8 +443,8 @@ static int internal_valid_message_handler(nl_msg *msg, void *arg)
             }\r
 \r
             pthread_mutex_unlock(&info->cb_lock);\r
-\r
-            (*cb_func)(msg, cb_arg);\r
+            if (cb_func)\r
+                (*cb_func)(msg, cb_arg);\r
             if (cmd != NULL) {\r
                 cmd->releaseRef();\r
             }\r