15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 3fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati * Copyright (C) 2014 Google, Inc. 45738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 55738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 65738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * you may not use this file except in compliance with the License. 75738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * You may obtain a copy of the License at: 85738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 95738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * See the License for the specific language governing permissions and 155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * limitations under the License. 165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 19985d4b6986b787839ba72470f96be841f7721a17Marie Janssen#define LOG_TAG "bt_btif_sock" 20985d4b6986b787839ba72470f96be841f7721a17Marie Janssen 21fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati#include <assert.h> 22db554581079863974af8e1289646f5deea6fc044Marie Janssen 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bluetooth.h> 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <hardware/bt_sock.h> 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bta_api.h" 27fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati#include "btif_common.h" 28db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btif_sock_l2cap.h" 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "btif_sock_rfc.h" 30e93ac125b887651e835fe59f4d1f9b3c5baa844cIan McKellar#include "btif_sock_sco.h" 318372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz#include "btif_sock_sdp.h" 32db554581079863974af8e1289646f5deea6fc044Marie Janssen#include "btif_sock_thread.h" 330229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski#include "btif_uid.h" 34fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati#include "btif_util.h" 350f9b91e150e153229235c163861198e23600e636Sharvil Nanavati#include "osi/include/thread.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 370229bd4f183266b103daa18cf95c175aabe87217Adam Lesinskistatic 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); 380229bd4f183266b103daa18cf95c175aabe87217Adam Lesinskistatic 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); 395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void btsock_signaled(int fd, int type, int flags, uint32_t user_id); 415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 42fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavatistatic int thread_handle = -1; 43c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavatistatic thread_t *thread; 44fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 45fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavatibtsock_interface_t *btif_sock_get_interface(void) { 46fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati static btsock_interface_t interface = { 47fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati sizeof(interface), 48fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_listen, 49fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_connect 50fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati }; 51fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 528372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz 53fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati return &interface; 545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 55fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 560229bd4f183266b103daa18cf95c175aabe87217Adam Lesinskibt_status_t btif_sock_init(uid_set_t* uid_set) { 57fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati assert(thread_handle == -1); 58c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati assert(thread == NULL); 59fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 60fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_thread_init(); 61fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati thread_handle = btsock_thread_create(btsock_signaled, NULL); 62fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati if (thread_handle == -1) { 63db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s unable to create btsock_thread.", __func__); 64c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati goto error; 65fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati } 66fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 670229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski bt_status_t status = btsock_rfc_init(thread_handle, uid_set); 68fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati if (status != BT_STATUS_SUCCESS) { 69db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s error initializing RFCOMM sockets: %d", __func__, status); 70c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati goto error; 71c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati } 72c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati 730229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski status = btsock_l2cap_init(thread_handle, uid_set); 748372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz if (status != BT_STATUS_SUCCESS) { 75db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s error initializing L2CAP sockets: %d", __func__, status); 768372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz goto error; 778372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz } 788372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz 79c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread = thread_new("btif_sock"); 80c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati if (!thread) { 81db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s error creating new thread.", __func__); 82c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati btsock_rfc_cleanup(); 83c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati goto error; 84fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati } 85fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 86c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati status = btsock_sco_init(thread); 87fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati if (status != BT_STATUS_SUCCESS) { 88db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s error initializing SCO sockets: %d", __func__, status); 895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project btsock_rfc_cleanup(); 90c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati goto error; 91fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati } 92fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 93fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati return BT_STATUS_SUCCESS; 94c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati 95c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavatierror:; 96c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread_free(thread); 97c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread = NULL; 98c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati if (thread_handle != -1) 99c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati btsock_thread_exit(thread_handle); 100c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread_handle = -1; 1010229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski uid_set = NULL; 102c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati return BT_STATUS_FAIL; 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 105fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavativoid btif_sock_cleanup(void) { 106fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati if (thread_handle == -1) 107fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati return; 108fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 109c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread_stop(thread); 110c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread_join(thread); 111fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_thread_exit(thread_handle); 112fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_rfc_cleanup(); 113fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_sco_cleanup(); 1148372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz btsock_l2cap_cleanup(); 115c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread_free(thread); 116fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati thread_handle = -1; 117c8aaee2c9393ef28fdbdcf28be80172f387205fcSharvil Nanavati thread = NULL; 1185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 119fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 1200229bd4f183266b103daa18cf95c175aabe87217Adam Lesinskistatic 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) { 1218372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz if((flags & BTSOCK_FLAG_NO_SDP) == 0) { 1228372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz assert(service_uuid != NULL || channel > 0); 1238372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz assert(sock_fd != NULL); 1248372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz } 125fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 126fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati *sock_fd = INVALID_FD; 127fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati bt_status_t status = BT_STATUS_FAIL; 128fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 129fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati switch (type) { 130fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati case BTSOCK_RFCOMM: 1310229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags, app_uid); 132fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 1338372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz case BTSOCK_L2CAP: 1340229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski status = btsock_l2cap_listen(service_name, channel, sock_fd, flags, app_uid); 1358372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz break; 136fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 137fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati case BTSOCK_SCO: 138fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati status = btsock_sco_listen(sock_fd, flags); 139fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 140fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 141fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati default: 142db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type); 143fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati status = BT_STATUS_UNSUPPORTED; 144fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 145fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati } 146fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati return status; 1475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 148fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 1490229bd4f183266b103daa18cf95c175aabe87217Adam Lesinskistatic 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) { 150fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati assert(uuid != NULL || channel > 0); 151fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati assert(bd_addr != NULL); 152fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati assert(sock_fd != NULL); 153fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 154fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati *sock_fd = INVALID_FD; 155fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati bt_status_t status = BT_STATUS_FAIL; 156fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 157fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati switch (type) { 158fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati case BTSOCK_RFCOMM: 1590229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags, app_uid); 160fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 161fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 1628372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz case BTSOCK_L2CAP: 1630229bd4f183266b103daa18cf95c175aabe87217Adam Lesinski status = btsock_l2cap_connect(bd_addr, channel, sock_fd, flags, app_uid); 1648372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz break; 1658372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz 166fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati case BTSOCK_SCO: 167fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati status = btsock_sco_connect(bd_addr, sock_fd, flags); 168fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 169fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 170fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati default: 171db554581079863974af8e1289646f5deea6fc044Marie Janssen LOG_ERROR(LOG_TAG, "%s unknown/unsupported socket type: %d", __func__, type); 172fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati status = BT_STATUS_UNSUPPORTED; 173fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 174fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati } 175fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati return status; 176fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati} 177fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati 178fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavatistatic void btsock_signaled(int fd, int type, int flags, uint32_t user_id) { 179fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati switch (type) { 180fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati case BTSOCK_RFCOMM: 181fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati btsock_rfc_signaled(fd, flags, user_id); 182fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 1838372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz case BTSOCK_L2CAP: 1848372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz btsock_l2cap_signaled(fd, flags, user_id); 1858372aa5fa535ee4f09c09981b6125b54ace31fe2Kim Schulz break; 186fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati default: 187fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati assert(false && "Invalid socket type"); 188fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati break; 189fe4ec6ba40c011cfd3599d45fbda3c6575a07189Sharvil Nanavati } 1905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 191