Home | History | Annotate | Download | only in src
      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 #include <hardware/bluetooth.h>
     23 #include <hardware/bt_sock.h>
     24 
     25 #include "bta_api.h"
     26 #include "btif_common.h"
     27 #include "btif_sock_rfc.h"
     28 #include "btif_sock_sco.h"
     29 #include "btif_sock_thread.h"
     30 #include "btif_sock_l2cap.h"
     31 #include "btif_sock_sdp.h"
     32 #include "btif_util.h"
     33 #include "osi/include/thread.h"
     34 
     35 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);
     36 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);
     37 
     38 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id);
     39 
     40 static int thread_handle = -1;
     41 static thread_t *thread;
     42 
     43 btsock_interface_t *btif_sock_get_interface(void) {
     44   static btsock_interface_t interface = {
     45     sizeof(interface),
     46     btsock_listen,
     47     btsock_connect
     48   };
     49 
     50 
     51   return &interface;
     52 }
     53 
     54 bt_status_t btif_sock_init(void) {
     55   assert(thread_handle == -1);
     56   assert(thread == NULL);
     57 
     58   btsock_thread_init();
     59   thread_handle = btsock_thread_create(btsock_signaled, NULL);
     60   if (thread_handle == -1) {
     61     LOG_ERROR("%s unable to create btsock_thread.", __func__);
     62     goto error;
     63   }
     64 
     65   bt_status_t status = btsock_rfc_init(thread_handle);
     66   if (status != BT_STATUS_SUCCESS) {
     67     LOG_ERROR("%s error initializing RFCOMM sockets: %d", __func__, status);
     68     goto error;
     69   }
     70 
     71   status = btsock_l2cap_init(thread_handle);
     72   if (status != BT_STATUS_SUCCESS) {
     73     LOG_ERROR("%s error initializing L2CAP sockets: %d", __func__, status);
     74     goto error;
     75   }
     76 
     77   thread = thread_new("btif_sock");
     78   if (!thread) {
     79     LOG_ERROR("%s error creating new thread.", __func__);
     80     btsock_rfc_cleanup();
     81     goto error;
     82   }
     83 
     84   status = btsock_sco_init(thread);
     85   if (status != BT_STATUS_SUCCESS) {
     86     LOG_ERROR("%s error initializing SCO sockets: %d", __func__, status);
     87     btsock_rfc_cleanup();
     88     goto error;
     89   }
     90 
     91   return BT_STATUS_SUCCESS;
     92 
     93 error:;
     94   thread_free(thread);
     95   thread = NULL;
     96   if (thread_handle != -1)
     97     btsock_thread_exit(thread_handle);
     98   thread_handle = -1;
     99   return BT_STATUS_FAIL;
    100 }
    101 
    102 void btif_sock_cleanup(void) {
    103   if (thread_handle == -1)
    104     return;
    105 
    106   thread_stop(thread);
    107   thread_join(thread);
    108   btsock_thread_exit(thread_handle);
    109   btsock_rfc_cleanup();
    110   btsock_sco_cleanup();
    111   btsock_l2cap_cleanup();
    112   thread_free(thread);
    113   thread_handle = -1;
    114   thread = NULL;
    115 }
    116 
    117 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) {
    118   if((flags & BTSOCK_FLAG_NO_SDP) == 0) {
    119       assert(service_uuid != NULL || channel > 0);
    120       assert(sock_fd != NULL);
    121   }
    122 
    123   *sock_fd = INVALID_FD;
    124   bt_status_t status = BT_STATUS_FAIL;
    125 
    126   switch (type) {
    127     case BTSOCK_RFCOMM:
    128       status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags);
    129       break;
    130     case BTSOCK_L2CAP:
    131       status = btsock_l2cap_listen(service_name, channel, sock_fd, flags);
    132       break;
    133 
    134     case BTSOCK_SCO:
    135       status = btsock_sco_listen(sock_fd, flags);
    136       break;
    137 
    138     default:
    139       LOG_ERROR("%s unknown/unsupported socket type: %d", __func__, type);
    140       status = BT_STATUS_UNSUPPORTED;
    141       break;
    142   }
    143   return status;
    144 }
    145 
    146 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) {
    147   assert(uuid != NULL || channel > 0);
    148   assert(bd_addr != NULL);
    149   assert(sock_fd != NULL);
    150 
    151   *sock_fd = INVALID_FD;
    152   bt_status_t status = BT_STATUS_FAIL;
    153 
    154   switch (type) {
    155     case BTSOCK_RFCOMM:
    156       status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags);
    157       break;
    158 
    159     case BTSOCK_L2CAP:
    160       status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags);
    161       break;
    162 
    163     case BTSOCK_SCO:
    164       status = btsock_sco_connect(bd_addr, sock_fd, flags);
    165       break;
    166 
    167     default:
    168       LOG_ERROR("%s unknown/unsupported socket type: %d", __func__, type);
    169       status = BT_STATUS_UNSUPPORTED;
    170       break;
    171   }
    172   return status;
    173 }
    174 
    175 static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) {
    176   switch (type) {
    177     case BTSOCK_RFCOMM:
    178       btsock_rfc_signaled(fd, flags, user_id);
    179       break;
    180     case BTSOCK_L2CAP:
    181       btsock_l2cap_signaled(fd, flags, user_id);
    182       break;
    183     default:
    184       assert(false && "Invalid socket type");
    185       break;
    186   }
    187 }
    188