OSDN Git Service

am f29a2fb..e07ad10 from mirror-m-wireless-internal-release
[android-x86/system-bt.git] / btif / src / btif_sock_thread.c
index 71cf5db..459aeba 100644 (file)
@@ -32,6 +32,7 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <errno.h>
+#include <features.h>
 #include <string.h>
 #include <sys/types.h>
 #include <sys/socket.h>
 #include <cutils/sockets.h>
 #include <alloca.h>
 
-#define LOG_TAG "BTIF_SOCK"
+#define LOG_TAG "bt_btif_sock"
 #include "btif_common.h"
 #include "btif_util.h"
 
-#include "bd.h"
 
 #include "bta_api.h"
 #include "btif_sock.h"
 #include "btif_sock_thread.h"
 #include "btif_sock_util.h"
 
-#include <cutils/log.h>
 #define asrt(s) if(!(s)) APPL_TRACE_ERROR("## %s assert %s failed at line:%d ##",__FUNCTION__, #s, __LINE__)
 #define print_events(events) do { \
     APPL_TRACE_DEBUG("print poll event:%x", events); \
@@ -82,7 +81,8 @@
 #define CMD_WAKEUP       1
 #define CMD_EXIT         2
 #define CMD_ADD_FD       3
-#define CMD_USER_PRIVATE 4
+#define CMD_REMOVE_FD    4
+#define CMD_USER_PRIVATE 5
 
 typedef struct {
     struct pollfd pfd;
@@ -95,7 +95,7 @@ typedef struct {
     int poll_count;
     poll_slot_t ps[MAX_POLL];
     int psi[MAX_POLL]; //index of poll slot
-    volatile pid_t thread_id;
+    volatile pthread_t thread_id;
     btsock_signaled_cb callback;
     btsock_cmd_cb cmd_callback;
     int used;
@@ -111,18 +111,86 @@ static inline void add_poll(int h, int fd, int type, int flags, uint32_t user_id
 
 static pthread_mutex_t thread_slot_lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
 
-static inline pthread_t create_thread(void *(*start_routine)(void *), void * arg)
+static inline void set_socket_blocking(int s, int blocking)
+{
+    int opts;
+    opts = fcntl(s, F_GETFL);
+    if (opts<0) APPL_TRACE_ERROR("set blocking (%s)", strerror(errno));
+    if(blocking)
+        opts &= ~O_NONBLOCK;
+    else opts |= O_NONBLOCK;
+    if (fcntl(s, F_SETFL, opts) < 0)
+        APPL_TRACE_ERROR("set blocking (%s)", strerror(errno));
+}
+
+static inline int create_server_socket(const char* name)
+{
+    int s = socket(AF_LOCAL, SOCK_STREAM, 0);
+    if(s < 0)
+        return -1;
+    APPL_TRACE_DEBUG("covert name to android abstract name:%s", name);
+    if(socket_local_server_bind(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT) >= 0)
+    {
+        if(listen(s, 5) == 0)
+        {
+            APPL_TRACE_DEBUG("listen to local socket:%s, fd:%d", name, s);
+            return s;
+        }
+        else APPL_TRACE_ERROR("listen to local socket:%s, fd:%d failed, errno:%d", name, s, errno);
+    }
+    else APPL_TRACE_ERROR("create local socket:%s fd:%d, failed, errno:%d", name, s, errno);
+    close(s);
+    return -1;
+}
+static inline int connect_server_socket(const char* name)
+{
+    int s = socket(AF_LOCAL, SOCK_STREAM, 0);
+    if(s < 0)
+        return -1;
+    set_socket_blocking(s, TRUE);
+    if(socket_local_client_connect(s, name, ANDROID_SOCKET_NAMESPACE_ABSTRACT, SOCK_STREAM) >= 0)
+    {
+        APPL_TRACE_DEBUG("connected to local socket:%s, fd:%d", name, s);
+        return s;
+    }
+    else APPL_TRACE_ERROR("connect to local socket:%s, fd:%d failed, errno:%d", name, s, errno);
+    close(s);
+    return -1;
+}
+static inline int accept_server_socket(int s)
+{
+    struct sockaddr_un client_address;
+    socklen_t clen;
+    int fd = accept(s, (struct sockaddr*)&client_address, &clen);
+    APPL_TRACE_DEBUG("accepted fd:%d for server fd:%d", fd, s);
+    return fd;
+}
+
+static inline int create_thread(void *(*start_routine)(void *), void * arg,
+                                pthread_t * thread_id)
 {
     pthread_attr_t thread_attr;
     pthread_attr_init(&thread_attr);
     pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
-    pthread_t thread_id = -1;
-    if( pthread_create(&thread_id, &thread_attr, start_routine, arg)!=0 )
+    int policy;
+    int min_pri=0;
+       int ret = -1;
+    struct sched_param param;
+
+    if ((ret = pthread_create(thread_id, &thread_attr, start_routine, arg))!=0 )
     {
         APPL_TRACE_ERROR("pthread_create : %s", strerror(errno));
-        return -1;
+        return ret;
     }
-    return thread_id;
+    /* We need to lower the priority of this thread to ensure the stack gets
+     * priority over transfer to a socket */
+    pthread_getschedparam(*thread_id, &policy, &param);
+    min_pri = sched_get_priority_min(policy);
+    if (param.sched_priority > min_pri) {
+        param.sched_priority -= 1;
+    }
+    pthread_setschedparam(*thread_id, policy, &param);
+    return ret;
 }
 static void init_poll(int cmd_fd);
 static int alloc_thread_slot()
@@ -180,17 +248,19 @@ int btsock_thread_create(btsock_signaled_cb callback, btsock_cmd_cb cmd_callback
     if(h >= 0)
     {
         init_poll(h);
-        if((ts[h].thread_id = create_thread(sock_poll_thread, (void*)(uintptr_t)h)) != -1)
-        {
-            APPL_TRACE_DEBUG("h:%d, thread id:%d", h, ts[h].thread_id);
-            ts[h].callback = callback;
-            ts[h].cmd_callback = cmd_callback;
-        }
-        else
+        pthread_t thread;
+        int status = create_thread(sock_poll_thread, (void*)(uintptr_t)h, &thread);
+        if (status)
         {
+            APPL_TRACE_ERROR("create_thread failed: %s", strerror(status));
             free_thread_slot(h);
-            h = -1;
+            return -1;
         }
+
+        ts[h].thread_id = thread;
+        APPL_TRACE_DEBUG("h:%d, thread id:%d", h, ts[h].thread_id);
+        ts[h].callback = callback;
+        ts[h].cmd_callback = cmd_callback;
     }
     return h;
 }
@@ -257,6 +327,24 @@ int btsock_thread_add_fd(int h, int fd, int type, int flags, uint32_t user_id)
     APPL_TRACE_DEBUG("adding fd:%d, flags:0x%x", fd, flags);
     return send(ts[h].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
 }
+
+bool btsock_thread_remove_fd_and_close(int thread_handle, int fd)
+{
+    if (thread_handle < 0 || thread_handle >= MAX_THREAD)
+    {
+        APPL_TRACE_ERROR("%s invalid thread handle: %d", __func__, thread_handle);
+        return false;
+    }
+    if (fd == -1)
+    {
+        APPL_TRACE_ERROR("%s invalid file descriptor.", __func__);
+        return false;
+    }
+
+    sock_cmd_t cmd = {CMD_REMOVE_FD, fd, 0, 0, 0};
+    return send(ts[thread_handle].cmd_fdw, &cmd, sizeof(cmd), 0) == sizeof(cmd);
+}
+
 int btsock_thread_post_cmd(int h, int type, const unsigned char* data, int size, uint32_t user_id)
 {
     if(h < 0 || h >= MAX_THREAD)
@@ -424,6 +512,18 @@ static int process_cmd_sock(int h)
         case CMD_ADD_FD:
             add_poll(h, cmd.fd, cmd.type, cmd.flags, cmd.user_id);
             break;
+        case CMD_REMOVE_FD:
+            for (int i = 1; i < MAX_POLL; ++i)
+            {
+                poll_slot_t *poll_slot = &ts[h].ps[i];
+                if (poll_slot->pfd.fd == cmd.fd)
+                {
+                    remove_poll(h, poll_slot, poll_slot->flags);
+                    break;
+                }
+            }
+            close(cmd.fd);
+            break;
         case CMD_WAKEUP:
             break;
         case CMD_USER_PRIVATE:
@@ -538,4 +638,3 @@ static void *sock_poll_thread(void *arg)
     APPL_TRACE_DEBUG("socket poll thread exiting, h:%d", h);
     return 0;
 }
-