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 35static bt_status_t btsock_listen(btsock_type_t type, const char *service_name, const uint8_t *uuid, int channel, int *sock_fd, int flags); 36static 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 38static void btsock_signaled(int fd, int type, int flags, uint32_t user_id); 39 40static int thread_handle = -1; 41static thread_t *thread; 42 43btsock_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 54bt_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 93error:; 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 102void 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 117static 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 146static 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 175static 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