1 /****************************************************************************** 2 * 3 * Copyright (C) 2003-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 (HL) action functions for 22 * the state machine. 23 * 24 ******************************************************************************/ 25 26 #include <string.h> 27 28 #include "bt_target.h" 29 #if (HL_INCLUDED == TRUE) 30 31 #include "bt_common.h" 32 #include "bta_hl_api.h" 33 #include "bta_hl_int.h" 34 #include "bta_sys.h" 35 #include "mca_api.h" 36 #include "mca_defs.h" 37 #include "osi/include/osi.h" 38 #include "port_api.h" 39 #include "sdp_api.h" 40 #include "utl.h" 41 42 /***************************************************************************** 43 * Local Function prototypes 44 ****************************************************************************/ 45 #if (BTA_HL_DEBUG == TRUE) 46 static const char* bta_hl_mcap_evt_code(uint8_t evt_code); 47 static const char* bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code); 48 static const char* bta_hl_cback_evt_code(uint8_t evt_code); 49 #endif 50 static void bta_hl_sdp_cback(uint8_t sdp_op, uint8_t app_idx, uint8_t mcl_idx, 51 uint8_t mdl_idx, uint16_t status); 52 static void bta_hl_sdp_cback0(uint16_t status); 53 static void bta_hl_sdp_cback1(uint16_t status); 54 static void bta_hl_sdp_cback2(uint16_t status); 55 static void bta_hl_sdp_cback3(uint16_t status); 56 static void bta_hl_sdp_cback4(uint16_t status); 57 static void bta_hl_sdp_cback5(uint16_t status); 58 static void bta_hl_sdp_cback6(uint16_t status); 59 60 static tSDP_DISC_CMPL_CB* const bta_hl_sdp_cback_arr[] = { 61 bta_hl_sdp_cback0, bta_hl_sdp_cback1, bta_hl_sdp_cback2, bta_hl_sdp_cback3, 62 bta_hl_sdp_cback4, bta_hl_sdp_cback5, bta_hl_sdp_cback6}; 63 64 /******************************************************************************* 65 * 66 * Function bta_hl_dch_mca_cong_change 67 * 68 * Description Action routine for processing congestion change notification 69 * 70 * Returns void 71 * 72 ******************************************************************************/ 73 void bta_hl_dch_mca_cong_change(uint8_t app_idx, uint8_t mcl_idx, 74 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 75 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 76 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 77 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 78 tMCA_CONG_CHG* p_cong_chg = &p_data->mca_evt.mca_data.cong_chg; 79 tBTA_HL evt_data; 80 81 #if (BTA_HL_DEBUG == TRUE) 82 APPL_TRACE_DEBUG("bta_hl_dch_mca_cong_change mdl_id=%d cong=%d", 83 p_cong_chg->mdl_id, p_cong_chg->cong); 84 #endif 85 evt_data.dch_cong_ind.cong = p_dcb->cong = p_cong_chg->cong; 86 evt_data.dch_cong_ind.mdl_handle = p_dcb->mdl_handle; 87 evt_data.dch_cong_ind.mcl_handle = p_mcb->mcl_handle; 88 evt_data.dch_cong_ind.app_handle = p_acb->app_handle; 89 90 p_acb->p_cback(BTA_HL_CONG_CHG_IND_EVT, (tBTA_HL*)&evt_data); 91 } 92 93 /******************************************************************************* 94 * 95 * Function bta_hl_dch_echo_test 96 * 97 * Description Action routine for processing echo test request 98 * 99 * Returns void 100 * 101 ******************************************************************************/ 102 void bta_hl_dch_echo_test(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 103 UNUSED_ATTR tBTA_HL_DATA* p_data) { 104 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 105 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 106 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 107 108 #if (BTA_HL_DEBUG == TRUE) 109 APPL_TRACE_DEBUG("bta_hl_dch_echo_test"); 110 #endif 111 112 p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_GET_ECHO_DATA; 113 p_dcb->cout_oper |= BTA_HL_CO_GET_ECHO_DATA_MASK; 114 115 bta_hl_co_get_echo_data( 116 p_acb->app_id, p_mcb->mcl_handle, p_dcb->p_echo_tx_pkt->len, 117 BTA_HL_GET_BUF_PTR(p_dcb->p_echo_tx_pkt), BTA_HL_CI_GET_ECHO_DATA_EVT); 118 } 119 /******************************************************************************* 120 * 121 * Function bta_hl_dch_sdp_init 122 * 123 * Description Action routine for processing DCH SDP initiation 124 * 125 * Returns void 126 * 127 ******************************************************************************/ 128 void bta_hl_dch_sdp_init(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 129 tBTA_HL_DATA* p_data) { 130 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 131 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 132 133 #if (BTA_HL_DEBUG == TRUE) 134 APPL_TRACE_DEBUG("bta_hl_dch_sdp_init"); 135 #endif 136 if (p_mcb->sdp_oper == BTA_HL_SDP_OP_NONE) { 137 p_mcb->sdp_mdl_idx = mdl_idx; 138 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) { 139 p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_OPEN_INIT; 140 141 } else { 142 p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_RECONNECT_INIT; 143 } 144 145 if (bta_hl_init_sdp(p_mcb->sdp_oper, app_idx, mcl_idx, mdl_idx) != 146 BTA_HL_STATUS_OK) { 147 APPL_TRACE_ERROR("SDP INIT failed"); 148 p_mcb->sdp_oper = BTA_HL_SDP_OP_NONE; 149 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT, 150 p_data); 151 } 152 } else { 153 APPL_TRACE_ERROR("SDP in use"); 154 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT, 155 p_data); 156 } 157 } 158 159 /******************************************************************************* 160 * 161 * Function bta_hl_dch_close_echo_test 162 * 163 * Description Action routine for processing the closing of echo test 164 * 165 * Returns void 166 * 167 ******************************************************************************/ 168 void bta_hl_dch_close_echo_test(uint8_t app_idx, uint8_t mcl_idx, 169 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 170 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 171 172 #if (BTA_HL_DEBUG == TRUE) 173 APPL_TRACE_DEBUG("bta_hl_dch_close_echo_test"); 174 #endif 175 176 switch (p_dcb->echo_oper) { 177 case BTA_HL_ECHO_OP_DCH_CLOSE_CFM: 178 case BTA_HL_ECHO_OP_OPEN_IND: 179 case BTA_HL_ECHO_OP_ECHO_PKT: 180 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST; 181 break; 182 case BTA_HL_ECHO_OP_MDL_CREATE_CFM: 183 case BTA_HL_ECHO_OP_DCH_OPEN_CFM: 184 case BTA_HL_ECHO_OP_LOOP_BACK: 185 default: 186 break; 187 } 188 189 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) != MCA_SUCCESS) { 190 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 191 p_data); 192 } 193 } 194 195 /******************************************************************************* 196 * 197 * Function bta_hl_dch_mca_rcv_data 198 * 199 * Description Action routine for processing the received data 200 * 201 * Returns void 202 * 203 ******************************************************************************/ 204 void bta_hl_dch_mca_rcv_data(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 205 tBTA_HL_DATA* p_data) { 206 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 207 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 208 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 209 210 #if (BTA_HL_DEBUG == TRUE) 211 APPL_TRACE_DEBUG("bta_hl_dch_mca_rcv_data"); 212 #endif 213 214 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 215 switch (p_dcb->echo_oper) { 216 case BTA_HL_ECHO_OP_ECHO_PKT: 217 218 if (MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, 219 p_data->mca_rcv_data_evt.p_pkt) != MCA_SUCCESS) { 220 osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt); 221 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 222 BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data); 223 } 224 break; 225 case BTA_HL_ECHO_OP_LOOP_BACK: 226 227 p_dcb->p_echo_rx_pkt = p_data->mca_rcv_data_evt.p_pkt; 228 p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_PUT_ECHO_DATA; 229 p_dcb->cout_oper |= BTA_HL_CO_PUT_ECHO_DATA_MASK; 230 p_dcb->ci_put_echo_data_status = BTA_HL_STATUS_FAIL; 231 232 bta_hl_co_put_echo_data(p_acb->app_id, p_mcb->mcl_handle, 233 p_dcb->p_echo_rx_pkt->len, 234 BTA_HL_GET_BUF_PTR(p_dcb->p_echo_rx_pkt), 235 BTA_HL_CI_PUT_ECHO_DATA_EVT); 236 break; 237 default: 238 APPL_TRACE_ERROR("Unknonw echo_oper=%d", p_dcb->echo_oper); 239 break; 240 } 241 242 } else { 243 p_dcb->cout_oper |= BTA_HL_CO_PUT_RX_DATA_MASK; 244 p_dcb->p_rx_pkt = p_data->mca_rcv_data_evt.p_pkt; 245 246 bta_hl_co_put_rx_data( 247 p_acb->app_id, p_dcb->mdl_handle, p_dcb->p_rx_pkt->len, 248 BTA_HL_GET_BUF_PTR(p_dcb->p_rx_pkt), BTA_HL_CI_PUT_RX_DATA_EVT); 249 } 250 } 251 252 /******************************************************************************* 253 * 254 * Function bta_hl_dch_ci_put_echo_data 255 * 256 * Description Action routine for processing the call-in of the 257 * put echo data event 258 * 259 * Returns void 260 * 261 ******************************************************************************/ 262 void bta_hl_dch_ci_put_echo_data(uint8_t app_idx, uint8_t mcl_idx, 263 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 264 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 265 266 #if (BTA_HL_DEBUG == TRUE) 267 APPL_TRACE_DEBUG("bta_hl_dch_ci_put_echo_data"); 268 #endif 269 270 p_dcb->cout_oper &= ~BTA_HL_CO_PUT_ECHO_DATA_MASK; 271 osi_free_and_reset((void**)&p_dcb->p_echo_rx_pkt); 272 p_dcb->ci_put_echo_data_status = p_data->ci_get_put_echo_data.status; 273 274 p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_CLOSE_CFM; 275 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 276 BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data); 277 } 278 279 /******************************************************************************* 280 * 281 * Function bta_hl_dch_ci_get_echo_data 282 * 283 * Description Action routine for processing the call-in of the 284 * get echo data event 285 * 286 * Returns void 287 * 288 ******************************************************************************/ 289 void bta_hl_dch_ci_get_echo_data(uint8_t app_idx, uint8_t mcl_idx, 290 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 291 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 292 tBTA_HL_STATUS status; 293 294 #if (BTA_HL_DEBUG == TRUE) 295 APPL_TRACE_DEBUG("bta_hl_dch_ci_get_echo_data"); 296 #endif 297 298 p_dcb->cout_oper &= ~BTA_HL_CO_GET_ECHO_DATA_MASK; 299 300 if (!p_dcb->abort_oper) { 301 status = p_data->ci_get_put_echo_data.status; 302 if (status == BTA_HL_STATUS_OK) { 303 p_dcb->echo_oper = BTA_HL_ECHO_OP_MDL_CREATE_CFM; 304 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_OPEN_EVT, 305 p_data); 306 } else { 307 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 308 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 309 } 310 } else { 311 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 312 p_data); 313 } 314 } 315 316 /******************************************************************************* 317 * 318 * Function bta_hl_dch_ci_put_rx_data 319 * 320 * Description Action routine for processing the call-in of the 321 * put rx data event 322 * 323 * Returns void 324 * 325 ******************************************************************************/ 326 void bta_hl_dch_ci_put_rx_data(uint8_t app_idx, uint8_t mcl_idx, 327 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 328 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 329 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 330 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 331 tBTA_HL evt_data; 332 333 #if (BTA_HL_DEBUG == TRUE) 334 APPL_TRACE_DEBUG("bta_hl_dch_ci_put_rx_data"); 335 #endif 336 337 p_dcb->cout_oper &= ~BTA_HL_CO_PUT_RX_DATA_MASK; 338 osi_free_and_reset((void**)&p_dcb->p_rx_pkt); 339 bta_hl_build_rcv_data_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 340 p_dcb->mdl_handle); 341 p_acb->p_cback(BTA_HL_DCH_RCV_DATA_IND_EVT, (tBTA_HL*)&evt_data); 342 if (p_dcb->close_pending) { 343 if (!p_dcb->cout_oper) { 344 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, 345 p_data); 346 } 347 } 348 } 349 350 /******************************************************************************* 351 * 352 * Function bta_hl_dch_ci_get_tx_data 353 * 354 * Description Action routine for processing the call-in of the 355 * get tx data event 356 * 357 * Returns void 358 * 359 ******************************************************************************/ 360 void bta_hl_dch_ci_get_tx_data(uint8_t app_idx, uint8_t mcl_idx, 361 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 362 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 363 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 364 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 365 tMCA_RESULT result; 366 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 367 bool free_buf = false; 368 bool close_dch = false; 369 tBTA_HL evt_data; 370 371 #if (BTA_HL_DEBUG == TRUE) 372 APPL_TRACE_DEBUG("bta_hl_dch_ci_get_tx_data"); 373 #endif 374 375 if (p_data != NULL) { 376 status = p_data->ci_get_put_data.status; 377 APPL_TRACE_WARNING("%s: status=%d", __func__, status); 378 } 379 380 p_dcb->cout_oper &= ~BTA_HL_CO_GET_TX_DATA_MASK; 381 382 if (p_dcb->close_pending) { 383 status = BTA_HL_STATUS_FAIL; 384 free_buf = true; 385 386 if (!p_dcb->cout_oper) { 387 close_dch = true; 388 } 389 } else if (status == BTA_HL_STATUS_FAIL) { 390 free_buf = TRUE; 391 } else { 392 result = MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_tx_pkt); 393 if (result != MCA_SUCCESS) { 394 if (result == MCA_BUSY) { 395 status = BTA_HL_STATUS_DCH_BUSY; 396 } else { 397 status = BTA_HL_STATUS_FAIL; 398 } 399 free_buf = true; 400 } else { 401 p_dcb->p_tx_pkt = NULL; 402 } 403 } 404 405 if (free_buf) osi_free_and_reset((void**)&p_dcb->p_tx_pkt); 406 407 bta_hl_build_send_data_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 408 p_dcb->mdl_handle, status); 409 p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT, (tBTA_HL*)&evt_data); 410 411 if (close_dch) { 412 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, 413 p_data); 414 } 415 } 416 417 /******************************************************************************* 418 * 419 * Function bta_hl_dch_send_data 420 * 421 * Description Action routine for processing api send data request 422 * 423 * Returns void 424 * 425 ******************************************************************************/ 426 void bta_hl_dch_send_data(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 427 tBTA_HL_DATA* p_data) { 428 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 429 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 430 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 431 tBTA_HL evt_data; 432 bool success = true; 433 434 #if (BTA_HL_DEBUG == TRUE) 435 APPL_TRACE_DEBUG("bta_hl_dch_send_data"); 436 #endif 437 438 if (!(p_dcb->cout_oper & BTA_HL_CO_GET_TX_DATA_MASK)) { 439 // p_dcb->chnl_cfg.fcs may be BTA_HL_MCA_USE_FCS (0x11) or BTA_HL_MCA_NO_FCS 440 // (0x10) or BTA_HL_DEFAULT_SOURCE_FCS (1) 441 bool fcs_use = (bool)(p_dcb->chnl_cfg.fcs & BTA_HL_MCA_FCS_USE_MASK); 442 p_dcb->p_tx_pkt = bta_hl_get_buf(p_data->api_send_data.pkt_size, fcs_use); 443 if (p_dcb->p_tx_pkt != NULL) { 444 bta_hl_co_get_tx_data( 445 p_acb->app_id, p_dcb->mdl_handle, p_data->api_send_data.pkt_size, 446 BTA_HL_GET_BUF_PTR(p_dcb->p_tx_pkt), BTA_HL_CI_GET_TX_DATA_EVT); 447 p_dcb->cout_oper |= BTA_HL_CO_GET_TX_DATA_MASK; 448 } else { 449 success = false; 450 } 451 } else { 452 success = false; 453 } 454 455 if (!success) { 456 bta_hl_build_send_data_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 457 p_dcb->mdl_handle, BTA_HL_STATUS_FAIL); 458 p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT, (tBTA_HL*)&evt_data); 459 } 460 } 461 462 /******************************************************************************* 463 * 464 * Function bta_hl_dch_close_cmpl 465 * 466 * Description Action routine for processing the close complete event 467 * 468 * Returns void 469 * 470 ******************************************************************************/ 471 void bta_hl_dch_close_cmpl(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 472 tBTA_HL_DATA* p_data) { 473 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 474 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 475 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 476 tBTA_HL evt_data; 477 tBTA_HL_EVT event = 0; 478 bool send_evt = true; 479 tBTA_HL_STATUS status; 480 481 #if (BTA_HL_DEBUG == TRUE) 482 APPL_TRACE_DEBUG("bta_hl_dch_close_cmpl dch oper=%s", 483 bta_hl_dch_oper_code(p_dcb->dch_oper)); 484 #endif 485 486 switch (p_dcb->dch_oper) { 487 case BTA_HL_DCH_OP_LOCAL_OPEN: 488 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 489 490 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 491 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 492 BTA_HL_STATUS_OK); 493 event = BTA_HL_DCH_ABORT_CFM_EVT; 494 } else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK) { 495 bta_hl_build_abort_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle); 496 event = BTA_HL_DCH_ABORT_IND_EVT; 497 } else { 498 bta_hl_build_dch_open_cfm(&evt_data, p_acb->app_handle, 499 p_mcb->mcl_handle, BTA_HL_INVALID_MDL_HANDLE, 500 0, 0, 0, 0, 0, BTA_HL_STATUS_FAIL); 501 event = BTA_HL_DCH_OPEN_CFM_EVT; 502 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT) { 503 event = BTA_HL_DCH_RECONNECT_CFM_EVT; 504 } 505 } 506 break; 507 508 case BTA_HL_DCH_OP_LOCAL_CLOSE: 509 case BTA_HL_DCH_OP_REMOTE_DELETE: 510 case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT: 511 case BTA_HL_DCH_OP_NONE: 512 513 bta_hl_build_dch_close_cfm(&evt_data, p_acb->app_handle, 514 p_mcb->mcl_handle, p_dcb->mdl_handle, 515 BTA_HL_STATUS_OK); 516 event = BTA_HL_DCH_CLOSE_CFM_EVT; 517 break; 518 519 case BTA_HL_DCH_OP_REMOTE_CLOSE: 520 bta_hl_build_dch_close_ind(&evt_data, p_acb->app_handle, 521 p_mcb->mcl_handle, p_dcb->mdl_handle, 522 p_dcb->intentional_close); 523 event = BTA_HL_DCH_CLOSE_IND_EVT; 524 break; 525 526 case BTA_HL_DCH_OP_REMOTE_OPEN: 527 528 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 529 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 530 BTA_HL_STATUS_OK); 531 event = BTA_HL_DCH_ABORT_CFM_EVT; 532 } else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK) { 533 bta_hl_build_abort_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle); 534 event = BTA_HL_DCH_ABORT_IND_EVT; 535 } else { 536 bta_hl_build_dch_close_ind(&evt_data, p_acb->app_handle, 537 p_mcb->mcl_handle, p_dcb->mdl_handle, 538 p_dcb->intentional_close); 539 event = BTA_HL_DCH_CLOSE_IND_EVT; 540 } 541 break; 542 543 case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST: 544 /* this is normal echo test close */ 545 case BTA_HL_DCH_OP_REMOTE_CREATE: 546 case BTA_HL_DCH_OP_REMOTE_RECONNECT: 547 send_evt = false; 548 break; 549 550 default: 551 #if (BTA_HL_DEBUG == TRUE) 552 APPL_TRACE_ERROR("DCH operation not found oper=%s", 553 bta_hl_dch_oper_code(p_dcb->dch_oper)); 554 #endif 555 send_evt = false; 556 break; 557 } 558 559 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 560 p_mcb->echo_test = false; 561 send_evt = false; 562 563 if (p_dcb->dch_oper != BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST) { 564 switch (p_dcb->echo_oper) { 565 case BTA_HL_ECHO_OP_CI_GET_ECHO_DATA: 566 case BTA_HL_ECHO_OP_SDP_INIT: 567 case BTA_HL_ECHO_OP_MDL_CREATE_CFM: 568 case BTA_HL_ECHO_OP_DCH_OPEN_CFM: 569 case BTA_HL_ECHO_OP_LOOP_BACK: 570 571 status = BTA_HL_STATUS_FAIL; 572 send_evt = true; 573 break; 574 case BTA_HL_ECHO_OP_OPEN_IND: 575 case BTA_HL_ECHO_OP_ECHO_PKT: 576 break; 577 default: 578 APPL_TRACE_ERROR("Invalid echo_oper=%d", p_dcb->echo_oper); 579 break; 580 } 581 } else { 582 status = p_dcb->ci_put_echo_data_status; 583 send_evt = true; 584 } 585 586 if (send_evt) { 587 bta_hl_build_echo_test_cfm(&evt_data, p_acb->app_handle, 588 p_mcb->mcl_handle, status); 589 event = BTA_HL_DCH_ECHO_TEST_CFM_EVT; 590 } 591 } 592 593 bta_hl_clean_mdl_cb(app_idx, mcl_idx, mdl_idx); 594 595 if (send_evt) { 596 if (p_acb->p_cback) { 597 #if (BTA_HL_DEBUG == TRUE) 598 APPL_TRACE_DEBUG("Send Event: %s", bta_hl_cback_evt_code(event)); 599 #endif 600 p_acb->p_cback(event, (tBTA_HL*)&evt_data); 601 } 602 } 603 /* check cch close is in progress or not */ 604 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, false); 605 } 606 /******************************************************************************* 607 * 608 * Function bta_hl_dch_mca_close_ind 609 * 610 * Description Action routine for processing the close indication 611 * 612 * Returns void 613 * 614 ******************************************************************************/ 615 void bta_hl_dch_mca_close_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 616 tBTA_HL_DATA* p_data) { 617 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 618 619 #if (BTA_HL_DEBUG == TRUE) 620 APPL_TRACE_DEBUG("bta_hl_dch_mca_close_ind dch oper=%s", 621 bta_hl_dch_oper_code(p_dcb->dch_oper)); 622 #endif 623 624 p_dcb->intentional_close = false; 625 if (p_data->mca_evt.mca_data.close_ind.reason == L2CAP_DISC_OK) { 626 p_dcb->intentional_close = true; 627 } 628 629 if (!p_dcb->cout_oper) { 630 if ((p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_OPEN) && 631 (p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_RECONNECT)) { 632 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CLOSE; 633 } 634 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 635 p_data); 636 } else { 637 p_dcb->close_pending = true; 638 } 639 } 640 641 /******************************************************************************* 642 * 643 * Function bta_hl_dch_mca_close_cfm 644 * 645 * Description Action routine for processing the close confirmation 646 * 647 * Returns void 648 * 649 ******************************************************************************/ 650 void bta_hl_dch_mca_close_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 651 tBTA_HL_DATA* p_data) { 652 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 653 654 #if (BTA_HL_DEBUG == TRUE) 655 APPL_TRACE_DEBUG("bta_hl_dch_mca_close_cfm dch_oper=%s", 656 bta_hl_dch_oper_code(p_dcb->dch_oper)); 657 #endif 658 659 switch (p_dcb->dch_oper) { 660 case BTA_HL_DCH_OP_LOCAL_CLOSE: 661 case BTA_HL_DCH_OP_LOCAL_OPEN: 662 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 663 case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST: 664 case BTA_HL_DCH_OP_REMOTE_DELETE: 665 case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT: 666 case BTA_HL_DCH_OP_NONE: 667 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 668 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 669 break; 670 default: 671 #if (BTA_HL_DEBUG == TRUE) 672 APPL_TRACE_ERROR("Invalid dch_oper=%s for close cfm", 673 bta_hl_dch_oper_code(p_dcb->dch_oper)); 674 #endif 675 break; 676 } 677 } 678 679 /******************************************************************************* 680 * 681 * Function bta_hl_dch_mca_close 682 * 683 * Description Action routine for processing the DCH close request 684 * 685 * Returns void 686 * 687 ******************************************************************************/ 688 void bta_hl_dch_mca_close(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 689 tBTA_HL_DATA* p_data) { 690 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 691 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 692 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 693 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 694 tBTA_HL evt_data; 695 696 #if (BTA_HL_DEBUG == TRUE) 697 APPL_TRACE_DEBUG("bta_hl_dch_mca_close"); 698 #endif 699 if (!p_dcb->cout_oper) { 700 p_dcb->close_pending = false; 701 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) { 702 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE; 703 } else { 704 status = BTA_HL_STATUS_FAIL; 705 } 706 707 if ((status != BTA_HL_STATUS_OK) && 708 (p_mcb->cch_close_dch_oper != BTA_HL_CCH_CLOSE_OP_DCH_CLOSE)) { 709 bta_hl_build_dch_close_cfm(&evt_data, p_acb->app_handle, 710 p_mcb->mcl_handle, 711 p_data->api_dch_close.mdl_handle, status); 712 p_acb->p_cback(BTA_HL_DCH_CLOSE_CFM_EVT, (tBTA_HL*)&evt_data); 713 } 714 } else { 715 p_dcb->close_pending = true; 716 } 717 } 718 719 /******************************************************************************* 720 * 721 * Function bta_hl_dch_mca_open_ind 722 * 723 * Description Action routine for processing the open indication 724 * 725 * Returns void 726 * 727 ******************************************************************************/ 728 void bta_hl_dch_mca_open_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 729 tBTA_HL_DATA* p_data) { 730 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 731 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 732 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 733 tMCA_DL_OPEN* p_open_ind = &p_data->mca_evt.mca_data.open_ind; 734 tBTA_HL evt_data; 735 tBTA_HL_EVT event; 736 uint8_t old_dch_oper = BTA_HL_DCH_OP_NONE; 737 bool send_event = false; 738 739 #if (BTA_HL_DEBUG == TRUE) 740 APPL_TRACE_DEBUG("bta_hl_dch_mca_open_ind"); 741 #endif 742 if ((p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_OPEN) || 743 (p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_RECONNECT)) { 744 p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE)p_open_ind->mdl; 745 p_dcb->mtu = p_open_ind->mtu; 746 747 evt_data.dch_open_ind.mdl_handle = p_dcb->mdl_handle; 748 evt_data.dch_open_ind.mcl_handle = p_mcb->mcl_handle; 749 evt_data.dch_open_ind.app_handle = p_acb->app_handle; 750 751 evt_data.dch_open_ind.local_mdep_id = p_dcb->local_mdep_id; 752 evt_data.dch_open_ind.mdl_id = p_dcb->mdl_id; 753 evt_data.dch_open_ind.mtu = p_dcb->mtu; 754 755 if (p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE) { 756 evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_RELIABLE; 757 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 758 p_dcb->is_the_first_reliable = true; 759 } 760 } else { 761 evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_STREAMING; 762 } 763 evt_data.dch_open_ind.first_reliable = p_dcb->is_the_first_reliable; 764 765 old_dch_oper = p_dcb->dch_oper; 766 p_dcb->dch_oper = BTA_HL_DCH_OP_NONE; 767 } 768 769 switch (old_dch_oper) { 770 case BTA_HL_DCH_OP_REMOTE_OPEN: 771 772 p_dcb->dch_mode = evt_data.dch_open_ind.dch_mode; 773 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) { 774 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 775 event = BTA_HL_DCH_OPEN_IND_EVT; 776 send_event = true; 777 } else { 778 p_dcb->echo_oper = BTA_HL_ECHO_OP_ECHO_PKT; 779 } 780 781 break; 782 783 case BTA_HL_DCH_OP_REMOTE_RECONNECT: 784 785 if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx)) { 786 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 787 event = BTA_HL_DCH_RECONNECT_IND_EVT; 788 send_event = true; 789 } else { 790 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) { 791 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT; 792 } else { 793 APPL_TRACE_ERROR("Unabel to close DCH for reconnect cfg mismatch"); 794 } 795 } 796 break; 797 default: 798 break; 799 } 800 801 if (send_event) { 802 p_acb->p_cback(event, (tBTA_HL*)&evt_data); 803 } 804 } 805 806 /******************************************************************************* 807 * 808 * Function bta_hl_dch_mca_open_cfm 809 * 810 * Description Action routine for processing the open confirmation 811 * 812 * Returns void 813 * 814 ******************************************************************************/ 815 void bta_hl_dch_mca_open_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 816 tBTA_HL_DATA* p_data) { 817 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 818 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 819 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 820 tMCA_DL_OPEN* p_open_cfm = &p_data->mca_evt.mca_data.open_cfm; 821 tBTA_HL evt_data; 822 tBTA_HL_EVT event; 823 uint8_t old_dch_oper = BTA_HL_DCH_OP_NONE; 824 tBTA_HL_DCH_MODE dch_mode = BTA_HL_DCH_MODE_STREAMING; 825 bool send_event = false; 826 827 #if (BTA_HL_DEBUG == TRUE) 828 APPL_TRACE_DEBUG("bta_hl_dch_mca_open_cfm"); 829 #endif 830 if ((p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) || 831 (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT)) { 832 p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE)p_open_cfm->mdl; 833 p_dcb->mtu = p_open_cfm->mtu; 834 835 /*todo verify dch_mode, mtu and fcs for reconnect */ 836 if (p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE) { 837 dch_mode = BTA_HL_DCH_MODE_RELIABLE; 838 } 839 840 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) { 841 if (dch_mode == BTA_HL_DCH_MODE_RELIABLE) { 842 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 843 p_dcb->is_the_first_reliable = true; 844 } 845 } 846 } 847 848 bta_hl_build_dch_open_cfm( 849 &evt_data, p_acb->app_handle, p_mcb->mcl_handle, p_dcb->mdl_handle, 850 p_dcb->local_mdep_id, p_dcb->mdl_id, dch_mode, 851 p_dcb->is_the_first_reliable, p_dcb->mtu, BTA_HL_STATUS_OK); 852 853 old_dch_oper = p_dcb->dch_oper; 854 p_dcb->dch_oper = BTA_HL_DCH_OP_NONE; 855 } else { 856 APPL_TRACE_ERROR("Error dch oper =%d", p_dcb->dch_oper); 857 return; 858 } 859 860 switch (old_dch_oper) { 861 case BTA_HL_DCH_OP_LOCAL_OPEN: 862 863 p_dcb->dch_mode = dch_mode; 864 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) { 865 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 866 event = BTA_HL_DCH_OPEN_CFM_EVT; 867 send_event = true; 868 } else { 869 p_dcb->echo_oper = BTA_HL_ECHO_OP_LOOP_BACK; 870 if (MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_echo_tx_pkt) != 871 MCA_SUCCESS) { 872 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 873 BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data); 874 } else { 875 p_dcb->p_echo_tx_pkt = NULL; 876 } 877 } 878 break; 879 880 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 881 882 if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx)) { 883 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 884 event = BTA_HL_DCH_RECONNECT_CFM_EVT; 885 send_event = true; 886 } else { 887 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) { 888 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT; 889 } else { 890 APPL_TRACE_ERROR("Unabel to close DCH for reconnect cfg mismatch"); 891 } 892 } 893 break; 894 default: 895 break; 896 } 897 898 if (send_event) p_acb->p_cback(event, (tBTA_HL*)&evt_data); 899 } 900 901 /******************************************************************************* 902 * 903 * Function bta_hl_dch_mca_abort_ind 904 * 905 * Description Action routine for processing the abort indication 906 * 907 * Returns void 908 * 909 ******************************************************************************/ 910 void bta_hl_dch_mca_abort_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 911 tBTA_HL_DATA* p_data) { 912 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 913 914 #if (BTA_HL_DEBUG == TRUE) 915 APPL_TRACE_DEBUG("bta_hl_dch_mca_abort_ind"); 916 #endif 917 918 p_dcb->abort_oper |= BTA_HL_ABORT_REMOTE_MASK; 919 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 920 p_data); 921 } 922 923 /******************************************************************************* 924 * 925 * Function bta_hl_dch_mca_abort_cfm 926 * 927 * Description Action routine for processing the abort confirmation 928 * 929 * Returns void 930 * 931 ******************************************************************************/ 932 void bta_hl_dch_mca_abort_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 933 tBTA_HL_DATA* p_data) { 934 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 935 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 936 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 937 tBTA_HL evt_data; 938 939 #if (BTA_HL_DEBUG == TRUE) 940 APPL_TRACE_DEBUG("bta_hl_dch_mca_abort_cfm"); 941 #endif 942 943 if (p_dcb->abort_oper) { 944 if (p_data->mca_evt.mca_data.abort_cfm.rsp_code != MCA_RSP_SUCCESS) { 945 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 946 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 947 BTA_HL_STATUS_FAIL); 948 p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT, (tBTA_HL*)&evt_data); 949 } 950 } else { 951 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 952 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 953 } 954 } else { 955 APPL_TRACE_ERROR("Not expecting Abort CFM "); 956 } 957 } 958 959 /******************************************************************************* 960 * 961 * Function bta_hl_dch_mca_abort 962 * 963 * Description Action routine for processing the abort request 964 * 965 * Returns void 966 * 967 ******************************************************************************/ 968 void bta_hl_dch_mca_abort(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 969 tBTA_HL_DATA* p_data) { 970 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 971 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 972 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 973 tMCA_RESULT mca_result; 974 tBTA_HL evt_data; 975 976 if (((p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) || 977 (p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_RECONNECT_INIT)) && 978 (p_mcb->sdp_mdl_idx == mdl_idx)) { 979 p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK; 980 return; 981 } else if (p_dcb->echo_oper == BTA_HL_ECHO_OP_CI_GET_ECHO_DATA) { 982 p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK; 983 return; 984 } 985 986 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 987 988 mca_result = MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 989 if (mca_result != MCA_SUCCESS) { 990 if (mca_result == MCA_NO_RESOURCES) { 991 p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK; 992 } else { 993 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 994 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 995 BTA_HL_STATUS_FAIL); 996 p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT, (tBTA_HL*)&evt_data); 997 } 998 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, false); 999 } 1000 } 1001 1002 #if (BTA_HL_DEBUG == TRUE) 1003 APPL_TRACE_DEBUG("bta_hl_dch_mca_abort abort_oper=0x%x", p_dcb->abort_oper); 1004 #endif 1005 } 1006 1007 /******************************************************************************* 1008 * 1009 * Function bta_hl_dch_mca_reconnect_ind 1010 * 1011 * Description Action routine for processing the reconnect indication 1012 * 1013 * Returns void 1014 * 1015 ******************************************************************************/ 1016 void bta_hl_dch_mca_reconnect_ind(uint8_t app_idx, uint8_t mcl_idx, 1017 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1018 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1019 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1020 tBTA_HL_MDL_CFG* p_mdl_cfg; 1021 tMCA_EVT_HDR* p_reconnect_ind = &p_data->mca_evt.mca_data.reconnect_ind; 1022 uint8_t mdl_cfg_idx, in_use_mdl_idx, mdep_cfg_idx; 1023 uint8_t rsp_code = MCA_RSP_SUCCESS; 1024 1025 #if (BTA_HL_DEBUG == TRUE) 1026 APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect_ind mdl_id=%d", 1027 p_reconnect_ind->mdl_id); 1028 #endif 1029 1030 if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id, 1031 &mdl_cfg_idx)) { 1032 if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id, 1033 &in_use_mdl_idx)) { 1034 p_mdl_cfg = BTA_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx); 1035 1036 if (bta_hl_find_mdep_cfg_idx(app_idx, p_mdl_cfg->local_mdep_id, 1037 &mdep_cfg_idx)) { 1038 p_dcb->in_use = true; 1039 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_RECONNECT; 1040 p_dcb->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 1041 p_dcb->peer_mdep_id = 0xFF; 1042 p_dcb->local_mdep_id = p_mdl_cfg->local_mdep_id; 1043 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1044 p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN; 1045 p_dcb->mdl_id = p_reconnect_ind->mdl_id; 1046 p_dcb->mdl_cfg_idx_included = true; 1047 p_dcb->mdl_cfg_idx = mdl_cfg_idx; 1048 p_dcb->dch_mode = p_mdl_cfg->dch_mode; 1049 bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx, 1050 &p_dcb->max_rx_apdu_size, 1051 &p_dcb->max_tx_apdu_size); 1052 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1053 } else { 1054 rsp_code = MCA_RSP_BAD_MDL; 1055 } 1056 } else { 1057 rsp_code = MCA_RSP_BAD_MDL; 1058 } 1059 } else { 1060 rsp_code = MCA_RSP_BAD_MDL; 1061 } 1062 1063 if (MCA_ReconnectMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1064 p_dcb->mdl_id, rsp_code, 1065 &p_dcb->chnl_cfg) != MCA_SUCCESS) { 1066 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1067 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1068 p_data); 1069 } 1070 } 1071 1072 /******************************************************************************* 1073 * 1074 * Function bta_hl_dch_mca_reconnect_cfm 1075 * 1076 * Description Action routine for processing the reconenct confirmation 1077 * 1078 * Returns void 1079 * 1080 ******************************************************************************/ 1081 void bta_hl_dch_mca_reconnect_cfm(uint8_t app_idx, uint8_t mcl_idx, 1082 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1083 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1084 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1085 tMCA_RSP_EVT* p_reconnect_cfm = &p_data->mca_evt.mca_data.reconnect_cfm; 1086 1087 #if (BTA_HL_DEBUG == TRUE) 1088 APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect_cfm"); 1089 #endif 1090 if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) { 1091 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 1092 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, 1093 p_data); 1094 return; 1095 } 1096 1097 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT) { 1098 if (p_reconnect_cfm->rsp_code == MCA_RSP_SUCCESS) { 1099 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1100 1101 if (MCA_DataChnlCfg((tMCA_CL)p_mcb->mcl_handle, &p_dcb->chnl_cfg) != 1102 MCA_SUCCESS) { 1103 /* should be able to abort so no checking of the return code */ 1104 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1105 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1106 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1107 } 1108 } else { 1109 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1110 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1111 } 1112 } 1113 } 1114 1115 /******************************************************************************* 1116 * 1117 * Function bta_hl_dch_mca_reconnect 1118 * 1119 * Description Action routine for processing the reconnect request 1120 * 1121 * Returns void 1122 * 1123 ******************************************************************************/ 1124 void bta_hl_dch_mca_reconnect(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1125 tBTA_HL_DATA* p_data) { 1126 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1127 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1128 tMCA_CHNL_CFG* p_chnl_cfg = NULL; 1129 uint8_t sdp_idx; 1130 1131 #if (BTA_HL_DEBUG == TRUE) 1132 APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect"); 1133 #endif 1134 if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm, 1135 &sdp_idx)) { 1136 p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm; 1137 if (MCA_ReconnectMdl((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1138 p_mcb->data_psm, p_dcb->mdl_id, 1139 p_chnl_cfg) != MCA_SUCCESS) { 1140 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1141 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1142 } 1143 } else { 1144 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1145 p_data); 1146 } 1147 } 1148 1149 /******************************************************************************* 1150 * 1151 * Function bta_hl_dch_create_rsp 1152 * 1153 * Description Action routine for processing BTA_HL_API_DCH_CREATE_RSP_EVT 1154 * 1155 * Returns void 1156 * 1157 ******************************************************************************/ 1158 void bta_hl_dch_create_rsp(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1159 tBTA_HL_DATA* p_data) { 1160 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1161 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1162 tBTA_HL_API_DCH_CREATE_RSP* p_create_rsp = &p_data->api_dch_create_rsp; 1163 uint8_t mca_rsp_code = MCA_RSP_SUCCESS; 1164 1165 #if (BTA_HL_DEBUG == TRUE) 1166 APPL_TRACE_DEBUG("bta_hl_dch_create_rsp"); 1167 #endif 1168 if (p_create_rsp->rsp_code == BTA_HL_DCH_CREATE_RSP_SUCCESS) { 1169 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN; 1170 p_dcb->local_cfg = p_create_rsp->cfg_rsp; 1171 1172 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1173 } else { 1174 mca_rsp_code = MCA_RSP_CFG_REJ; 1175 } 1176 1177 if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1178 p_dcb->mdl_id, p_dcb->local_cfg, mca_rsp_code, 1179 &p_dcb->chnl_cfg) != MCA_SUCCESS) { 1180 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1181 p_data); 1182 } 1183 } 1184 1185 /******************************************************************************* 1186 * 1187 * Function bta_hl_dch_mca_create_ind 1188 * 1189 * Description Action routine for processing 1190 * 1191 * Returns void 1192 * 1193 ******************************************************************************/ 1194 void bta_hl_dch_mca_create_ind(uint8_t app_idx, uint8_t mcl_idx, 1195 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1196 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1197 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1198 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1199 tMCA_CREATE_IND* p_create_ind = &p_data->mca_evt.mca_data.create_ind; 1200 uint8_t mdep_cfg_idx; 1201 uint8_t cfg_rsp; 1202 uint8_t rsp_code = MCA_RSP_SUCCESS; 1203 bool send_create_ind_evt = false; 1204 tBTA_HL evt_data; 1205 tBTA_HL_ECHO_CFG* p_echo_cfg; 1206 1207 #if (BTA_HL_DEBUG == TRUE) 1208 APPL_TRACE_DEBUG("bta_hl_dch_mca_create_ind"); 1209 #endif 1210 1211 if (bta_hl_find_mdep_cfg_idx(app_idx, p_create_ind->dep_id, &mdep_cfg_idx)) { 1212 if (p_create_ind->dep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1213 if (bta_hl_find_echo_cfg_rsp(app_idx, mcl_idx, mdep_cfg_idx, 1214 p_create_ind->cfg, &cfg_rsp)) { 1215 p_dcb->in_use = true; 1216 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN; 1217 p_dcb->local_mdep_id = p_create_ind->dep_id; 1218 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1219 p_dcb->local_cfg = cfg_rsp; 1220 p_dcb->remote_cfg = p_create_ind->cfg; 1221 p_dcb->mdl_id = p_create_ind->mdl_id; 1222 p_dcb->mdl_cfg_idx_included = false; 1223 p_echo_cfg = BTA_HL_GET_ECHO_CFG_PTR(app_idx); 1224 p_dcb->max_rx_apdu_size = p_echo_cfg->max_rx_apdu_size; 1225 p_dcb->max_tx_apdu_size = p_echo_cfg->max_tx_apdu_size; 1226 1227 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1228 } else { 1229 rsp_code = MCA_RSP_CFG_REJ; 1230 } 1231 } else 1232 1233 { 1234 p_dcb->in_use = true; 1235 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CREATE; 1236 p_dcb->local_mdep_id = p_create_ind->dep_id; 1237 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1238 p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN; 1239 p_dcb->remote_cfg = p_create_ind->cfg; 1240 p_dcb->mdl_id = p_create_ind->mdl_id; 1241 p_dcb->mdl_cfg_idx_included = false; 1242 bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx, 1243 &p_dcb->max_rx_apdu_size, 1244 &p_dcb->max_tx_apdu_size); 1245 send_create_ind_evt = true; 1246 } 1247 } else { 1248 rsp_code = MCA_RSP_BAD_MDEP; 1249 } 1250 1251 if (send_create_ind_evt) { 1252 evt_data.dch_create_ind.mcl_handle = p_mcb->mcl_handle; 1253 evt_data.dch_create_ind.app_handle = p_acb->app_handle; 1254 evt_data.dch_create_ind.local_mdep_id = p_dcb->local_mdep_id; 1255 evt_data.dch_create_ind.mdl_id = p_dcb->mdl_id; 1256 evt_data.dch_create_ind.cfg = p_dcb->remote_cfg; 1257 evt_data.dch_create_ind.bd_addr = p_mcb->bd_addr; 1258 p_acb->p_cback(BTA_HL_DCH_CREATE_IND_EVT, (tBTA_HL*)&evt_data); 1259 } else { 1260 if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1261 p_dcb->mdl_id, p_dcb->local_cfg, rsp_code, 1262 &p_dcb->chnl_cfg) != MCA_SUCCESS) { 1263 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1264 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1265 } else { 1266 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1267 p_mcb->echo_test = true; 1268 p_dcb->echo_oper = BTA_HL_ECHO_OP_OPEN_IND; 1269 } 1270 } 1271 } 1272 } 1273 1274 /******************************************************************************* 1275 * 1276 * Function bta_hl_dch_mca_create_cfm 1277 * 1278 * Description Action routine for processing 1279 * 1280 * Returns void 1281 * 1282 ******************************************************************************/ 1283 void bta_hl_dch_mca_create_cfm(uint8_t app_idx, uint8_t mcl_idx, 1284 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1285 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1286 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1287 tMCA_CREATE_CFM* p_create_cfm = &p_data->mca_evt.mca_data.create_cfm; 1288 1289 #if (BTA_HL_DEBUG == TRUE) 1290 APPL_TRACE_DEBUG("bta_hl_dch_mca_create_cfm"); 1291 #endif 1292 1293 if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) { 1294 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 1295 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, 1296 p_data); 1297 return; 1298 } 1299 1300 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) { 1301 if (p_create_cfm->rsp_code == MCA_RSP_SUCCESS) { 1302 if (bta_hl_validate_cfg(app_idx, mcl_idx, mdl_idx, p_create_cfm->cfg)) { 1303 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1304 1305 if (MCA_DataChnlCfg((tMCA_CL)p_mcb->mcl_handle, &p_dcb->chnl_cfg) != 1306 MCA_SUCCESS) { 1307 /* this should not happen */ 1308 APPL_TRACE_ERROR("Unable to create data channel"); 1309 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1310 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1311 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1312 } else { 1313 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1314 p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_OPEN_CFM; 1315 } 1316 } 1317 } else { 1318 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1319 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1320 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1321 } 1322 } else { 1323 APPL_TRACE_ERROR("MCA Create- failed"); 1324 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1325 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1326 } 1327 } 1328 } 1329 1330 /******************************************************************************* 1331 * 1332 * Function bta_hl_dch_mca_create 1333 * 1334 * Description Action routine for processing the MDL create request 1335 * 1336 * Returns void 1337 * 1338 ******************************************************************************/ 1339 void bta_hl_dch_mca_create(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1340 tBTA_HL_DATA* p_data) { 1341 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1342 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1343 tMCA_RESULT result; 1344 uint8_t sdp_idx; 1345 1346 #if (BTA_HL_DEBUG == TRUE) 1347 APPL_TRACE_DEBUG("bta_hl_dch_mca_create"); 1348 #endif 1349 1350 if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm, 1351 &sdp_idx) && 1352 bta_hl_validate_peer_cfg(app_idx, mcl_idx, mdl_idx, p_dcb->peer_mdep_id, 1353 p_dcb->peer_mdep_role, sdp_idx)) { 1354 p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm; 1355 result = MCA_CreateMdl((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1356 p_mcb->data_psm, p_dcb->mdl_id, p_dcb->peer_mdep_id, 1357 p_dcb->local_cfg, NULL); 1358 if (result != MCA_SUCCESS) { 1359 APPL_TRACE_ERROR("MCA_CreateMdl FAIL mca_result=%d", result); 1360 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1361 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1362 } 1363 } else { 1364 APPL_TRACE_ERROR("MCA Create- SDP idx or peer MDEP cfg not found"); 1365 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1366 p_data); 1367 } 1368 } 1369 1370 /******************************************************************************* 1371 * 1372 * Function bta_hl_dch_sdp_fail 1373 * 1374 * Description Action routine for processing the SDP failed event 1375 * 1376 * Returns void 1377 * 1378 ******************************************************************************/ 1379 void bta_hl_dch_sdp_fail(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1380 tBTA_HL_DATA* p_data) { 1381 #if (BTA_HL_DEBUG == TRUE) 1382 APPL_TRACE_DEBUG("bta_hl_dch_sdp_fail"); 1383 #endif 1384 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1385 p_data); 1386 } 1387 1388 /****************************************************************************** 1389 * 1390 * Function bta_hl_sdp_cback 1391 * 1392 * Description This is the SDP callback function used by HL. 1393 * This function will be executed by SDP when the service 1394 * search is completed. If the search is successful, it 1395 * finds the first record in the database that matches the 1396 * UUID of the search. Then retrieves the scn from the 1397 * record. 1398 * 1399 * Returns void. 1400 * 1401 *****************************************************************************/ 1402 static void bta_hl_sdp_cback(uint8_t sdp_oper, uint8_t app_idx, uint8_t mcl_idx, 1403 uint8_t mdl_idx, uint16_t status) { 1404 tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1405 tBTA_HL_SDP_REC* p_hdp_rec; 1406 tBTA_HL_CCH_SDP* p_cch_buf; 1407 tBTA_HL_DCH_SDP* p_dch_buf; 1408 tSDP_DISC_REC* p_rec = NULL; 1409 tSDP_PROTOCOL_ELEM pe; 1410 tSDP_DISC_ATTR* p_attr; 1411 uint8_t i, rec_cnt; 1412 tBTA_HL_SUP_FEATURE_LIST_ELEM sup_feature; 1413 bool sdp_parsing_ok = false, result = false; 1414 uint16_t event; 1415 tBTA_HL_MDL_CB* p_dcb; 1416 uint16_t service_uuid; 1417 uint16_t name_len; 1418 1419 #if (BTA_HL_DEBUG == TRUE) 1420 APPL_TRACE_DEBUG( 1421 "bta_hl_sdp_cback status:%d sdp_oper=%d app_idx=%d, mcl_idx=%d, " 1422 "mdl_idx=%d", 1423 status, sdp_oper, app_idx, mcl_idx, mdl_idx); 1424 #endif 1425 1426 rec_cnt = 0; 1427 service_uuid = bta_hl_get_service_uuids(sdp_oper, app_idx, mcl_idx, mdl_idx); 1428 1429 if (status == SDP_SUCCESS || status == SDP_DB_FULL) { 1430 memset(&p_cb->sdp, 0, sizeof(tBTA_HL_SDP)); 1431 do { 1432 if (bta_hl_find_service_in_db(app_idx, mcl_idx, service_uuid, &p_rec)) { 1433 p_hdp_rec = &p_cb->sdp.sdp_rec[rec_cnt]; 1434 p_cb->sdp.num_recs = rec_cnt + 1; 1435 } else { 1436 break; 1437 } 1438 1439 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe)) { 1440 p_hdp_rec->ctrl_psm = (uint16_t)pe.params[0]; 1441 } else { 1442 APPL_TRACE_WARNING("Control PSM not found"); 1443 break; 1444 } 1445 if (SDP_FindAddProtoListsElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe)) { 1446 p_hdp_rec->data_psm = (uint16_t)pe.params[0]; 1447 } else { 1448 APPL_TRACE_WARNING("Data PSM not found"); 1449 break; 1450 } 1451 1452 p_hdp_rec->srv_name[0] = '\0'; 1453 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 1454 if (p_attr != NULL) { 1455 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN) 1456 name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 1457 else 1458 name_len = BT_MAX_SERVICE_NAME_LEN; 1459 memcpy(p_hdp_rec->srv_name, p_attr->attr_value.v.array, name_len); 1460 } 1461 1462 p_hdp_rec->srv_desp[0] = '\0'; 1463 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_DESCRIPTION); 1464 if (p_attr != NULL) { 1465 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN) 1466 name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 1467 else 1468 name_len = BT_MAX_SERVICE_NAME_LEN; 1469 memcpy(p_hdp_rec->srv_desp, p_attr->attr_value.v.array, name_len); 1470 } 1471 1472 p_hdp_rec->provider_name[0] = '\0'; 1473 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PROVIDER_NAME); 1474 if (p_attr != NULL) { 1475 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN) 1476 name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 1477 else 1478 name_len = BT_MAX_SERVICE_NAME_LEN; 1479 memcpy(p_hdp_rec->provider_name, p_attr->attr_value.v.array, name_len); 1480 } 1481 1482 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_MCAP_SUP_PROC); 1483 if (p_attr != NULL) { 1484 p_hdp_rec->mcap_sup_proc = p_attr->attr_value.v.u8; 1485 } else { 1486 APPL_TRACE_WARNING("MCAP SUP PROC not found"); 1487 break; 1488 } 1489 1490 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_SUP_FEAT_LIST); 1491 if (p_attr != NULL) { 1492 if (bta_hl_fill_sup_feature_list(p_attr, &sup_feature)) { 1493 p_hdp_rec->num_mdeps = (uint8_t)sup_feature.num_elems; 1494 APPL_TRACE_WARNING("bta_hl_sdp_cback num_mdeps %d", 1495 sup_feature.num_elems); 1496 for (i = 0; i < sup_feature.num_elems; i++) { 1497 p_hdp_rec->mdep_cfg[i].data_type = 1498 sup_feature.list_elem[i].data_type; 1499 p_hdp_rec->mdep_cfg[i].mdep_id = sup_feature.list_elem[i].mdep_id; 1500 p_hdp_rec->mdep_cfg[i].mdep_role = 1501 sup_feature.list_elem[i].mdep_role; 1502 /* Check MDEP Description pointer to prevent crash due to null 1503 * pointer */ 1504 if (sup_feature.list_elem[i].p_mdep_desp != NULL) { 1505 strlcpy(p_hdp_rec->mdep_cfg[i].mdep_desp, 1506 sup_feature.list_elem[i].p_mdep_desp, 1507 BTA_HL_MDEP_DESP_LEN); 1508 } else { 1509 APPL_TRACE_ERROR( 1510 "bta_hl_sdp_cback Incorrect Mdep[%d] Description (Null ptr)", 1511 i); 1512 } 1513 } 1514 1515 sdp_parsing_ok = true; 1516 } else { 1517 APPL_TRACE_WARNING("HDP supported feature list fill failed"); 1518 break; 1519 } 1520 } else { 1521 APPL_TRACE_WARNING("HDP supported feature list not found"); 1522 break; 1523 } 1524 #if (BTA_HL_DEBUG == TRUE) 1525 APPL_TRACE_DEBUG("record=%d ctrl_psm=%0x data_psm=%x", rec_cnt + 1, 1526 p_hdp_rec->ctrl_psm, p_hdp_rec->data_psm); 1527 APPL_TRACE_DEBUG("srv_name=[%s]", (p_hdp_rec->srv_name[0] != '\0') 1528 ? p_hdp_rec->srv_name 1529 : "NULL"); 1530 APPL_TRACE_DEBUG("srv_desp=[%s]", (p_hdp_rec->srv_desp[0] != '\0') 1531 ? p_hdp_rec->srv_desp 1532 : "NULL"); 1533 for (i = 0; i < sup_feature.num_elems; i++) { 1534 APPL_TRACE_DEBUG( 1535 "index=0x%02x mdep_id=0x%04x data type=0x%04x mdep role=%s(0x%02x)", 1536 (i + 1), p_hdp_rec->mdep_cfg[i].mdep_id, 1537 p_hdp_rec->mdep_cfg[i].data_type, 1538 (p_hdp_rec->mdep_cfg[i].mdep_role == BTA_HL_MDEP_ROLE_SOURCE) 1539 ? "Src" 1540 : "Snk", 1541 p_hdp_rec->mdep_cfg[i].mdep_role); 1542 } 1543 APPL_TRACE_DEBUG("provider_name=[%s]", 1544 (p_hdp_rec->provider_name[0] != '\0') 1545 ? p_hdp_rec->provider_name 1546 : "NULL"); 1547 APPL_TRACE_DEBUG("found MCAP sup procedure=%d", 1548 p_cb->sdp.sdp_rec[rec_cnt].mcap_sup_proc); 1549 #endif 1550 rec_cnt++; 1551 if (rec_cnt >= BTA_HL_NUM_SDP_RECS) { 1552 APPL_TRACE_WARNING("No more spaces for SDP recs max_rec_cnt=%d", 1553 BTA_HL_NUM_SDP_RECS); 1554 break; 1555 } 1556 1557 } while (true); 1558 } 1559 1560 osi_free_and_reset((void**)&p_cb->p_db); 1561 1562 if ((status == SDP_SUCCESS || status == SDP_DB_FULL) && p_cb->sdp.num_recs && 1563 sdp_parsing_ok) { 1564 result = true; 1565 } else { 1566 APPL_TRACE_WARNING( 1567 "SDP Failed sdp_status=%d num_recs=%d sdp_parsing_ok=%d ", status, 1568 p_cb->sdp.num_recs, sdp_parsing_ok); 1569 } 1570 1571 p_cb->sdp_oper = BTA_HL_SDP_OP_NONE; 1572 1573 switch (sdp_oper) { 1574 case BTA_HL_SDP_OP_CCH_INIT: 1575 case BTA_HL_SDP_OP_SDP_QUERY_NEW: 1576 case BTA_HL_SDP_OP_SDP_QUERY_CURRENT: 1577 1578 /* send result in event back to BTA */ 1579 p_cch_buf = (tBTA_HL_CCH_SDP*)osi_malloc(sizeof(tBTA_HL_CCH_SDP)); 1580 if (result) { 1581 if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT) { 1582 event = BTA_HL_CCH_SDP_OK_EVT; 1583 if (p_cb->close_pending) event = BTA_HL_CCH_SDP_FAIL_EVT; 1584 } else { 1585 event = BTA_HL_SDP_QUERY_OK_EVT; 1586 } 1587 } else { 1588 if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT) 1589 event = BTA_HL_CCH_SDP_FAIL_EVT; 1590 else 1591 event = BTA_HL_SDP_QUERY_FAIL_EVT; 1592 } 1593 p_cch_buf->hdr.event = event; 1594 1595 p_cch_buf->app_idx = app_idx; 1596 p_cch_buf->mcl_idx = mcl_idx; 1597 p_cch_buf->release_mcl_cb = false; 1598 if (sdp_oper == BTA_HL_SDP_OP_SDP_QUERY_NEW) 1599 p_cch_buf->release_mcl_cb = true; 1600 1601 bta_sys_sendmsg(p_cch_buf); 1602 break; 1603 case BTA_HL_SDP_OP_DCH_OPEN_INIT: 1604 case BTA_HL_SDP_OP_DCH_RECONNECT_INIT: 1605 p_dch_buf = (tBTA_HL_DCH_SDP*)osi_malloc(sizeof(tBTA_HL_DCH_SDP)); 1606 p_dch_buf->hdr.event = BTA_HL_DCH_SDP_FAIL_EVT; 1607 p_dch_buf->app_idx = app_idx; 1608 p_dch_buf->mcl_idx = mcl_idx; 1609 p_dch_buf->mdl_idx = mdl_idx; 1610 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1611 if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) { 1612 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 1613 result = false; 1614 } 1615 if (result) { 1616 if (sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) { 1617 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1618 p_dch_buf->hdr.event = BTA_HL_DCH_ECHO_TEST_EVT; 1619 } else { 1620 p_dch_buf->hdr.event = BTA_HL_DCH_OPEN_EVT; 1621 } 1622 } else { 1623 p_dch_buf->hdr.event = BTA_HL_DCH_RECONNECT_EVT; 1624 } 1625 } 1626 bta_sys_sendmsg(p_dch_buf); 1627 break; 1628 default: 1629 break; 1630 } 1631 } 1632 1633 /****************************************************************************** 1634 * 1635 * Function bta_hl_sdp_cback0 1636 * 1637 * Description This is the SDP callback function used by index = 0 1638 * 1639 * Returns void. 1640 * 1641 *****************************************************************************/ 1642 static void bta_hl_sdp_cback0(uint16_t status) { 1643 bta_hl_sdp_cback(bta_hl_cb.scb[0].sdp_oper, bta_hl_cb.scb[0].app_idx, 1644 bta_hl_cb.scb[0].mcl_idx, bta_hl_cb.scb[0].mdl_idx, status); 1645 bta_hl_deallocate_spd_cback(0); 1646 } 1647 1648 /****************************************************************************** 1649 * 1650 * Function bta_hl_sdp_cback1 1651 * 1652 * Description This is the SDP callback function used by index = 1 1653 * 1654 * Parameters status - status of the SDP callabck 1655 * 1656 * Returns void. 1657 * 1658 *****************************************************************************/ 1659 static void bta_hl_sdp_cback1(uint16_t status) { 1660 bta_hl_sdp_cback(bta_hl_cb.scb[1].sdp_oper, bta_hl_cb.scb[1].app_idx, 1661 bta_hl_cb.scb[1].mcl_idx, bta_hl_cb.scb[1].mdl_idx, status); 1662 bta_hl_deallocate_spd_cback(1); 1663 } 1664 1665 /****************************************************************************** 1666 * 1667 * Function bta_hl_sdp_cback2 1668 * 1669 * Description This is the SDP callback function used by index = 2 1670 * 1671 * Returns void. 1672 * 1673 *****************************************************************************/ 1674 static void bta_hl_sdp_cback2(uint16_t status) { 1675 bta_hl_sdp_cback(bta_hl_cb.scb[2].sdp_oper, bta_hl_cb.scb[2].app_idx, 1676 bta_hl_cb.scb[2].mcl_idx, bta_hl_cb.scb[2].mdl_idx, status); 1677 bta_hl_deallocate_spd_cback(2); 1678 } 1679 1680 /****************************************************************************** 1681 * 1682 * Function bta_hl_sdp_cback3 1683 * 1684 * Description This is the SDP callback function used by index = 3 1685 * 1686 * Returns void. 1687 * 1688 *****************************************************************************/ 1689 static void bta_hl_sdp_cback3(uint16_t status) { 1690 bta_hl_sdp_cback(bta_hl_cb.scb[3].sdp_oper, bta_hl_cb.scb[3].app_idx, 1691 bta_hl_cb.scb[3].mcl_idx, bta_hl_cb.scb[3].mdl_idx, status); 1692 bta_hl_deallocate_spd_cback(3); 1693 } 1694 1695 /****************************************************************************** 1696 * 1697 * Function bta_hl_sdp_cback4 1698 * 1699 * Description This is the SDP callback function used by index = 4 1700 * 1701 * Parameters status - status of the SDP callabck 1702 * 1703 * Returns void. 1704 * 1705 *****************************************************************************/ 1706 static void bta_hl_sdp_cback4(uint16_t status) { 1707 bta_hl_sdp_cback(bta_hl_cb.scb[4].sdp_oper, bta_hl_cb.scb[4].app_idx, 1708 bta_hl_cb.scb[4].mcl_idx, bta_hl_cb.scb[4].mdl_idx, status); 1709 bta_hl_deallocate_spd_cback(4); 1710 } 1711 1712 /****************************************************************************** 1713 * 1714 * Function bta_hl_sdp_cback5 1715 * 1716 * Description This is the SDP callback function used by index = 5 1717 * 1718 * Parameters status - status of the SDP callabck 1719 * 1720 * Returns void. 1721 * 1722 *****************************************************************************/ 1723 static void bta_hl_sdp_cback5(uint16_t status) { 1724 bta_hl_sdp_cback(bta_hl_cb.scb[5].sdp_oper, bta_hl_cb.scb[5].app_idx, 1725 bta_hl_cb.scb[5].mcl_idx, bta_hl_cb.scb[5].mdl_idx, status); 1726 bta_hl_deallocate_spd_cback(5); 1727 } 1728 1729 /****************************************************************************** 1730 * 1731 * Function bta_hl_sdp_cback6 1732 * 1733 * Description This is the SDP callback function used by index = 6 1734 * 1735 * Returns void. 1736 * 1737 *****************************************************************************/ 1738 static void bta_hl_sdp_cback6(uint16_t status) { 1739 bta_hl_sdp_cback(bta_hl_cb.scb[6].sdp_oper, bta_hl_cb.scb[6].app_idx, 1740 bta_hl_cb.scb[6].mcl_idx, bta_hl_cb.scb[6].mdl_idx, status); 1741 bta_hl_deallocate_spd_cback(6); 1742 } 1743 1744 /******************************************************************************* 1745 * 1746 * Function bta_hl_deallocate_spd_cback 1747 * 1748 * Description Deallocate a SDP control block 1749 * 1750 * Returns bool - true found 1751 * false not found 1752 * 1753 ******************************************************************************/ 1754 void bta_hl_deallocate_spd_cback(uint8_t sdp_cback_idx) { 1755 tBTA_HL_SDP_CB* p_spd_cb = &bta_hl_cb.scb[sdp_cback_idx]; 1756 1757 memset(p_spd_cb, 0, sizeof(tBTA_HL_SDP_CB)); 1758 1759 #if (BTA_HL_DEBUG == TRUE) 1760 APPL_TRACE_DEBUG("bta_hl_deallocate_spd_cback index=%d", sdp_cback_idx); 1761 #endif 1762 } 1763 1764 /******************************************************************************* 1765 * 1766 * Function bta_hl_allocate_spd_cback 1767 * 1768 * Description Finds a not in used SDP control block index 1769 * 1770 * 1771 * Returns bool - true found 1772 * false not found 1773 * 1774 ******************************************************************************/ 1775 tSDP_DISC_CMPL_CB* bta_hl_allocate_spd_cback(tBTA_HL_SDP_OPER sdp_oper, 1776 uint8_t app_idx, uint8_t mcl_idx, 1777 uint8_t mdl_idx, 1778 uint8_t* p_sdp_cback_idx) { 1779 uint8_t i; 1780 tSDP_DISC_CMPL_CB* p_cbcak = NULL; 1781 1782 for (i = 0; i < BTA_HL_NUM_SDP_CBACKS; i++) { 1783 if (!bta_hl_cb.scb[i].in_use) { 1784 p_cbcak = bta_hl_sdp_cback_arr[i]; 1785 bta_hl_cb.scb[i].in_use = true; 1786 bta_hl_cb.scb[i].sdp_oper = sdp_oper; 1787 bta_hl_cb.scb[i].app_idx = app_idx; 1788 bta_hl_cb.scb[i].mcl_idx = mcl_idx; 1789 bta_hl_cb.scb[i].mdl_idx = mdl_idx; 1790 *p_sdp_cback_idx = i; 1791 break; 1792 } 1793 } 1794 1795 if (i == BTA_HL_NUM_SDP_CBACKS) { 1796 APPL_TRACE_WARNING("No scb is available to allocate") 1797 } else { 1798 #if (BTA_HL_DEBUG == TRUE) 1799 APPL_TRACE_DEBUG("bta_hl_allocate_spd_cback cback_idx=%d ", i); 1800 APPL_TRACE_DEBUG("sdp_oper=%d, app_idx=%d, mcl_idx=%d, mdl_idx=%d", 1801 bta_hl_cb.scb[i].sdp_oper, bta_hl_cb.scb[i].app_idx, 1802 bta_hl_cb.scb[i].mcl_idx, bta_hl_cb.scb[i].mdl_idx); 1803 #endif 1804 } 1805 return p_cbcak; 1806 } 1807 1808 /******************************************************************************* 1809 * 1810 * Function bta_hl_init_sdp 1811 * 1812 * Description Action routine for processing the SDP initiattion request 1813 * 1814 * Returns void 1815 * 1816 ******************************************************************************/ 1817 tBTA_HL_STATUS bta_hl_init_sdp(tBTA_HL_SDP_OPER sdp_oper, uint8_t app_idx, 1818 uint8_t mcl_idx, uint8_t mdl_idx) { 1819 tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1820 tSDP_UUID uuid_list; 1821 uint16_t attr_list[BTA_HL_NUM_SRCH_ATTR]; 1822 uint16_t num_attrs = BTA_HL_NUM_SRCH_ATTR; 1823 tBTA_HL_STATUS status; 1824 uint8_t sdp_cback_idx; 1825 #if (BTA_HL_DEBUG == TRUE) 1826 APPL_TRACE_DEBUG( 1827 "bta_hl_init_sdp sdp_oper=%d app_idx=%d mcl_idx=%d, mdl_idx=%d", sdp_oper, 1828 app_idx, mcl_idx, mdl_idx); 1829 #endif 1830 p_cb->sdp_cback = bta_hl_allocate_spd_cback(sdp_oper, app_idx, mcl_idx, 1831 mdl_idx, &sdp_cback_idx); 1832 if (p_cb->sdp_cback != NULL) { 1833 if (p_cb->p_db == NULL) 1834 (p_cb->p_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_HL_DISC_SIZE)); 1835 attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST; 1836 attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST; 1837 attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST; 1838 attr_list[3] = ATTR_ID_ADDITION_PROTO_DESC_LISTS; 1839 attr_list[4] = ATTR_ID_SERVICE_NAME; 1840 attr_list[5] = ATTR_ID_SERVICE_DESCRIPTION; 1841 attr_list[6] = ATTR_ID_PROVIDER_NAME; 1842 attr_list[7] = ATTR_ID_HDP_SUP_FEAT_LIST; 1843 attr_list[8] = ATTR_ID_HDP_DATA_EXCH_SPEC; 1844 attr_list[9] = ATTR_ID_HDP_MCAP_SUP_PROC; 1845 1846 uuid_list.len = LEN_UUID_16; 1847 uuid_list.uu.uuid16 = UUID_SERVCLASS_HDP_PROFILE; 1848 SDP_InitDiscoveryDb(p_cb->p_db, BTA_HL_DISC_SIZE, 1, &uuid_list, num_attrs, 1849 attr_list); 1850 1851 if (!SDP_ServiceSearchAttributeRequest(p_cb->bd_addr, p_cb->p_db, 1852 p_cb->sdp_cback)) { 1853 status = BTA_HL_STATUS_FAIL; 1854 } else { 1855 status = BTA_HL_STATUS_OK; 1856 } 1857 } else { 1858 status = BTA_HL_STATUS_SDP_NO_RESOURCE; 1859 } 1860 1861 if (status != BTA_HL_STATUS_OK) { 1862 osi_free_and_reset((void**)&p_cb->p_db); 1863 if (status != BTA_HL_STATUS_SDP_NO_RESOURCE) 1864 bta_hl_deallocate_spd_cback(sdp_cback_idx); 1865 } 1866 1867 return status; 1868 } 1869 1870 /******************************************************************************* 1871 * 1872 * Function bta_hl_cch_sdp_init 1873 * 1874 * Description Action routine for processing the CCH SDP init event 1875 * 1876 * Returns void 1877 * 1878 ******************************************************************************/ 1879 void bta_hl_cch_sdp_init(uint8_t app_idx, uint8_t mcl_idx, 1880 tBTA_HL_DATA* p_data) { 1881 tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1882 #if (BTA_HL_DEBUG == TRUE) 1883 APPL_TRACE_DEBUG("bta_hl_cch_init_sdp"); 1884 #endif 1885 if (p_cb->sdp_oper == BTA_HL_SDP_OP_NONE) { 1886 p_cb->app_id = p_data->api_cch_open.app_id; 1887 p_cb->sdp_oper = BTA_HL_SDP_OP_CCH_INIT; 1888 1889 if (bta_hl_init_sdp(p_cb->sdp_oper, app_idx, mcl_idx, 0xFF) != 1890 BTA_HL_STATUS_OK) { 1891 p_cb->sdp_oper = BTA_HL_SDP_OP_NONE; 1892 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_SDP_FAIL_EVT, p_data); 1893 } 1894 } else { 1895 APPL_TRACE_ERROR("SDP in use"); 1896 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_SDP_FAIL_EVT, p_data); 1897 } 1898 } 1899 1900 /******************************************************************************* 1901 * 1902 * Function bta_hl_cch_mca_open 1903 * 1904 * Description Action routine for processing the CCH open request 1905 * 1906 * Returns void 1907 * 1908 ******************************************************************************/ 1909 void bta_hl_cch_mca_open(uint8_t app_idx, uint8_t mcl_idx, 1910 tBTA_HL_DATA* p_data) { 1911 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1912 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1913 uint8_t sdp_idx; 1914 1915 #if (BTA_HL_DEBUG == TRUE) 1916 APPL_TRACE_DEBUG("bta_hl_cch_mca_open"); 1917 #endif 1918 1919 if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->req_ctrl_psm, 1920 &sdp_idx)) { 1921 p_mcb->ctrl_psm = p_mcb->sdp.sdp_rec[sdp_idx].ctrl_psm; 1922 p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm; 1923 if (MCA_ConnectReq((tMCA_HANDLE)p_acb->app_handle, p_mcb->bd_addr, 1924 p_mcb->ctrl_psm, p_mcb->sec_mask) != MCA_SUCCESS) { 1925 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, 1926 p_data); 1927 } 1928 } else { 1929 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data); 1930 } 1931 } 1932 1933 /******************************************************************************* 1934 * 1935 * Function bta_hl_cch_mca_close 1936 * 1937 * Description Action routine for processing the CCH close request 1938 * 1939 * Returns void 1940 * 1941 ******************************************************************************/ 1942 void bta_hl_cch_mca_close(uint8_t app_idx, uint8_t mcl_idx, 1943 tBTA_HL_DATA* p_data) { 1944 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1945 1946 #if (BTA_HL_DEBUG == TRUE) 1947 APPL_TRACE_DEBUG("bta_hl_cch_mca_close mcl_handle=%d", p_mcb->mcl_handle); 1948 #endif 1949 if (p_mcb->sdp_oper != BTA_HL_SDP_OP_CCH_INIT) { 1950 if (p_mcb->mcl_handle) { 1951 if (MCA_DisconnectReq((tMCA_HANDLE)p_mcb->mcl_handle) != MCA_SUCCESS) { 1952 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, 1953 p_data); 1954 } 1955 } else { 1956 p_mcb->close_pending = true; 1957 APPL_TRACE_DEBUG( 1958 "No valid mcl_handle to stop the CCH setup now so wait until CCH is " 1959 "up then close it"); 1960 } 1961 } else { 1962 p_mcb->close_pending = true; 1963 APPL_TRACE_DEBUG( 1964 "can not stop the CCH setup becasue SDP is in progress so wait until " 1965 "it is done"); 1966 } 1967 } 1968 1969 /******************************************************************************* 1970 * 1971 * Function bta_hl_cch_close_cmpl 1972 * 1973 * Description Action routine for processing the CCH close complete event 1974 * 1975 * Returns void 1976 * 1977 ******************************************************************************/ 1978 void bta_hl_cch_close_cmpl(uint8_t app_idx, uint8_t mcl_idx, 1979 tBTA_HL_DATA* p_data) { 1980 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1981 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1982 1983 tBTA_HL evt_data; 1984 tBTA_HL_EVT event; 1985 bool send_evt = true; 1986 #if (BTA_HL_DEBUG == TRUE) 1987 APPL_TRACE_DEBUG("bta_hl_cch_close_cmpl"); 1988 #endif 1989 bta_sys_conn_close(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr); 1990 1991 if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE && 1992 p_mcb->force_close_local_cch_opening) { 1993 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_OPEN; 1994 APPL_TRACE_DEBUG( 1995 "change cch_oper from BTA_HL_CCH_OP_LOCAL_CLOSE to " 1996 "BTA_HL_CCH_OP_LOCAL_OPEN"); 1997 } 1998 1999 switch (p_mcb->cch_oper) { 2000 case BTA_HL_CCH_OP_LOCAL_OPEN: 2001 bta_hl_build_cch_open_cfm(&evt_data, p_mcb->app_id, p_acb->app_handle, 2002 p_mcb->mcl_handle, p_mcb->bd_addr, 2003 BTA_HL_STATUS_FAIL); 2004 event = BTA_HL_CCH_OPEN_CFM_EVT; 2005 break; 2006 case BTA_HL_CCH_OP_LOCAL_CLOSE: 2007 bta_hl_build_cch_close_cfm(&evt_data, p_acb->app_handle, 2008 p_mcb->mcl_handle, BTA_HL_STATUS_OK); 2009 event = BTA_HL_CCH_CLOSE_CFM_EVT; 2010 break; 2011 case BTA_HL_CCH_OP_REMOTE_CLOSE: 2012 bta_hl_build_cch_close_ind(&evt_data, p_acb->app_handle, 2013 p_mcb->mcl_handle, p_mcb->intentional_close); 2014 event = BTA_HL_CCH_CLOSE_IND_EVT; 2015 break; 2016 default: 2017 send_evt = false; 2018 break; 2019 } 2020 2021 memset(p_mcb, 0, sizeof(tBTA_HL_MCL_CB)); 2022 2023 if (send_evt) p_acb->p_cback(event, (tBTA_HL*)&evt_data); 2024 2025 bta_hl_check_deregistration(app_idx, p_data); 2026 } 2027 2028 /******************************************************************************* 2029 * 2030 * Function bta_hl_cch_mca_disconnect 2031 * 2032 * Description Action routine for processing the CCH disconnect indication 2033 * 2034 * Returns void 2035 * 2036 ******************************************************************************/ 2037 void bta_hl_cch_mca_disconnect(uint8_t app_idx, uint8_t mcl_idx, 2038 tBTA_HL_DATA* p_data) { 2039 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2040 tBTA_HL_MDL_CB* p_dcb; 2041 uint8_t i; 2042 #if (BTA_HL_DEBUG == TRUE) 2043 APPL_TRACE_DEBUG("bta_hl_cch_mca_disconnect"); 2044 #endif 2045 2046 p_mcb->intentional_close = false; 2047 if (p_data->mca_evt.mca_data.disconnect_ind.reason == L2CAP_DISC_OK) { 2048 p_mcb->intentional_close = true; 2049 } 2050 2051 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) { 2052 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, i); 2053 if (p_dcb->in_use && (p_dcb->dch_state != BTA_HL_DCH_IDLE_ST)) { 2054 if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) { 2055 bta_hl_dch_sm_execute(app_idx, mcl_idx, i, BTA_HL_DCH_CLOSE_CMPL_EVT, 2056 p_data); 2057 } else { 2058 bta_hl_dch_sm_execute(app_idx, mcl_idx, i, BTA_HL_MCA_CLOSE_IND_EVT, 2059 p_data); 2060 } 2061 } 2062 } 2063 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data); 2064 } 2065 2066 /******************************************************************************* 2067 * 2068 * Function bta_hl_cch_mca_disc_open 2069 * 2070 * Description Action routine for disconnect the just opened Control 2071 * channel 2072 * 2073 * Returns void 2074 * 2075 ******************************************************************************/ 2076 void bta_hl_cch_mca_disc_open(uint8_t app_idx, uint8_t mcl_idx, 2077 tBTA_HL_DATA* p_data) { 2078 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2079 2080 #if (BTA_HL_DEBUG == TRUE) 2081 APPL_TRACE_DEBUG("bta_hl_cch_mca_disc_open mcl_handle=0x%x close_pending=%d", 2082 p_data->mca_evt.mcl_handle, p_mcb->close_pending); 2083 #endif 2084 2085 p_mcb->close_pending = false; 2086 p_mcb->mcl_handle = p_data->mca_evt.mcl_handle; 2087 bta_hl_cch_mca_close(app_idx, mcl_idx, p_data); 2088 } 2089 2090 /******************************************************************************* 2091 * 2092 * Function bta_hl_cch_mca_rsp_tout 2093 * 2094 * Description Action routine for processing the MCAP response timeout 2095 * 2096 * Returns void 2097 * 2098 ******************************************************************************/ 2099 void bta_hl_cch_mca_rsp_tout(uint8_t app_idx, uint8_t mcl_idx, 2100 tBTA_HL_DATA* p_data) { 2101 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2102 #if (BTA_HL_DEBUG == TRUE) 2103 APPL_TRACE_DEBUG("bta_hl_cch_mca_rsp_tout"); 2104 #endif 2105 2106 p_mcb->rsp_tout = true; 2107 2108 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, true); 2109 } 2110 2111 /******************************************************************************* 2112 * 2113 * Function bta_hl_cch_mca_connect 2114 * 2115 * Description Action routine for processing the CCH connect indication 2116 * 2117 * Returns void 2118 * 2119 ******************************************************************************/ 2120 void bta_hl_cch_mca_connect(uint8_t app_idx, uint8_t mcl_idx, 2121 tBTA_HL_DATA* p_data) { 2122 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 2123 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 2124 tBTA_HL evt_data; 2125 tBTA_HL_EVT event; 2126 bool send_event = true; 2127 2128 #if (BTA_HL_DEBUG == TRUE) 2129 APPL_TRACE_DEBUG("bta_hl_cch_mca_connect mcl_handle=%d ", 2130 p_data->mca_evt.mcl_handle); 2131 #endif 2132 2133 p_mcb->mcl_handle = p_data->mca_evt.mcl_handle; 2134 p_mcb->bd_addr = p_data->mca_evt.mca_data.connect_ind.bd_addr; 2135 p_mcb->cch_mtu = p_data->mca_evt.mca_data.connect_ind.mtu; 2136 2137 bta_sys_conn_open(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr); 2138 switch (p_mcb->cch_oper) { 2139 case BTA_HL_CCH_OP_LOCAL_OPEN: 2140 bta_hl_build_cch_open_cfm(&evt_data, p_mcb->app_id, p_acb->app_handle, 2141 p_mcb->mcl_handle, p_mcb->bd_addr, 2142 BTA_HL_STATUS_OK); 2143 event = BTA_HL_CCH_OPEN_CFM_EVT; 2144 break; 2145 case BTA_HL_CCH_OP_REMOTE_OPEN: 2146 bta_hl_build_cch_open_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 2147 p_mcb->bd_addr); 2148 event = BTA_HL_CCH_OPEN_IND_EVT; 2149 break; 2150 default: 2151 send_event = false; 2152 break; 2153 } 2154 2155 p_mcb->cch_oper = BTA_HL_CCH_OP_NONE; 2156 if (send_event) p_acb->p_cback(event, (tBTA_HL*)&evt_data); 2157 } 2158 2159 /******************************************************************************* 2160 * 2161 * Function bta_hl_mcap_ctrl_cback 2162 * 2163 * Description MCAP control callback function for HL. 2164 * 2165 * Returns void 2166 * 2167 ******************************************************************************/ 2168 void bta_hl_mcap_ctrl_cback(tMCA_HANDLE handle, tMCA_CL mcl, uint8_t event, 2169 tMCA_CTRL* p_data) { 2170 bool send_event = true; 2171 uint16_t mca_event; 2172 2173 #if (BTA_HL_DEBUG == TRUE) 2174 APPL_TRACE_EVENT("bta_hl_mcap_ctrl_cback event[%s]", 2175 bta_hl_mcap_evt_code(event)); 2176 #endif 2177 2178 switch (event) { 2179 case MCA_CREATE_IND_EVT: 2180 mca_event = (uint16_t)BTA_HL_MCA_CREATE_IND_EVT; 2181 break; 2182 case MCA_CREATE_CFM_EVT: 2183 mca_event = (uint16_t)BTA_HL_MCA_CREATE_CFM_EVT; 2184 break; 2185 case MCA_RECONNECT_IND_EVT: 2186 mca_event = (uint16_t)BTA_HL_MCA_RECONNECT_IND_EVT; 2187 break; 2188 case MCA_RECONNECT_CFM_EVT: 2189 mca_event = (uint16_t)BTA_HL_MCA_RECONNECT_CFM_EVT; 2190 break; 2191 case MCA_ABORT_IND_EVT: 2192 mca_event = (uint16_t)BTA_HL_MCA_ABORT_IND_EVT; 2193 break; 2194 case MCA_ABORT_CFM_EVT: 2195 mca_event = (uint16_t)BTA_HL_MCA_ABORT_CFM_EVT; 2196 break; 2197 case MCA_DELETE_IND_EVT: 2198 mca_event = (uint16_t)BTA_HL_MCA_DELETE_IND_EVT; 2199 break; 2200 case MCA_DELETE_CFM_EVT: 2201 mca_event = (uint16_t)BTA_HL_MCA_DELETE_CFM_EVT; 2202 break; 2203 case MCA_CONNECT_IND_EVT: 2204 mca_event = (uint16_t)BTA_HL_MCA_CONNECT_IND_EVT; 2205 break; 2206 case MCA_DISCONNECT_IND_EVT: 2207 mca_event = (uint16_t)BTA_HL_MCA_DISCONNECT_IND_EVT; 2208 break; 2209 case MCA_OPEN_IND_EVT: 2210 mca_event = (uint16_t)BTA_HL_MCA_OPEN_IND_EVT; 2211 break; 2212 case MCA_OPEN_CFM_EVT: 2213 mca_event = (uint16_t)BTA_HL_MCA_OPEN_CFM_EVT; 2214 break; 2215 case MCA_CLOSE_IND_EVT: 2216 mca_event = (uint16_t)BTA_HL_MCA_CLOSE_IND_EVT; 2217 break; 2218 case MCA_CLOSE_CFM_EVT: 2219 mca_event = (uint16_t)BTA_HL_MCA_CLOSE_CFM_EVT; 2220 break; 2221 case MCA_CONG_CHG_EVT: 2222 mca_event = (uint16_t)BTA_HL_MCA_CONG_CHG_EVT; 2223 break; 2224 case MCA_RSP_TOUT_IND_EVT: 2225 mca_event = (uint16_t)BTA_HL_MCA_RSP_TOUT_IND_EVT; 2226 break; 2227 case MCA_ERROR_RSP_EVT: 2228 2229 default: 2230 send_event = false; 2231 break; 2232 } 2233 2234 if (send_event) { 2235 tBTA_HL_MCA_EVT* p_msg = 2236 (tBTA_HL_MCA_EVT*)osi_malloc(sizeof(tBTA_HL_MCA_EVT)); 2237 p_msg->hdr.event = mca_event; 2238 p_msg->app_handle = (tBTA_HL_APP_HANDLE)handle; 2239 p_msg->mcl_handle = (tBTA_HL_MCL_HANDLE)mcl; 2240 memcpy(&p_msg->mca_data, p_data, sizeof(tMCA_CTRL)); 2241 bta_sys_sendmsg(p_msg); 2242 } 2243 } 2244 2245 /******************************************************************************* 2246 * 2247 * Function bta_hl_mcap_data_cback 2248 * 2249 * Description MCAP data callback function for HL. 2250 * 2251 * Returns void 2252 * 2253 ******************************************************************************/ 2254 void bta_hl_mcap_data_cback(tMCA_DL mdl, BT_HDR* p_pkt) { 2255 uint8_t app_idx, mcl_idx, mdl_idx; 2256 if (bta_hl_find_mdl_idx_using_handle((tBTA_HL_MDL_HANDLE)mdl, &app_idx, 2257 &mcl_idx, &mdl_idx)) { 2258 tBTA_HL_MCA_RCV_DATA_EVT* p_msg = 2259 (tBTA_HL_MCA_RCV_DATA_EVT*)osi_malloc(sizeof(tBTA_HL_MCA_RCV_DATA_EVT)); 2260 p_msg->hdr.event = BTA_HL_MCA_RCV_DATA_EVT; 2261 p_msg->app_idx = app_idx; 2262 p_msg->mcl_idx = mcl_idx; 2263 p_msg->mdl_idx = mdl_idx; 2264 p_msg->p_pkt = p_pkt; 2265 bta_sys_sendmsg(p_msg); 2266 } 2267 } 2268 2269 /***************************************************************************** 2270 * Debug Functions 2271 ****************************************************************************/ 2272 #if (BTA_HL_DEBUG == TRUE) 2273 2274 #define CASE_RETURN_STR(const) \ 2275 case const: \ 2276 return #const; 2277 2278 /******************************************************************************* 2279 * 2280 * Function bta_hl_mcap_evt_code 2281 * 2282 * Description get the MCAP event string pointer 2283 * 2284 * Returns char * - event string pointer 2285 * 2286 ******************************************************************************/ 2287 static const char* bta_hl_mcap_evt_code(uint8_t evt_code) { 2288 switch (evt_code) { 2289 CASE_RETURN_STR(MCA_ERROR_RSP_EVT) 2290 CASE_RETURN_STR(MCA_CREATE_IND_EVT) 2291 CASE_RETURN_STR(MCA_CREATE_CFM_EVT) 2292 CASE_RETURN_STR(MCA_RECONNECT_IND_EVT) 2293 CASE_RETURN_STR(MCA_RECONNECT_CFM_EVT) 2294 CASE_RETURN_STR(MCA_ABORT_IND_EVT) 2295 CASE_RETURN_STR(MCA_ABORT_CFM_EVT) 2296 CASE_RETURN_STR(MCA_DELETE_IND_EVT) 2297 CASE_RETURN_STR(MCA_DELETE_CFM_EVT) 2298 CASE_RETURN_STR(MCA_CONNECT_IND_EVT) 2299 CASE_RETURN_STR(MCA_DISCONNECT_IND_EVT) 2300 CASE_RETURN_STR(MCA_OPEN_IND_EVT) 2301 CASE_RETURN_STR(MCA_OPEN_CFM_EVT) 2302 CASE_RETURN_STR(MCA_CLOSE_IND_EVT) 2303 CASE_RETURN_STR(MCA_CLOSE_CFM_EVT) 2304 CASE_RETURN_STR(MCA_CONG_CHG_EVT) 2305 CASE_RETURN_STR(MCA_RSP_TOUT_IND_EVT) 2306 default: 2307 return "Unknown MCAP event code"; 2308 } 2309 } 2310 2311 /******************************************************************************* 2312 * 2313 * Function bta_hl_cback_evt_code 2314 * 2315 * Description get the HDP event string pointer 2316 * 2317 * Returns char * - event string pointer 2318 * 2319 ******************************************************************************/ 2320 static const char* bta_hl_cback_evt_code(uint8_t evt_code) { 2321 switch (evt_code) { 2322 CASE_RETURN_STR(BTA_HL_CCH_OPEN_IND_EVT) 2323 CASE_RETURN_STR(BTA_HL_CCH_OPEN_CFM_EVT) 2324 CASE_RETURN_STR(BTA_HL_CCH_CLOSE_IND_EVT) 2325 CASE_RETURN_STR(BTA_HL_CCH_CLOSE_CFM_EVT) 2326 CASE_RETURN_STR(BTA_HL_DCH_OPEN_IND_EVT) 2327 CASE_RETURN_STR(BTA_HL_DCH_OPEN_CFM_EVT) 2328 CASE_RETURN_STR(BTA_HL_DCH_CLOSE_IND_EVT) 2329 CASE_RETURN_STR(BTA_HL_DCH_CLOSE_CFM_EVT) 2330 CASE_RETURN_STR(BTA_HL_DCH_RCV_DATA_IND_EVT) 2331 CASE_RETURN_STR(BTA_HL_REGISTER_CFM_EVT) 2332 CASE_RETURN_STR(BTA_HL_DEREGISTER_CFM_EVT) 2333 CASE_RETURN_STR(BTA_HL_DCH_RECONNECT_CFM_EVT) 2334 CASE_RETURN_STR(BTA_HL_DCH_RECONNECT_IND_EVT) 2335 CASE_RETURN_STR(BTA_HL_DCH_ECHO_TEST_CFM_EVT) 2336 CASE_RETURN_STR(BTA_HL_SDP_QUERY_CFM_EVT) 2337 CASE_RETURN_STR(BTA_HL_CONG_CHG_IND_EVT) 2338 CASE_RETURN_STR(BTA_HL_DCH_CREATE_IND_EVT) 2339 CASE_RETURN_STR(BTA_HL_DELETE_MDL_IND_EVT) 2340 CASE_RETURN_STR(BTA_HL_DELETE_MDL_CFM_EVT) 2341 CASE_RETURN_STR(BTA_HL_DCH_ABORT_IND_EVT) 2342 CASE_RETURN_STR(BTA_HL_DCH_ABORT_CFM_EVT) 2343 default: 2344 return "Unknown HDP event code"; 2345 } 2346 } 2347 2348 /******************************************************************************* 2349 * 2350 * Function bta_hl_dch_oper_code 2351 * 2352 * Description Get the DCH operation string 2353 * 2354 * Returns char * - DCH operation string pointer 2355 * 2356 ******************************************************************************/ 2357 static const char* bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code) { 2358 switch (oper_code) { 2359 CASE_RETURN_STR(BTA_HL_DCH_OP_NONE) 2360 CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_CREATE) 2361 CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_OPEN) 2362 CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_OPEN) 2363 CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_CLOSE) 2364 CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_CLOSE) 2365 CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_DELETE) 2366 CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_DELETE) 2367 CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_RECONNECT) 2368 CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_RECONNECT) 2369 CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST) 2370 CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT) 2371 default: 2372 return "Unknown DCH oper code"; 2373 } 2374 } 2375 2376 #endif /* Debug Functions */ 2377 #endif /* HL_INCLUDED */ 2378