Home | History | Annotate | Download | only in src
      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 
     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 
     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 
    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 
    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 
    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 
    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 
    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