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 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 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 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 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 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 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