• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 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 <atomic>
22 
23 #include <base/logging.h>
24 
25 #include <hardware/bluetooth.h>
26 #include <hardware/bt_sock.h>
27 
28 #include "bta_api.h"
29 #include "btif_common.h"
30 #include "btif_sock_l2cap.h"
31 #include "btif_sock_rfc.h"
32 #include "btif_sock_sco.h"
33 #include "btif_sock_sdp.h"
34 #include "btif_sock_thread.h"
35 #include "btif_uid.h"
36 #include "btif_util.h"
37 #include "device/include/controller.h"
38 #include "osi/include/thread.h"
39 
40 using bluetooth::Uuid;
41 
42 static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
43                                  const Uuid* uuid, int channel, int* sock_fd,
44                                  int flags, int app_uid);
45 static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
46                                   const Uuid* uuid, int channel, int* sock_fd,
47                                   int flags, int app_uid);
48 
49 static void btsock_request_max_tx_data_length(const RawAddress& bd_addr);
50 
51 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
52 
53 static std::atomic_int thread_handle{-1};
54 static thread_t* thread;
55 
btif_sock_get_interface(void)56 const btsock_interface_t* btif_sock_get_interface(void) {
57   static btsock_interface_t interface = {
58       sizeof(interface), btsock_listen, /* listen */
59       btsock_connect,                   /* connect */
60       btsock_request_max_tx_data_length /* request_max_tx_data_length */
61   };
62 
63   return &interface;
64 }
65 
btif_sock_init(uid_set_t * uid_set)66 bt_status_t btif_sock_init(uid_set_t* uid_set) {
67   CHECK(thread_handle == -1);
68   CHECK(thread == NULL);
69 
70   bt_status_t status;
71   btsock_thread_init();
72   thread_handle = btsock_thread_create(btsock_signaled, NULL);
73   if (thread_handle == -1) {
74     LOG_ERROR(LOG_TAG, "%s unable to create btsock_thread.", __func__);
75     goto error;
76   }
77 
78   status = btsock_rfc_init(thread_handle, uid_set);
79   if (status != BT_STATUS_SUCCESS) {
80     LOG_ERROR(LOG_TAG, "%s error initializing RFCOMM sockets: %d", __func__,
81               status);
82     goto error;
83   }
84 
85   status = btsock_l2cap_init(thread_handle, uid_set);
86   if (status != BT_STATUS_SUCCESS) {
87     LOG_ERROR(LOG_TAG, "%s error initializing L2CAP sockets: %d", __func__,
88               status);
89     goto error;
90   }
91 
92   thread = thread_new("btif_sock");
93   if (!thread) {
94     LOG_ERROR(LOG_TAG, "%s error creating new thread.", __func__);
95     btsock_rfc_cleanup();
96     goto error;
97   }
98 
99   status = btsock_sco_init(thread);
100   if (status != BT_STATUS_SUCCESS) {
101     LOG_ERROR(LOG_TAG, "%s error initializing SCO sockets: %d", __func__,
102               status);
103     btsock_rfc_cleanup();
104     goto error;
105   }
106 
107   return BT_STATUS_SUCCESS;
108 
109 error:;
110   thread_free(thread);
111   thread = NULL;
112   if (thread_handle != -1) btsock_thread_exit(thread_handle);
113   thread_handle = -1;
114   uid_set = NULL;
115   return BT_STATUS_FAIL;
116 }
117 
btif_sock_cleanup(void)118 void btif_sock_cleanup(void) {
119   int saved_handle = thread_handle;
120   if (std::atomic_exchange(&thread_handle, -1) == -1) return;
121 
122   btsock_thread_exit(saved_handle);
123   btsock_rfc_cleanup();
124   btsock_sco_cleanup();
125   btsock_l2cap_cleanup();
126   thread_free(thread);
127   thread = NULL;
128 }
129 
btsock_listen(btsock_type_t type,const char * service_name,const Uuid * service_uuid,int channel,int * sock_fd,int flags,int app_uid)130 static bt_status_t btsock_listen(btsock_type_t type, const char* service_name,
131                                  const Uuid* service_uuid, int channel,
132                                  int* sock_fd, int flags, int app_uid) {
133   if ((flags & BTSOCK_FLAG_NO_SDP) == 0) {
134     CHECK(sock_fd != NULL);
135   }
136 
137   *sock_fd = INVALID_FD;
138   bt_status_t status = BT_STATUS_FAIL;
139   int original_channel = channel;
140 
141   switch (type) {
142     case BTSOCK_RFCOMM:
143       status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd,
144                                  flags, app_uid);
145       break;
146     case BTSOCK_L2CAP:
147       status =
148           btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid);
149       break;
150     case BTSOCK_L2CAP_LE:
151       if (flags & BTSOCK_FLAG_NO_SDP) {
152         /* Set channel to zero so that it will be assigned */
153         channel = 0;
154       } else if (channel <= 0) {
155         LOG_ERROR(LOG_TAG, "%s: type BTSOCK_L2CAP_LE: invalid channel=%d",
156                   __func__, channel);
157         break;
158       }
159       flags |= BTSOCK_FLAG_LE_COC;
160       LOG_DEBUG(
161           LOG_TAG,
162           "%s: type=BTSOCK_L2CAP_LE, channel=0x%x, original=0x%x, flags=0x%x",
163           __func__, channel, original_channel, flags);
164       status =
165           btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid);
166       break;
167     case BTSOCK_SCO:
168       status = btsock_sco_listen(sock_fd, flags);
169       break;
170 
171     default:
172       LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__,
173                 type);
174       status = BT_STATUS_UNSUPPORTED;
175       break;
176   }
177   return status;
178 }
179 
btsock_connect(const RawAddress * bd_addr,btsock_type_t type,const Uuid * uuid,int channel,int * sock_fd,int flags,int app_uid)180 static bt_status_t btsock_connect(const RawAddress* bd_addr, btsock_type_t type,
181                                   const Uuid* uuid, int channel, int* sock_fd,
182                                   int flags, int app_uid) {
183   CHECK(bd_addr != NULL);
184   CHECK(sock_fd != NULL);
185 
186   *sock_fd = INVALID_FD;
187   bt_status_t status = BT_STATUS_FAIL;
188 
189   switch (type) {
190     case BTSOCK_RFCOMM:
191       status =
192           btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags, app_uid);
193       break;
194 
195     case BTSOCK_L2CAP:
196       status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags, app_uid);
197       break;
198 
199     case BTSOCK_L2CAP_LE:
200       flags |= BTSOCK_FLAG_LE_COC;
201       LOG_DEBUG(LOG_TAG, "%s: type=BTSOCK_L2CAP_LE, channel=0x%x, flags=0x%x",
202                 __func__, channel, flags);
203       status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags, app_uid);
204       break;
205 
206     case BTSOCK_SCO:
207       status = btsock_sco_connect(bd_addr, sock_fd, flags);
208       break;
209 
210     default:
211       LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__,
212                 type);
213       status = BT_STATUS_UNSUPPORTED;
214       break;
215   }
216   return status;
217 }
218 
btsock_request_max_tx_data_length(const RawAddress & remote_device)219 static void btsock_request_max_tx_data_length(const RawAddress& remote_device) {
220   const controller_t* controller = controller_get_interface();
221   uint16_t max_len = controller->get_ble_maximum_tx_data_length();
222 
223   DVLOG(2) << __func__ << ": max_len=" << max_len;
224 
225   BTA_DmBleSetDataLength(remote_device, max_len);
226 }
227 
btsock_signaled(int fd,int type,int flags,uint32_t user_id)228 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) {
229   switch (type) {
230     case BTSOCK_RFCOMM:
231       btsock_rfc_signaled(fd, flags, user_id);
232       break;
233     case BTSOCK_L2CAP:
234     case BTSOCK_L2CAP_LE:
235       /* Note: The caller may not distinguish between BTSOCK_L2CAP and
236        * BTSOCK_L2CAP_LE correctly */
237       btsock_l2cap_signaled(fd, flags, user_id);
238       break;
239     default:
240       CHECK(false && "Invalid socket type");
241       break;
242   }
243 }
244