15738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 25738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 35738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Copyright (C) 2009-2012 Broadcom Corporation 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 195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Filename: bt_hci_bdroid.c 225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * Description: Bluedroid Bluetooth Host/Controller interface library 245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * implementation 255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project * 265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ******************************************************************************/ 275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define LOG_TAG "bt_hci_bdroid" 295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 30c4e0e049e27622f01e93a4ac6beaec60d72d2364Sharvil Nanavati#include <assert.h> 315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include <utils/Log.h> 32dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 33dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#include "btsnoop.h" 345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_hci_bdroid.h" 35dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#include "bt_utils.h" 365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "bt_vendor_lib.h" 375738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "hci.h" 38dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#include "osi.h" 39dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#include "thread.h" 405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#include "userial.h" 41dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#include "utils.h" 42f3b23f231a39176ea371c4da717e084b3d7cc15aSharvil Nanavati#include "vendor.h" 435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifndef BTHC_DBG 455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define BTHC_DBG FALSE 465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#if (BTHC_DBG == TRUE) 495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define BTHCDBG(param, ...) {ALOGD(param, ## __VA_ARGS__);} 505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#define BTHCDBG(param, ...) {} 525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao/* Vendor epilog process timeout period */ 55dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic const uint32_t EPILOG_TIMEOUT_MS = 3000; 5667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Externs 595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 605738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 615738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectextern int num_hci_cmd_pkts; 625738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_init(void); 635738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_cleanup(void); 645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_enable(uint8_t turn_on); 655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_wake_deassert(void); 665738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_allow_bt_device_sleep(void); 675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid lpm_wake_assert(void); 685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectvoid init_vnd_if(unsigned char *local_bdaddr); 695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Variables 725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectbt_hc_callbacks_t *bt_hc_cbacks = NULL; 755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source ProjecttHCI_IF *p_hci_if; 76dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavativolatile bool fwcfg_acked; 776c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton// Cleanup state indication. 786c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Mantonvolatile bool has_cleaned_up = false; 795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Local type definitions 825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/* Host/Controller lib thread control block */ 855738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projecttypedef struct 865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 87dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_t *worker_thread; 887be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_t worker_thread_lock; 89dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati bool epilog_timer_created; 9067e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao timer_t epilog_timer_id; 915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} bt_hc_cb_t; 925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Static Variables 955738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic bt_hc_cb_t hc_cb; 98dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic bool tx_cmd_pkts_pending = false; 99dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic BUFFER_Q tx_q; 1005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 1015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/****************************************************************************** 1025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Functions 1035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project******************************************************************************/ 1045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 105dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_preload(UNUSED_ATTR void *context) { 106dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati userial_open(USERIAL_PORT_1); 107dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati vendor_send_command(BT_VND_OP_FW_CFG, NULL); 108dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 109dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 110dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_postload(UNUSED_ATTR void *context) { 111dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati /* Start from SCO related H/W configuration, if SCO configuration 112dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * is required. Then, follow with reading requests of getting 113dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * ACL data length for both BR/EDR and LE. 114dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati */ 115dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati int result = vendor_send_command(BT_VND_OP_SCO_CFG, NULL); 116dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (result == -1) 117dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati p_hci_if->get_acl_max_len(); 118dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 1193f9fbe74c1d6e774d3f21275515c7b895715aec5Sharvil Nanavati 120dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_tx(UNUSED_ATTR void *context) { 121dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati /* 122dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * We will go through every packets in the tx queue. 123dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * Fine to clear tx_cmd_pkts_pending. 124dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati */ 125dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati tx_cmd_pkts_pending = false; 126dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati HC_BT_HDR *sending_msg_que[64]; 127dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati size_t sending_msg_count = 0; 128dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati int sending_hci_cmd_pkts_count = 0; 129dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati utils_lock(); 130dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati HC_BT_HDR *p_next_msg = tx_q.p_first; 131dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati while (p_next_msg && sending_msg_count < ARRAY_SIZE(sending_msg_que)) 132dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati { 133dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if ((p_next_msg->event & MSG_EVT_MASK)==MSG_STACK_TO_HC_HCI_CMD) 134dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati { 135dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati /* 136dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * if we have used up controller's outstanding HCI command 137dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * credits (normally is 1), skip all HCI command packets in 138dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * the queue. 139dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * The pending command packets will be sent once controller 140dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * gives back us credits through CommandCompleteEvent or 141dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati * CommandStatusEvent. 142dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati */ 143dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (tx_cmd_pkts_pending || 144dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati (sending_hci_cmd_pkts_count >= num_hci_cmd_pkts)) 145dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati { 146dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati tx_cmd_pkts_pending = true; 147dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati p_next_msg = utils_getnext(p_next_msg); 148dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati continue; 149dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati } 150dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati sending_hci_cmd_pkts_count++; 151dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati } 152dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 153dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati HC_BT_HDR *p_msg = p_next_msg; 154dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati p_next_msg = utils_getnext(p_msg); 155dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati utils_remove_from_queue_unlocked(&tx_q, p_msg); 156dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati sending_msg_que[sending_msg_count++] = p_msg; 157dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati } 158dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati utils_unlock(); 159dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati for(size_t i = 0; i < sending_msg_count; i++) 160dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati p_hci_if->send(sending_msg_que[i]); 161dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (tx_cmd_pkts_pending) 162dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati BTHCDBG("Used up Tx Cmd credits"); 163dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 164dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 165dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_rx(UNUSED_ATTR void *context) { 166dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#ifndef HCI_USE_MCT 167dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati p_hci_if->rcv(); 168dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 169dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (tx_cmd_pkts_pending && num_hci_cmd_pkts > 0) { 170dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati // Got HCI Cmd credits from controller. Send whatever data 171dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati // we have in our tx queue. We can call |event_tx| directly 172dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati // here since we're already on the worker thread. 173dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati event_tx(NULL); 174dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati } 175dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati#endif 176dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 177dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 178dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_lpm_enable(UNUSED_ATTR void *context) { 179dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati lpm_enable(true); 180dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 181dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 182dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_lpm_disable(UNUSED_ATTR void *context) { 183dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati lpm_enable(false); 184dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 185dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 186dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_lpm_wake_device(UNUSED_ATTR void *context) { 187dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati lpm_wake_assert(); 188dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 189dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 190dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_lpm_allow_sleep(UNUSED_ATTR void *context) { 191dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati lpm_allow_bt_device_sleep(); 192dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 193dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 194dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_lpm_idle_timeout(UNUSED_ATTR void *context) { 195dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati lpm_wake_deassert(); 196dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 197dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 198dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_epilog(UNUSED_ATTR void *context) { 199dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati vendor_send_command(BT_VND_OP_EPILOG, NULL); 200dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 201dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 202dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void event_tx_cmd(void *msg) { 203dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati HC_BT_HDR *p_msg = (HC_BT_HDR *)msg; 204dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 205dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati BTHCDBG("%s: p_msg: %p, event: 0x%x", __func__, p_msg, p_msg->event); 206dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 207dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati int event = p_msg->event & MSG_EVT_MASK; 208dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati int sub_event = p_msg->event & MSG_SUB_EVT_MASK; 209dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (event == MSG_CTRL_TO_HC_CMD && sub_event == BT_HC_AUDIO_STATE) { 210dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati vendor_send_command(BT_VND_OP_SET_AUDIO_STATE, p_msg->data); 211dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati } else { 212dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati ALOGW("%s (event: 0x%x, sub_event: 0x%x) not supported", __func__, event, sub_event); 213dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati } 214dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 215dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati bt_hc_cbacks->dealloc(msg); 216dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 217dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 218dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavativoid bthc_rx_ready(void) { 2197be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_lock(&hc_cb.worker_thread_lock); 2207be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2217be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati if (hc_cb.worker_thread) 2227be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati thread_post(hc_cb.worker_thread, event_rx, NULL); 2237be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2247be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_unlock(&hc_cb.worker_thread_lock); 225dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 226dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 227dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavativoid bthc_tx(HC_BT_HDR *buf) { 2287be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_lock(&hc_cb.worker_thread_lock); 2297be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2307be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati if (hc_cb.worker_thread) { 2317be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati if (buf) 2327be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati utils_enqueue(&tx_q, buf); 2337be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati thread_post(hc_cb.worker_thread, event_tx, NULL); 2347be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati } 2357be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2367be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_unlock(&hc_cb.worker_thread_lock); 237dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati} 238dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati 239dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavativoid bthc_idle_timeout(void) { 2407be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_lock(&hc_cb.worker_thread_lock); 2417be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2427be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati if (hc_cb.worker_thread) 2437be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati thread_post(hc_cb.worker_thread, event_lpm_idle_timeout, NULL); 2447be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2457be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_unlock(&hc_cb.worker_thread_lock); 2465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 2475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 24867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao/******************************************************************************* 24967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 25067e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** Function epilog_wait_timeout 25167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 25267e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** Description Timeout thread of epilog watchdog timer 25367e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 25467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** Returns None 25567e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 25667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao*******************************************************************************/ 257dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void epilog_wait_timeout(UNUSED_ATTR union sigval arg) 25867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao{ 25967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ALOGI("...epilog_wait_timeout..."); 2607be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 261dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_free(hc_cb.worker_thread); 2627be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 2637be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_lock(&hc_cb.worker_thread_lock); 264dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.worker_thread = NULL; 2657be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_unlock(&hc_cb.worker_thread_lock); 26667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao} 26767e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 26867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao/******************************************************************************* 26967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 27067e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** Function epilog_wait_timer 27167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 27267e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** Description Launch epilog watchdog timer 27367e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 27467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** Returns None 27567e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao** 27667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao*******************************************************************************/ 27767e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chaostatic void epilog_wait_timer(void) 27867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao{ 27967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao int status; 28067e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao struct itimerspec ts; 28167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao struct sigevent se; 28267e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao uint32_t timeout_ms = EPILOG_TIMEOUT_MS; 28367e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 28467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao se.sigev_notify = SIGEV_THREAD; 28567e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao se.sigev_value.sival_ptr = &hc_cb.epilog_timer_id; 28667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao se.sigev_notify_function = epilog_wait_timeout; 28767e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao se.sigev_notify_attributes = NULL; 28867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 28967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao status = timer_create(CLOCK_MONOTONIC, &se, &hc_cb.epilog_timer_id); 29067e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 29167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao if (status == 0) 29267e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao { 293dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.epilog_timer_created = true; 29467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ts.it_value.tv_sec = timeout_ms/1000; 29567e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ts.it_value.tv_nsec = 1000000*(timeout_ms%1000); 29667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ts.it_interval.tv_sec = 0; 29767e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ts.it_interval.tv_nsec = 0; 29867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 29967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao status = timer_settime(hc_cb.epilog_timer_id, 0, &ts, 0); 30067e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao if (status == -1) 30167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ALOGE("Failed to fire epilog watchdog timer"); 30267e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao } 30367e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao else 30467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao { 30567e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao ALOGE("Failed to create epilog watchdog timer"); 306dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.epilog_timer_created = false; 30767e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao } 30867e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao} 30967e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 3105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/***************************************************************************** 3115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** BLUETOOTH HOST/CONTROLLER INTERFACE LIBRARY FUNCTIONS 3135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 3145738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*****************************************************************************/ 3155738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int init(const bt_hc_callbacks_t* p_cb, unsigned char *local_bdaddr) 3175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 318dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati int result; 3195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGI("init"); 3215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project if (p_cb == NULL) 3235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGE("init failed with no user callbacks!"); 3255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return BT_HC_STATUS_FAIL; 3265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 328dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.epilog_timer_created = false; 329dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati fwcfg_acked = false; 3306c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton has_cleaned_up = false; 33167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 3327be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_init(&hc_cb.worker_thread_lock, NULL); 3337be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 3345738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* store reference to user callbacks */ 3355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks = (bt_hc_callbacks_t *) p_cb; 3365738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 337f3b23f231a39176ea371c4da717e084b3d7cc15aSharvil Nanavati vendor_open(local_bdaddr); 3385738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3395738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_init(); 3405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#ifdef HCI_USE_MCT 3415738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project extern tHCI_IF hci_mct_func_table; 3425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_hci_if = &hci_mct_func_table; 3435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#else 3445738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project extern tHCI_IF hci_h4_func_table; 3455738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_hci_if = &hci_h4_func_table; 3465738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project#endif 3475738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3485738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_hci_if->init(); 3495738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3505738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_init(); 3515738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lpm_init(); 3525738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3535738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_queue_init(&tx_q); 3545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 355dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (hc_cb.worker_thread) 3565738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3575738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project ALOGW("init has been called repeatedly without calling cleanup ?"); 3585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3595738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3603eae42f2a383adaaf83336dc4c92afd2de2c4112Mattias Agren // Set prio here and let hci worker thread inherit prio 3613eae42f2a383adaaf83336dc4c92afd2de2c4112Mattias Agren // remove once new thread api (thread_set_priority() ?) 3623eae42f2a383adaaf83336dc4c92afd2de2c4112Mattias Agren // can switch prio 3633eae42f2a383adaaf83336dc4c92afd2de2c4112Mattias Agren raise_priority_a2dp(TASK_HIGH_HCI_WORKER); 3643eae42f2a383adaaf83336dc4c92afd2de2c4112Mattias Agren 365dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.worker_thread = thread_new("bt_hc_worker"); 366dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (!hc_cb.worker_thread) { 367dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati ALOGE("%s unable to create worker thread.", __func__); 3685738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return BT_HC_STATUS_FAIL; 3695738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 3705738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3715738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return BT_HC_STATUS_SUCCESS; 3725738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3735738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3745738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3755738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/** Chip power control */ 3765738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic void set_power(bt_hc_chip_power_state_t state) 3775738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3785738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project int pwr_state; 3795738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3805738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BTHCDBG("set_power %d", state); 3815738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3825738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project /* Calling vendor-specific part */ 3835738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project pwr_state = (state == BT_HC_CHIP_PWR_ON) ? BT_VND_PWR_ON : BT_VND_PWR_OFF; 3845738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 385f3b23f231a39176ea371c4da717e084b3d7cc15aSharvil Nanavati vendor_send_command(BT_VND_OP_POWER_CTRL, &pwr_state); 3865738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 3875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3885738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/** Configure low power mode wake state */ 3905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic int lpm(bt_hc_low_power_event_t event) 3915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 3925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project switch (event) 3935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 3945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case BT_HC_LPM_DISABLE: 395dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_lpm_disable, NULL); 3965738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 3975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 3985738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case BT_HC_LPM_ENABLE: 399dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_lpm_enable, NULL); 4005738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4025738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case BT_HC_LPM_WAKE_ASSERT: 403dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_lpm_wake_device, NULL); 4045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project case BT_HC_LPM_WAKE_DEASSERT: 407dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_lpm_allow_sleep, NULL); 4085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project break; 4095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 410dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati return BT_HC_STATUS_SUCCESS; 4115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4145cd8bff2dd0337cb52bf48f312e3d2d55a8882fbMike J. Chen/** Called prior to stack initialization */ 415dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void preload(UNUSED_ATTR TRANSAC transac) { 416dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati BTHCDBG("preload"); 417dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_preload, NULL); 4185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/** Called post stack initialization */ 421dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic void postload(UNUSED_ATTR TRANSAC transac) { 422dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati BTHCDBG("postload"); 423dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_postload, NULL); 4245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/** Transmit frame */ 427dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic int transmit_buf(TRANSAC transac, UNUSED_ATTR char *p_buf, UNUSED_ATTR int len) { 428dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati bthc_tx((HC_BT_HDR *)transac); 429dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati return BT_HC_STATUS_SUCCESS; 4305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4315738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4325738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/** Controls HCI logging on/off */ 433311e88dd46311534c6fd1a25ec9c5c1da6d55dedAndre Eisenbachstatic int logging(bt_hc_logging_state_t state, char *p_path, bool save_existing) { 434dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati BTHCDBG("logging %d", state); 4355738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 436dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (state != BT_HC_LOGGING_ON) 437dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati btsnoop_close(); 438dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati else if (p_path != NULL) 439311e88dd46311534c6fd1a25ec9c5c1da6d55dedAndre Eisenbach btsnoop_open(p_path, save_existing); 4405738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 441dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati return BT_HC_STATUS_SUCCESS; 4425738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 4435738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 44466432dcffe211e317d35978283a04a96d5620bdfMatthew Xie/** sends command HC controller to configure platform specific behaviour */ 445dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavatistatic int tx_hc_cmd(TRANSAC transac, char *p_buf, int len) { 446dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati BTHCDBG("tx_hc_cmd: transac %p", transac); 447dd29f036a8cde94b3c296fb08ee3e9b2d65c15e0Svetoslav Ganov 448dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (!transac) 449dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati return BT_HC_STATUS_FAIL; 45066432dcffe211e317d35978283a04a96d5620bdfMatthew Xie 451dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_tx_cmd, transac); 452dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati return BT_HC_STATUS_SUCCESS; 45366432dcffe211e317d35978283a04a96d5620bdfMatthew Xie} 4545738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4556c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton// Closes the interface. 4566c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton// This routine is not thread safe. 4576c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Mantonstatic void cleanup(void) 4585738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 4596c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton if (has_cleaned_up) { 4606c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton ALOGW("%s Already cleaned up for this session\n", __func__); 4616c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton return; 4626c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton } 4636c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton 4645738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project BTHCDBG("cleanup"); 4655738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 466dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (hc_cb.worker_thread) 4675738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project { 468dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (fwcfg_acked) 46948ebe2c6928d8fd4dc97c8adb138c3440714dc89YK Jeffrey Chao { 47048ebe2c6928d8fd4dc97c8adb138c3440714dc89YK Jeffrey Chao epilog_wait_timer(); 47111aa94d9988464aae233fae303f614ca48fcc834Chris Manton // Stop reading thread 47211aa94d9988464aae233fae303f614ca48fcc834Chris Manton userial_close_reader(); 47311aa94d9988464aae233fae303f614ca48fcc834Chris Manton 474dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_post(hc_cb.worker_thread, event_epilog, NULL); 47548ebe2c6928d8fd4dc97c8adb138c3440714dc89YK Jeffrey Chao } 476dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati thread_free(hc_cb.worker_thread); 4777be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 4787be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_lock(&hc_cb.worker_thread_lock); 479dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.worker_thread = NULL; 4807be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_unlock(&hc_cb.worker_thread_lock); 48167e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao 482dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati if (hc_cb.epilog_timer_created) 48367e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao { 48467e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao timer_delete(hc_cb.epilog_timer_id); 485dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati hc_cb.epilog_timer_created = false; 48667e4077c23bb9cc045885ae01cc83b38faecb71bYK Jeffrey Chao } 4875738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project } 48811aa94d9988464aae233fae303f614ca48fcc834Chris Manton BTHCDBG("%s Finalizing cleanup\n", __func__); 4895738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4905738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lpm_cleanup(); 4915738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project userial_close(); 4925738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project p_hci_if->cleanup(); 4935738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project utils_cleanup(); 4945738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 495f3b23f231a39176ea371c4da717e084b3d7cc15aSharvil Nanavati set_power(BT_VND_PWR_OFF); 496f3b23f231a39176ea371c4da717e084b3d7cc15aSharvil Nanavati vendor_close(); 4975738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 4987be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati pthread_mutex_destroy(&hc_cb.worker_thread_lock); 4997be309d0bd3296b37f2a16bf7cf8323f2658b3bdSharvil Nanavati 500dd28edb310906c63ba4535ccd02f3ca4d496f021Sharvil Nanavati fwcfg_acked = false; 5015738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project bt_hc_cbacks = NULL; 5026c25e796a4d661ef76e9b6af253bbbfbae46a344Chris Manton has_cleaned_up = true; 5035738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 5045738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5055738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectstatic const bt_hc_interface_t bluetoothHCLibInterface = { 5065738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project sizeof(bt_hc_interface_t), 5075738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project init, 5085738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project set_power, 5095738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project lpm, 5105738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project preload, 5115738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project postload, 5125738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project transmit_buf, 5135738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project logging, 51466432dcffe211e317d35978283a04a96d5620bdfMatthew Xie cleanup, 51566432dcffe211e317d35978283a04a96d5620bdfMatthew Xie tx_hc_cmd, 5165738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project}; 5175738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project 5185738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project/******************************************************************************* 5195738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5205738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Function bt_hc_get_interface 5215738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5225738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Description Caller calls this function to get API instance 5235738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5245738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** Returns API table 5255738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project** 5265738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project*******************************************************************************/ 5275738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Projectconst bt_hc_interface_t *bt_hc_get_interface(void) 5285738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project{ 5295738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project return &bluetoothHCLibInterface; 5305738f83aeb59361a0a2eda2460113f6dc919427The Android Open Source Project} 531