1 /****************************************************************************** 2 * 3 * Copyright 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 using bluetooth::Uuid; 43 44 /***************************************************************************** 45 * Local Function prototypes 46 ****************************************************************************/ 47 #if (BTA_HL_DEBUG == TRUE) 48 static const char* bta_hl_mcap_evt_code(uint8_t evt_code); 49 static const char* bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code); 50 static const char* bta_hl_cback_evt_code(uint8_t evt_code); 51 #endif 52 static void bta_hl_sdp_cback(uint8_t sdp_op, uint8_t app_idx, uint8_t mcl_idx, 53 uint8_t mdl_idx, uint16_t status); 54 static void bta_hl_sdp_cback0(uint16_t status); 55 static void bta_hl_sdp_cback1(uint16_t status); 56 static void bta_hl_sdp_cback2(uint16_t status); 57 static void bta_hl_sdp_cback3(uint16_t status); 58 static void bta_hl_sdp_cback4(uint16_t status); 59 static void bta_hl_sdp_cback5(uint16_t status); 60 static void bta_hl_sdp_cback6(uint16_t status); 61 62 static tSDP_DISC_CMPL_CB* const bta_hl_sdp_cback_arr[] = { 63 bta_hl_sdp_cback0, bta_hl_sdp_cback1, bta_hl_sdp_cback2, bta_hl_sdp_cback3, 64 bta_hl_sdp_cback4, bta_hl_sdp_cback5, bta_hl_sdp_cback6}; 65 66 /******************************************************************************* 67 * 68 * Function bta_hl_dch_mca_cong_change 69 * 70 * Description Action routine for processing congestion change notification 71 * 72 * Returns void 73 * 74 ******************************************************************************/ 75 void bta_hl_dch_mca_cong_change(uint8_t app_idx, uint8_t mcl_idx, 76 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 77 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 78 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 79 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 80 tMCA_CONG_CHG* p_cong_chg = &p_data->mca_evt.mca_data.cong_chg; 81 tBTA_HL evt_data; 82 83 #if (BTA_HL_DEBUG == TRUE) 84 APPL_TRACE_DEBUG("bta_hl_dch_mca_cong_change mdl_id=%d cong=%d", 85 p_cong_chg->mdl_id, p_cong_chg->cong); 86 #endif 87 evt_data.dch_cong_ind.cong = p_dcb->cong = p_cong_chg->cong; 88 evt_data.dch_cong_ind.mdl_handle = p_dcb->mdl_handle; 89 evt_data.dch_cong_ind.mcl_handle = p_mcb->mcl_handle; 90 evt_data.dch_cong_ind.app_handle = p_acb->app_handle; 91 92 p_acb->p_cback(BTA_HL_CONG_CHG_IND_EVT, (tBTA_HL*)&evt_data); 93 } 94 95 /******************************************************************************* 96 * 97 * Function bta_hl_dch_echo_test 98 * 99 * Description Action routine for processing echo test request 100 * 101 * Returns void 102 * 103 ******************************************************************************/ 104 void bta_hl_dch_echo_test(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 105 UNUSED_ATTR tBTA_HL_DATA* p_data) { 106 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 107 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 108 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 109 110 #if (BTA_HL_DEBUG == TRUE) 111 APPL_TRACE_DEBUG("bta_hl_dch_echo_test"); 112 #endif 113 114 p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_GET_ECHO_DATA; 115 p_dcb->cout_oper |= BTA_HL_CO_GET_ECHO_DATA_MASK; 116 117 bta_hl_co_get_echo_data( 118 p_acb->app_id, p_mcb->mcl_handle, p_dcb->p_echo_tx_pkt->len, 119 BTA_HL_GET_BUF_PTR(p_dcb->p_echo_tx_pkt), BTA_HL_CI_GET_ECHO_DATA_EVT); 120 } 121 /******************************************************************************* 122 * 123 * Function bta_hl_dch_sdp_init 124 * 125 * Description Action routine for processing DCH SDP initiation 126 * 127 * Returns void 128 * 129 ******************************************************************************/ 130 void bta_hl_dch_sdp_init(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 131 tBTA_HL_DATA* p_data) { 132 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 133 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 134 135 #if (BTA_HL_DEBUG == TRUE) 136 APPL_TRACE_DEBUG("bta_hl_dch_sdp_init"); 137 #endif 138 if (p_mcb->sdp_oper == BTA_HL_SDP_OP_NONE) { 139 p_mcb->sdp_mdl_idx = mdl_idx; 140 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) { 141 p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_OPEN_INIT; 142 143 } else { 144 p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_RECONNECT_INIT; 145 } 146 147 if (bta_hl_init_sdp(p_mcb->sdp_oper, app_idx, mcl_idx, mdl_idx) != 148 BTA_HL_STATUS_OK) { 149 APPL_TRACE_ERROR("SDP INIT failed"); 150 p_mcb->sdp_oper = BTA_HL_SDP_OP_NONE; 151 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT, 152 p_data); 153 } 154 } else { 155 APPL_TRACE_ERROR("SDP in use"); 156 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT, 157 p_data); 158 } 159 } 160 161 /******************************************************************************* 162 * 163 * Function bta_hl_dch_close_echo_test 164 * 165 * Description Action routine for processing the closing of echo test 166 * 167 * Returns void 168 * 169 ******************************************************************************/ 170 void bta_hl_dch_close_echo_test(uint8_t app_idx, uint8_t mcl_idx, 171 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 172 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 173 174 #if (BTA_HL_DEBUG == TRUE) 175 APPL_TRACE_DEBUG("bta_hl_dch_close_echo_test"); 176 #endif 177 178 switch (p_dcb->echo_oper) { 179 case BTA_HL_ECHO_OP_DCH_CLOSE_CFM: 180 case BTA_HL_ECHO_OP_OPEN_IND: 181 case BTA_HL_ECHO_OP_ECHO_PKT: 182 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST; 183 break; 184 case BTA_HL_ECHO_OP_MDL_CREATE_CFM: 185 case BTA_HL_ECHO_OP_DCH_OPEN_CFM: 186 case BTA_HL_ECHO_OP_LOOP_BACK: 187 default: 188 break; 189 } 190 191 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) != MCA_SUCCESS) { 192 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 193 p_data); 194 } 195 } 196 197 /******************************************************************************* 198 * 199 * Function bta_hl_dch_mca_rcv_data 200 * 201 * Description Action routine for processing the received data 202 * 203 * Returns void 204 * 205 ******************************************************************************/ 206 void bta_hl_dch_mca_rcv_data(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 207 tBTA_HL_DATA* p_data) { 208 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 209 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 210 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 211 212 #if (BTA_HL_DEBUG == TRUE) 213 APPL_TRACE_DEBUG("bta_hl_dch_mca_rcv_data"); 214 #endif 215 216 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 217 switch (p_dcb->echo_oper) { 218 case BTA_HL_ECHO_OP_ECHO_PKT: 219 220 if (MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, 221 p_data->mca_rcv_data_evt.p_pkt) != MCA_SUCCESS) { 222 osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt); 223 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 224 BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data); 225 } 226 break; 227 case BTA_HL_ECHO_OP_LOOP_BACK: 228 229 p_dcb->p_echo_rx_pkt = p_data->mca_rcv_data_evt.p_pkt; 230 p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_PUT_ECHO_DATA; 231 p_dcb->cout_oper |= BTA_HL_CO_PUT_ECHO_DATA_MASK; 232 p_dcb->ci_put_echo_data_status = BTA_HL_STATUS_FAIL; 233 234 bta_hl_co_put_echo_data(p_acb->app_id, p_mcb->mcl_handle, 235 p_dcb->p_echo_rx_pkt->len, 236 BTA_HL_GET_BUF_PTR(p_dcb->p_echo_rx_pkt), 237 BTA_HL_CI_PUT_ECHO_DATA_EVT); 238 break; 239 default: 240 APPL_TRACE_ERROR("Unknonw echo_oper=%d", p_dcb->echo_oper); 241 break; 242 } 243 244 } else { 245 p_dcb->cout_oper |= BTA_HL_CO_PUT_RX_DATA_MASK; 246 p_dcb->p_rx_pkt = p_data->mca_rcv_data_evt.p_pkt; 247 248 bta_hl_co_put_rx_data( 249 p_acb->app_id, p_dcb->mdl_handle, p_dcb->p_rx_pkt->len, 250 BTA_HL_GET_BUF_PTR(p_dcb->p_rx_pkt), BTA_HL_CI_PUT_RX_DATA_EVT); 251 } 252 } 253 254 /******************************************************************************* 255 * 256 * Function bta_hl_dch_ci_put_echo_data 257 * 258 * Description Action routine for processing the call-in of the 259 * put echo data event 260 * 261 * Returns void 262 * 263 ******************************************************************************/ 264 void bta_hl_dch_ci_put_echo_data(uint8_t app_idx, uint8_t mcl_idx, 265 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 266 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 267 268 #if (BTA_HL_DEBUG == TRUE) 269 APPL_TRACE_DEBUG("bta_hl_dch_ci_put_echo_data"); 270 #endif 271 272 p_dcb->cout_oper &= ~BTA_HL_CO_PUT_ECHO_DATA_MASK; 273 osi_free_and_reset((void**)&p_dcb->p_echo_rx_pkt); 274 p_dcb->ci_put_echo_data_status = p_data->ci_get_put_echo_data.status; 275 276 p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_CLOSE_CFM; 277 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 278 BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data); 279 } 280 281 /******************************************************************************* 282 * 283 * Function bta_hl_dch_ci_get_echo_data 284 * 285 * Description Action routine for processing the call-in of the 286 * get echo data event 287 * 288 * Returns void 289 * 290 ******************************************************************************/ 291 void bta_hl_dch_ci_get_echo_data(uint8_t app_idx, uint8_t mcl_idx, 292 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 293 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 294 tBTA_HL_STATUS status; 295 296 #if (BTA_HL_DEBUG == TRUE) 297 APPL_TRACE_DEBUG("bta_hl_dch_ci_get_echo_data"); 298 #endif 299 300 p_dcb->cout_oper &= ~BTA_HL_CO_GET_ECHO_DATA_MASK; 301 302 if (!p_dcb->abort_oper) { 303 status = p_data->ci_get_put_echo_data.status; 304 if (status == BTA_HL_STATUS_OK) { 305 p_dcb->echo_oper = BTA_HL_ECHO_OP_MDL_CREATE_CFM; 306 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_OPEN_EVT, 307 p_data); 308 } else { 309 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 310 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 311 } 312 } else { 313 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 314 p_data); 315 } 316 } 317 318 /******************************************************************************* 319 * 320 * Function bta_hl_dch_ci_put_rx_data 321 * 322 * Description Action routine for processing the call-in of the 323 * put rx data event 324 * 325 * Returns void 326 * 327 ******************************************************************************/ 328 void bta_hl_dch_ci_put_rx_data(uint8_t app_idx, uint8_t mcl_idx, 329 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 330 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 331 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 332 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 333 tBTA_HL evt_data; 334 335 #if (BTA_HL_DEBUG == TRUE) 336 APPL_TRACE_DEBUG("bta_hl_dch_ci_put_rx_data"); 337 #endif 338 339 p_dcb->cout_oper &= ~BTA_HL_CO_PUT_RX_DATA_MASK; 340 osi_free_and_reset((void**)&p_dcb->p_rx_pkt); 341 bta_hl_build_rcv_data_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 342 p_dcb->mdl_handle); 343 p_acb->p_cback(BTA_HL_DCH_RCV_DATA_IND_EVT, (tBTA_HL*)&evt_data); 344 if (p_dcb->close_pending) { 345 if (!p_dcb->cout_oper) { 346 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, 347 p_data); 348 } 349 } 350 } 351 352 /******************************************************************************* 353 * 354 * Function bta_hl_dch_ci_get_tx_data 355 * 356 * Description Action routine for processing the call-in of the 357 * get tx data event 358 * 359 * Returns void 360 * 361 ******************************************************************************/ 362 void bta_hl_dch_ci_get_tx_data(uint8_t app_idx, uint8_t mcl_idx, 363 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 364 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 365 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 366 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 367 tMCA_RESULT result; 368 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 369 bool free_buf = false; 370 bool close_dch = false; 371 tBTA_HL evt_data; 372 373 #if (BTA_HL_DEBUG == TRUE) 374 APPL_TRACE_DEBUG("bta_hl_dch_ci_get_tx_data"); 375 #endif 376 377 if (p_data != NULL) { 378 status = p_data->ci_get_put_data.status; 379 APPL_TRACE_WARNING("%s: status=%d", __func__, status); 380 } 381 382 p_dcb->cout_oper &= ~BTA_HL_CO_GET_TX_DATA_MASK; 383 384 if (p_dcb->close_pending) { 385 status = BTA_HL_STATUS_FAIL; 386 free_buf = true; 387 388 if (!p_dcb->cout_oper) { 389 close_dch = true; 390 } 391 } else if (status == BTA_HL_STATUS_FAIL) { 392 free_buf = TRUE; 393 } else { 394 result = MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_tx_pkt); 395 if (result != MCA_SUCCESS) { 396 if (result == MCA_BUSY) { 397 status = BTA_HL_STATUS_DCH_BUSY; 398 } else { 399 status = BTA_HL_STATUS_FAIL; 400 } 401 free_buf = true; 402 } else { 403 p_dcb->p_tx_pkt = NULL; 404 } 405 } 406 407 if (free_buf) osi_free_and_reset((void**)&p_dcb->p_tx_pkt); 408 409 bta_hl_build_send_data_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 410 p_dcb->mdl_handle, status); 411 p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT, (tBTA_HL*)&evt_data); 412 413 if (close_dch) { 414 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT, 415 p_data); 416 } 417 } 418 419 /******************************************************************************* 420 * 421 * Function bta_hl_dch_send_data 422 * 423 * Description Action routine for processing api send data request 424 * 425 * Returns void 426 * 427 ******************************************************************************/ 428 void bta_hl_dch_send_data(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 429 tBTA_HL_DATA* p_data) { 430 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 431 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 432 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 433 tBTA_HL evt_data; 434 bool success = true; 435 436 #if (BTA_HL_DEBUG == TRUE) 437 APPL_TRACE_DEBUG("bta_hl_dch_send_data"); 438 #endif 439 440 if (!(p_dcb->cout_oper & BTA_HL_CO_GET_TX_DATA_MASK)) { 441 // p_dcb->chnl_cfg.fcs may be BTA_HL_MCA_USE_FCS (0x11) or BTA_HL_MCA_NO_FCS 442 // (0x10) or BTA_HL_DEFAULT_SOURCE_FCS (1) 443 bool fcs_use = (bool)(p_dcb->chnl_cfg.fcs & BTA_HL_MCA_FCS_USE_MASK); 444 p_dcb->p_tx_pkt = bta_hl_get_buf(p_data->api_send_data.pkt_size, fcs_use); 445 if (p_dcb->p_tx_pkt != NULL) { 446 bta_hl_co_get_tx_data( 447 p_acb->app_id, p_dcb->mdl_handle, p_data->api_send_data.pkt_size, 448 BTA_HL_GET_BUF_PTR(p_dcb->p_tx_pkt), BTA_HL_CI_GET_TX_DATA_EVT); 449 p_dcb->cout_oper |= BTA_HL_CO_GET_TX_DATA_MASK; 450 } else { 451 success = false; 452 } 453 } else { 454 success = false; 455 } 456 457 if (!success) { 458 bta_hl_build_send_data_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 459 p_dcb->mdl_handle, BTA_HL_STATUS_FAIL); 460 p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT, (tBTA_HL*)&evt_data); 461 } 462 } 463 464 /******************************************************************************* 465 * 466 * Function bta_hl_dch_close_cmpl 467 * 468 * Description Action routine for processing the close complete event 469 * 470 * Returns void 471 * 472 ******************************************************************************/ 473 void bta_hl_dch_close_cmpl(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 474 tBTA_HL_DATA* p_data) { 475 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 476 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 477 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 478 tBTA_HL evt_data; 479 tBTA_HL_EVT event = 0; 480 bool send_evt = true; 481 tBTA_HL_STATUS status; 482 483 #if (BTA_HL_DEBUG == TRUE) 484 APPL_TRACE_DEBUG("bta_hl_dch_close_cmpl dch oper=%s", 485 bta_hl_dch_oper_code(p_dcb->dch_oper)); 486 #endif 487 488 switch (p_dcb->dch_oper) { 489 case BTA_HL_DCH_OP_LOCAL_OPEN: 490 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 491 492 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 493 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 494 BTA_HL_STATUS_OK); 495 event = BTA_HL_DCH_ABORT_CFM_EVT; 496 } else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK) { 497 bta_hl_build_abort_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle); 498 event = BTA_HL_DCH_ABORT_IND_EVT; 499 } else { 500 bta_hl_build_dch_open_cfm(&evt_data, p_acb->app_handle, 501 p_mcb->mcl_handle, BTA_HL_INVALID_MDL_HANDLE, 502 0, 0, 0, 0, 0, BTA_HL_STATUS_FAIL); 503 event = BTA_HL_DCH_OPEN_CFM_EVT; 504 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT) { 505 event = BTA_HL_DCH_RECONNECT_CFM_EVT; 506 } 507 } 508 break; 509 510 case BTA_HL_DCH_OP_LOCAL_CLOSE: 511 case BTA_HL_DCH_OP_REMOTE_DELETE: 512 case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT: 513 case BTA_HL_DCH_OP_NONE: 514 515 bta_hl_build_dch_close_cfm(&evt_data, p_acb->app_handle, 516 p_mcb->mcl_handle, p_dcb->mdl_handle, 517 BTA_HL_STATUS_OK); 518 event = BTA_HL_DCH_CLOSE_CFM_EVT; 519 break; 520 521 case BTA_HL_DCH_OP_REMOTE_CLOSE: 522 bta_hl_build_dch_close_ind(&evt_data, p_acb->app_handle, 523 p_mcb->mcl_handle, p_dcb->mdl_handle, 524 p_dcb->intentional_close); 525 event = BTA_HL_DCH_CLOSE_IND_EVT; 526 break; 527 528 case BTA_HL_DCH_OP_REMOTE_OPEN: 529 530 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 531 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 532 BTA_HL_STATUS_OK); 533 event = BTA_HL_DCH_ABORT_CFM_EVT; 534 } else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK) { 535 bta_hl_build_abort_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle); 536 event = BTA_HL_DCH_ABORT_IND_EVT; 537 } else { 538 bta_hl_build_dch_close_ind(&evt_data, p_acb->app_handle, 539 p_mcb->mcl_handle, p_dcb->mdl_handle, 540 p_dcb->intentional_close); 541 event = BTA_HL_DCH_CLOSE_IND_EVT; 542 } 543 break; 544 545 case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST: 546 /* this is normal echo test close */ 547 case BTA_HL_DCH_OP_REMOTE_CREATE: 548 case BTA_HL_DCH_OP_REMOTE_RECONNECT: 549 send_evt = false; 550 break; 551 552 default: 553 #if (BTA_HL_DEBUG == TRUE) 554 APPL_TRACE_ERROR("DCH operation not found oper=%s", 555 bta_hl_dch_oper_code(p_dcb->dch_oper)); 556 #endif 557 send_evt = false; 558 break; 559 } 560 561 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 562 p_mcb->echo_test = false; 563 send_evt = false; 564 565 if (p_dcb->dch_oper != BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST) { 566 switch (p_dcb->echo_oper) { 567 case BTA_HL_ECHO_OP_CI_GET_ECHO_DATA: 568 case BTA_HL_ECHO_OP_SDP_INIT: 569 case BTA_HL_ECHO_OP_MDL_CREATE_CFM: 570 case BTA_HL_ECHO_OP_DCH_OPEN_CFM: 571 case BTA_HL_ECHO_OP_LOOP_BACK: 572 573 status = BTA_HL_STATUS_FAIL; 574 send_evt = true; 575 break; 576 case BTA_HL_ECHO_OP_OPEN_IND: 577 case BTA_HL_ECHO_OP_ECHO_PKT: 578 break; 579 default: 580 APPL_TRACE_ERROR("Invalid echo_oper=%d", p_dcb->echo_oper); 581 break; 582 } 583 } else { 584 status = p_dcb->ci_put_echo_data_status; 585 send_evt = true; 586 } 587 588 if (send_evt) { 589 bta_hl_build_echo_test_cfm(&evt_data, p_acb->app_handle, 590 p_mcb->mcl_handle, status); 591 event = BTA_HL_DCH_ECHO_TEST_CFM_EVT; 592 } 593 } 594 595 bta_hl_clean_mdl_cb(app_idx, mcl_idx, mdl_idx); 596 597 if (send_evt) { 598 if (p_acb->p_cback) { 599 #if (BTA_HL_DEBUG == TRUE) 600 APPL_TRACE_DEBUG("Send Event: %s", bta_hl_cback_evt_code(event)); 601 #endif 602 p_acb->p_cback(event, (tBTA_HL*)&evt_data); 603 } 604 } 605 /* check cch close is in progress or not */ 606 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, false); 607 } 608 /******************************************************************************* 609 * 610 * Function bta_hl_dch_mca_close_ind 611 * 612 * Description Action routine for processing the close indication 613 * 614 * Returns void 615 * 616 ******************************************************************************/ 617 void bta_hl_dch_mca_close_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 618 tBTA_HL_DATA* p_data) { 619 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 620 621 #if (BTA_HL_DEBUG == TRUE) 622 APPL_TRACE_DEBUG("bta_hl_dch_mca_close_ind dch oper=%s", 623 bta_hl_dch_oper_code(p_dcb->dch_oper)); 624 #endif 625 626 p_dcb->intentional_close = false; 627 if (p_data->mca_evt.mca_data.close_ind.reason == L2CAP_DISC_OK) { 628 p_dcb->intentional_close = true; 629 } 630 631 if (!p_dcb->cout_oper) { 632 if ((p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_OPEN) && 633 (p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_RECONNECT)) { 634 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CLOSE; 635 } 636 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 637 p_data); 638 } else { 639 p_dcb->close_pending = true; 640 } 641 } 642 643 /******************************************************************************* 644 * 645 * Function bta_hl_dch_mca_close_cfm 646 * 647 * Description Action routine for processing the close confirmation 648 * 649 * Returns void 650 * 651 ******************************************************************************/ 652 void bta_hl_dch_mca_close_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 653 tBTA_HL_DATA* p_data) { 654 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 655 656 #if (BTA_HL_DEBUG == TRUE) 657 APPL_TRACE_DEBUG("bta_hl_dch_mca_close_cfm dch_oper=%s", 658 bta_hl_dch_oper_code(p_dcb->dch_oper)); 659 #endif 660 661 switch (p_dcb->dch_oper) { 662 case BTA_HL_DCH_OP_LOCAL_CLOSE: 663 case BTA_HL_DCH_OP_LOCAL_OPEN: 664 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 665 case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST: 666 case BTA_HL_DCH_OP_REMOTE_DELETE: 667 case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT: 668 case BTA_HL_DCH_OP_NONE: 669 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 670 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 671 break; 672 default: 673 #if (BTA_HL_DEBUG == TRUE) 674 APPL_TRACE_ERROR("Invalid dch_oper=%s for close cfm", 675 bta_hl_dch_oper_code(p_dcb->dch_oper)); 676 #endif 677 break; 678 } 679 } 680 681 /******************************************************************************* 682 * 683 * Function bta_hl_dch_mca_close 684 * 685 * Description Action routine for processing the DCH close request 686 * 687 * Returns void 688 * 689 ******************************************************************************/ 690 void bta_hl_dch_mca_close(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 691 tBTA_HL_DATA* p_data) { 692 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 693 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 694 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 695 tBTA_HL_STATUS status = BTA_HL_STATUS_OK; 696 tBTA_HL evt_data; 697 698 #if (BTA_HL_DEBUG == TRUE) 699 APPL_TRACE_DEBUG("bta_hl_dch_mca_close"); 700 #endif 701 if (!p_dcb->cout_oper) { 702 p_dcb->close_pending = false; 703 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) { 704 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE; 705 } else { 706 status = BTA_HL_STATUS_FAIL; 707 } 708 709 if ((status != BTA_HL_STATUS_OK) && 710 (p_mcb->cch_close_dch_oper != BTA_HL_CCH_CLOSE_OP_DCH_CLOSE)) { 711 bta_hl_build_dch_close_cfm(&evt_data, p_acb->app_handle, 712 p_mcb->mcl_handle, 713 p_data->api_dch_close.mdl_handle, status); 714 p_acb->p_cback(BTA_HL_DCH_CLOSE_CFM_EVT, (tBTA_HL*)&evt_data); 715 } 716 } else { 717 p_dcb->close_pending = true; 718 } 719 } 720 721 /******************************************************************************* 722 * 723 * Function bta_hl_dch_mca_open_ind 724 * 725 * Description Action routine for processing the open indication 726 * 727 * Returns void 728 * 729 ******************************************************************************/ 730 void bta_hl_dch_mca_open_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 731 tBTA_HL_DATA* p_data) { 732 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 733 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 734 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 735 tMCA_DL_OPEN* p_open_ind = &p_data->mca_evt.mca_data.open_ind; 736 tBTA_HL evt_data; 737 tBTA_HL_EVT event; 738 uint8_t old_dch_oper = BTA_HL_DCH_OP_NONE; 739 bool send_event = false; 740 741 #if (BTA_HL_DEBUG == TRUE) 742 APPL_TRACE_DEBUG("bta_hl_dch_mca_open_ind"); 743 #endif 744 if ((p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_OPEN) || 745 (p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_RECONNECT)) { 746 p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE)p_open_ind->mdl; 747 p_dcb->mtu = p_open_ind->mtu; 748 749 evt_data.dch_open_ind.mdl_handle = p_dcb->mdl_handle; 750 evt_data.dch_open_ind.mcl_handle = p_mcb->mcl_handle; 751 evt_data.dch_open_ind.app_handle = p_acb->app_handle; 752 753 evt_data.dch_open_ind.local_mdep_id = p_dcb->local_mdep_id; 754 evt_data.dch_open_ind.mdl_id = p_dcb->mdl_id; 755 evt_data.dch_open_ind.mtu = p_dcb->mtu; 756 757 if (p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE) { 758 evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_RELIABLE; 759 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 760 p_dcb->is_the_first_reliable = true; 761 } 762 } else { 763 evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_STREAMING; 764 } 765 evt_data.dch_open_ind.first_reliable = p_dcb->is_the_first_reliable; 766 767 old_dch_oper = p_dcb->dch_oper; 768 p_dcb->dch_oper = BTA_HL_DCH_OP_NONE; 769 } 770 771 switch (old_dch_oper) { 772 case BTA_HL_DCH_OP_REMOTE_OPEN: 773 774 p_dcb->dch_mode = evt_data.dch_open_ind.dch_mode; 775 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) { 776 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 777 event = BTA_HL_DCH_OPEN_IND_EVT; 778 send_event = true; 779 } else { 780 p_dcb->echo_oper = BTA_HL_ECHO_OP_ECHO_PKT; 781 } 782 783 break; 784 785 case BTA_HL_DCH_OP_REMOTE_RECONNECT: 786 787 if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx)) { 788 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 789 event = BTA_HL_DCH_RECONNECT_IND_EVT; 790 send_event = true; 791 } else { 792 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) { 793 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT; 794 } else { 795 APPL_TRACE_ERROR("Unabel to close DCH for reconnect cfg mismatch"); 796 } 797 } 798 break; 799 default: 800 break; 801 } 802 803 if (send_event) { 804 p_acb->p_cback(event, (tBTA_HL*)&evt_data); 805 } 806 } 807 808 /******************************************************************************* 809 * 810 * Function bta_hl_dch_mca_open_cfm 811 * 812 * Description Action routine for processing the open confirmation 813 * 814 * Returns void 815 * 816 ******************************************************************************/ 817 void bta_hl_dch_mca_open_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 818 tBTA_HL_DATA* p_data) { 819 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 820 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 821 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 822 tMCA_DL_OPEN* p_open_cfm = &p_data->mca_evt.mca_data.open_cfm; 823 tBTA_HL evt_data; 824 tBTA_HL_EVT event; 825 uint8_t old_dch_oper = BTA_HL_DCH_OP_NONE; 826 tBTA_HL_DCH_MODE dch_mode = BTA_HL_DCH_MODE_STREAMING; 827 bool send_event = false; 828 829 #if (BTA_HL_DEBUG == TRUE) 830 APPL_TRACE_DEBUG("bta_hl_dch_mca_open_cfm"); 831 #endif 832 if ((p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) || 833 (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT)) { 834 p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE)p_open_cfm->mdl; 835 p_dcb->mtu = p_open_cfm->mtu; 836 837 /*todo verify dch_mode, mtu and fcs for reconnect */ 838 if (p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE) { 839 dch_mode = BTA_HL_DCH_MODE_RELIABLE; 840 } 841 842 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) { 843 if (dch_mode == BTA_HL_DCH_MODE_RELIABLE) { 844 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) { 845 p_dcb->is_the_first_reliable = true; 846 } 847 } 848 } 849 850 bta_hl_build_dch_open_cfm( 851 &evt_data, p_acb->app_handle, p_mcb->mcl_handle, p_dcb->mdl_handle, 852 p_dcb->local_mdep_id, p_dcb->mdl_id, dch_mode, 853 p_dcb->is_the_first_reliable, p_dcb->mtu, BTA_HL_STATUS_OK); 854 855 old_dch_oper = p_dcb->dch_oper; 856 p_dcb->dch_oper = BTA_HL_DCH_OP_NONE; 857 } else { 858 APPL_TRACE_ERROR("Error dch oper =%d", p_dcb->dch_oper); 859 return; 860 } 861 862 switch (old_dch_oper) { 863 case BTA_HL_DCH_OP_LOCAL_OPEN: 864 865 p_dcb->dch_mode = dch_mode; 866 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) { 867 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 868 event = BTA_HL_DCH_OPEN_CFM_EVT; 869 send_event = true; 870 } else { 871 p_dcb->echo_oper = BTA_HL_ECHO_OP_LOOP_BACK; 872 if (MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_echo_tx_pkt) != 873 MCA_SUCCESS) { 874 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 875 BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data); 876 } else { 877 p_dcb->p_echo_tx_pkt = NULL; 878 } 879 } 880 break; 881 882 case BTA_HL_DCH_OP_LOCAL_RECONNECT: 883 884 if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx)) { 885 bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx); 886 event = BTA_HL_DCH_RECONNECT_CFM_EVT; 887 send_event = true; 888 } else { 889 if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) { 890 p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT; 891 } else { 892 APPL_TRACE_ERROR("Unabel to close DCH for reconnect cfg mismatch"); 893 } 894 } 895 break; 896 default: 897 break; 898 } 899 900 if (send_event) p_acb->p_cback(event, (tBTA_HL*)&evt_data); 901 } 902 903 /******************************************************************************* 904 * 905 * Function bta_hl_dch_mca_abort_ind 906 * 907 * Description Action routine for processing the abort indication 908 * 909 * Returns void 910 * 911 ******************************************************************************/ 912 void bta_hl_dch_mca_abort_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 913 tBTA_HL_DATA* p_data) { 914 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 915 916 #if (BTA_HL_DEBUG == TRUE) 917 APPL_TRACE_DEBUG("bta_hl_dch_mca_abort_ind"); 918 #endif 919 920 p_dcb->abort_oper |= BTA_HL_ABORT_REMOTE_MASK; 921 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 922 p_data); 923 } 924 925 /******************************************************************************* 926 * 927 * Function bta_hl_dch_mca_abort_cfm 928 * 929 * Description Action routine for processing the abort confirmation 930 * 931 * Returns void 932 * 933 ******************************************************************************/ 934 void bta_hl_dch_mca_abort_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 935 tBTA_HL_DATA* p_data) { 936 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 937 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 938 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 939 tBTA_HL evt_data; 940 941 #if (BTA_HL_DEBUG == TRUE) 942 APPL_TRACE_DEBUG("bta_hl_dch_mca_abort_cfm"); 943 #endif 944 945 if (p_dcb->abort_oper) { 946 if (p_data->mca_evt.mca_data.abort_cfm.rsp_code != MCA_RSP_SUCCESS) { 947 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 948 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 949 BTA_HL_STATUS_FAIL); 950 p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT, (tBTA_HL*)&evt_data); 951 } 952 } else { 953 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 954 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 955 } 956 } else { 957 APPL_TRACE_ERROR("Not expecting Abort CFM "); 958 } 959 } 960 961 /******************************************************************************* 962 * 963 * Function bta_hl_dch_mca_abort 964 * 965 * Description Action routine for processing the abort request 966 * 967 * Returns void 968 * 969 ******************************************************************************/ 970 void bta_hl_dch_mca_abort(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 971 tBTA_HL_DATA* p_data) { 972 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 973 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 974 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 975 tMCA_RESULT mca_result; 976 tBTA_HL evt_data; 977 978 if (((p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) || 979 (p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_RECONNECT_INIT)) && 980 (p_mcb->sdp_mdl_idx == mdl_idx)) { 981 p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK; 982 return; 983 } else if (p_dcb->echo_oper == BTA_HL_ECHO_OP_CI_GET_ECHO_DATA) { 984 p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK; 985 return; 986 } 987 988 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 989 990 mca_result = MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 991 if (mca_result != MCA_SUCCESS) { 992 if (mca_result == MCA_NO_RESOURCES) { 993 p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK; 994 } else { 995 if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) { 996 bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle, 997 BTA_HL_STATUS_FAIL); 998 p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT, (tBTA_HL*)&evt_data); 999 } 1000 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, false); 1001 } 1002 } 1003 1004 #if (BTA_HL_DEBUG == TRUE) 1005 APPL_TRACE_DEBUG("bta_hl_dch_mca_abort abort_oper=0x%x", p_dcb->abort_oper); 1006 #endif 1007 } 1008 1009 /******************************************************************************* 1010 * 1011 * Function bta_hl_dch_mca_reconnect_ind 1012 * 1013 * Description Action routine for processing the reconnect indication 1014 * 1015 * Returns void 1016 * 1017 ******************************************************************************/ 1018 void bta_hl_dch_mca_reconnect_ind(uint8_t app_idx, uint8_t mcl_idx, 1019 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1020 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1021 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1022 tBTA_HL_MDL_CFG* p_mdl_cfg; 1023 tMCA_EVT_HDR* p_reconnect_ind = &p_data->mca_evt.mca_data.reconnect_ind; 1024 uint8_t mdl_cfg_idx, in_use_mdl_idx, mdep_cfg_idx; 1025 uint8_t rsp_code = MCA_RSP_SUCCESS; 1026 1027 #if (BTA_HL_DEBUG == TRUE) 1028 APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect_ind mdl_id=%d", 1029 p_reconnect_ind->mdl_id); 1030 #endif 1031 1032 if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id, 1033 &mdl_cfg_idx)) { 1034 if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id, 1035 &in_use_mdl_idx)) { 1036 p_mdl_cfg = BTA_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx); 1037 1038 if (bta_hl_find_mdep_cfg_idx(app_idx, p_mdl_cfg->local_mdep_id, 1039 &mdep_cfg_idx)) { 1040 p_dcb->in_use = true; 1041 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_RECONNECT; 1042 p_dcb->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT); 1043 p_dcb->peer_mdep_id = 0xFF; 1044 p_dcb->local_mdep_id = p_mdl_cfg->local_mdep_id; 1045 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1046 p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN; 1047 p_dcb->mdl_id = p_reconnect_ind->mdl_id; 1048 p_dcb->mdl_cfg_idx_included = true; 1049 p_dcb->mdl_cfg_idx = mdl_cfg_idx; 1050 p_dcb->dch_mode = p_mdl_cfg->dch_mode; 1051 bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx, 1052 &p_dcb->max_rx_apdu_size, 1053 &p_dcb->max_tx_apdu_size); 1054 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1055 } else { 1056 rsp_code = MCA_RSP_BAD_MDL; 1057 } 1058 } else { 1059 rsp_code = MCA_RSP_BAD_MDL; 1060 } 1061 } else { 1062 rsp_code = MCA_RSP_BAD_MDL; 1063 } 1064 1065 if (MCA_ReconnectMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1066 p_dcb->mdl_id, rsp_code, 1067 &p_dcb->chnl_cfg) != MCA_SUCCESS) { 1068 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1069 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1070 p_data); 1071 } 1072 } 1073 1074 /******************************************************************************* 1075 * 1076 * Function bta_hl_dch_mca_reconnect_cfm 1077 * 1078 * Description Action routine for processing the reconenct confirmation 1079 * 1080 * Returns void 1081 * 1082 ******************************************************************************/ 1083 void bta_hl_dch_mca_reconnect_cfm(uint8_t app_idx, uint8_t mcl_idx, 1084 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1085 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1086 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1087 tMCA_RSP_EVT* p_reconnect_cfm = &p_data->mca_evt.mca_data.reconnect_cfm; 1088 1089 #if (BTA_HL_DEBUG == TRUE) 1090 APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect_cfm"); 1091 #endif 1092 if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) { 1093 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 1094 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, 1095 p_data); 1096 return; 1097 } 1098 1099 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT) { 1100 if (p_reconnect_cfm->rsp_code == MCA_RSP_SUCCESS) { 1101 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1102 1103 if (MCA_DataChnlCfg((tMCA_CL)p_mcb->mcl_handle, &p_dcb->chnl_cfg) != 1104 MCA_SUCCESS) { 1105 /* should be able to abort so no checking of the return code */ 1106 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1107 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1108 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1109 } 1110 } else { 1111 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1112 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1113 } 1114 } 1115 } 1116 1117 /******************************************************************************* 1118 * 1119 * Function bta_hl_dch_mca_reconnect 1120 * 1121 * Description Action routine for processing the reconnect request 1122 * 1123 * Returns void 1124 * 1125 ******************************************************************************/ 1126 void bta_hl_dch_mca_reconnect(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1127 tBTA_HL_DATA* p_data) { 1128 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1129 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1130 tMCA_CHNL_CFG* p_chnl_cfg = NULL; 1131 uint8_t sdp_idx; 1132 1133 #if (BTA_HL_DEBUG == TRUE) 1134 APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect"); 1135 #endif 1136 if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm, 1137 &sdp_idx)) { 1138 p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm; 1139 if (MCA_ReconnectMdl((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1140 p_mcb->data_psm, p_dcb->mdl_id, 1141 p_chnl_cfg) != MCA_SUCCESS) { 1142 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1143 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1144 } 1145 } else { 1146 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1147 p_data); 1148 } 1149 } 1150 1151 /******************************************************************************* 1152 * 1153 * Function bta_hl_dch_create_rsp 1154 * 1155 * Description Action routine for processing BTA_HL_API_DCH_CREATE_RSP_EVT 1156 * 1157 * Returns void 1158 * 1159 ******************************************************************************/ 1160 void bta_hl_dch_create_rsp(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1161 tBTA_HL_DATA* p_data) { 1162 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1163 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1164 tBTA_HL_API_DCH_CREATE_RSP* p_create_rsp = &p_data->api_dch_create_rsp; 1165 uint8_t mca_rsp_code = MCA_RSP_SUCCESS; 1166 1167 #if (BTA_HL_DEBUG == TRUE) 1168 APPL_TRACE_DEBUG("bta_hl_dch_create_rsp"); 1169 #endif 1170 if (p_create_rsp->rsp_code == BTA_HL_DCH_CREATE_RSP_SUCCESS) { 1171 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN; 1172 p_dcb->local_cfg = p_create_rsp->cfg_rsp; 1173 1174 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1175 } else { 1176 mca_rsp_code = MCA_RSP_CFG_REJ; 1177 } 1178 1179 if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1180 p_dcb->mdl_id, p_dcb->local_cfg, mca_rsp_code, 1181 &p_dcb->chnl_cfg) != MCA_SUCCESS) { 1182 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1183 p_data); 1184 } 1185 } 1186 1187 /******************************************************************************* 1188 * 1189 * Function bta_hl_dch_mca_create_ind 1190 * 1191 * Description Action routine for processing 1192 * 1193 * Returns void 1194 * 1195 ******************************************************************************/ 1196 void bta_hl_dch_mca_create_ind(uint8_t app_idx, uint8_t mcl_idx, 1197 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1198 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx); 1199 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1200 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1201 tMCA_CREATE_IND* p_create_ind = &p_data->mca_evt.mca_data.create_ind; 1202 uint8_t mdep_cfg_idx; 1203 uint8_t cfg_rsp; 1204 uint8_t rsp_code = MCA_RSP_SUCCESS; 1205 bool send_create_ind_evt = false; 1206 tBTA_HL evt_data; 1207 tBTA_HL_ECHO_CFG* p_echo_cfg; 1208 1209 #if (BTA_HL_DEBUG == TRUE) 1210 APPL_TRACE_DEBUG("bta_hl_dch_mca_create_ind"); 1211 #endif 1212 1213 if (bta_hl_find_mdep_cfg_idx(app_idx, p_create_ind->dep_id, &mdep_cfg_idx)) { 1214 if (p_create_ind->dep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1215 if (bta_hl_find_echo_cfg_rsp(app_idx, mcl_idx, mdep_cfg_idx, 1216 p_create_ind->cfg, &cfg_rsp)) { 1217 p_dcb->in_use = true; 1218 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN; 1219 p_dcb->local_mdep_id = p_create_ind->dep_id; 1220 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1221 p_dcb->local_cfg = cfg_rsp; 1222 p_dcb->remote_cfg = p_create_ind->cfg; 1223 p_dcb->mdl_id = p_create_ind->mdl_id; 1224 p_dcb->mdl_cfg_idx_included = false; 1225 p_echo_cfg = BTA_HL_GET_ECHO_CFG_PTR(app_idx); 1226 p_dcb->max_rx_apdu_size = p_echo_cfg->max_rx_apdu_size; 1227 p_dcb->max_tx_apdu_size = p_echo_cfg->max_tx_apdu_size; 1228 1229 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1230 } else { 1231 rsp_code = MCA_RSP_CFG_REJ; 1232 } 1233 } else 1234 1235 { 1236 p_dcb->in_use = true; 1237 p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CREATE; 1238 p_dcb->local_mdep_id = p_create_ind->dep_id; 1239 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx; 1240 p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN; 1241 p_dcb->remote_cfg = p_create_ind->cfg; 1242 p_dcb->mdl_id = p_create_ind->mdl_id; 1243 p_dcb->mdl_cfg_idx_included = false; 1244 bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx, 1245 &p_dcb->max_rx_apdu_size, 1246 &p_dcb->max_tx_apdu_size); 1247 send_create_ind_evt = true; 1248 } 1249 } else { 1250 rsp_code = MCA_RSP_BAD_MDEP; 1251 } 1252 1253 if (send_create_ind_evt) { 1254 evt_data.dch_create_ind.mcl_handle = p_mcb->mcl_handle; 1255 evt_data.dch_create_ind.app_handle = p_acb->app_handle; 1256 evt_data.dch_create_ind.local_mdep_id = p_dcb->local_mdep_id; 1257 evt_data.dch_create_ind.mdl_id = p_dcb->mdl_id; 1258 evt_data.dch_create_ind.cfg = p_dcb->remote_cfg; 1259 evt_data.dch_create_ind.bd_addr = p_mcb->bd_addr; 1260 p_acb->p_cback(BTA_HL_DCH_CREATE_IND_EVT, (tBTA_HL*)&evt_data); 1261 } else { 1262 if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1263 p_dcb->mdl_id, p_dcb->local_cfg, rsp_code, 1264 &p_dcb->chnl_cfg) != MCA_SUCCESS) { 1265 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1266 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1267 } else { 1268 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1269 p_mcb->echo_test = true; 1270 p_dcb->echo_oper = BTA_HL_ECHO_OP_OPEN_IND; 1271 } 1272 } 1273 } 1274 } 1275 1276 /******************************************************************************* 1277 * 1278 * Function bta_hl_dch_mca_create_cfm 1279 * 1280 * Description Action routine for processing 1281 * 1282 * Returns void 1283 * 1284 ******************************************************************************/ 1285 void bta_hl_dch_mca_create_cfm(uint8_t app_idx, uint8_t mcl_idx, 1286 uint8_t mdl_idx, tBTA_HL_DATA* p_data) { 1287 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1288 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1289 tMCA_CREATE_CFM* p_create_cfm = &p_data->mca_evt.mca_data.create_cfm; 1290 1291 #if (BTA_HL_DEBUG == TRUE) 1292 APPL_TRACE_DEBUG("bta_hl_dch_mca_create_cfm"); 1293 #endif 1294 1295 if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) { 1296 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 1297 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT, 1298 p_data); 1299 return; 1300 } 1301 1302 if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) { 1303 if (p_create_cfm->rsp_code == MCA_RSP_SUCCESS) { 1304 if (bta_hl_validate_cfg(app_idx, mcl_idx, mdl_idx, p_create_cfm->cfg)) { 1305 bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data); 1306 1307 if (MCA_DataChnlCfg((tMCA_CL)p_mcb->mcl_handle, &p_dcb->chnl_cfg) != 1308 MCA_SUCCESS) { 1309 /* this should not happen */ 1310 APPL_TRACE_ERROR("Unable to create data channel"); 1311 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1312 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1313 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1314 } else { 1315 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1316 p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_OPEN_CFM; 1317 } 1318 } 1319 } else { 1320 MCA_Abort((tMCA_CL)p_mcb->mcl_handle); 1321 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1322 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1323 } 1324 } else { 1325 APPL_TRACE_ERROR("MCA Create- failed"); 1326 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1327 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1328 } 1329 } 1330 } 1331 1332 /******************************************************************************* 1333 * 1334 * Function bta_hl_dch_mca_create 1335 * 1336 * Description Action routine for processing the MDL create request 1337 * 1338 * Returns void 1339 * 1340 ******************************************************************************/ 1341 void bta_hl_dch_mca_create(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1342 tBTA_HL_DATA* p_data) { 1343 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1344 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1345 tMCA_RESULT result; 1346 uint8_t sdp_idx; 1347 1348 #if (BTA_HL_DEBUG == TRUE) 1349 APPL_TRACE_DEBUG("bta_hl_dch_mca_create"); 1350 #endif 1351 1352 if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm, 1353 &sdp_idx) && 1354 bta_hl_validate_peer_cfg(app_idx, mcl_idx, mdl_idx, p_dcb->peer_mdep_id, 1355 p_dcb->peer_mdep_role, sdp_idx)) { 1356 p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm; 1357 result = MCA_CreateMdl((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id, 1358 p_mcb->data_psm, p_dcb->mdl_id, p_dcb->peer_mdep_id, 1359 p_dcb->local_cfg, NULL); 1360 if (result != MCA_SUCCESS) { 1361 APPL_TRACE_ERROR("MCA_CreateMdl FAIL mca_result=%d", result); 1362 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, 1363 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data); 1364 } 1365 } else { 1366 APPL_TRACE_ERROR("MCA Create- SDP idx or peer MDEP cfg not found"); 1367 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1368 p_data); 1369 } 1370 } 1371 1372 /******************************************************************************* 1373 * 1374 * Function bta_hl_dch_sdp_fail 1375 * 1376 * Description Action routine for processing the SDP failed event 1377 * 1378 * Returns void 1379 * 1380 ******************************************************************************/ 1381 void bta_hl_dch_sdp_fail(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx, 1382 tBTA_HL_DATA* p_data) { 1383 #if (BTA_HL_DEBUG == TRUE) 1384 APPL_TRACE_DEBUG("bta_hl_dch_sdp_fail"); 1385 #endif 1386 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT, 1387 p_data); 1388 } 1389 1390 /****************************************************************************** 1391 * 1392 * Function bta_hl_sdp_cback 1393 * 1394 * Description This is the SDP callback function used by HL. 1395 * This function will be executed by SDP when the service 1396 * search is completed. If the search is successful, it 1397 * finds the first record in the database that matches the 1398 * UUID of the search. Then retrieves the scn from the 1399 * record. 1400 * 1401 * Returns void. 1402 * 1403 *****************************************************************************/ 1404 static void bta_hl_sdp_cback(uint8_t sdp_oper, uint8_t app_idx, uint8_t mcl_idx, 1405 uint8_t mdl_idx, uint16_t status) { 1406 tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1407 tBTA_HL_SDP_REC* p_hdp_rec; 1408 tBTA_HL_CCH_SDP* p_cch_buf; 1409 tBTA_HL_DCH_SDP* p_dch_buf; 1410 tSDP_DISC_REC* p_rec = NULL; 1411 tSDP_PROTOCOL_ELEM pe; 1412 tSDP_DISC_ATTR* p_attr; 1413 uint8_t i, rec_cnt; 1414 tBTA_HL_SUP_FEATURE_LIST_ELEM sup_feature; 1415 bool sdp_parsing_ok = false, result = false; 1416 uint16_t event; 1417 tBTA_HL_MDL_CB* p_dcb; 1418 uint16_t service_uuid; 1419 uint16_t name_len; 1420 1421 #if (BTA_HL_DEBUG == TRUE) 1422 APPL_TRACE_DEBUG( 1423 "bta_hl_sdp_cback status:%d sdp_oper=%d app_idx=%d, mcl_idx=%d, " 1424 "mdl_idx=%d", 1425 status, sdp_oper, app_idx, mcl_idx, mdl_idx); 1426 #endif 1427 1428 rec_cnt = 0; 1429 service_uuid = bta_hl_get_service_uuids(sdp_oper, app_idx, mcl_idx, mdl_idx); 1430 1431 if (status == SDP_SUCCESS || status == SDP_DB_FULL) { 1432 memset(&p_cb->sdp, 0, sizeof(tBTA_HL_SDP)); 1433 do { 1434 if (bta_hl_find_service_in_db(app_idx, mcl_idx, service_uuid, &p_rec)) { 1435 p_hdp_rec = &p_cb->sdp.sdp_rec[rec_cnt]; 1436 p_cb->sdp.num_recs = rec_cnt + 1; 1437 } else { 1438 break; 1439 } 1440 1441 if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe)) { 1442 p_hdp_rec->ctrl_psm = (uint16_t)pe.params[0]; 1443 } else { 1444 APPL_TRACE_WARNING("Control PSM not found"); 1445 break; 1446 } 1447 if (SDP_FindAddProtoListsElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe)) { 1448 p_hdp_rec->data_psm = (uint16_t)pe.params[0]; 1449 } else { 1450 APPL_TRACE_WARNING("Data PSM not found"); 1451 break; 1452 } 1453 1454 p_hdp_rec->srv_name[0] = '\0'; 1455 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME); 1456 if (p_attr != NULL) { 1457 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN) 1458 name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 1459 else 1460 name_len = BT_MAX_SERVICE_NAME_LEN; 1461 memcpy(p_hdp_rec->srv_name, p_attr->attr_value.v.array, name_len); 1462 } 1463 1464 p_hdp_rec->srv_desp[0] = '\0'; 1465 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_DESCRIPTION); 1466 if (p_attr != NULL) { 1467 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN) 1468 name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 1469 else 1470 name_len = BT_MAX_SERVICE_NAME_LEN; 1471 memcpy(p_hdp_rec->srv_desp, p_attr->attr_value.v.array, name_len); 1472 } 1473 1474 p_hdp_rec->provider_name[0] = '\0'; 1475 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PROVIDER_NAME); 1476 if (p_attr != NULL) { 1477 if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN) 1478 name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type); 1479 else 1480 name_len = BT_MAX_SERVICE_NAME_LEN; 1481 memcpy(p_hdp_rec->provider_name, p_attr->attr_value.v.array, name_len); 1482 } 1483 1484 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_MCAP_SUP_PROC); 1485 if (p_attr != NULL) { 1486 p_hdp_rec->mcap_sup_proc = p_attr->attr_value.v.u8; 1487 } else { 1488 APPL_TRACE_WARNING("MCAP SUP PROC not found"); 1489 break; 1490 } 1491 1492 p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_SUP_FEAT_LIST); 1493 if (p_attr != NULL) { 1494 if (bta_hl_fill_sup_feature_list(p_attr, &sup_feature)) { 1495 p_hdp_rec->num_mdeps = (uint8_t)sup_feature.num_elems; 1496 APPL_TRACE_WARNING("bta_hl_sdp_cback num_mdeps %d", 1497 sup_feature.num_elems); 1498 for (i = 0; i < sup_feature.num_elems; i++) { 1499 p_hdp_rec->mdep_cfg[i].data_type = 1500 sup_feature.list_elem[i].data_type; 1501 p_hdp_rec->mdep_cfg[i].mdep_id = sup_feature.list_elem[i].mdep_id; 1502 p_hdp_rec->mdep_cfg[i].mdep_role = 1503 sup_feature.list_elem[i].mdep_role; 1504 /* Check MDEP Description pointer to prevent crash due to null 1505 * pointer */ 1506 if (sup_feature.list_elem[i].p_mdep_desp != NULL) { 1507 strlcpy(p_hdp_rec->mdep_cfg[i].mdep_desp, 1508 sup_feature.list_elem[i].p_mdep_desp, 1509 BTA_HL_MDEP_DESP_LEN); 1510 } else { 1511 APPL_TRACE_ERROR( 1512 "bta_hl_sdp_cback Incorrect Mdep[%d] Description (Null ptr)", 1513 i); 1514 } 1515 } 1516 1517 sdp_parsing_ok = true; 1518 } else { 1519 APPL_TRACE_WARNING("HDP supported feature list fill failed"); 1520 break; 1521 } 1522 } else { 1523 APPL_TRACE_WARNING("HDP supported feature list not found"); 1524 break; 1525 } 1526 #if (BTA_HL_DEBUG == TRUE) 1527 APPL_TRACE_DEBUG("record=%d ctrl_psm=%0x data_psm=%x", rec_cnt + 1, 1528 p_hdp_rec->ctrl_psm, p_hdp_rec->data_psm); 1529 APPL_TRACE_DEBUG("srv_name=[%s]", (p_hdp_rec->srv_name[0] != '\0') 1530 ? p_hdp_rec->srv_name 1531 : "NULL"); 1532 APPL_TRACE_DEBUG("srv_desp=[%s]", (p_hdp_rec->srv_desp[0] != '\0') 1533 ? p_hdp_rec->srv_desp 1534 : "NULL"); 1535 for (i = 0; i < sup_feature.num_elems; i++) { 1536 APPL_TRACE_DEBUG( 1537 "index=0x%02x mdep_id=0x%04x data type=0x%04x mdep role=%s(0x%02x)", 1538 (i + 1), p_hdp_rec->mdep_cfg[i].mdep_id, 1539 p_hdp_rec->mdep_cfg[i].data_type, 1540 (p_hdp_rec->mdep_cfg[i].mdep_role == BTA_HL_MDEP_ROLE_SOURCE) 1541 ? "Src" 1542 : "Snk", 1543 p_hdp_rec->mdep_cfg[i].mdep_role); 1544 } 1545 APPL_TRACE_DEBUG("provider_name=[%s]", 1546 (p_hdp_rec->provider_name[0] != '\0') 1547 ? p_hdp_rec->provider_name 1548 : "NULL"); 1549 APPL_TRACE_DEBUG("found MCAP sup procedure=%d", 1550 p_cb->sdp.sdp_rec[rec_cnt].mcap_sup_proc); 1551 #endif 1552 rec_cnt++; 1553 if (rec_cnt >= BTA_HL_NUM_SDP_RECS) { 1554 APPL_TRACE_WARNING("No more spaces for SDP recs max_rec_cnt=%d", 1555 BTA_HL_NUM_SDP_RECS); 1556 break; 1557 } 1558 1559 } while (true); 1560 } 1561 1562 osi_free_and_reset((void**)&p_cb->p_db); 1563 1564 if ((status == SDP_SUCCESS || status == SDP_DB_FULL) && p_cb->sdp.num_recs && 1565 sdp_parsing_ok) { 1566 result = true; 1567 } else { 1568 APPL_TRACE_WARNING( 1569 "SDP Failed sdp_status=%d num_recs=%d sdp_parsing_ok=%d ", status, 1570 p_cb->sdp.num_recs, sdp_parsing_ok); 1571 } 1572 1573 p_cb->sdp_oper = BTA_HL_SDP_OP_NONE; 1574 1575 switch (sdp_oper) { 1576 case BTA_HL_SDP_OP_CCH_INIT: 1577 case BTA_HL_SDP_OP_SDP_QUERY_NEW: 1578 case BTA_HL_SDP_OP_SDP_QUERY_CURRENT: 1579 1580 /* send result in event back to BTA */ 1581 p_cch_buf = (tBTA_HL_CCH_SDP*)osi_malloc(sizeof(tBTA_HL_CCH_SDP)); 1582 if (result) { 1583 if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT) { 1584 event = BTA_HL_CCH_SDP_OK_EVT; 1585 if (p_cb->close_pending) event = BTA_HL_CCH_SDP_FAIL_EVT; 1586 } else { 1587 event = BTA_HL_SDP_QUERY_OK_EVT; 1588 } 1589 } else { 1590 if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT) 1591 event = BTA_HL_CCH_SDP_FAIL_EVT; 1592 else 1593 event = BTA_HL_SDP_QUERY_FAIL_EVT; 1594 } 1595 p_cch_buf->hdr.event = event; 1596 1597 p_cch_buf->app_idx = app_idx; 1598 p_cch_buf->mcl_idx = mcl_idx; 1599 p_cch_buf->release_mcl_cb = false; 1600 if (sdp_oper == BTA_HL_SDP_OP_SDP_QUERY_NEW) 1601 p_cch_buf->release_mcl_cb = true; 1602 1603 bta_sys_sendmsg(p_cch_buf); 1604 break; 1605 case BTA_HL_SDP_OP_DCH_OPEN_INIT: 1606 case BTA_HL_SDP_OP_DCH_RECONNECT_INIT: 1607 p_dch_buf = (tBTA_HL_DCH_SDP*)osi_malloc(sizeof(tBTA_HL_DCH_SDP)); 1608 p_dch_buf->hdr.event = BTA_HL_DCH_SDP_FAIL_EVT; 1609 p_dch_buf->app_idx = app_idx; 1610 p_dch_buf->mcl_idx = mcl_idx; 1611 p_dch_buf->mdl_idx = mdl_idx; 1612 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx); 1613 if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) { 1614 p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK; 1615 result = false; 1616 } 1617 if (result) { 1618 if (sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) { 1619 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) { 1620 p_dch_buf->hdr.event = BTA_HL_DCH_ECHO_TEST_EVT; 1621 } else { 1622 p_dch_buf->hdr.event = BTA_HL_DCH_OPEN_EVT; 1623 } 1624 } else { 1625 p_dch_buf->hdr.event = BTA_HL_DCH_RECONNECT_EVT; 1626 } 1627 } 1628 bta_sys_sendmsg(p_dch_buf); 1629 break; 1630 default: 1631 break; 1632 } 1633 } 1634 1635 /****************************************************************************** 1636 * 1637 * Function bta_hl_sdp_cback0 1638 * 1639 * Description This is the SDP callback function used by index = 0 1640 * 1641 * Returns void. 1642 * 1643 *****************************************************************************/ 1644 static void bta_hl_sdp_cback0(uint16_t status) { 1645 bta_hl_sdp_cback(bta_hl_cb.scb[0].sdp_oper, bta_hl_cb.scb[0].app_idx, 1646 bta_hl_cb.scb[0].mcl_idx, bta_hl_cb.scb[0].mdl_idx, status); 1647 bta_hl_deallocate_spd_cback(0); 1648 } 1649 1650 /****************************************************************************** 1651 * 1652 * Function bta_hl_sdp_cback1 1653 * 1654 * Description This is the SDP callback function used by index = 1 1655 * 1656 * Parameters status - status of the SDP callabck 1657 * 1658 * Returns void. 1659 * 1660 *****************************************************************************/ 1661 static void bta_hl_sdp_cback1(uint16_t status) { 1662 bta_hl_sdp_cback(bta_hl_cb.scb[1].sdp_oper, bta_hl_cb.scb[1].app_idx, 1663 bta_hl_cb.scb[1].mcl_idx, bta_hl_cb.scb[1].mdl_idx, status); 1664 bta_hl_deallocate_spd_cback(1); 1665 } 1666 1667 /****************************************************************************** 1668 * 1669 * Function bta_hl_sdp_cback2 1670 * 1671 * Description This is the SDP callback function used by index = 2 1672 * 1673 * Returns void. 1674 * 1675 *****************************************************************************/ 1676 static void bta_hl_sdp_cback2(uint16_t status) { 1677 bta_hl_sdp_cback(bta_hl_cb.scb[2].sdp_oper, bta_hl_cb.scb[2].app_idx, 1678 bta_hl_cb.scb[2].mcl_idx, bta_hl_cb.scb[2].mdl_idx, status); 1679 bta_hl_deallocate_spd_cback(2); 1680 } 1681 1682 /****************************************************************************** 1683 * 1684 * Function bta_hl_sdp_cback3 1685 * 1686 * Description This is the SDP callback function used by index = 3 1687 * 1688 * Returns void. 1689 * 1690 *****************************************************************************/ 1691 static void bta_hl_sdp_cback3(uint16_t status) { 1692 bta_hl_sdp_cback(bta_hl_cb.scb[3].sdp_oper, bta_hl_cb.scb[3].app_idx, 1693 bta_hl_cb.scb[3].mcl_idx, bta_hl_cb.scb[3].mdl_idx, status); 1694 bta_hl_deallocate_spd_cback(3); 1695 } 1696 1697 /****************************************************************************** 1698 * 1699 * Function bta_hl_sdp_cback4 1700 * 1701 * Description This is the SDP callback function used by index = 4 1702 * 1703 * Parameters status - status of the SDP callabck 1704 * 1705 * Returns void. 1706 * 1707 *****************************************************************************/ 1708 static void bta_hl_sdp_cback4(uint16_t status) { 1709 bta_hl_sdp_cback(bta_hl_cb.scb[4].sdp_oper, bta_hl_cb.scb[4].app_idx, 1710 bta_hl_cb.scb[4].mcl_idx, bta_hl_cb.scb[4].mdl_idx, status); 1711 bta_hl_deallocate_spd_cback(4); 1712 } 1713 1714 /****************************************************************************** 1715 * 1716 * Function bta_hl_sdp_cback5 1717 * 1718 * Description This is the SDP callback function used by index = 5 1719 * 1720 * Parameters status - status of the SDP callabck 1721 * 1722 * Returns void. 1723 * 1724 *****************************************************************************/ 1725 static void bta_hl_sdp_cback5(uint16_t status) { 1726 bta_hl_sdp_cback(bta_hl_cb.scb[5].sdp_oper, bta_hl_cb.scb[5].app_idx, 1727 bta_hl_cb.scb[5].mcl_idx, bta_hl_cb.scb[5].mdl_idx, status); 1728 bta_hl_deallocate_spd_cback(5); 1729 } 1730 1731 /****************************************************************************** 1732 * 1733 * Function bta_hl_sdp_cback6 1734 * 1735 * Description This is the SDP callback function used by index = 6 1736 * 1737 * Returns void. 1738 * 1739 *****************************************************************************/ 1740 static void bta_hl_sdp_cback6(uint16_t status) { 1741 bta_hl_sdp_cback(bta_hl_cb.scb[6].sdp_oper, bta_hl_cb.scb[6].app_idx, 1742 bta_hl_cb.scb[6].mcl_idx, bta_hl_cb.scb[6].mdl_idx, status); 1743 bta_hl_deallocate_spd_cback(6); 1744 } 1745 1746 /******************************************************************************* 1747 * 1748 * Function bta_hl_deallocate_spd_cback 1749 * 1750 * Description Deallocate a SDP control block 1751 * 1752 * Returns bool - true found 1753 * false not found 1754 * 1755 ******************************************************************************/ 1756 void bta_hl_deallocate_spd_cback(uint8_t sdp_cback_idx) { 1757 tBTA_HL_SDP_CB* p_spd_cb = &bta_hl_cb.scb[sdp_cback_idx]; 1758 1759 memset(p_spd_cb, 0, sizeof(tBTA_HL_SDP_CB)); 1760 1761 #if (BTA_HL_DEBUG == TRUE) 1762 APPL_TRACE_DEBUG("bta_hl_deallocate_spd_cback index=%d", sdp_cback_idx); 1763 #endif 1764 } 1765 1766 /******************************************************************************* 1767 * 1768 * Function bta_hl_allocate_spd_cback 1769 * 1770 * Description Finds a not in used SDP control block index 1771 * 1772 * 1773 * Returns bool - true found 1774 * false not found 1775 * 1776 ******************************************************************************/ 1777 tSDP_DISC_CMPL_CB* bta_hl_allocate_spd_cback(tBTA_HL_SDP_OPER sdp_oper, 1778 uint8_t app_idx, uint8_t mcl_idx, 1779 uint8_t mdl_idx, 1780 uint8_t* p_sdp_cback_idx) { 1781 uint8_t i; 1782 tSDP_DISC_CMPL_CB* p_cbcak = NULL; 1783 1784 for (i = 0; i < BTA_HL_NUM_SDP_CBACKS; i++) { 1785 if (!bta_hl_cb.scb[i].in_use) { 1786 p_cbcak = bta_hl_sdp_cback_arr[i]; 1787 bta_hl_cb.scb[i].in_use = true; 1788 bta_hl_cb.scb[i].sdp_oper = sdp_oper; 1789 bta_hl_cb.scb[i].app_idx = app_idx; 1790 bta_hl_cb.scb[i].mcl_idx = mcl_idx; 1791 bta_hl_cb.scb[i].mdl_idx = mdl_idx; 1792 *p_sdp_cback_idx = i; 1793 break; 1794 } 1795 } 1796 1797 if (i == BTA_HL_NUM_SDP_CBACKS) { 1798 APPL_TRACE_WARNING("No scb is available to allocate") 1799 } else { 1800 #if (BTA_HL_DEBUG == TRUE) 1801 APPL_TRACE_DEBUG("bta_hl_allocate_spd_cback cback_idx=%d ", i); 1802 APPL_TRACE_DEBUG("sdp_oper=%d, app_idx=%d, mcl_idx=%d, mdl_idx=%d", 1803 bta_hl_cb.scb[i].sdp_oper, bta_hl_cb.scb[i].app_idx, 1804 bta_hl_cb.scb[i].mcl_idx, bta_hl_cb.scb[i].mdl_idx); 1805 #endif 1806 } 1807 return p_cbcak; 1808 } 1809 1810 /******************************************************************************* 1811 * 1812 * Function bta_hl_init_sdp 1813 * 1814 * Description Action routine for processing the SDP initiattion request 1815 * 1816 * Returns void 1817 * 1818 ******************************************************************************/ 1819 tBTA_HL_STATUS bta_hl_init_sdp(tBTA_HL_SDP_OPER sdp_oper, uint8_t app_idx, 1820 uint8_t mcl_idx, uint8_t mdl_idx) { 1821 tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx); 1822 uint16_t attr_list[BTA_HL_NUM_SRCH_ATTR]; 1823 uint16_t num_attrs = BTA_HL_NUM_SRCH_ATTR; 1824 tBTA_HL_STATUS status; 1825 uint8_t sdp_cback_idx; 1826 #if (BTA_HL_DEBUG == TRUE) 1827 APPL_TRACE_DEBUG( 1828 "bta_hl_init_sdp sdp_oper=%d app_idx=%d mcl_idx=%d, mdl_idx=%d", sdp_oper, 1829 app_idx, mcl_idx, mdl_idx); 1830 #endif 1831 p_cb->sdp_cback = bta_hl_allocate_spd_cback(sdp_oper, app_idx, mcl_idx, 1832 mdl_idx, &sdp_cback_idx); 1833 if (p_cb->sdp_cback != NULL) { 1834 if (p_cb->p_db == NULL) 1835 (p_cb->p_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_HL_DISC_SIZE)); 1836 attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST; 1837 attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST; 1838 attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST; 1839 attr_list[3] = ATTR_ID_ADDITION_PROTO_DESC_LISTS; 1840 attr_list[4] = ATTR_ID_SERVICE_NAME; 1841 attr_list[5] = ATTR_ID_SERVICE_DESCRIPTION; 1842 attr_list[6] = ATTR_ID_PROVIDER_NAME; 1843 attr_list[7] = ATTR_ID_HDP_SUP_FEAT_LIST; 1844 attr_list[8] = ATTR_ID_HDP_DATA_EXCH_SPEC; 1845 attr_list[9] = ATTR_ID_HDP_MCAP_SUP_PROC; 1846 1847 Uuid uuid_list = Uuid::From16Bit(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