From fe4ec6ba40c011cfd3599d45fbda3c6575a07189 Mon Sep 17 00:00:00 2001 From: Sharvil Nanavati Date: Thu, 21 Aug 2014 13:17:43 -0700 Subject: [PATCH] Rewrite the btif_sock module. The initialization flow now handles errors. The btif_sock module is now solely responsible for managing the lifetime of the btsock_thread it creates. This change lays the foundation for switching all btif sockets to use the OSI primitives. --- btif/include/btif_sock.h | 20 +--- btif/src/btif_sock.c | 257 +++++++++++++++++++++-------------------------- 2 files changed, 121 insertions(+), 156 deletions(-) diff --git a/btif/include/btif_sock.h b/btif/include/btif_sock.h index ad2c71da5..1747230fc 100644 --- a/btif/include/btif_sock.h +++ b/btif/include/btif_sock.h @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2009-2012 Broadcom Corporation + * Copyright (C) 2014 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,21 +16,11 @@ * ******************************************************************************/ -/******************************************************************************* - * - * Filename: btif_sock.h - * - * Description: Bluetooth socket Interface - * - *******************************************************************************/ - -#ifndef BTIF_SOCK_H -#define BTIF_SOCK_H +#pragma once #include -bt_status_t btif_sock_init(); -btsock_interface_t *btif_sock_get_interface(); -void btif_sock_cleanup(); +btsock_interface_t *btif_sock_get_interface(void); -#endif +bt_status_t btif_sock_init(void); +void btif_sock_cleanup(void); diff --git a/btif/src/btif_sock.c b/btif/src/btif_sock.c index a1e57fa2a..624897db1 100644 --- a/btif/src/btif_sock.c +++ b/btif/src/btif_sock.c @@ -1,6 +1,6 @@ /****************************************************************************** * - * Copyright (C) 2009-2012 Broadcom Corporation + * Copyright (C) 2014 Google, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,163 +16,138 @@ * ******************************************************************************/ +#define LOG_TAG "btif_sock" -/************************************************************************************ - * - * Filename: btif_sock.c - * - * Description: Bluetooth Socket Interface - * - * - ***********************************************************************************/ - +#include #include #include -#define LOG_TAG "BTIF_SOCK" -#include "btif_common.h" -#include "btif_util.h" - #include "bd.h" - #include "bta_api.h" -#include "btif_sock_thread.h" +#include "btif_common.h" #include "btif_sock_rfc.h" #include "btif_sock_sco.h" +#include "btif_sock_thread.h" +#include "btif_util.h" +#include "osi.h" -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); -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); +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); +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); static void btsock_signaled(int fd, int type, int flags, uint32_t user_id); -/******************************************************************************* -** -** Function btsock_ini -** -** Description initializes the bt socket interface -** -** Returns bt_status_t -** -*******************************************************************************/ -static btsock_interface_t sock_if = { - sizeof(sock_if), - btsock_listen, - btsock_connect - }; -btsock_interface_t *btif_sock_get_interface() -{ - return &sock_if; +static int thread_handle = -1; + +btsock_interface_t *btif_sock_get_interface(void) { + static btsock_interface_t interface = { + sizeof(interface), + btsock_listen, + btsock_connect + }; + + return &interface; } -bt_status_t btif_sock_init() -{ - static volatile int binit; - if(!binit) - { - //fix me, the process doesn't exit right now. don't set the init flag for now - //binit = 1; - BTIF_TRACE_DEBUG("btsock initializing..."); - btsock_thread_init(); - int handle = btsock_thread_create(btsock_signaled, NULL); - if(handle >= 0) - { - if (btsock_rfc_init(handle) == BT_STATUS_SUCCESS) - { - if (btsock_sco_init(handle) == BT_STATUS_SUCCESS) - { - BTIF_TRACE_DEBUG("btsock successfully initialized"); - return BT_STATUS_SUCCESS; - } - // failure - btsock_rfc_cleanup(); - } - } - } - else BTIF_TRACE_ERROR("btsock interface already initialized"); + +bt_status_t btif_sock_init(void) { + assert(thread_handle == -1); + + btsock_thread_init(); + thread_handle = btsock_thread_create(btsock_signaled, NULL); + if (thread_handle == -1) { + ALOGE("%s unable to create btsock_thread.", __func__); return BT_STATUS_FAIL; -} -void btif_sock_cleanup() -{ + } + + bt_status_t status = btsock_rfc_init(thread_handle); + if (status != BT_STATUS_SUCCESS) { + ALOGE("%s error initializing RFCOMM sockets: %d", __func__, status); + btsock_thread_exit(thread_handle); + thread_handle = -1; + return BT_STATUS_FAIL; + } + + status = btsock_sco_init(thread_handle); + if (status != BT_STATUS_SUCCESS) { + btsock_thread_exit(thread_handle); + thread_handle = -1; btsock_rfc_cleanup(); - btsock_sco_cleanup(); - BTIF_TRACE_DEBUG("leaving"); + return BT_STATUS_FAIL; + } + + return BT_STATUS_SUCCESS; } -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) -{ - if((service_uuid == NULL && channel <= 0) || sock_fd == NULL) - { - BTIF_TRACE_ERROR("invalid parameters, uuid:%p, channel:%d, sock_fd:%p", service_uuid, channel, sock_fd); - return BT_STATUS_PARM_INVALID; - } - *sock_fd = -1; - bt_status_t status = BT_STATUS_FAIL; - switch(type) - { - case BTSOCK_RFCOMM: - status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags); - break; - case BTSOCK_L2CAP: - BTIF_TRACE_ERROR("bt l2cap socket type not supported, type:%d", type); - status = BT_STATUS_UNSUPPORTED; - break; - case BTSOCK_SCO: - status = btsock_sco_listen(sock_fd, flags); - break; - default: - BTIF_TRACE_ERROR("unknown bt socket type:%d", type); - status = BT_STATUS_UNSUPPORTED; - break; - } - return status; +void btif_sock_cleanup(void) { + if (thread_handle == -1) + return; + + btsock_thread_exit(thread_handle); + btsock_rfc_cleanup(); + btsock_sco_cleanup(); + thread_handle = -1; } -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) -{ - if((uuid == NULL && channel <= 0) || bd_addr == NULL || sock_fd == NULL) - { - BTIF_TRACE_ERROR("invalid parameters, bd_addr:%p, uuid:%p, channel:%d, sock_fd:%p", - bd_addr, uuid, channel, sock_fd); - return BT_STATUS_PARM_INVALID; - } - *sock_fd = -1; - bt_status_t status = BT_STATUS_FAIL; - switch(type) - { - case BTSOCK_RFCOMM: - status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags); - break; - case BTSOCK_L2CAP: - BTIF_TRACE_ERROR("bt l2cap socket type not supported, type:%d", type); - status = BT_STATUS_UNSUPPORTED; - break; - case BTSOCK_SCO: - status = btsock_sco_connect(bd_addr, sock_fd, flags); - break; - default: - BTIF_TRACE_ERROR("unknown bt socket type:%d", type); - status = BT_STATUS_UNSUPPORTED; - break; - } - return status; + +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) { + assert(service_uuid != NULL || channel > 0); + assert(sock_fd != NULL); + + *sock_fd = INVALID_FD; + bt_status_t status = BT_STATUS_FAIL; + + switch (type) { + case BTSOCK_RFCOMM: + status = btsock_rfc_listen(service_name, service_uuid, channel, sock_fd, flags); + break; + + case BTSOCK_SCO: + status = btsock_sco_listen(sock_fd, flags); + break; + + default: + ALOGE("%s unknown/unsupported socket type: %d", __func__, type); + status = BT_STATUS_UNSUPPORTED; + break; + } + return status; } -static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) -{ - switch(type) - { - case BTSOCK_RFCOMM: - btsock_rfc_signaled(fd, flags, user_id); - break; - case BTSOCK_L2CAP: - BTIF_TRACE_ERROR("bt l2cap socket type not supported, fd:%d, flags:%d", fd, flags); - break; - case BTSOCK_SCO: - btsock_sco_signaled(fd, flags, user_id); - break; - default: - BTIF_TRACE_ERROR("unknown socket type:%d, fd:%d, flags:%d", type, fd, flags); - break; - } + +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) { + assert(uuid != NULL || channel > 0); + assert(bd_addr != NULL); + assert(sock_fd != NULL); + + *sock_fd = INVALID_FD; + bt_status_t status = BT_STATUS_FAIL; + + switch (type) { + case BTSOCK_RFCOMM: + status = btsock_rfc_connect(bd_addr, uuid, channel, sock_fd, flags); + break; + + case BTSOCK_SCO: + status = btsock_sco_connect(bd_addr, sock_fd, flags); + break; + + default: + ALOGE("%s unknown/unsupported socket type: %d", __func__, type); + status = BT_STATUS_UNSUPPORTED; + break; + } + return status; +} + +static void btsock_signaled(int fd, int type, int flags, uint32_t user_id) { + switch (type) { + case BTSOCK_RFCOMM: + btsock_rfc_signaled(fd, flags, user_id); + break; + + case BTSOCK_SCO: + btsock_sco_signaled(fd, flags, user_id); + break; + + default: + assert(false && "Invalid socket type"); + break; + } } -- 2.11.0