1/****************************************************************************** 2 * 3 * Copyright (C) 1998-2012 Broadcom Corporation 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/****************************************************************************** 20 * 21 * This file contains the HeaLth device profile main functions and state 22 * machine. 23 * 24 ******************************************************************************/ 25#include <string.h> 26 27#include "bt_target.h" 28#if defined(HL_INCLUDED) && (HL_INCLUDED == TRUE) 29 30 31 32#include "bta_hl_api.h" 33#include "bta_hl_int.h" 34#include "gki.h" 35#include "utl.h" 36#include "bd.h" 37#include "l2c_api.h" 38#include "mca_defs.h" 39 40 41#if (BTA_HL_DEBUG == TRUE) && (BT_USE_TRACES == TRUE) 42static char *bta_hl_cch_state_code(tBTA_HL_CCH_STATE state_code); 43static char *bta_hl_dch_state_code(tBTA_HL_DCH_STATE state_code); 44#endif 45 46extern UINT16 L2CA_AllocateRandomPsm(void); 47extern UINT16 L2CA_AllocatePsm(void); 48/***************************************************************************** 49** DCH State Table 50*****************************************************************************/ 51/***************************************************************************** 52** Constants and types 53*****************************************************************************/ 54/* state machine action enumeration list for DCH */ 55/* The order of this enumeration must be the same as bta_hl_dch_act_tbl[] */ 56enum 57{ 58 BTA_HL_DCH_MCA_CREATE, 59 BTA_HL_DCH_MCA_CREATE_CFM, 60 BTA_HL_DCH_MCA_CREATE_IND, 61 BTA_HL_DCH_MCA_OPEN_CFM, 62 BTA_HL_DCH_MCA_OPEN_IND, 63 BTA_HL_DCH_MCA_CLOSE, 64 BTA_HL_DCH_MCA_CLOSE_CFM, 65 BTA_HL_DCH_MCA_CLOSE_IND, 66 BTA_HL_DCH_CLOSE_CMPL, 67 BTA_HL_DCH_MCA_RCV_DATA, 68 69 BTA_HL_DCH_SDP_INIT, 70 BTA_HL_DCH_MCA_RECONNECT, 71 BTA_HL_DCH_MCA_RECONNECT_IND, 72 BTA_HL_DCH_MCA_RECONNECT_CFM, 73 BTA_HL_DCH_CLOSE_ECHO_TEST, 74 BTA_HL_DCH_CREATE_RSP, 75 BTA_HL_DCH_MCA_ABORT, 76 BTA_HL_DCH_MCA_ABORT_IND, 77 BTA_HL_DCH_MCA_ABORT_CFM, 78 BTA_HL_DCH_MCA_CONG_CHANGE, 79 80 BTA_HL_DCH_SDP_FAIL, 81 BTA_HL_DCH_SEND_DATA, 82 BTA_HL_DCH_CI_GET_TX_DATA, 83 BTA_HL_DCH_CI_PUT_RX_DATA, 84 BTA_HL_DCH_CI_GET_ECHO_DATA, 85 BTA_HL_DCH_ECHO_TEST, 86 BTA_HL_DCH_CI_PUT_ECHO_DATA, 87 BTA_HL_DCH_IGNORE 88}; 89 90typedef void (*tBTA_HL_DCH_ACTION)(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx, tBTA_HL_DATA *p_data); 91 92static const tBTA_HL_DCH_ACTION bta_hl_dch_action[] = 93{ 94 bta_hl_dch_mca_create, 95 bta_hl_dch_mca_create_cfm, 96 bta_hl_dch_mca_create_ind, 97 bta_hl_dch_mca_open_cfm, 98 bta_hl_dch_mca_open_ind, 99 bta_hl_dch_mca_close, 100 bta_hl_dch_mca_close_cfm, 101 bta_hl_dch_mca_close_ind, 102 bta_hl_dch_close_cmpl, 103 bta_hl_dch_mca_rcv_data, 104 105 bta_hl_dch_sdp_init, 106 bta_hl_dch_mca_reconnect, 107 bta_hl_dch_mca_reconnect_ind, 108 bta_hl_dch_mca_reconnect_cfm, 109 bta_hl_dch_close_echo_test, 110 bta_hl_dch_create_rsp, 111 bta_hl_dch_mca_abort, 112 bta_hl_dch_mca_abort_ind, 113 bta_hl_dch_mca_abort_cfm, 114 bta_hl_dch_mca_cong_change, 115 116 bta_hl_dch_sdp_fail, 117 bta_hl_dch_send_data, 118 bta_hl_dch_ci_get_tx_data, 119 bta_hl_dch_ci_put_rx_data, 120 bta_hl_dch_ci_get_echo_data, 121 bta_hl_dch_echo_test, 122 bta_hl_dch_ci_put_echo_data, 123}; 124 125 126/* state table information */ 127#define BTA_HL_DCH_ACTIONS 1 /* number of actions */ 128#define BTA_HL_DCH_ACTION_COL 0 /* position of action */ 129#define BTA_HL_DCH_NEXT_STATE 1 /* position of next state */ 130#define BTA_HL_DCH_NUM_COLS 2 /* number of columns in state tables */ 131 132/* state table for idle state */ 133static const UINT8 bta_hl_dch_st_idle[][BTA_HL_DCH_NUM_COLS] = 134{ 135/* Event Action 1 Next state */ 136/* BTA_HL_DCH_SDP_INIT_EVT */ {BTA_HL_DCH_SDP_INIT, BTA_HL_DCH_OPENING_ST}, 137/* BTA_HL_DCH_OPEN_EVT */ {BTA_HL_DCH_MCA_CREATE, BTA_HL_DCH_OPENING_ST}, 138/* BTA_HL_MCA_CREATE_IND_EVT */ {BTA_HL_DCH_MCA_CREATE_IND, BTA_HL_DCH_OPENING_ST}, 139/* BTA_HL_MCA_CREATE_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 140/* BTA_HL_MCA_OPEN_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 141 142/* BTA_HL_MCA_OPEN_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 143/* BTA_HL_DCH_CLOSE_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 144/* BTA_HL_MCA_CLOSE_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 145/* BTA_HL_MCA_CLOSE_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 146/* BTA_HL_API_SEND_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 147 148/* BTA_HL_MCA_RCV_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 149/* BTA_HL_DCH_CLOSE_CMPL_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 150/* BTA_HL_DCH_RECONNECT_EVT */ {BTA_HL_DCH_MCA_RECONNECT, BTA_HL_DCH_OPENING_ST}, 151/* BTA_HL_DCH_SDP_FAIL_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 152/* BTA_HL_MCA_RECONNECT_IND_EVT*/ {BTA_HL_DCH_MCA_RECONNECT_IND, BTA_HL_DCH_OPENING_ST}, 153 154/* BTA_HL_MCA_RECONNECT_CFM_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 155/* BTA_HL_DCH_CLOSE_ECHO_TEST_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 156/* BTA_HL_API_DCH_CREATE_RSP_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 157/* BTA_HL_DCH_ABORT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 158/* BTA_HL_MCA_ABORT_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 159 160/* BTA_HL_MCA_ABORT_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 161/* BTA_HL_MCA_CONG_CHG_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 162/* BTA_HL_CI_GET_TX_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 163/* BTA_HL_CI_PUT_RX_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 164/* BTA_HL_CI_GET_ECHO_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 165/* BTA_HL_DCH_ECHO_TEST_EVT */ {BTA_HL_DCH_ECHO_TEST, BTA_HL_DCH_OPENING_ST}, 166/* BTA_HL_CI_PUT_ECHO_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST} 167}; 168 169/* state table for opening state */ 170static const UINT8 bta_hl_dch_st_opening[][BTA_HL_DCH_NUM_COLS] = 171{ 172/* Event Action 1 Next state */ 173/* BTA_HL_DCH_SDP_INIT_EVT */ {BTA_HL_DCH_SDP_INIT, BTA_HL_DCH_OPENING_ST}, 174/* BTA_HL_DCH_OPEN_EVT */ {BTA_HL_DCH_MCA_CREATE, BTA_HL_DCH_OPENING_ST}, 175/* BTA_HL_MCA_CREATE_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST}, 176/* BTA_HL_MCA_CREATE_CFM_EVT */ {BTA_HL_DCH_MCA_CREATE_CFM, BTA_HL_DCH_OPENING_ST}, 177/* BTA_HL_MCA_OPEN_IND_EVT */ {BTA_HL_DCH_MCA_OPEN_IND, BTA_HL_DCH_OPEN_ST}, 178/* BTA_HL_MCA_OPEN_CFM_EVT */ {BTA_HL_DCH_MCA_OPEN_CFM, BTA_HL_DCH_OPEN_ST}, 179/* BTA_HL_DCH_CLOSE_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST}, 180/* BTA_HL_MCA_CLOSE_IND_EVT */ {BTA_HL_DCH_MCA_CLOSE_IND, BTA_HL_DCH_CLOSING_ST}, 181/* BTA_HL_MCA_CLOSE_CFM_EVT */ {BTA_HL_DCH_MCA_CLOSE_CFM, BTA_HL_DCH_CLOSING_ST}, 182/* BTA_HL_API_SEND_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 183 184/* BTA_HL_MCA_RCV_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 185/* BTA_HL_DCH_CLOSE_CMPL_EVT */ {BTA_HL_DCH_CLOSE_CMPL, BTA_HL_DCH_IDLE_ST}, 186/* BTA_HL_DCH_RECONNECT_EVT */ {BTA_HL_DCH_MCA_RECONNECT, BTA_HL_DCH_OPENING_ST}, 187/* BTA_HL_DCH_SDP_FAIL_EVT */ {BTA_HL_DCH_SDP_FAIL, BTA_HL_DCH_CLOSING_ST}, 188/* BTA_HL_MCA_RECONNECT_IND_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_IDLE_ST}, 189/* BTA_HL_MCA_RECONNECT_CFM_EVT*/ {BTA_HL_DCH_MCA_RECONNECT_CFM, BTA_HL_DCH_OPENING_ST}, 190/* BTA_HL_DCH_CLOSE_ECHO_TEST_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST}, 191/* BTA_HL_API_DCH_CREATE_RSP_EVT */ {BTA_HL_DCH_CREATE_RSP, BTA_HL_DCH_OPENING_ST}, 192/* BTA_HL_DCH_ABORT_EVT */ {BTA_HL_DCH_MCA_ABORT, BTA_HL_DCH_OPENING_ST}, 193/* BTA_HL_MCA_ABORT_IND_EVT */ {BTA_HL_DCH_MCA_ABORT_IND, BTA_HL_DCH_OPENING_ST}, 194 195/* BTA_HL_MCA_ABORT_CFM_EVT */ {BTA_HL_DCH_MCA_ABORT_CFM, BTA_HL_DCH_OPENING_ST}, 196/* BTA_HL_MCA_CONG_CHG_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST}, 197/* BTA_HL_CI_GET_TX_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST}, 198/* BTA_HL_CI_PUT_RX_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST}, 199/* BTA_HL_CI_GET_ECHO_DATA_EVT */ {BTA_HL_DCH_CI_GET_ECHO_DATA, BTA_HL_DCH_OPENING_ST}, 200/* BTA_HL_DCH_ECHO_TEST_EVT */ {BTA_HL_DCH_ECHO_TEST, BTA_HL_DCH_OPENING_ST}, 201/* BTA_HL_CI_PUT_ECHO_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPENING_ST} 202}; 203 204/* state table for open state */ 205static const UINT8 bta_hl_dch_st_open[][BTA_HL_DCH_NUM_COLS] = 206{ 207/* Event Action 1 Next state */ 208/* BTA_HL_DCH_SDP_INIT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 209/* BTA_HL_DCH_OPEN_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 210/* BTA_HL_MCA_CREATE_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 211/* BTA_HL_MCA_CREATE_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 212/* BTA_HL_MCA_OPEN_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 213/* BTA_HL_MCA_OPEN_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 214/* BTA_HL_DCH_CLOSE_EVT */ {BTA_HL_DCH_MCA_CLOSE, BTA_HL_DCH_CLOSING_ST}, 215/* BTA_HL_MCA_CLOSE_IND_EVT */ {BTA_HL_DCH_MCA_CLOSE_IND, BTA_HL_DCH_CLOSING_ST}, 216/* BTA_HL_MCA_CLOSE_CFM_EVT */ {BTA_HL_DCH_MCA_CLOSE_CFM, BTA_HL_DCH_CLOSING_ST}, 217/* BTA_HL_API_SEND_DATA_EVT */ {BTA_HL_DCH_SEND_DATA, BTA_HL_DCH_OPEN_ST}, 218 219/* BTA_HL_MCA_RCV_DATA_EVT */ {BTA_HL_DCH_MCA_RCV_DATA, BTA_HL_DCH_OPEN_ST}, 220/* BTA_HL_DCH_CLOSE_CMPL_EVT */ {BTA_HL_DCH_CLOSE_CMPL, BTA_HL_DCH_IDLE_ST}, 221/* BTA_HL_DCH_RECONNECT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 222/* BTA_HL_DCH_SDP_FAIL_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 223/* BTA_HL_MCA_RECONNECT_IND_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 224/* BTA_HL_MCA_RECONNECT_CFM_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 225/* BTA_HL_DCH_CLOSE_ECHO_TEST_EVT*/ {BTA_HL_DCH_CLOSE_ECHO_TEST, BTA_HL_DCH_CLOSING_ST}, 226/* BTA_HL_API_DCH_CREATE_RSP_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 227/* BTA_HL_DCH_ABORT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 228/* BTA_HL_MCA_ABORT_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 229 230/* BTA_HL_DCH_ABORT_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 231/* BTA_HL_MCA_CONG_CHG_EVT */ {BTA_HL_DCH_MCA_CONG_CHANGE, BTA_HL_DCH_OPEN_ST}, 232/* BTA_HL_CI_GET_TX_DATA_EVT */ {BTA_HL_DCH_CI_GET_TX_DATA, BTA_HL_DCH_OPEN_ST}, 233/* BTA_HL_CI_PUT_RX_DATA_EVT */ {BTA_HL_DCH_CI_PUT_RX_DATA, BTA_HL_DCH_OPEN_ST}, 234/* BTA_HL_CI_GET_ECHO_DATA_EVT */ {BTA_HL_DCH_CI_GET_ECHO_DATA, BTA_HL_DCH_OPEN_ST}, 235/* BTA_HL_DCH_ECHO_TEST_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_OPEN_ST}, 236/* BTA_HL_CI_PUT_ECHO_DATA_EVT */ {BTA_HL_DCH_CI_PUT_ECHO_DATA, BTA_HL_DCH_OPEN_ST} 237}; 238 239 240/* state table for closing state */ 241static const UINT8 bta_hl_dch_st_closing[][BTA_HL_DCH_NUM_COLS] = 242{ 243/* Event Action 1 Next state */ 244/* BTA_HL_DCH_SDP_INIT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 245/* BTA_HL_DCH_OPEN_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 246/* BTA_HL_MCA_CREATE_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 247/* BTA_HL_MCA_CREATE_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 248/* BTA_HL_MCA_OPEN_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 249/* BTA_HL_MCA_OPEN_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 250/* BTA_HL_DCH_CLOSE_EVT */ {BTA_HL_DCH_MCA_CLOSE, BTA_HL_DCH_CLOSING_ST}, 251/* BTA_HL_MCA_CLOSE_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 252/* BTA_HL_MCA_CLOSE_CFM_EVT */ {BTA_HL_DCH_MCA_CLOSE_CFM, BTA_HL_DCH_CLOSING_ST}, 253/* BTA_HL_API_SEND_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 254 255/* BTA_HL_MCA_RCV_DATA_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 256/* BTA_HL_DCH_CLOSE_CMPL_EVT */ {BTA_HL_DCH_CLOSE_CMPL, BTA_HL_DCH_IDLE_ST}, 257/* BTA_HL_DCH_RECONNECT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 258/* BTA_HL_DCH_SDP_FAIL_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 259/* BTA_HL_MCA_RECONNECT_IND_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 260/* BTA_HL_MCA_RECONNECT_CFM_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 261/* BTA_HL_DCH_CLOSE_ECHO_TEST_EVT*/ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 262/* BTA_HL_API_DCH_CREATE_RSP_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 263/* BTA_HL_DCH_ABORT_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 264/* BTA_HL_MCA_ABORT_IND_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 265 266/* BTA_HL_DCH_ABORT_CFM_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 267/* BTA_HL_MCA_CONG_CHG_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 268/* BTA_HL_CI_GET_TX_DATA_EVT */ {BTA_HL_DCH_CI_GET_TX_DATA, BTA_HL_DCH_CLOSING_ST}, 269/* BTA_HL_CI_PUT_RX_DATA_EVT */ {BTA_HL_DCH_CI_PUT_RX_DATA, BTA_HL_DCH_CLOSING_ST}, 270/* BTA_HL_CI_GET_ECHO_DATA_EVT */ {BTA_HL_DCH_CI_GET_ECHO_DATA, BTA_HL_DCH_CLOSING_ST}, 271/* BTA_HL_DCH_ECHO_TEST_EVT */ {BTA_HL_DCH_IGNORE, BTA_HL_DCH_CLOSING_ST}, 272/* BTA_HL_CI_PUT_ECHO_DATA_EVT */ {BTA_HL_DCH_CI_PUT_ECHO_DATA, BTA_HL_DCH_CLOSING_ST} 273}; 274 275/* type for state table */ 276typedef const UINT8 (*tBTA_HL_DCH_ST_TBL)[BTA_HL_DCH_NUM_COLS]; 277 278/* state table */ 279const tBTA_HL_DCH_ST_TBL bta_hl_dch_st_tbl[] = 280{ 281 bta_hl_dch_st_idle, 282 bta_hl_dch_st_opening, 283 bta_hl_dch_st_open, 284 bta_hl_dch_st_closing 285}; 286 287/***************************************************************************** 288** CCH State Table 289*****************************************************************************/ 290/***************************************************************************** 291** Constants and types 292*****************************************************************************/ 293/* state machine action enumeration list for CCH */ 294enum 295{ 296 BTA_HL_CCH_SDP_INIT, 297 BTA_HL_CCH_MCA_OPEN, 298 BTA_HL_CCH_MCA_CLOSE, 299 BTA_HL_CCH_CLOSE_CMPL, 300 BTA_HL_CCH_MCA_CONNECT, 301 BTA_HL_CCH_MCA_DISCONNECT, 302 BTA_HL_CCH_MCA_RSP_TOUT, 303 BTA_HL_CCH_IGNORE 304}; 305 306/* type for action functions */ 307typedef void (*tBTA_HL_CCH_ACTION)(UINT8 app_idx, UINT8 mcl_idx, tBTA_HL_DATA *p_data); 308 309/* action function list for MAS */ 310const tBTA_HL_CCH_ACTION bta_hl_cch_action[] = 311{ 312 bta_hl_cch_sdp_init, 313 bta_hl_cch_mca_open, 314 bta_hl_cch_mca_close, 315 bta_hl_cch_close_cmpl, 316 bta_hl_cch_mca_connect, 317 bta_hl_cch_mca_disconnect, 318 bta_hl_cch_mca_rsp_tout 319}; 320 321 322/* state table information */ 323#define BTA_HL_CCH_ACTIONS 1 /* number of actions */ 324#define BTA_HL_CCH_NEXT_STATE 1 /* position of next state */ 325#define BTA_HL_CCH_NUM_COLS 2 /* number of columns in state tables */ 326 327 328/* state table for MAS idle state */ 329static const UINT8 bta_hl_cch_st_idle[][BTA_HL_CCH_NUM_COLS] = 330{ 331/* Event Action 1 Next state */ 332/* BTA_HL_CCH_OPEN_EVT */ {BTA_HL_CCH_SDP_INIT, BTA_HL_CCH_OPENING_ST}, 333/* BTA_HL_CCH_SDP_OK_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_IDLE_ST}, 334/* BTA_HL_CCH_SDP_FAIL_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_IDLE_ST}, 335/* BTA_HL_MCA_CONNECT_IND_EVT */ {BTA_HL_CCH_MCA_CONNECT, BTA_HL_CCH_OPEN_ST}, 336/* BTA_HL_MCA_DISCONNECT_IND_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_IDLE_ST}, 337/* BTA_HL_CCH_CLOSE_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_IDLE_ST}, 338/* BTA_HL_CCH_CLOSE_CMPL_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_IDLE_ST}, 339/* BTA_HL_CCH_CLOSE_CMPL_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_IDLE_ST} 340}; 341 342/* state table for obex/rfcomm connection state */ 343static const UINT8 bta_hl_cch_st_opening[][BTA_HL_CCH_NUM_COLS] = 344{ 345/* Event Action 1 Next state */ 346/* BTA_HL_CCH_OPEN_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_OPENING_ST}, 347/* BTA_HL_CCH_SDP_OK_EVT */ {BTA_HL_CCH_MCA_OPEN, BTA_HL_CCH_OPENING_ST}, 348/* BTA_HL_CCH_SDP_FAIL_EVT */ {BTA_HL_CCH_CLOSE_CMPL, BTA_HL_CCH_IDLE_ST}, 349/* BTA_HL_MCA_CONNECT_IND_EVT */ {BTA_HL_CCH_MCA_CONNECT, BTA_HL_CCH_OPEN_ST}, 350/* BTA_HL_MCA_DISCONNECT_IND_EVT */ {BTA_HL_CCH_MCA_DISCONNECT, BTA_HL_CCH_CLOSING_ST}, 351/* BTA_HL_CCH_CLOSE_EVT */ {BTA_HL_CCH_MCA_CLOSE, BTA_HL_CCH_CLOSING_ST}, 352/* BTA_HL_CCH_CLOSE_CMPL_EVT */ {BTA_HL_CCH_CLOSE_CMPL, BTA_HL_CCH_IDLE_ST}, 353/* BTA_HL_MCA_RSP_TOUT_IND_EVT */ {BTA_HL_CCH_MCA_RSP_TOUT, BTA_HL_CCH_CLOSING_ST} 354}; 355 356/* state table for open state */ 357static const UINT8 bta_hl_cch_st_open[][BTA_HL_CCH_NUM_COLS] = 358{ 359/* Event Action 1 Next state */ 360/* BTA_HL_CCH_OPEN_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_OPEN_ST}, 361/* BTA_HL_CCH_SDP_OK_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_OPEN_ST}, 362/* BTA_HL_CCH_SDP_FAIL_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_OPEN_ST}, 363/* BTA_HL_MCA_CONNECT_IND_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_OPEN_ST}, 364/* BTA_HL_MCA_DISCONNECT_IND_EVT */ {BTA_HL_CCH_MCA_DISCONNECT, BTA_HL_CCH_CLOSING_ST}, 365/* BTA_HL_CCH_CLOSE_EVT */ {BTA_HL_CCH_MCA_CLOSE, BTA_HL_CCH_CLOSING_ST}, 366/* BTA_HL_CCH_CLOSE_CMPL_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_OPEN_ST}, 367/* BTA_HL_MCA_RSP_TOUT_IND_EVT */ {BTA_HL_CCH_MCA_RSP_TOUT, BTA_HL_CCH_CLOSING_ST} 368}; 369 370/* state table for closing state */ 371static const UINT8 bta_hl_cch_st_closing[][BTA_HL_CCH_NUM_COLS] = 372{ 373/* Event Action 1 Next state */ 374/* BTA_HL_CCH_OPEN_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_CLOSING_ST}, 375/* BTA_HL_CCH_SDP_OK_EVT */ {BTA_HL_CCH_CLOSE_CMPL, BTA_HL_CCH_IDLE_ST}, 376/* BTA_HL_CCH_SDP_FAIL_EVT */ {BTA_HL_CCH_CLOSE_CMPL, BTA_HL_CCH_IDLE_ST}, 377/* BTA_HL_MCA_CONNECT_IND_EVT */ {BTA_HL_CCH_MCA_CONNECT, BTA_HL_CCH_OPEN_ST}, 378/* BTA_HL_MCA_DISCONNECT_IND_EVT */ {BTA_HL_CCH_MCA_DISCONNECT, BTA_HL_CCH_CLOSING_ST}, 379/* BTA_HL_CCH_CLOSE_EVT */ {BTA_HL_CCH_MCA_CLOSE, BTA_HL_CCH_CLOSING_ST}, 380/* BTA_HL_CCH_CLOSE_CMPL_EVT */ {BTA_HL_CCH_CLOSE_CMPL, BTA_HL_CCH_IDLE_ST}, 381/* BTA_HL_MCA_RSP_TOUT_IND_EVT */ {BTA_HL_CCH_IGNORE, BTA_HL_CCH_CLOSING_ST} 382}; 383 384/* type for state table CCH */ 385typedef const UINT8 (*tBTA_HL_CCH_ST_TBL)[BTA_HL_CCH_NUM_COLS]; 386 387/* MAS state table */ 388const tBTA_HL_CCH_ST_TBL bta_hl_cch_st_tbl[] = 389{ 390 bta_hl_cch_st_idle, 391 bta_hl_cch_st_opening, 392 bta_hl_cch_st_open, 393 bta_hl_cch_st_closing 394}; 395 396 397/***************************************************************************** 398** Global data 399*****************************************************************************/ 400 401/* HL control block */ 402#if BTA_DYNAMIC_MEMORY == FALSE 403tBTA_HL_CB bta_hl_cb; 404#endif 405 406 407/******************************************************************************* 408** 409** Function bta_hl_cch_sm_execute 410** 411** Description State machine event handling function for CCH 412** 413** Returns void 414** 415*******************************************************************************/ 416void bta_hl_cch_sm_execute(UINT8 app_idx, UINT8 mcl_idx, 417 UINT16 event, tBTA_HL_DATA *p_data) 418{ 419 tBTA_HL_CCH_ST_TBL state_table; 420 UINT8 action; 421 int i; 422 tBTA_HL_MCL_CB *p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 423 424#if (BTA_HL_DEBUG == TRUE) && (BT_USE_TRACES == TRUE) 425 tBTA_HL_CCH_STATE in_state = p_cb->cch_state; 426 UINT16 cur_evt = event; 427 APPL_TRACE_DEBUG3("HDP CCH Event Handler: State 0x%02x [%s], Event [%s]", in_state, 428 bta_hl_cch_state_code(in_state), 429 bta_hl_evt_code(cur_evt)); 430#endif 431 432 /* look up the state table for the current state */ 433 state_table = bta_hl_cch_st_tbl[p_cb->cch_state]; 434 435 event &= 0x00FF; 436 437 /* set next state */ 438 p_cb->cch_state = state_table[event][BTA_HL_CCH_NEXT_STATE]; 439 440 for (i = 0; i < BTA_HL_CCH_ACTIONS; i++) 441 { 442 if ((action = state_table[event][i]) != BTA_HL_CCH_IGNORE) 443 { 444 (*bta_hl_cch_action[action])(app_idx, mcl_idx, p_data); 445 } 446 else 447 { 448 /* discard HDP data */ 449 bta_hl_discard_data(p_data->hdr.event, p_data); 450 break; 451 } 452 } 453#if (BTA_HL_DEBUG == TRUE) && (BT_USE_TRACES == TRUE) 454 if (in_state != p_cb->cch_state) 455 { 456 APPL_TRACE_DEBUG3("HL CCH State Change: [%s] -> [%s] after [%s]", 457 bta_hl_cch_state_code(in_state), 458 bta_hl_cch_state_code(p_cb->cch_state), 459 bta_hl_evt_code(cur_evt)); 460 } 461#endif 462 463} 464 465/******************************************************************************* 466** 467** Function bta_hl_dch_sm_execute 468** 469** Description State machine event handling function for DCH 470** 471** Returns void 472** 473*******************************************************************************/ 474void bta_hl_dch_sm_execute(UINT8 app_idx, UINT8 mcl_idx, UINT8 mdl_idx, 475 UINT16 event, tBTA_HL_DATA *p_data) 476{ 477 tBTA_HL_DCH_ST_TBL state_table; 478 UINT8 action; 479 int i; 480 tBTA_HL_MDL_CB *p_cb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 481 482#if (BTA_HL_DEBUG == TRUE) && (BT_USE_TRACES == TRUE) 483 tBTA_HL_DCH_STATE in_state = p_cb->dch_state; 484 UINT16 cur_evt = event; 485 APPL_TRACE_DEBUG3("HDP DCH Event Handler: State 0x%02x [%s], Event [%s]", in_state, 486 bta_hl_dch_state_code(in_state), 487 bta_hl_evt_code(cur_evt)); 488#endif 489 490 /* look up the state table for the current state */ 491 state_table = bta_hl_dch_st_tbl[p_cb->dch_state]; 492 event -= BTA_HL_DCH_EVT_MIN; 493 494 /* set next state */ 495 p_cb->dch_state = state_table[event][BTA_HL_DCH_NEXT_STATE]; 496 497 for (i = 0; i < BTA_HL_DCH_ACTIONS; i++) 498 { 499 if ((action = state_table[event][i]) != BTA_HL_DCH_IGNORE) 500 { 501 (*bta_hl_dch_action[action])(app_idx, mcl_idx, mdl_idx, p_data); 502 } 503 else 504 { 505 /* discard mas data */ 506 bta_hl_discard_data(p_data->hdr.event, p_data); 507 break; 508 } 509 } 510 511 512#if (BTA_HL_DEBUG == TRUE) && (BT_USE_TRACES == TRUE) 513 if (in_state != p_cb->dch_state) 514 { 515 APPL_TRACE_DEBUG3("HL DCH State Change: [%s] -> [%s] after [%s]", 516 bta_hl_dch_state_code(in_state), 517 bta_hl_dch_state_code(p_cb->dch_state), 518 bta_hl_evt_code(cur_evt)); 519 } 520#endif 521} 522/******************************************************************************* 523** 524** Function bta_hl_api_enable 525** 526** Description Process the API enable request to enable the HL subsystem 527** 528** Returns void 529** 530*******************************************************************************/ 531static void bta_hl_api_enable(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 532{ 533 tBTA_HL_CTRL evt_data; 534 535 /* If already enabled then reject this request */ 536 if (p_cb->enable) 537 { 538 APPL_TRACE_ERROR0("HL is already enabled"); 539 evt_data.enable_cfm.status = BTA_HL_STATUS_FAIL; 540 if (p_data->api_enable.p_cback) 541 p_data->api_enable.p_cback(BTA_HL_CTRL_ENABLE_CFM_EVT, (tBTA_HL_CTRL *) &evt_data); 542 return; 543 } 544 545 /* Done with checking. now perform the enable oepration*/ 546 /* initialize control block */ 547 memset(p_cb, 0, sizeof(tBTA_HL_CB)); 548 p_cb->enable = TRUE; 549 p_cb->p_ctrl_cback = p_data->api_enable.p_cback; 550 evt_data.enable_cfm.status = BTA_HL_STATUS_OK; 551 if (p_data->api_enable.p_cback) 552 p_data->api_enable.p_cback(BTA_HL_CTRL_ENABLE_CFM_EVT, (tBTA_HL_CTRL *) &evt_data); 553 554} 555/******************************************************************************* 556** 557** Function bta_hl_api_disable 558** 559** Description Process the API disable request to disable the HL subsystem 560** 561** Returns void 562** 563*******************************************************************************/ 564static void bta_hl_api_disable(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 565{ 566 tBTA_HL_CTRL evt_data; 567 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 568 569 if (p_cb->enable) 570 { 571 p_cb->disabling = TRUE; 572 bta_hl_check_disable(p_data); 573 } 574 else 575 { 576 status = BTA_HL_STATUS_FAIL; 577 evt_data.disable_cfm.status = status; 578 if (p_cb->p_ctrl_cback) p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT, (tBTA_HL_CTRL *) &evt_data); 579 } 580 581 582#if BTA_HL_DEBUG == TRUE 583 if (status != BTA_HL_STATUS_OK) 584 { 585 APPL_TRACE_DEBUG1("bta_hl_api_disable status =%s", bta_hl_status_code(status)); 586 } 587#endif 588 589} 590 591/******************************************************************************* 592** 593** Function bta_hl_api_register 594** 595** Description Process the API registration request to register an HDP applciation 596** 597** Returns void 598** 599*******************************************************************************/ 600static void bta_hl_api_register(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 601{ 602 tBTA_HL evt_data; 603 UINT8 app_idx; 604 tBTA_HL_APP_CB *p_acb; 605 tBTA_HL_STATUS status = BTA_HL_STATUS_FAIL; 606 607 if (p_cb->enable) 608 { 609 if (!bta_hl_is_a_duplicate_id(p_data->api_reg.app_id)) 610 { 611 if (bta_hl_find_avail_app_idx(&app_idx)) 612 { 613 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 614 p_acb->in_use = TRUE; 615 p_acb->app_id = p_data->api_reg.app_id; 616 p_acb->p_cback = p_data->api_reg.p_cback; 617 p_acb->sec_mask = p_data->api_reg.sec_mask; 618 p_acb->dev_type = p_data->api_reg.dev_type; 619 BCM_STRNCPY_S(p_acb->srv_name, sizeof(p_acb->srv_name), p_data->api_reg.srv_name, BTA_SERVICE_NAME_LEN); 620 BCM_STRNCPY_S(p_acb->srv_desp, sizeof(p_acb->srv_desp), p_data->api_reg.srv_desp, BTA_SERVICE_DESP_LEN); 621 BCM_STRNCPY_S(p_acb->provider_name, sizeof(p_acb->provider_name), p_data->api_reg.provider_name, BTA_PROVIDER_NAME_LEN); 622 bta_hl_cb.p_alloc_psm = L2CA_AllocatePSM; 623 p_acb->ctrl_psm = bta_hl_cb.p_alloc_psm(); 624 p_acb->data_psm = bta_hl_cb.p_alloc_psm(); 625 p_acb->p_mcap_cback = bta_hl_mcap_ctrl_cback; 626 status = bta_hl_app_registration(app_idx); 627 } 628 else 629 { 630 status = BTA_HL_STATUS_NO_RESOURCE; 631 } 632 } 633 else 634 { 635 status = BTA_HL_STATUS_DUPLICATE_APP_ID; 636 } 637 } 638 639 if (status != BTA_HL_STATUS_OK) 640 { 641 if ((status != BTA_HL_STATUS_DUPLICATE_APP_ID) && 642 (status != BTA_HL_STATUS_NO_RESOURCE)) 643 { 644 memset(p_acb, 0, sizeof(tBTA_HL_APP_CB)); 645 } 646 } 647#if BTA_HL_DEBUG == TRUE 648 if (status != BTA_HL_STATUS_OK) 649 { 650 APPL_TRACE_DEBUG1("bta_hl_api_register status =%s", bta_hl_status_code(status)); 651 } 652#endif 653 654 evt_data.reg_cfm.status = status; 655 evt_data.reg_cfm.app_id = p_data->api_reg.app_id; 656 evt_data.reg_cfm.app_handle = p_acb->app_handle; 657 if (p_data->api_reg.p_cback) 658 { 659 p_data->api_reg.p_cback(BTA_HL_REGISTER_CFM_EVT, (tBTA_HL *) &evt_data); 660 } 661 662 if (status == BTA_HL_STATUS_OK) 663 { 664 evt_data.sdp_info_ind.app_handle = p_acb->app_handle; 665 evt_data.sdp_info_ind.ctrl_psm = p_acb->ctrl_psm; 666 evt_data.sdp_info_ind.data_psm = p_acb->data_psm; 667 evt_data.sdp_info_ind.data_x_spec = BTA_HL_SDP_IEEE_11073_20601; 668 evt_data.sdp_info_ind.mcap_sup_procs = BTA_HL_MCAP_SUP_PROC_MASK ; 669 670 if (p_data->api_reg.p_cback) 671 { 672 p_data->api_reg.p_cback(BTA_HL_SDP_INFO_IND_EVT, (tBTA_HL *) &evt_data); 673 } 674 } 675} 676 677/******************************************************************************* 678** 679** Function bta_hl_api_deregister 680** 681** Description Process the API de-registration request 682** 683** Returns void 684** 685*******************************************************************************/ 686static void bta_hl_api_deregister(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 687{ 688 689 UINT8 app_idx; 690 tBTA_HL_APP_CB *p_acb; 691 692 if (bta_hl_find_app_idx_using_handle(p_data->api_dereg.app_handle, &app_idx)) 693 { 694 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 695 p_acb->deregistering= TRUE; 696 bta_hl_check_deregistration(app_idx,p_data); 697 } 698 else 699 { 700 APPL_TRACE_ERROR1("Inavlide app_handle=%d", p_data->api_dereg.app_handle); 701 } 702} 703 704/******************************************************************************* 705** 706** Function bta_hl_api_cch_open 707** 708** Description Process the API CCH open request 709** 710** Returns void 711** 712*******************************************************************************/ 713static void bta_hl_api_cch_open(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 714{ 715 tBTA_HL evt_data; 716 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 717 UINT8 app_idx, mcl_idx; 718 tBTA_HL_APP_CB *p_acb; 719 tBTA_HL_MCL_CB *p_mcb; 720 721 if (bta_hl_find_app_idx_using_handle(p_data->api_cch_open.app_handle, &app_idx)) 722 { 723 724 if (!bta_hl_find_mcl_idx(app_idx, p_data->api_cch_open.bd_addr, &mcl_idx)) 725 { 726 if (bta_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) 727 { 728 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 729 p_mcb->in_use = TRUE; 730 p_mcb->req_ctrl_psm = p_data->api_cch_open.ctrl_psm; 731 p_mcb->sec_mask = p_data->api_cch_open.sec_mask; 732 bdcpy(p_mcb->bd_addr, p_data->api_cch_open.bd_addr); 733 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_OPEN; 734 } 735 else 736 { 737 status = BTA_HL_STATUS_NO_RESOURCE; 738 } 739 } 740 else 741 { 742 /* Only one MCL per BD_ADDR */ 743 status = BTA_HL_STATUS_FAIL; 744 } 745 } 746 else 747 { 748 status = BTA_HL_STATUS_INVALID_APP_HANDLE; 749 } 750#if BTA_HL_DEBUG == TRUE 751 if (status != BTA_HL_STATUS_OK) 752 { 753 APPL_TRACE_DEBUG1("bta_hl_api_cch_open status =%s", bta_hl_status_code(status)); 754 } 755#endif 756 switch (status) 757 { 758 case BTA_HL_STATUS_OK: 759 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_OPEN_EVT, p_data); 760 break; 761 case BTA_HL_STATUS_NO_RESOURCE: 762 case BTA_HL_STATUS_FAIL: 763 bta_hl_build_cch_open_cfm(&evt_data, p_data->api_cch_open.app_handle, 764 0, 765 p_data->api_cch_open.bd_addr, 766 status); 767 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 768 p_acb->p_cback(BTA_HL_CCH_OPEN_CFM_EVT,(tBTA_HL *) &evt_data ); 769 break; 770 default: 771 APPL_TRACE_ERROR1("status code=%d", status); 772 break; 773 } 774} 775 776/******************************************************************************* 777** 778** Function bta_hl_api_cch_close 779** 780** Description Process the API CCH close request 781** 782** Returns void 783** 784*******************************************************************************/ 785static void bta_hl_api_cch_close(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 786{ 787 tBTA_HL evt_data; 788 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 789 UINT8 app_idx, mcl_idx; 790 tBTA_HL_APP_CB *p_acb; 791 tBTA_HL_MCL_CB *p_mcb; 792 793 if (bta_hl_find_mcl_idx_using_handle(p_data->api_cch_close.mcl_handle, &app_idx, &mcl_idx)) 794 { 795 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 796 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE; 797 } 798 else 799 { 800 status = BTA_HL_STATUS_INVALID_MCL_HANDLE; 801 } 802#if BTA_HL_DEBUG == TRUE 803 if (status != BTA_HL_STATUS_OK) 804 { 805 APPL_TRACE_DEBUG1("bta_hl_api_cch_close status =%s", bta_hl_status_code(status)); 806 } 807#endif 808 switch (status) 809 { 810 case BTA_HL_STATUS_OK: 811 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, TRUE); 812 break; 813 814 case BTA_HL_STATUS_FAIL: 815 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 816 bta_hl_build_cch_close_cfm(&evt_data, 817 p_acb->app_handle, 818 p_data->api_cch_close.mcl_handle, 819 status); 820 p_acb->p_cback(BTA_HL_CCH_CLOSE_CFM_EVT,(tBTA_HL *) &evt_data ); 821 break; 822 823 default: 824 APPL_TRACE_ERROR1("status code=%d", status); 825 break; 826 827 } 828 829} 830 831/******************************************************************************* 832** 833** Function bta_hl_api_dch_open 834** 835** Description Process the API DCH open request 836** 837** Returns void 838** 839*******************************************************************************/ 840static void bta_hl_api_dch_open(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 841{ 842 tBTA_HL evt_data; 843 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 844 UINT8 app_idx, mcl_idx, mdl_idx; 845 tBTA_HL_APP_CB *p_acb; 846 tBTA_HL_MCL_CB *p_mcb; 847 tBTA_HL_MDL_CB *p_dcb; 848 tBTA_HL_MDEP_CFG *p_mdep_cfg; 849 UINT8 mdep_cfg_idx; 850 851 if (bta_hl_find_mcl_idx_using_handle(p_data->api_dch_open.mcl_handle, &app_idx, &mcl_idx)) 852 { 853 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 854 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 855 856 if (p_mcb->cch_state == BTA_HL_CCH_OPEN_ST) 857 { 858 if (bta_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) 859 { 860 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 861 862 if (bta_hl_find_mdep_cfg_idx(app_idx, p_data->api_dch_open.local_mdep_id, &mdep_cfg_idx)) 863 { 864 if ( mdep_cfg_idx && 865 (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SINK)) 866 { 867 p_data->api_dch_open.local_cfg = BTA_HL_DCH_CFG_NO_PREF; 868 } 869 870 if ((status = bta_hl_chk_local_cfg(app_idx,mcl_idx,mdep_cfg_idx,p_data->api_dch_open.local_cfg)) 871 == BTA_HL_STATUS_OK) 872 { 873 874 if (p_data->api_dch_open.local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) 875 { 876 if (bta_hl_set_ctrl_psm_for_dch(app_idx, mcl_idx, mdl_idx, p_data->api_dch_open.ctrl_psm)) 877 { 878 p_mdep_cfg = BTA_HL_GET_MDEP_CFG_PTR(app_idx, mdep_cfg_idx); 879 p_dcb->in_use = TRUE; 880 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_OPEN; 881 p_dcb->sec_mask = p_data->api_dch_open.sec_mask; 882 p_dcb->local_mdep_id = p_data->api_dch_open.local_mdep_id; 883 p_dcb->peer_mdep_id = p_data->api_dch_open.peer_mdep_id; 884 885 if (p_mdep_cfg->mdep_role == BTA_HL_MDEP_ROLE_SINK) 886 { 887 p_dcb->peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE; 888 } 889 else 890 { 891 p_dcb->peer_mdep_role = BTA_HL_MDEP_ROLE_SINK; 892 } 893 894 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 895 p_dcb->local_cfg = p_data->api_dch_open.local_cfg; 896 897 bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx, 898 &p_dcb->max_rx_apdu_size, 899 &p_dcb->max_tx_apdu_size); 900 p_dcb->mdl_id = bta_hl_allocate_mdl_id(app_idx,mcl_idx,mdl_idx); 901 p_dcb->mdl_cfg_idx_included = FALSE; 902 } 903 else 904 { 905 status = BTA_HL_STATUS_INVALID_CTRL_PSM; 906 } 907 908 } 909 else 910 { 911 status = BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID; 912 } 913 } 914 } 915 else 916 { 917 status = BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID; 918 } 919 } 920 else 921 { 922 status = BTA_HL_STATUS_NO_RESOURCE; 923 } 924 } 925 else 926 { 927 status = BTA_HL_STATUS_NO_CCH; 928 } 929 } 930 else 931 { 932 status = BTA_HL_STATUS_INVALID_MCL_HANDLE; 933 } 934 935#if BTA_HL_DEBUG == TRUE 936 if (status != BTA_HL_STATUS_OK) 937 { 938 APPL_TRACE_DEBUG1("bta_hl_api_dch_open status =%s", bta_hl_status_code(status)); 939 } 940#endif 941 switch (status) 942 { 943 case BTA_HL_STATUS_OK: 944 if (p_mcb->sdp.num_recs) 945 { 946 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_OPEN_EVT, p_data); 947 } 948 else 949 { 950 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_INIT_EVT, p_data); 951 } 952 break; 953 case BTA_HL_STATUS_INVALID_DCH_CFG: 954 case BTA_HL_STATUS_NO_FIRST_RELIABLE: 955 case BTA_HL_STATUS_NO_CCH: 956 case BTA_HL_STATUS_NO_RESOURCE: 957 case BTA_HL_STATUS_FAIL: 958 case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID: 959 case BTA_HL_STATUS_INVALID_CTRL_PSM: 960 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 961 bta_hl_build_dch_open_cfm(&evt_data, 962 p_acb->app_handle, 963 p_data->api_dch_open.mcl_handle, 964 BTA_HL_INVALID_MDL_HANDLE, 965 0,0,0,0,0, status); 966 p_acb->p_cback(BTA_HL_DCH_OPEN_CFM_EVT,(tBTA_HL *) &evt_data ); 967 break; 968 default: 969 APPL_TRACE_ERROR1("Status code=%d", status); 970 break; 971 972 } 973 974} 975/******************************************************************************* 976** 977** Function bta_hl_api_dch_close 978** 979** Description Process the API DCH close request 980** 981** Returns void 982** 983*******************************************************************************/ 984static void bta_hl_api_dch_close(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 985{ 986 tBTA_HL evt_data; 987 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 988 UINT8 app_idx, mcl_idx, mdl_idx; 989 tBTA_HL_APP_CB *p_acb; 990 tBTA_HL_MCL_CB *p_mcb; 991 tBTA_HL_MDL_CB *p_dcb; 992 993 994 if (bta_hl_find_mdl_idx_using_handle(p_data->api_dch_close.mdl_handle, &app_idx, &mcl_idx, &mdl_idx )) 995 { 996 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 997 if (p_dcb->dch_state != BTA_HL_DCH_OPEN_ST) 998 { 999 status = BTA_HL_STATUS_FAIL; 1000 } 1001 } 1002 else 1003 { 1004 status = BTA_HL_STATUS_INVALID_MDL_HANDLE; 1005 } 1006 1007#if BTA_HL_DEBUG == TRUE 1008 if (status != BTA_HL_STATUS_OK) 1009 { 1010 APPL_TRACE_DEBUG1("bta_hl_api_dch_close status =%s", bta_hl_status_code(status)); 1011 } 1012#endif 1013 1014 switch (status) 1015 { 1016 case BTA_HL_STATUS_OK: 1017 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, p_data); 1018 break; 1019 case BTA_HL_STATUS_FAIL: 1020 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1021 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1022 bta_hl_build_dch_close_cfm(&evt_data, 1023 p_acb->app_handle, 1024 p_mcb->mcl_handle, 1025 p_data->api_dch_close.mdl_handle, 1026 status); 1027 1028 p_acb->p_cback(BTA_HL_DCH_CLOSE_CFM_EVT,(tBTA_HL *) &evt_data ); 1029 break; 1030 default: 1031 APPL_TRACE_ERROR1("Status code=%d", status); 1032 break; 1033 } 1034} 1035 1036 1037/******************************************************************************* 1038** 1039** Function bta_hl_api_dch_reconnect 1040** 1041** Description Process the API DCH reconnect request 1042** 1043** Returns void 1044** 1045*******************************************************************************/ 1046static void bta_hl_api_dch_reconnect(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1047{ 1048 tBTA_HL evt_data; 1049 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1050 UINT8 app_idx, mcl_idx, mdl_idx; 1051 tBTA_HL_APP_CB *p_acb; 1052 tBTA_HL_MCL_CB *p_mcb; 1053 tBTA_HL_MDL_CB *p_dcb; 1054 UINT8 mdep_cfg_idx; 1055 UINT8 mdl_cfg_idx; 1056 1057 if (bta_hl_find_mcl_idx_using_handle(p_data->api_dch_open.mcl_handle, &app_idx, &mcl_idx)) 1058 { 1059 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1060 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1061 if (p_mcb->cch_state == BTA_HL_CCH_OPEN_ST) 1062 { 1063 if (bta_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) 1064 { 1065 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1066 if (bta_hl_validate_reconnect_params(app_idx, mcl_idx, &(p_data->api_dch_reconnect), 1067 &mdep_cfg_idx, &mdl_cfg_idx )) 1068 { 1069 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx) && 1070 (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode != BTA_HL_DCH_MODE_RELIABLE)) 1071 { 1072 status = BTA_HL_STATUS_NO_FIRST_RELIABLE; 1073 } 1074 else 1075 { 1076 if (bta_hl_set_ctrl_psm_for_dch(app_idx, mcl_idx, mdl_idx, p_data->api_dch_open.ctrl_psm)) 1077 { 1078 p_dcb->in_use = TRUE; 1079 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_RECONNECT; 1080 p_dcb->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 1081 p_dcb->local_mdep_id = p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id; 1082 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1083 p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN; 1084 p_dcb->mdl_id = p_data->api_dch_reconnect.mdl_id; 1085 p_dcb->mdl_cfg_idx_included = TRUE; 1086 p_dcb->mdl_cfg_idx = mdl_cfg_idx; 1087 p_dcb->dch_mode = p_acb->mdl_cfg[mdl_cfg_idx].dch_mode; 1088 bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx, 1089 &p_dcb->max_rx_apdu_size, 1090 &p_dcb->max_tx_apdu_size); 1091 } 1092 else 1093 { 1094 status = BTA_HL_STATUS_INVALID_CTRL_PSM; 1095 } 1096 } 1097 } 1098 else 1099 { 1100 status = BTA_HL_STATUS_INVALID_RECONNECT_CFG; 1101 } 1102 } 1103 else 1104 { 1105 status = BTA_HL_STATUS_NO_RESOURCE; 1106 } 1107 } 1108 else 1109 { 1110 status = BTA_HL_STATUS_NO_CCH; 1111 } 1112 } 1113 else 1114 { 1115 status = BTA_HL_STATUS_INVALID_MCL_HANDLE; 1116 } 1117 1118#if BTA_HL_DEBUG == TRUE 1119 if (status != BTA_HL_STATUS_OK) 1120 { 1121 APPL_TRACE_DEBUG1("bta_hl_api_dch_reconnect status=%s", bta_hl_status_code(status)); 1122 } 1123#endif 1124 1125 switch (status) 1126 { 1127 case BTA_HL_STATUS_OK: 1128 if (p_mcb->sdp.num_recs) 1129 { 1130 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_RECONNECT_EVT, p_data); 1131 } 1132 else 1133 { 1134 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_INIT_EVT, p_data); 1135 } 1136 break; 1137 case BTA_HL_STATUS_INVALID_RECONNECT_CFG: 1138 case BTA_HL_STATUS_NO_FIRST_RELIABLE: 1139 case BTA_HL_STATUS_NO_CCH: 1140 case BTA_HL_STATUS_NO_RESOURCE: 1141 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1142 bta_hl_build_dch_open_cfm(&evt_data, 1143 p_acb->app_handle, 1144 p_data->api_dch_reconnect.mcl_handle, 1145 BTA_HL_INVALID_MDL_HANDLE, 1146 0,p_data->api_dch_reconnect.mdl_id,0,0,0, status); 1147 p_acb->p_cback(BTA_HL_DCH_RECONNECT_CFM_EVT,(tBTA_HL *) &evt_data ); 1148 break; 1149 default: 1150 APPL_TRACE_ERROR1("Status code=%d", status); 1151 break; 1152 } 1153} 1154 1155/******************************************************************************* 1156** 1157** Function bta_hl_api_dch_echo_test 1158** 1159** Description Process the API Echo test request 1160** 1161** Returns void 1162** 1163*******************************************************************************/ 1164static void bta_hl_api_dch_echo_test(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1165{ 1166 tBTA_HL evt_data; 1167 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1168 UINT8 app_idx, mcl_idx, mdl_idx; 1169 tBTA_HL_APP_CB *p_acb; 1170 tBTA_HL_MCL_CB *p_mcb; 1171 tBTA_HL_MDL_CB *p_dcb; 1172 tBTA_HL_ECHO_CFG *p_echo_cfg; 1173 1174 1175 if (bta_hl_find_mcl_idx_using_handle(p_data->api_dch_echo_test.mcl_handle, &app_idx, &mcl_idx)) 1176 { 1177 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1178 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1179 if (p_mcb->cch_state == BTA_HL_CCH_OPEN_ST) 1180 { 1181 if (!p_mcb->echo_test ) 1182 { 1183 if (bta_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) 1184 { 1185 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1186 1187 if ((p_data->api_dch_echo_test.local_cfg == BTA_HL_DCH_CFG_RELIABLE) || 1188 (p_data->api_dch_echo_test.local_cfg == BTA_HL_DCH_CFG_STREAMING)) 1189 { 1190 if ((p_dcb->p_echo_tx_pkt = bta_hl_get_buf(p_data->api_dch_echo_test.pkt_size)) != NULL ) 1191 { 1192 if (bta_hl_set_ctrl_psm_for_dch(app_idx, mcl_idx, mdl_idx, p_data->api_dch_open.ctrl_psm)) 1193 { 1194 p_dcb->in_use = TRUE; 1195 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_OPEN; 1196 p_dcb->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 1197 p_dcb->local_mdep_cfg_idx = BTA_HL_ECHO_TEST_MDEP_CFG_IDX; 1198 p_dcb->local_cfg = p_data->api_dch_echo_test.local_cfg; 1199 p_dcb->local_mdep_id = BTA_HL_ECHO_TEST_MDEP_ID; 1200 p_dcb->peer_mdep_id = BTA_HL_ECHO_TEST_MDEP_ID; 1201 p_dcb->mdl_id = bta_hl_allocate_mdl_id(app_idx,mcl_idx,mdl_idx); 1202 p_dcb->mdl_cfg_idx_included = FALSE; 1203 p_echo_cfg = BTA_HL_GET_ECHO_CFG_PTR(app_idx); 1204 p_dcb->max_rx_apdu_size = p_echo_cfg->max_rx_apdu_size; 1205 p_dcb->max_tx_apdu_size = p_echo_cfg->max_tx_apdu_size; 1206 p_mcb->echo_test = TRUE; 1207 p_mcb->echo_mdl_idx = mdl_idx; 1208 } 1209 else 1210 { 1211 status = BTA_HL_STATUS_INVALID_CTRL_PSM; 1212 } 1213 } 1214 else 1215 { 1216 status = BTA_HL_STATUS_NO_RESOURCE; 1217 } 1218 } 1219 else 1220 { 1221 status = BTA_HL_STATUS_INVALID_DCH_CFG; 1222 } 1223 } 1224 else 1225 { 1226 status = BTA_HL_STATUS_NO_RESOURCE; 1227 } 1228 } 1229 else 1230 { 1231 status = BTA_HL_STATUS_ECHO_TEST_BUSY; 1232 } 1233 } 1234 else 1235 { 1236 status = BTA_HL_STATUS_NO_CCH; 1237 } 1238 } 1239 else 1240 { 1241 status = BTA_HL_STATUS_NO_MCL; 1242 } 1243 1244#if BTA_HL_DEBUG == TRUE 1245 if (status != BTA_HL_STATUS_OK) 1246 { 1247 APPL_TRACE_DEBUG1("bta_hl_api_dch_echo_test status=%s", bta_hl_status_code(status)); 1248 } 1249#endif 1250 1251 switch (status) 1252 { 1253 case BTA_HL_STATUS_OK: 1254 if (p_mcb->sdp.num_recs) 1255 { 1256 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ECHO_TEST_EVT, p_data); 1257 } 1258 else 1259 { 1260 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_INIT_EVT, p_data); 1261 } 1262 break; 1263 case BTA_HL_STATUS_NO_CCH: 1264 case BTA_HL_STATUS_ECHO_TEST_BUSY: 1265 case BTA_HL_STATUS_NO_RESOURCE: 1266 case BTA_HL_STATUS_INVALID_DCH_CFG: 1267 bta_hl_build_echo_test_cfm(&evt_data, 1268 p_acb->app_handle, 1269 p_mcb->mcl_handle, 1270 status); 1271 p_acb->p_cback(BTA_HL_DCH_ECHO_TEST_CFM_EVT,(tBTA_HL *) &evt_data ); 1272 break; 1273 1274 default: 1275 APPL_TRACE_ERROR1("Status code=%s", status); 1276 break; 1277 } 1278} 1279 1280 1281/******************************************************************************* 1282** 1283** Function bta_hl_api_sdp_query 1284** 1285** Description Process the API SDP query request 1286** 1287** Returns void 1288** 1289*******************************************************************************/ 1290static void bta_hl_api_sdp_query(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1291{ 1292 tBTA_HL evt_data; 1293 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1294 UINT8 app_idx, mcl_idx; 1295 tBTA_HL_APP_CB *p_acb; 1296 tBTA_HL_MCL_CB *p_mcb; 1297 1298 1299 if (bta_hl_find_app_idx_using_handle(p_data->api_sdp_query.app_handle, &app_idx)) 1300 { 1301 if (!bta_hl_find_mcl_idx(app_idx, p_data->api_sdp_query.bd_addr, &mcl_idx)) 1302 { 1303 if (bta_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) 1304 { 1305 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1306 p_mcb->in_use = TRUE; 1307 bdcpy(p_mcb->bd_addr, p_data->api_sdp_query.bd_addr); 1308 p_mcb->sdp_oper = BTA_HL_SDP_OP_SDP_QUERY_NEW ; 1309 } 1310 else 1311 { 1312 status = BTA_HL_STATUS_NO_RESOURCE; 1313 } 1314 } 1315 else 1316 { 1317 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1318 if (p_mcb->sdp_oper != BTA_HL_SDP_OP_NONE) 1319 { 1320 status = BTA_HL_STATUS_SDP_NO_RESOURCE; 1321 } 1322 else 1323 { 1324 p_mcb->sdp_oper = BTA_HL_SDP_OP_SDP_QUERY_CURRENT; 1325 } 1326 } 1327 } 1328 else 1329 { 1330 status = BTA_HL_STATUS_INVALID_APP_HANDLE; 1331 } 1332 1333 if (status == BTA_HL_STATUS_OK) 1334 { 1335 status = bta_hl_init_sdp( p_mcb->sdp_oper, app_idx, mcl_idx, 0xFF); 1336 if ( (status != BTA_HL_STATUS_OK) && 1337 (p_mcb->sdp_oper == BTA_HL_SDP_OP_SDP_QUERY_NEW) ) 1338 { 1339 memset(p_mcb, 0 ,sizeof(tBTA_HL_MCL_CB)); 1340 } 1341 } 1342#if BTA_HL_DEBUG == TRUE 1343 if (status != BTA_HL_STATUS_OK) 1344 { 1345 APPL_TRACE_DEBUG1("bta_hl_api_sdp_query status=%s", bta_hl_status_code(status)); 1346 } 1347#endif 1348 switch (status) 1349 { 1350 case BTA_HL_STATUS_NO_RESOURCE: 1351 case BTA_HL_STATUS_FAIL: 1352 case BTA_HL_STATUS_SDP_NO_RESOURCE: 1353 bta_hl_build_sdp_query_cfm(&evt_data, 1354 p_data->api_sdp_query.app_handle, 1355 p_data->api_sdp_query.bd_addr, 1356 NULL, 1357 status); 1358 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1359 p_acb->p_cback(BTA_HL_SDP_QUERY_CFM_EVT,(tBTA_HL *) &evt_data ); 1360 break; 1361 case BTA_HL_STATUS_OK: 1362 break; 1363 default: 1364 APPL_TRACE_ERROR1("Status code=%d", status); 1365 break; 1366 } 1367} 1368 1369 1370 1371 1372/******************************************************************************* 1373** 1374** Function bta_hl_sdp_query_results 1375** 1376** Description Process the SDP query results 1377** 1378** Returns void 1379** 1380*******************************************************************************/ 1381static void bta_hl_sdp_query_results(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1382{ 1383 tBTA_HL evt_data; 1384 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1385 UINT8 app_idx = p_data->cch_sdp.app_idx; 1386 UINT8 mcl_idx = p_data->cch_sdp.mcl_idx; 1387 tBTA_HL_APP_CB *p_acb = BTA_HL_GET_APP_CB_PTR( app_idx); 1388 tBTA_HL_MCL_CB *p_mcb = BTA_HL_GET_MCL_CB_PTR( app_idx, mcl_idx); 1389 tBTA_HL_SDP *p_sdp=NULL; 1390 tBTA_HL_SDP_OPER sdp_oper; 1391 UINT16 event; 1392 BOOLEAN release_sdp_buf=FALSE; 1393 1394 event = p_data->hdr.event; 1395 sdp_oper = p_mcb->sdp_oper; 1396 1397 if ( event == BTA_HL_SDP_QUERY_OK_EVT) 1398 { 1399 if ((p_sdp = (tBTA_HL_SDP *)GKI_getbuf((UINT16)(sizeof(tBTA_HL_SDP)))) != NULL) 1400 { 1401 memcpy(p_sdp, &p_mcb->sdp, sizeof(tBTA_HL_SDP)); 1402 release_sdp_buf = TRUE; 1403 } 1404 else 1405 { 1406 status = BTA_HL_STATUS_SDP_NO_RESOURCE; 1407 } 1408 } 1409 else 1410 { 1411 status = BTA_HL_STATUS_SDP_FAIL; 1412 } 1413 1414#if BTA_HL_DEBUG == TRUE 1415 if (status != BTA_HL_STATUS_OK) 1416 { 1417 APPL_TRACE_DEBUG1("bta_hl_sdp_query_results status=%s", bta_hl_status_code(status)); 1418 } 1419#endif 1420 1421 bta_hl_build_sdp_query_cfm(&evt_data,p_acb->app_handle, 1422 p_mcb->bd_addr,p_sdp,status); 1423 p_acb->p_cback(BTA_HL_SDP_QUERY_CFM_EVT,(tBTA_HL *) &evt_data ); 1424 1425 if (release_sdp_buf) 1426 { 1427 utl_freebuf((void **) &p_sdp); 1428 } 1429 1430 if (p_data->cch_sdp.release_mcl_cb) 1431 { 1432 memset(p_mcb, 0 ,sizeof(tBTA_HL_MCL_CB)); 1433 } 1434 else 1435 { 1436 if (p_mcb->close_pending) 1437 { 1438 bta_hl_check_cch_close(app_idx,mcl_idx,p_data, TRUE); 1439 } 1440 1441 if (!p_mcb->ctrl_psm) 1442 { 1443 /* this is a control channel acceptor do not store the sdp records*/ 1444 memset(&p_mcb->sdp, 0, sizeof(tBTA_HL_SDP)); 1445 } 1446 } 1447} 1448 1449 1450/******************************************************************************* 1451** 1452** Function bta_hl_api_delete_mdl 1453** 1454** Description Process the API DELETE MDL request 1455** 1456** Returns void 1457** 1458*******************************************************************************/ 1459static void bta_hl_api_delete_mdl(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1460{ 1461 tBTA_HL evt_data; 1462 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1463 UINT8 app_idx, mcl_idx; 1464 tBTA_HL_APP_CB *p_acb; 1465 tBTA_HL_MCL_CB *p_mcb; 1466 1467 if (bta_hl_find_mcl_idx_using_handle(p_data->api_delete_mdl.mcl_handle, &app_idx, &mcl_idx )) 1468 { 1469 if (bta_hl_is_mdl_value_valid(p_data->api_delete_mdl.mdl_id)) 1470 { 1471 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1472 if (bta_hl_is_mdl_exsit_in_mcl(app_idx, 1473 p_mcb->bd_addr, 1474 p_data->api_delete_mdl.mdl_id)) 1475 { 1476 1477 1478 p_mcb->delete_mdl.mcl_handle = p_data->api_delete_mdl.mcl_handle; 1479 p_mcb->delete_mdl.mdl_id = p_data->api_delete_mdl.mdl_id; 1480 p_mcb->delete_mdl.delete_req_pending = TRUE; 1481 1482 if (MCA_Delete((tMCA_CL) p_mcb->mcl_handle, 1483 p_data->api_delete_mdl.mdl_id)!= MCA_SUCCESS) 1484 { 1485 status = BTA_HL_STATUS_FAIL; 1486 memset(&p_mcb->delete_mdl, 0, sizeof(tBTA_HL_DELETE_MDL)); 1487 } 1488 } 1489 else 1490 { 1491 status = BTA_HL_STATUS_NO_MDL_ID_FOUND; 1492 } 1493 } 1494 else 1495 { 1496 status = BTA_HL_STATUS_INVALID_MDL_ID; 1497 } 1498 } 1499 else 1500 { 1501 status = BTA_HL_STATUS_INVALID_MCL_HANDLE; 1502 } 1503 1504#if BTA_HL_DEBUG == TRUE 1505 if (status != BTA_HL_STATUS_OK) 1506 { 1507 APPL_TRACE_DEBUG1("bta_hl_api_delete_mdl status=%s", bta_hl_status_code(status)); 1508 } 1509#endif 1510 switch (status) 1511 { 1512 case BTA_HL_STATUS_OK: 1513 break; 1514 case BTA_HL_STATUS_FAIL: 1515 case BTA_HL_STATUS_NO_MDL_ID_FOUND: 1516 case BTA_HL_STATUS_INVALID_MDL_ID: 1517 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1518 bta_hl_build_delete_mdl_cfm(&evt_data, 1519 p_acb->app_handle, 1520 p_data->api_delete_mdl.mcl_handle, 1521 p_data->api_delete_mdl.mdl_id, 1522 status); 1523 1524 p_acb->p_cback(BTA_HL_DELETE_MDL_CFM_EVT,(tBTA_HL *) &evt_data ); 1525 break; 1526 case BTA_HL_STATUS_INVALID_APP_HANDLE: 1527 default: 1528 APPL_TRACE_ERROR1("status code =%d", status); 1529 break; 1530 } 1531} 1532 1533/******************************************************************************* 1534** 1535** Function bta_hl_mca_delete_mdl_cfm 1536** 1537** Description Process the DELETE MDL confirmation event 1538** 1539** Returns void 1540** 1541*******************************************************************************/ 1542static void bta_hl_mca_delete_mdl_cfm(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1543{ 1544 tBTA_HL evt_data; 1545 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1546 UINT8 app_idx, mcl_idx; 1547 tMCA_RSP_EVT *p_delete_cfm = &p_data->mca_evt.mca_data.delete_cfm; 1548 tBTA_HL_MCL_CB *p_mcb; 1549 BOOLEAN send_cfm_evt = TRUE; 1550 tBTA_HL_APP_CB *p_acb; 1551 1552 if (bta_hl_find_mcl_idx_using_handle(p_data->mca_evt.mcl_handle, &app_idx, &mcl_idx)) 1553 { 1554 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1555 if ( p_mcb->delete_mdl.delete_req_pending) 1556 { 1557 if (p_delete_cfm->rsp_code == MCA_RSP_SUCCESS ) 1558 { 1559 1560 if (!bta_hl_delete_mdl_cfg(app_idx, 1561 p_mcb->bd_addr , 1562 p_delete_cfm->mdl_id)) 1563 { 1564 status = BTA_HL_STATUS_FAIL; 1565 } 1566 } 1567 else 1568 { 1569 status = BTA_HL_STATUS_FAIL; 1570 } 1571 1572 memset(&p_mcb->delete_mdl, 0, sizeof(tBTA_HL_DELETE_MDL)); 1573 } 1574 else 1575 { 1576 send_cfm_evt = FALSE; 1577 } 1578 } 1579 else 1580 { 1581 send_cfm_evt = FALSE; 1582 } 1583 1584#if BTA_HL_DEBUG == TRUE 1585 if (status != BTA_HL_STATUS_OK) 1586 { 1587 APPL_TRACE_DEBUG1("bta_hl_api_delete_mdl status=%s", bta_hl_status_code(status)); 1588 } 1589#endif 1590 1591 if (send_cfm_evt) 1592 { 1593 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1594 bta_hl_build_delete_mdl_cfm(&evt_data, 1595 p_acb->app_handle, 1596 p_mcb->mcl_handle, 1597 p_delete_cfm->mdl_id, 1598 status); 1599 1600 p_acb->p_cback(BTA_HL_DELETE_MDL_CFM_EVT,(tBTA_HL *) &evt_data ); 1601 } 1602} 1603 1604/******************************************************************************* 1605** 1606** Function bta_hl_mca_delete_mdl_ind 1607** 1608** Description Process the DELETE MDL indication event 1609** 1610** Returns void 1611** 1612*******************************************************************************/ 1613static void bta_hl_mca_delete_mdl_ind(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1614{ 1615 tBTA_HL evt_data; 1616 UINT8 app_idx, mcl_idx, mdl_idx; 1617 tMCA_EVT_HDR *p_delete_ind = &p_data->mca_evt.mca_data.delete_ind; 1618 tBTA_HL_MCL_CB *p_mcb; 1619 tBTA_HL_MDL_CB *p_dcb; 1620 BOOLEAN send_ind_evt = TRUE; 1621 tBTA_HL_APP_CB *p_acb; 1622 1623 if (bta_hl_find_mcl_idx_using_handle(p_data->mca_evt.mcl_handle, &app_idx, &mcl_idx) ) 1624 { 1625 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1626 1627 if (bta_hl_find_mdl_idx(app_idx, mcl_idx, p_delete_ind->mdl_id, &mdl_idx )) 1628 { 1629 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1630 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_DELETE; 1631 } 1632 if (bta_hl_delete_mdl_cfg(app_idx, 1633 p_mcb->bd_addr , 1634 p_delete_ind->mdl_id)) 1635 { 1636 send_ind_evt = TRUE; 1637 } 1638 } 1639 1640#if BTA_HL_DEBUG == TRUE 1641 if (!send_ind_evt) 1642 { 1643 APPL_TRACE_DEBUG1("bta_hl_mca_delete_mdl_ind is_send_ind_evt =%d", send_ind_evt); 1644 } 1645#endif 1646 1647 if (send_ind_evt) 1648 { 1649 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1650 evt_data.delete_mdl_ind.mcl_handle = p_mcb->mcl_handle; 1651 evt_data.delete_mdl_ind.app_handle = p_acb->app_handle; 1652 evt_data.delete_mdl_ind.mdl_id = p_delete_ind->mdl_id; 1653 p_acb->p_cback(BTA_HL_DELETE_MDL_IND_EVT,(tBTA_HL *) &evt_data ); 1654 } 1655} 1656 1657 1658 1659/******************************************************************************* 1660** 1661** Function bta_hl_api_dch_abort 1662** 1663** Description Process the API DCH abort request 1664** 1665** Returns void 1666** 1667*******************************************************************************/ 1668static void bta_hl_api_dch_abort(tBTA_HL_CB *p_cb, tBTA_HL_DATA *p_data) 1669{ 1670 1671 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 1672 UINT8 app_idx, mcl_idx, mdl_idx; 1673 tBTA_HL_APP_CB *p_acb; 1674 tBTA_HL_MCL_CB *p_mcb; 1675 tBTA_HL_MDL_CB *p_dcb; 1676 tBTA_HL evt_data; 1677 1678 1679 if (bta_hl_find_mcl_idx_using_handle(p_data->api_dch_abort.mcl_handle, &app_idx, &mcl_idx )) 1680 { 1681 1682 if (!bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx )) 1683 { 1684 status = BTA_HL_STATUS_NO_MDL_ID_FOUND; 1685 } 1686 else 1687 { 1688 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1689 if (p_dcb->abort_oper) 1690 { 1691 /* abort already in progress*/ 1692 status = BTA_HL_STATUS_FAIL; 1693 } 1694 else 1695 { 1696 p_dcb->abort_oper = BTA_HL_ABORT_LOCAL_MASK; 1697 } 1698 } 1699 } 1700 else 1701 { 1702 status = BTA_HL_STATUS_INVALID_MCL_HANDLE; 1703 } 1704 1705 1706#if BTA_HL_DEBUG == TRUE 1707 if (status != BTA_HL_STATUS_OK) 1708 { 1709 APPL_TRACE_DEBUG1("bta_hl_api_dch_abort status=%s", bta_hl_status_code(status)); 1710 } 1711#endif 1712 switch (status) 1713 { 1714 case BTA_HL_STATUS_OK: 1715 1716 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, p_data); 1717 break; 1718 case BTA_HL_STATUS_NO_MDL_ID_FOUND: 1719 case BTA_HL_STATUS_FAIL: 1720 1721 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1722 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1723 bta_hl_build_abort_cfm(&evt_data, 1724 p_acb->app_handle, 1725 p_mcb->mcl_handle, 1726 BTA_HL_STATUS_FAIL); 1727 p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT,(tBTA_HL *) &evt_data ); 1728 break; 1729 case BTA_HL_STATUS_INVALID_BD_ADDR: 1730 case BTA_HL_STATUS_INVALID_APP_HANDLE: 1731 default: 1732 APPL_TRACE_ERROR1("Status code=%d", status); 1733 break; 1734 } 1735} 1736 1737/******************************************************************************* 1738** 1739** Function bta_hl_hdl_event 1740** 1741** Description HL main event handling function. 1742** 1743** Returns void 1744** 1745*******************************************************************************/ 1746BOOLEAN bta_hl_hdl_event(BT_HDR *p_msg) 1747{ 1748 UINT8 app_idx, mcl_idx, mdl_idx; 1749 BOOLEAN success = TRUE; 1750 1751#if BTA_HL_DEBUG == TRUE 1752 APPL_TRACE_DEBUG1("BTA HL Event Handler: Event [%s]", 1753 bta_hl_evt_code(p_msg->event)); 1754#endif 1755 1756 switch (p_msg->event) 1757 { 1758 case BTA_HL_API_ENABLE_EVT: 1759 bta_hl_api_enable(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1760 break; 1761 case BTA_HL_API_DISABLE_EVT: 1762 bta_hl_api_disable(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1763 break; 1764 case BTA_HL_API_REGISTER_EVT: 1765 bta_hl_api_register(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1766 break; 1767 case BTA_HL_API_DEREGISTER_EVT: 1768 bta_hl_api_deregister(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1769 break; 1770 case BTA_HL_API_CCH_OPEN_EVT: 1771 bta_hl_api_cch_open(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1772 break; 1773 case BTA_HL_API_CCH_CLOSE_EVT: 1774 bta_hl_api_cch_close(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1775 break; 1776 case BTA_HL_API_DCH_OPEN_EVT: 1777 bta_hl_api_dch_open(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1778 break; 1779 case BTA_HL_API_DCH_CLOSE_EVT: 1780 bta_hl_api_dch_close(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1781 break; 1782 case BTA_HL_API_DELETE_MDL_EVT: 1783 bta_hl_api_delete_mdl(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1784 break; 1785 case BTA_HL_API_DCH_RECONNECT_EVT: 1786 bta_hl_api_dch_reconnect(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1787 break; 1788 1789 case BTA_HL_API_DCH_ECHO_TEST_EVT: 1790 bta_hl_api_dch_echo_test(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1791 break; 1792 1793 case BTA_HL_API_SDP_QUERY_EVT: 1794 bta_hl_api_sdp_query(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1795 break; 1796 1797 case BTA_HL_MCA_DELETE_CFM_EVT: 1798 bta_hl_mca_delete_mdl_cfm(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1799 break; 1800 1801 case BTA_HL_MCA_DELETE_IND_EVT: 1802 bta_hl_mca_delete_mdl_ind(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1803 break; 1804 1805 case BTA_HL_SDP_QUERY_OK_EVT: 1806 case BTA_HL_SDP_QUERY_FAIL_EVT: 1807 bta_hl_sdp_query_results(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1808 break; 1809 case BTA_HL_API_DCH_ABORT_EVT: 1810 bta_hl_api_dch_abort(&bta_hl_cb, (tBTA_HL_DATA *) p_msg); 1811 break; 1812 1813 1814 default: 1815 if (p_msg->event < BTA_HL_DCH_EVT_MIN) 1816 { 1817 if (bta_hl_find_cch_cb_indexes((tBTA_HL_DATA *) p_msg, &app_idx, &mcl_idx)) 1818 { 1819 bta_hl_cch_sm_execute( app_idx, 1820 mcl_idx, 1821 p_msg->event, (tBTA_HL_DATA *) p_msg); 1822 } 1823 else 1824 { 1825#if BTA_HL_DEBUG == TRUE 1826 APPL_TRACE_ERROR1("unable to find control block indexes for CCH: [event=%s]", 1827 bta_hl_evt_code(p_msg->event)); 1828#else 1829 APPL_TRACE_ERROR1("unable to find control block indexes for CCH: [event=%d]", p_msg->event); 1830#endif 1831 success = FALSE; 1832 } 1833 } 1834 else 1835 { 1836 if (bta_hl_find_dch_cb_indexes((tBTA_HL_DATA *) p_msg, &app_idx, &mcl_idx, &mdl_idx)) 1837 { 1838 bta_hl_dch_sm_execute( app_idx, 1839 mcl_idx, 1840 mdl_idx, 1841 p_msg->event, (tBTA_HL_DATA *) p_msg); 1842 } 1843 else 1844 { 1845 1846#if BTA_HL_DEBUG == TRUE 1847 APPL_TRACE_ERROR1("unable to find control block indexes for DCH : [event=%s]", 1848 bta_hl_evt_code(p_msg->event)); 1849#else 1850 APPL_TRACE_ERROR1("unable to find control block indexes for DCH: [event=%d]", p_msg->event); 1851#endif 1852 success = FALSE; 1853 } 1854 } 1855 1856 break; 1857 } 1858 1859 return(success); 1860} 1861 1862 1863/***************************************************************************** 1864** Debug Functions 1865*****************************************************************************/ 1866#if (BTA_HL_DEBUG == TRUE) && (BT_USE_TRACES == TRUE) 1867 1868/******************************************************************************* 1869** 1870** Function bta_hl_cch_state_code 1871** 1872** Description Map CCH state code to the corresponding state string 1873** 1874** Returns string pointer for the associated state name 1875** 1876*******************************************************************************/ 1877static char *bta_hl_cch_state_code(tBTA_HL_CCH_STATE state_code) 1878{ 1879 switch (state_code) 1880 { 1881 case BTA_HL_CCH_IDLE_ST: 1882 return "BTA_HL_CCH_IDLE_ST"; 1883 case BTA_HL_CCH_OPENING_ST: 1884 return "BTA_HL_CCH_OPENING_ST"; 1885 case BTA_HL_CCH_OPEN_ST: 1886 return "BTA_HL_CCH_OPEN_ST"; 1887 case BTA_HL_CCH_CLOSING_ST: 1888 return "BTA_HL_CCH_CLOSING_ST"; 1889 default: 1890 return "Unknown CCH state code"; 1891 } 1892} 1893 1894/******************************************************************************* 1895** 1896** Function bta_hl_dch_state_code 1897** 1898** Description Map DCH state code to the corresponding state string 1899** 1900** Returns string pointer for the associated state name 1901** 1902*******************************************************************************/ 1903static char *bta_hl_dch_state_code(tBTA_HL_DCH_STATE state_code) 1904{ 1905 switch (state_code) 1906 { 1907 case BTA_HL_DCH_IDLE_ST: 1908 return "BTA_HL_DCH_IDLE_ST"; 1909 case BTA_HL_DCH_OPENING_ST: 1910 return "BTA_HL_DCH_OPENING_ST"; 1911 case BTA_HL_DCH_OPEN_ST: 1912 return "BTA_HL_DCH_OPEN_ST"; 1913 case BTA_HL_DCH_CLOSING_ST: 1914 return "BTA_HL_DCH_CLOSING_ST"; 1915 default: 1916 return "Unknown DCH state code"; 1917 } 1918} 1919#endif /* Debug Functions */ 1920#endif /* HL_INCLUDED */ 1921