• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2014 Google, Inc.
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 #define LOG_TAG "bt_btif_sock"
20 
21 #include <assert.h>
22 
23 #include <hardware/bluetooth.h>
24 #include <hardware/bt_sock.h>
25 
26 #include "bta_api.h"
27 #include "btif_common.h"
28 #include "btif_sock_l2cap.h"
29 #include "btif_sock_rfc.h"
30 #include "btif_sock_sco.h"
31 #include "btif_sock_sdp.h"
32 #include "btif_sock_thread.h"
33 #include "btif_uid.h"
34 #include "btif_util.h"
35 #include "osi/include/thread.h"
36 
37 static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, const uint8_t *uuid, int channel, int *sock_fd, int flags, int app_uid);
38 static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t *uuid, int channel, int *sock_fd, int flags, int app_uid);
39 
40 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
41 
42 static int thread_handle = -1;
43 static thread_t *thread;
44 
btif_sock_get_interface(void)45 btsock_interface_t *btif_sock_get_interface(void) {
46   static btsock_interface_t interface = {
47     sizeof(interface),
48     btsock_listen,
49     btsock_connect
50   };
51 
52 
53   return &interface;
54 }
55 
btif_sock_init(uid_set_t * uid_set)56 bt_status_t btif_sock_init(uid_set_t* uid_set) {
57   assert(thread_handle == -1);
58   assert(thread == NULL);
59 
60   btsock_thread_init();
61   thread_handle = btsock_thread_create(btsock_signaled, NULL);
62   if (thread_handle == -1) {
63     LOG_ERROR(LOG_TAG, "%s unable to create btsock_thread.", __func__);
64     goto error;
65   }
66 
67   bt_status_t status = btsock_rfc_init(thread_handle, uid_set);
68   if (status != BT_STATUS_SUCCESS) {
69     LOG_ERROR(LOG_TAG, "%s error initializing RFCOMM sockets: %d", __func__, status);
70     goto error;
71   }
72 
73   status = btsock_l2cap_init(thread_handle, uid_set);
74   if (status != BT_STATUS_SUCCESS) {
75     LOG_ERROR(LOG_TAG, "%s error initializing L2CAP sockets: %d", __func__, status);
76     goto error;
77   }
78 
79   thread = thread_new("btif_sock");
80   if (!thread) {
81     LOG_ERROR(LOG_TAG, "%s error creating new thread.", __func__);
82     btsock_rfc_cleanup();
83     goto error;
84   }
85 
86   status = btsock_sco_init(thread);
87   if (status != BT_STATUS_SUCCESS) {
88     LOG_ERROR(LOG_TAG, "%s error initializing SCO sockets: %d", __func__, status);
89     btsock_rfc_cleanup();
90     goto error;
91   }
92 
93   return BT_STATUS_SUCCESS;
94 
95 error:;
96   thread_free(thread);
97   thread = NULL;
98   if (thread_handle != -1)
99     btsock_thread_exit(thread_handle);
100   thread_handle = -1;
101   uid_set = NULL;
102   return BT_STATUS_FAIL;
103 }
104 
btif_sock_cleanup(void)105 void btif_sock_cleanup(void) {
106   if (thread_handle == -1)
107     return;
108 
109   thread_stop(thread);
110   thread_join(thread);
111   btsock_thread_exit(thread_handle);
112   btsock_rfc_cleanup();
113   btsock_sco_cleanup();
114   btsock_l2cap_cleanup();
115   thread_free(thread);
116   thread_handle = -1;
117   thread = NULL;
118 }
119 
btsock_listen(btsock_type_t type,const char * service_name,const uint8_t * service_uuid,int channel,int * sock_fd,int flags,int app_uid)120 static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, const uint8_t *service_uuid, int channel, int *sock_fd, int flags, int app_uid) {
121   if((flags & BTSOCK_FLAG_NO_SDP) == 0) {
122       assert(service_uuid != NULL || channel > 0);
123       assert(sock_fd != NULL);
124   }
125 
126   *sock_fd = INVALID_FD;
127   bt_status_t status = BT_STATUS_FAIL;
128 
129   switch (type) {
130     case BTSOCK_RFCOMM:
131       status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags, app_uid);
132       break;
133     case BTSOCK_L2CAP:
134       status = btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid);
135       break;
136 
137     case BTSOCK_SCO:
138       status = btsock_sco_listen(sock_fd, flags);
139       break;
140 
141     default:
142       LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type);
143       status = BT_STATUS_UNSUPPORTED;
144       break;
145   }
146   return status;
147 }
148 
btsock_connect(const bt_bdaddr_t * bd_addr,btsock_type_t type,const uint8_t * uuid,int channel,int * sock_fd,int flags,int app_uid)149 static bt_status_t btsock_connect(const bt_bdaddr_t *bd_addr, btsock_type_t type, const uint8_t *uuid, int channel, int *sock_fd, int flags, int app_uid) {
150   assert(uuid != NULL || channel > 0);
151   assert(bd_addr != NULL);
152   assert(sock_fd != NULL);
153 
154   *sock_fd = INVALID_FD;
155   bt_status_t status = BT_STATUS_FAIL;
156 
157   switch (type) {
158     case BTSOCK_RFCOMM:
159       status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags, app_uid);
160       break;
161 
162     case BTSOCK_L2CAP:
163       status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags, app_uid);
164       break;
165 
166     case BTSOCK_SCO:
167       status = btsock_sco_connect(bd_addr, sock_fd, flags);
168       break;
169 
170     default:
171       LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type);
172       status = BT_STATUS_UNSUPPORTED;
173       break;
174   }
175   return status;
176 }
177 
btsock_signaled(int fd,int type,int flags,uint32_t user_id)178 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) {
179   switch (type) {
180     case BTSOCK_RFCOMM:
181       btsock_rfc_signaled(fd, flags, user_id);
182       break;
183     case BTSOCK_L2CAP:
184       btsock_l2cap_signaled(fd, flags, user_id);
185       break;
186     default:
187       assert(false && "Invalid socket type");
188       break;
189   }
190 }
191