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 implements utility functions for the HeaLth device profile
22 * (HL).
23 *
24 ******************************************************************************/
25
26 #include <stdio.h>
27 #include <string.h>
28
29 #include "bt_target.h"
30 #if (HL_INCLUDED == TRUE)
31
32 #include "bt_common.h"
33 #include "bta_hl_co.h"
34 #include "bta_hl_int.h"
35 #include "mca_api.h"
36 #include "mca_defs.h"
37 #include "osi/include/osi.h"
38 #include "utl.h"
39
40 /*******************************************************************************
41 *
42 * Function bta_hl_set_ctrl_psm_for_dch
43 *
44 * Description This function set the control PSM for the DCH setup
45 *
46 * Returns bool - true - control PSM setting is successful
47 ******************************************************************************/
bta_hl_set_ctrl_psm_for_dch(uint8_t app_idx,uint8_t mcl_idx,UNUSED_ATTR uint8_t mdl_idx,uint16_t ctrl_psm)48 bool bta_hl_set_ctrl_psm_for_dch(uint8_t app_idx, uint8_t mcl_idx,
49 UNUSED_ATTR uint8_t mdl_idx,
50 uint16_t ctrl_psm) {
51 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
52 bool success = true, update_ctrl_psm = false;
53
54 if (p_mcb->sdp.num_recs) {
55 if (p_mcb->ctrl_psm != ctrl_psm) {
56 /* can not use a different ctrl PSM than the current one*/
57 success = false;
58 }
59 } else {
60 /* No SDP info control i.e. channel was opened by the peer */
61 update_ctrl_psm = true;
62 }
63
64 if (success && update_ctrl_psm) {
65 p_mcb->ctrl_psm = ctrl_psm;
66 }
67
68 #if (BTA_HL_DEBUG == TRUE)
69 if (!success) {
70 APPL_TRACE_DEBUG(
71 "bta_hl_set_ctrl_psm_for_dch num_recs=%d success=%d update_ctrl_psm=%d "
72 "ctrl_psm=0x%x ",
73 p_mcb->sdp.num_recs, success, update_ctrl_psm, ctrl_psm);
74 }
75 #endif
76
77 return success;
78 }
79
80 /*******************************************************************************
81 *
82 * Function bta_hl_find_sdp_idx_using_ctrl_psm
83 *
84 * Description
85 *
86 * Returns true if found
87 *
88 ******************************************************************************/
bta_hl_find_sdp_idx_using_ctrl_psm(tBTA_HL_SDP * p_sdp,uint16_t ctrl_psm,uint8_t * p_sdp_idx)89 bool bta_hl_find_sdp_idx_using_ctrl_psm(tBTA_HL_SDP* p_sdp, uint16_t ctrl_psm,
90 uint8_t* p_sdp_idx) {
91 bool found = false;
92 tBTA_HL_SDP_REC* p_rec;
93 uint8_t i;
94
95 if (ctrl_psm != 0) {
96 for (i = 0; i < p_sdp->num_recs; i++) {
97 p_rec = &p_sdp->sdp_rec[i];
98 if (p_rec->ctrl_psm == ctrl_psm) {
99 *p_sdp_idx = i;
100 found = true;
101 break;
102 }
103 }
104 } else {
105 *p_sdp_idx = 0;
106 found = true;
107 }
108
109 #if (BTA_HL_DEBUG == TRUE)
110 if (!found) {
111 APPL_TRACE_DEBUG(
112 "bta_hl_find_sdp_idx_using_ctrl_psm found=%d sdp_idx=%d ctrl_psm=0x%x ",
113 found, *p_sdp_idx, ctrl_psm);
114 }
115 #endif
116 return found;
117 }
118
119 /*******************************************************************************
120 *
121 * Function bta_hl_set_user_tx_buf_size
122 *
123 * Description This function sets the user tx buffer size
124 *
125 * Returns uint16_t buf_size
126 *
127 ******************************************************************************/
128
bta_hl_set_user_tx_buf_size(uint16_t max_tx_size)129 uint16_t bta_hl_set_user_tx_buf_size(uint16_t max_tx_size) {
130 if (max_tx_size > BT_DEFAULT_BUFFER_SIZE) return BTA_HL_LRG_DATA_BUF_SIZE;
131 return L2CAP_INVALID_ERM_BUF_SIZE;
132 }
133
134 /*******************************************************************************
135 *
136 * Function bta_hl_set_user_rx_buf_size
137 *
138 * Description This function sets the user rx buffer size
139 *
140 * Returns uint16_t buf_size
141 *
142 ******************************************************************************/
143
bta_hl_set_user_rx_buf_size(uint16_t mtu)144 uint16_t bta_hl_set_user_rx_buf_size(uint16_t mtu) {
145 if (mtu > BT_DEFAULT_BUFFER_SIZE) return BTA_HL_LRG_DATA_BUF_SIZE;
146 return L2CAP_INVALID_ERM_BUF_SIZE;
147 }
148
149 /*******************************************************************************
150 *
151 * Function bta_hl_set_tx_win_size
152 *
153 * Description This function sets the tx window size
154 *
155 * Returns uint8_t tx_win_size
156 *
157 ******************************************************************************/
bta_hl_set_tx_win_size(uint16_t mtu,uint16_t mps)158 uint8_t bta_hl_set_tx_win_size(uint16_t mtu, uint16_t mps) {
159 uint8_t tx_win_size;
160
161 if (mtu <= mps) {
162 tx_win_size = 1;
163 } else {
164 if (mps > 0) {
165 tx_win_size = (mtu / mps) + 1;
166 } else {
167 APPL_TRACE_ERROR("The MPS is zero");
168 tx_win_size = 10;
169 }
170 }
171
172 #if (BTA_HL_DEBUG == TRUE)
173 APPL_TRACE_DEBUG("bta_hl_set_tx_win_size win_size=%d mtu=%d mps=%d",
174 tx_win_size, mtu, mps);
175 #endif
176 return tx_win_size;
177 }
178
179 /*******************************************************************************
180 *
181 * Function bta_hl_set_mps
182 *
183 * Description This function sets the MPS
184 *
185 * Returns uint16_t MPS
186 *
187 ******************************************************************************/
bta_hl_set_mps(uint16_t mtu)188 uint16_t bta_hl_set_mps(uint16_t mtu) {
189 uint16_t mps;
190 if (mtu > BTA_HL_L2C_MPS) {
191 mps = BTA_HL_L2C_MPS;
192 } else {
193 mps = mtu;
194 }
195 #if (BTA_HL_DEBUG == TRUE)
196 APPL_TRACE_DEBUG("bta_hl_set_mps mps=%d mtu=%d", mps, mtu);
197 #endif
198 return mps;
199 }
200
201 /*******************************************************************************
202 *
203 * Function bta_hl_clean_mdl_cb
204 *
205 * Description This function clean up the specified MDL control block
206 *
207 * Returns void
208 *
209 ******************************************************************************/
bta_hl_clean_mdl_cb(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)210 void bta_hl_clean_mdl_cb(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
211 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
212 #if (BTA_HL_DEBUG == TRUE)
213 APPL_TRACE_DEBUG("bta_hl_clean_mdl_cb app_idx=%d mcl_idx=%d mdl_idx=%d",
214 app_idx, mcl_idx, mdl_idx);
215 #endif
216 osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
217 osi_free_and_reset((void**)&p_dcb->p_rx_pkt);
218 osi_free_and_reset((void**)&p_dcb->p_echo_tx_pkt);
219 osi_free_and_reset((void**)&p_dcb->p_echo_rx_pkt);
220
221 memset((void*)p_dcb, 0, sizeof(tBTA_HL_MDL_CB));
222 }
223
224 /*******************************************************************************
225 *
226 * Function bta_hl_get_buf
227 *
228 * Description This function allocate a buffer based on the specified data size
229 *
230 * Returns BT_HDR *.
231 *
232 ******************************************************************************/
bta_hl_get_buf(uint16_t data_size,bool fcs_use)233 BT_HDR* bta_hl_get_buf(uint16_t data_size, bool fcs_use) {
234 size_t size = data_size + L2CAP_MIN_OFFSET + BT_HDR_SIZE + L2CAP_FCS_LEN +
235 L2CAP_EXT_CONTROL_OVERHEAD;
236
237 if (fcs_use) size += L2CAP_FCS_LEN;
238
239 BT_HDR* p_new = (BT_HDR*)osi_malloc(size);
240 p_new->len = data_size;
241 p_new->offset = L2CAP_MIN_OFFSET;
242
243 return p_new;
244 }
245
246 /*******************************************************************************
247 *
248 * Function bta_hl_find_service_in_db
249 *
250 * Description This function check the specified service class(es) can be find
251 * in the received SDP database
252 *
253 * Returns bool true - found
254 * false - not found
255 *
256 ******************************************************************************/
bta_hl_find_service_in_db(uint8_t app_idx,uint8_t mcl_idx,uint16_t service_uuid,tSDP_DISC_REC ** pp_rec)257 bool bta_hl_find_service_in_db(uint8_t app_idx, uint8_t mcl_idx,
258 uint16_t service_uuid, tSDP_DISC_REC** pp_rec) {
259 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
260 bool found = true;
261
262 switch (service_uuid) {
263 case UUID_SERVCLASS_HDP_SINK:
264 case UUID_SERVCLASS_HDP_SOURCE:
265 *pp_rec = SDP_FindServiceInDb(p_mcb->p_db, service_uuid, *pp_rec);
266 if (*pp_rec == NULL) {
267 found = false;
268 }
269 break;
270 default:
271 *pp_rec = bta_hl_find_sink_or_src_srv_class_in_db(p_mcb->p_db, *pp_rec);
272 if (*pp_rec == NULL) {
273 found = false;
274 }
275 break;
276 }
277 return found;
278 }
279
280 /*******************************************************************************
281 *
282 * Function bta_hl_get_service_uuids
283 *
284 *
285 * Description This function finds the service class(es) for both CCH and DCH
286 * operations
287 *
288 * Returns uint16_t - service_id
289 * if service_uuid = 0xFFFF then it means service uuid
290 * can be either Sink or Source
291 *
292 ******************************************************************************/
bta_hl_get_service_uuids(uint8_t sdp_oper,uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)293 uint16_t bta_hl_get_service_uuids(uint8_t sdp_oper, uint8_t app_idx,
294 uint8_t mcl_idx, uint8_t mdl_idx) {
295 tBTA_HL_MDL_CB* p_dcb;
296 uint16_t service_uuid = 0xFFFF; /* both Sink and Source */
297
298 switch (sdp_oper) {
299 case BTA_HL_SDP_OP_DCH_OPEN_INIT:
300 case BTA_HL_SDP_OP_DCH_RECONNECT_INIT:
301 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
302 if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
303 if (p_dcb->peer_mdep_role == BTA_HL_MDEP_ROLE_SINK) {
304 service_uuid = UUID_SERVCLASS_HDP_SINK;
305 } else {
306 service_uuid = UUID_SERVCLASS_HDP_SOURCE;
307 }
308 }
309 break;
310 case BTA_HL_SDP_OP_CCH_INIT:
311 default:
312 /* use default that is both Sink and Source */
313 break;
314 }
315 #if (BTA_HL_DEBUG == TRUE)
316 APPL_TRACE_DEBUG("bta_hl_get_service_uuids service_uuid=0x%x", service_uuid);
317 #endif
318 return service_uuid;
319 }
320
321 /*******************************************************************************
322 *
323 * Function bta_hl_find_echo_cfg_rsp
324 *
325 *
326 * Description This function finds the configuration response for the echo test
327 *
328 * Returns bool - true found
329 * false not found
330 *
331 ******************************************************************************/
bta_hl_find_echo_cfg_rsp(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdep_idx,uint8_t cfg,uint8_t * p_cfg_rsp)332 bool bta_hl_find_echo_cfg_rsp(uint8_t app_idx, uint8_t mcl_idx,
333 uint8_t mdep_idx, uint8_t cfg,
334 uint8_t* p_cfg_rsp) {
335 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
336 tBTA_HL_MDEP* p_mdep = &p_acb->sup_feature.mdep[mdep_idx];
337 bool status = true;
338
339 if (p_mdep->mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
340 if ((cfg == BTA_HL_DCH_CFG_RELIABLE) || (cfg == BTA_HL_DCH_CFG_STREAMING)) {
341 *p_cfg_rsp = cfg;
342 } else if (cfg == BTA_HL_DCH_CFG_NO_PREF) {
343 *p_cfg_rsp = BTA_HL_DEFAULT_ECHO_TEST_SRC_DCH_CFG;
344 } else {
345 status = false;
346 APPL_TRACE_ERROR("Inavlid echo cfg value");
347 }
348 return status;
349 }
350
351 #if (BTA_HL_DEBUG == TRUE)
352 if (!status) {
353 APPL_TRACE_DEBUG(
354 "bta_hl_find_echo_cfg_rsp status=failed app_idx=%d mcl_idx=%d "
355 "mdep_idx=%d cfg=%d",
356 app_idx, mcl_idx, mdep_idx, cfg);
357 }
358 #endif
359
360 return status;
361 }
362
363 /*******************************************************************************
364 *
365 * Function bta_hl_validate_dch_cfg
366 *
367 * Description This function validate the DCH configuration
368 *
369 * Returns bool - true cfg is valid
370 * false not valid
371 *
372 ******************************************************************************/
bta_hl_validate_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx,uint8_t cfg)373 bool bta_hl_validate_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
374 uint8_t cfg) {
375 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
376 bool is_valid = false;
377
378 if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx) &&
379 (cfg != BTA_HL_DCH_CFG_RELIABLE)) {
380 APPL_TRACE_ERROR("the first DCH should be a reliable channel");
381 return is_valid;
382 }
383
384 switch (p_dcb->local_cfg) {
385 case BTA_HL_DCH_CFG_NO_PREF:
386
387 if ((cfg == BTA_HL_DCH_CFG_RELIABLE) ||
388 (cfg == BTA_HL_DCH_CFG_STREAMING)) {
389 is_valid = true;
390 }
391 break;
392 case BTA_HL_DCH_CFG_RELIABLE:
393 case BTA_HL_DCH_CFG_STREAMING:
394 if (p_dcb->local_cfg == cfg) {
395 is_valid = true;
396 }
397 break;
398 default:
399 break;
400 }
401
402 #if (BTA_HL_DEBUG == TRUE)
403 if (!is_valid) {
404 APPL_TRACE_DEBUG("bta_hl_validate_dch_open_cfg is_valid=%d, cfg=%d",
405 is_valid, cfg);
406 }
407 #endif
408 return is_valid;
409 }
410
411 /*******************************************************************************
412 *
413 * Function bta_hl_find_cch_cb_indexes
414 *
415 * Description This function finds the indexes needed for the CCH state machine
416 *
417 * Returns bool - true found
418 * false not found
419 *
420 ******************************************************************************/
bta_hl_find_cch_cb_indexes(tBTA_HL_DATA * p_msg,uint8_t * p_app_idx,uint8_t * p_mcl_idx)421 bool bta_hl_find_cch_cb_indexes(tBTA_HL_DATA* p_msg, uint8_t* p_app_idx,
422 uint8_t* p_mcl_idx) {
423 bool found = false;
424 tBTA_HL_MCL_CB* p_mcb;
425 uint8_t app_idx = 0, mcl_idx = 0;
426
427 switch (p_msg->hdr.event) {
428 case BTA_HL_CCH_SDP_OK_EVT:
429 case BTA_HL_CCH_SDP_FAIL_EVT:
430 app_idx = p_msg->cch_sdp.app_idx;
431 mcl_idx = p_msg->cch_sdp.mcl_idx;
432 found = true;
433 break;
434
435 case BTA_HL_MCA_CONNECT_IND_EVT:
436
437 if (bta_hl_find_app_idx_using_handle(p_msg->mca_evt.app_handle,
438 &app_idx)) {
439 if (bta_hl_find_mcl_idx(app_idx,
440 p_msg->mca_evt.mca_data.connect_ind.bd_addr,
441 &mcl_idx)) {
442 /* local initiated */
443 found = true;
444 } else if (!bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle,
445 &app_idx, &mcl_idx) &&
446 bta_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) {
447 /* remote initiated */
448 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
449 p_mcb->in_use = true;
450 p_mcb->cch_oper = BTA_HL_CCH_OP_REMOTE_OPEN;
451 found = true;
452 }
453 }
454 break;
455
456 case BTA_HL_MCA_DISCONNECT_IND_EVT:
457
458 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
459 &mcl_idx)) {
460 found = true;
461 } else if (bta_hl_find_app_idx_using_handle(p_msg->mca_evt.app_handle,
462 &app_idx) &&
463 bta_hl_find_mcl_idx(
464 app_idx, p_msg->mca_evt.mca_data.disconnect_ind.bd_addr,
465 &mcl_idx)) {
466 found = true;
467 }
468
469 if (found) {
470 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
471 if ((p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) &&
472 (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_OPEN)) {
473 p_mcb->cch_oper = BTA_HL_CCH_OP_REMOTE_CLOSE;
474 }
475 }
476 break;
477
478 case BTA_HL_MCA_RSP_TOUT_IND_EVT:
479
480 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
481 &mcl_idx)) {
482 found = true;
483 }
484
485 if (found) {
486 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
487 if ((p_mcb->cch_oper != BTA_HL_CCH_OP_REMOTE_CLOSE) &&
488 (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_OPEN)) {
489 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
490 }
491 }
492 break;
493 default:
494 break;
495 }
496
497 if (found) {
498 *p_app_idx = app_idx;
499 *p_mcl_idx = mcl_idx;
500 }
501
502 #if (BTA_HL_DEBUG == TRUE)
503 if (!found) {
504 APPL_TRACE_DEBUG(
505 "bta_hl_find_cch_cb_indexes event=%s found=%d app_idx=%d mcl_idx=%d",
506 bta_hl_evt_code(p_msg->hdr.event), found, app_idx, mcl_idx);
507 }
508 #endif
509
510 return found;
511 }
512
513 /*******************************************************************************
514 *
515 * Function bta_hl_find_dch_cb_indexes
516 *
517 * Description This function finds the indexes needed for the DCH state machine
518 *
519 * Returns bool - true found
520 * false not found
521 *
522 ******************************************************************************/
bta_hl_find_dch_cb_indexes(tBTA_HL_DATA * p_msg,uint8_t * p_app_idx,uint8_t * p_mcl_idx,uint8_t * p_mdl_idx)523 bool bta_hl_find_dch_cb_indexes(tBTA_HL_DATA* p_msg, uint8_t* p_app_idx,
524 uint8_t* p_mcl_idx, uint8_t* p_mdl_idx) {
525 bool found = false;
526 tBTA_HL_MCL_CB* p_mcb;
527 uint8_t app_idx = 0, mcl_idx = 0, mdl_idx = 0;
528
529 switch (p_msg->hdr.event) {
530 case BTA_HL_MCA_CREATE_CFM_EVT:
531 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
532 &mcl_idx) &&
533 bta_hl_find_mdl_idx(app_idx, mcl_idx,
534 p_msg->mca_evt.mca_data.create_cfm.mdl_id,
535 &mdl_idx)) {
536 found = true;
537 }
538 break;
539
540 case BTA_HL_MCA_CREATE_IND_EVT:
541 case BTA_HL_MCA_RECONNECT_IND_EVT:
542 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
543 &mcl_idx) &&
544 bta_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
545 found = true;
546 }
547 break;
548
549 case BTA_HL_MCA_OPEN_CFM_EVT:
550 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
551 &mcl_idx) &&
552 bta_hl_find_mdl_idx(app_idx, mcl_idx,
553 p_msg->mca_evt.mca_data.open_cfm.mdl_id,
554 &mdl_idx)) {
555 found = true;
556 }
557 break;
558
559 case BTA_HL_MCA_OPEN_IND_EVT:
560 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
561 &mcl_idx) &&
562 bta_hl_find_mdl_idx(app_idx, mcl_idx,
563 p_msg->mca_evt.mca_data.open_ind.mdl_id,
564 &mdl_idx)) {
565 found = true;
566 }
567 break;
568
569 case BTA_HL_MCA_CLOSE_CFM_EVT:
570
571 if (bta_hl_find_mdl_idx_using_handle(
572 (tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.close_cfm.mdl,
573 &app_idx, &mcl_idx, &mdl_idx)) {
574 found = true;
575 }
576 break;
577 case BTA_HL_MCA_CLOSE_IND_EVT:
578
579 if (bta_hl_find_mdl_idx_using_handle(
580 (tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.close_ind.mdl,
581 &app_idx, &mcl_idx, &mdl_idx)) {
582 found = true;
583 }
584 break;
585 case BTA_HL_API_SEND_DATA_EVT:
586
587 if (bta_hl_find_mdl_idx_using_handle(p_msg->api_send_data.mdl_handle,
588 &app_idx, &mcl_idx, &mdl_idx)) {
589 found = true;
590 }
591
592 break;
593
594 case BTA_HL_MCA_CONG_CHG_EVT:
595
596 if (bta_hl_find_mdl_idx_using_handle(
597 (tBTA_HL_MDL_HANDLE)p_msg->mca_evt.mca_data.cong_chg.mdl,
598 &app_idx, &mcl_idx, &mdl_idx)) {
599 found = true;
600 }
601
602 break;
603
604 case BTA_HL_MCA_RCV_DATA_EVT:
605 app_idx = p_msg->mca_rcv_data_evt.app_idx;
606 mcl_idx = p_msg->mca_rcv_data_evt.mcl_idx;
607 mdl_idx = p_msg->mca_rcv_data_evt.mdl_idx;
608 found = true;
609 break;
610 case BTA_HL_DCH_RECONNECT_EVT:
611 case BTA_HL_DCH_OPEN_EVT:
612 case BTA_HL_DCH_ECHO_TEST_EVT:
613 case BTA_HL_DCH_SDP_FAIL_EVT:
614 app_idx = p_msg->dch_sdp.app_idx;
615 mcl_idx = p_msg->dch_sdp.mcl_idx;
616 mdl_idx = p_msg->dch_sdp.mdl_idx;
617 found = true;
618 break;
619 case BTA_HL_MCA_RECONNECT_CFM_EVT:
620 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
621 &mcl_idx) &&
622 bta_hl_find_mdl_idx(app_idx, mcl_idx,
623 p_msg->mca_evt.mca_data.reconnect_cfm.mdl_id,
624 &mdl_idx)) {
625 found = true;
626 }
627 break;
628
629 case BTA_HL_API_DCH_CREATE_RSP_EVT:
630 if (bta_hl_find_mcl_idx_using_handle(p_msg->api_dch_create_rsp.mcl_handle,
631 &app_idx, &mcl_idx) &&
632 bta_hl_find_mdl_idx(app_idx, mcl_idx,
633 p_msg->api_dch_create_rsp.mdl_id, &mdl_idx)) {
634 found = true;
635 }
636 break;
637 case BTA_HL_MCA_ABORT_IND_EVT:
638 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
639 &mcl_idx) &&
640 bta_hl_find_mdl_idx(app_idx, mcl_idx,
641 p_msg->mca_evt.mca_data.abort_ind.mdl_id,
642 &mdl_idx)) {
643 found = true;
644 }
645 break;
646 case BTA_HL_MCA_ABORT_CFM_EVT:
647 if (bta_hl_find_mcl_idx_using_handle(p_msg->mca_evt.mcl_handle, &app_idx,
648 &mcl_idx) &&
649 bta_hl_find_mdl_idx(app_idx, mcl_idx,
650 p_msg->mca_evt.mca_data.abort_cfm.mdl_id,
651 &mdl_idx)) {
652 found = true;
653 }
654 break;
655 case BTA_HL_CI_GET_TX_DATA_EVT:
656 case BTA_HL_CI_PUT_RX_DATA_EVT:
657 if (bta_hl_find_mdl_idx_using_handle(p_msg->ci_get_put_data.mdl_handle,
658 &app_idx, &mcl_idx, &mdl_idx)) {
659 found = true;
660 }
661 break;
662 case BTA_HL_CI_GET_ECHO_DATA_EVT:
663 case BTA_HL_CI_PUT_ECHO_DATA_EVT:
664 if (bta_hl_find_mcl_idx_using_handle(
665 p_msg->ci_get_put_echo_data.mcl_handle, &app_idx, &mcl_idx)) {
666 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
667 mdl_idx = p_mcb->echo_mdl_idx;
668 found = true;
669 }
670 break;
671
672 default:
673 break;
674 }
675
676 if (found) {
677 *p_app_idx = app_idx;
678 *p_mcl_idx = mcl_idx;
679 *p_mdl_idx = mdl_idx;
680 }
681 #if (BTA_HL_DEBUG == TRUE)
682 if (!found) {
683 APPL_TRACE_DEBUG(
684 "bta_hl_find_dch_cb_indexes event=%s found=%d app_idx=%d mcl_idx=%d "
685 "mdl_idx=%d",
686 bta_hl_evt_code(p_msg->hdr.event), found, *p_app_idx, *p_mcl_idx,
687 *p_mdl_idx);
688 }
689 #endif
690
691 return found;
692 }
693
694 /*******************************************************************************
695 *
696 * Function bta_hl_allocate_mdl_id
697 *
698 * Description This function allocates a MDL ID
699 *
700 * Returns uint16_t - MDL ID
701 *
702 ******************************************************************************/
bta_hl_allocate_mdl_id(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)703 uint16_t bta_hl_allocate_mdl_id(uint8_t app_idx, uint8_t mcl_idx,
704 uint8_t mdl_idx) {
705 uint16_t mdl_id = 0;
706 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
707 bool duplicate_id;
708 uint8_t i, mdl_cfg_idx;
709
710 do {
711 duplicate_id = false;
712 mdl_id = ((mdl_id + 1) & 0xFEFF);
713 /* check mdl_ids that are used for the current conenctions */
714 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
715 if (p_mcb->mdl[i].in_use && (i != mdl_idx) &&
716 (p_mcb->mdl[i].mdl_id == mdl_id)) {
717 duplicate_id = true;
718 break;
719 }
720 }
721
722 if (duplicate_id) {
723 /* start from the beginning to get another MDL value*/
724 continue;
725 } else {
726 /* check mdl_ids that are stored in the persistent memory */
727 if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) {
728 duplicate_id = true;
729 } else {
730 /* found a new MDL value */
731 break;
732 }
733 }
734
735 } while (true);
736
737 #if (BTA_HL_DEBUG == TRUE)
738 APPL_TRACE_DEBUG("bta_hl_allocate_mdl OK mdl_id=%d", mdl_id);
739 #endif
740 return mdl_id;
741 }
742 /*******************************************************************************
743 *
744 * Function bta_hl_find_mdl_idx
745 *
746 * Description This function finds the MDL index based on mdl_id
747 *
748 * Returns bool true-found
749 *
750 ******************************************************************************/
bta_hl_find_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint16_t mdl_id,uint8_t * p_mdl_idx)751 bool bta_hl_find_mdl_idx(uint8_t app_idx, uint8_t mcl_idx, uint16_t mdl_id,
752 uint8_t* p_mdl_idx) {
753 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
754 bool found = false;
755 uint8_t i;
756
757 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
758 if (p_mcb->mdl[i].in_use && (mdl_id != 0) &&
759 (p_mcb->mdl[i].mdl_id == mdl_id)) {
760 found = true;
761 *p_mdl_idx = i;
762 break;
763 }
764 }
765
766 #if (BTA_HL_DEBUG == TRUE)
767 if (!found) {
768 APPL_TRACE_DEBUG("bta_hl_find_mdl_idx found=%d mdl_id=%d mdl_idx=%d ",
769 found, mdl_id, i);
770 }
771 #endif
772
773 return found;
774 }
775
776 /*******************************************************************************
777 *
778 * Function bta_hl_find_an_active_mdl_idx
779 *
780 * Description This function finds an active MDL
781 *
782 * Returns bool true-found
783 *
784 ******************************************************************************/
bta_hl_find_an_active_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint8_t * p_mdl_idx)785 bool bta_hl_find_an_active_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
786 uint8_t* p_mdl_idx) {
787 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
788 bool found = false;
789 uint8_t i;
790
791 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
792 if (p_mcb->mdl[i].in_use &&
793 (p_mcb->mdl[i].dch_state == BTA_HL_DCH_OPEN_ST)) {
794 found = true;
795 *p_mdl_idx = i;
796 break;
797 }
798 }
799
800 #if (BTA_HL_DEBUG == TRUE)
801 if (found) {
802 APPL_TRACE_DEBUG(
803 "bta_hl_find_an_opened_mdl_idx found=%d app_idx=%d mcl_idx=%d "
804 "mdl_idx=%d",
805 found, app_idx, mcl_idx, i);
806 }
807 #endif
808
809 return found;
810 }
811
812 /*******************************************************************************
813 *
814 * Function bta_hl_find_dch_setup_mdl_idx
815 *
816 * Description This function finds a MDL which in the DCH setup state
817 *
818 * Returns bool true-found
819 *
820 ******************************************************************************/
bta_hl_find_dch_setup_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint8_t * p_mdl_idx)821 bool bta_hl_find_dch_setup_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
822 uint8_t* p_mdl_idx) {
823 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
824 bool found = false;
825 uint8_t i;
826
827 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
828 if (p_mcb->mdl[i].in_use &&
829 (p_mcb->mdl[i].dch_state == BTA_HL_DCH_OPENING_ST)) {
830 found = true;
831 *p_mdl_idx = i;
832 break;
833 }
834 }
835
836 #if (BTA_HL_DEBUG == TRUE)
837 if (found) {
838 APPL_TRACE_DEBUG(
839 "bta_hl_find_dch_setup_mdl_idx found=%d app_idx=%d mcl_idx=%d "
840 "mdl_idx=%d",
841 found, app_idx, mcl_idx, i);
842 }
843 #endif
844
845 return found;
846 }
847
848 /*******************************************************************************
849 *
850 * Function bta_hl_find_an_in_use_mcl_idx
851 *
852 * Description This function finds an in-use MCL control block index
853 *
854 * Returns bool true-found
855 *
856 ******************************************************************************/
bta_hl_find_an_in_use_mcl_idx(uint8_t app_idx,uint8_t * p_mcl_idx)857 bool bta_hl_find_an_in_use_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
858 tBTA_HL_MCL_CB* p_mcb;
859 bool found = false;
860 uint8_t i;
861
862 for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
863 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, i);
864 if (p_mcb->in_use && (p_mcb->cch_state != BTA_HL_CCH_IDLE_ST)) {
865 found = true;
866 *p_mcl_idx = i;
867 break;
868 }
869 }
870
871 #if (BTA_HL_DEBUG == TRUE)
872 if (found) {
873 APPL_TRACE_DEBUG(
874 "bta_hl_find_an_in_use_mcl_idx found=%d app_idx=%d mcl_idx=%d ", found,
875 app_idx, i);
876 }
877 #endif
878
879 return found;
880 }
881
882 /*******************************************************************************
883 *
884 * Function bta_hl_find_an_in_use_app_idx
885 *
886 * Description This function finds an in-use application control block index
887 *
888 * Returns bool true-found
889 *
890 ******************************************************************************/
bta_hl_find_an_in_use_app_idx(uint8_t * p_app_idx)891 bool bta_hl_find_an_in_use_app_idx(uint8_t* p_app_idx) {
892 tBTA_HL_APP_CB* p_acb;
893 bool found = false;
894 uint8_t i;
895
896 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
897 p_acb = BTA_HL_GET_APP_CB_PTR(i);
898 if (p_acb->in_use) {
899 found = true;
900 *p_app_idx = i;
901 break;
902 }
903 }
904
905 #if (BTA_HL_DEBUG == TRUE)
906 if (found) {
907 APPL_TRACE_DEBUG("bta_hl_find_an_in_use_app_idx found=%d app_idx=%d ",
908 found, i);
909 }
910 #endif
911
912 return found;
913 }
914 /*******************************************************************************
915 *
916 * Function bta_hl_find_app_idx
917 *
918 * Description This function finds the application control block index based on
919 * the application ID
920 *
921 * Returns bool true-found
922 *
923 ******************************************************************************/
bta_hl_find_app_idx(uint8_t app_id,uint8_t * p_app_idx)924 bool bta_hl_find_app_idx(uint8_t app_id, uint8_t* p_app_idx) {
925 bool found = false;
926 uint8_t i;
927
928 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
929 if (bta_hl_cb.acb[i].in_use && (bta_hl_cb.acb[i].app_id == app_id)) {
930 found = true;
931 *p_app_idx = i;
932 break;
933 }
934 }
935
936 #if (BTA_HL_DEBUG == TRUE)
937 APPL_TRACE_DEBUG("bta_hl_find_app_idx found=%d app_id=%d idx=%d ", found,
938 app_id, i);
939 #endif
940
941 return found;
942 }
943
944 /*******************************************************************************
945 *
946 * Function bta_hl_find_app_idx_using_handle
947 *
948 * Description This function finds the application control block index based on
949 * the application handle
950 *
951 * Returns bool true-found
952 *
953 ******************************************************************************/
bta_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle,uint8_t * p_app_idx)954 bool bta_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle,
955 uint8_t* p_app_idx) {
956 bool found = false;
957 uint8_t i;
958
959 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
960 if (bta_hl_cb.acb[i].in_use &&
961 (bta_hl_cb.acb[i].app_handle == app_handle)) {
962 found = true;
963 *p_app_idx = i;
964 break;
965 }
966 }
967
968 #if (BTA_HL_DEBUG == TRUE)
969 if (!found) {
970 APPL_TRACE_DEBUG(
971 "bta_hl_find_app_idx_using_mca_handle status=%d handle=%d app_idx=%d ",
972 found, app_handle, i);
973 }
974 #endif
975
976 return found;
977 }
978
979 /*******************************************************************************
980 *
981 * Function bta_hl_find_mcl_idx_using_handle
982 *
983 * Description This function finds the MCL control block index based on
984 * the MCL handle
985 *
986 * Returns bool true-found
987 *
988 ******************************************************************************/
bta_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle,uint8_t * p_app_idx,uint8_t * p_mcl_idx)989 bool bta_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle,
990 uint8_t* p_app_idx, uint8_t* p_mcl_idx) {
991 tBTA_HL_APP_CB* p_acb;
992 bool found = false;
993 uint8_t i = 0, j = 0;
994
995 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
996 p_acb = BTA_HL_GET_APP_CB_PTR(i);
997 if (p_acb->in_use) {
998 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
999 if (p_acb->mcb[j].mcl_handle == mcl_handle) {
1000 found = true;
1001 *p_app_idx = i;
1002 *p_mcl_idx = j;
1003 break;
1004 }
1005 }
1006 }
1007 }
1008
1009 #if (BTA_HL_DEBUG == TRUE)
1010 if (!found) {
1011 APPL_TRACE_DEBUG(
1012 "bta_hl_find_mcl_idx_using_handle found=%d app_idx=%d mcl_idx=%d",
1013 found, i, j);
1014 }
1015 #endif
1016 return found;
1017 }
1018
1019 /*******************************************************************************
1020 *
1021 * Function bta_hl_find_mcl_idx
1022 *
1023 * Description This function finds the MCL control block index based on
1024 * the peer BD address
1025 *
1026 * Returns bool true-found
1027 *
1028 ******************************************************************************/
bta_hl_find_mcl_idx(uint8_t app_idx,const RawAddress & p_bd_addr,uint8_t * p_mcl_idx)1029 bool bta_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
1030 uint8_t* p_mcl_idx) {
1031 bool found = false;
1032 uint8_t i;
1033
1034 for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
1035 if (bta_hl_cb.acb[app_idx].mcb[i].in_use &&
1036 bta_hl_cb.acb[app_idx].mcb[i].bd_addr == p_bd_addr) {
1037 found = true;
1038 *p_mcl_idx = i;
1039 break;
1040 }
1041 }
1042
1043 #if (BTA_HL_DEBUG == TRUE)
1044 if (!found) {
1045 APPL_TRACE_DEBUG("bta_hl_find_mcl_idx found=%d idx=%d", found, i);
1046 }
1047 #endif
1048 return found;
1049 }
1050
1051 /*******************************************************************************
1052 *
1053 * Function bta_hl_find_mdl_idx_using_handle
1054 *
1055 * Description This function finds the MDL control block index based on
1056 * the MDL handle
1057 *
1058 * Returns bool true-found
1059 *
1060 ******************************************************************************/
bta_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,uint8_t * p_app_idx,uint8_t * p_mcl_idx,uint8_t * p_mdl_idx)1061 bool bta_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
1062 uint8_t* p_app_idx, uint8_t* p_mcl_idx,
1063 uint8_t* p_mdl_idx) {
1064 tBTA_HL_APP_CB* p_acb;
1065 tBTA_HL_MCL_CB* p_mcb;
1066 tBTA_HL_MDL_CB* p_dcb;
1067 bool found = false;
1068 uint8_t i, j, k;
1069
1070 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1071 p_acb = BTA_HL_GET_APP_CB_PTR(i);
1072 if (p_acb->in_use) {
1073 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1074 p_mcb = BTA_HL_GET_MCL_CB_PTR(i, j);
1075 if (p_mcb->in_use) {
1076 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
1077 p_dcb = BTA_HL_GET_MDL_CB_PTR(i, j, k);
1078 if (p_dcb->in_use) {
1079 if (p_dcb->mdl_handle == mdl_handle) {
1080 found = true;
1081 *p_app_idx = i;
1082 *p_mcl_idx = j;
1083 *p_mdl_idx = k;
1084 break;
1085 }
1086 }
1087 }
1088 }
1089 }
1090 }
1091 }
1092
1093 #if (BTA_HL_DEBUG == TRUE)
1094 if (!found) {
1095 APPL_TRACE_DEBUG(
1096 "bta_hl_find_mdl_idx_using_handle found=%d mdl_handle=%d ", found,
1097 mdl_handle);
1098 }
1099 #endif
1100 return found;
1101 }
1102 /*******************************************************************************
1103 *
1104 * Function bta_hl_is_the_first_reliable_existed
1105 *
1106 * Description This function checks whether the first reliable DCH channel
1107 * has been setup on the MCL or not
1108 *
1109 * Returns bool - true exist
1110 * false does not exist
1111 *
1112 ******************************************************************************/
bta_hl_is_the_first_reliable_existed(uint8_t app_idx,uint8_t mcl_idx)1113 bool bta_hl_is_the_first_reliable_existed(uint8_t app_idx, uint8_t mcl_idx) {
1114 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1115 bool is_existed = false;
1116 uint8_t i;
1117
1118 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
1119 if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) {
1120 is_existed = true;
1121 break;
1122 }
1123 }
1124
1125 #if (BTA_HL_DEBUG == TRUE)
1126 APPL_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d ",
1127 is_existed);
1128 #endif
1129 return is_existed;
1130 }
1131
1132 /*******************************************************************************
1133 *
1134 * Function bta_hl_find_non_active_mdl_cfg
1135 *
1136 * Description This function finds a valid MDL configiration index and this
1137 * MDL ID is not active
1138 *
1139 * Returns bool - true found
1140 * false not found
1141 *
1142 ******************************************************************************/
bta_hl_find_non_active_mdl_cfg(uint8_t app_idx,uint8_t start_mdl_cfg_idx,uint8_t * p_mdl_cfg_idx)1143 bool bta_hl_find_non_active_mdl_cfg(uint8_t app_idx, uint8_t start_mdl_cfg_idx,
1144 uint8_t* p_mdl_cfg_idx) {
1145 tBTA_HL_MCL_CB* p_mcb;
1146 tBTA_HL_MDL_CB* p_dcb;
1147 tBTA_HL_MDL_CFG* p_mdl;
1148 bool mdl_in_use;
1149 bool found = false;
1150 uint8_t i, j, k;
1151
1152 for (i = start_mdl_cfg_idx; i < BTA_HL_NUM_MDL_CFGS; i++) {
1153 mdl_in_use = false;
1154 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1155 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1156 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, j);
1157 if (p_mcb->in_use && p_mdl->peer_bd_addr == p_mcb->bd_addr) {
1158 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
1159 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, j, k);
1160
1161 if (p_dcb->in_use && p_mdl->mdl_id == p_dcb->mdl_id) {
1162 mdl_in_use = true;
1163 break;
1164 }
1165 }
1166 }
1167
1168 if (mdl_in_use) {
1169 break;
1170 }
1171 }
1172
1173 if (!mdl_in_use) {
1174 *p_mdl_cfg_idx = i;
1175 found = true;
1176 break;
1177 }
1178 }
1179
1180 return found;
1181 }
1182
1183 /*******************************************************************************
1184 *
1185 * Function bta_hl_find_mdl_cfg_idx
1186 *
1187 * Description This function finds an available MDL configuration index
1188 *
1189 * Returns bool - true found
1190 * false not found
1191 *
1192 ******************************************************************************/
bta_hl_find_avail_mdl_cfg_idx(uint8_t app_idx,UNUSED_ATTR uint8_t mcl_idx,uint8_t * p_mdl_cfg_idx)1193 bool bta_hl_find_avail_mdl_cfg_idx(uint8_t app_idx, UNUSED_ATTR uint8_t mcl_idx,
1194 uint8_t* p_mdl_cfg_idx) {
1195 tBTA_HL_MDL_CFG *p_mdl, *p_mdl1, *p_mdl2;
1196 uint8_t i;
1197 bool found = false;
1198 uint8_t first_mdl_cfg_idx, second_mdl_cfg_idx, older_mdl_cfg_idx;
1199 bool done;
1200
1201 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1202 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1203 if (!p_mdl->active) {
1204 /* found an unused space to store mdl cfg*/
1205 found = true;
1206 *p_mdl_cfg_idx = i;
1207 break;
1208 }
1209 }
1210
1211 if (!found) {
1212 /* all available mdl cfg spaces are in use so we need to find the mdl cfg
1213 which is
1214 not currently in use and has the the oldest time stamp to remove*/
1215
1216 found = true;
1217 if (bta_hl_find_non_active_mdl_cfg(app_idx, 0, &first_mdl_cfg_idx)) {
1218 if (bta_hl_find_non_active_mdl_cfg(
1219 app_idx, (uint8_t)(first_mdl_cfg_idx + 1), &second_mdl_cfg_idx)) {
1220 done = false;
1221 while (!done) {
1222 p_mdl1 = BTA_HL_GET_MDL_CFG_PTR(app_idx, first_mdl_cfg_idx);
1223 p_mdl2 = BTA_HL_GET_MDL_CFG_PTR(app_idx, second_mdl_cfg_idx);
1224
1225 if (p_mdl1->time < p_mdl2->time) {
1226 older_mdl_cfg_idx = first_mdl_cfg_idx;
1227 } else {
1228 older_mdl_cfg_idx = second_mdl_cfg_idx;
1229 }
1230
1231 if (bta_hl_find_non_active_mdl_cfg(app_idx,
1232 (uint8_t)(second_mdl_cfg_idx + 1),
1233 &second_mdl_cfg_idx)) {
1234 first_mdl_cfg_idx = older_mdl_cfg_idx;
1235 } else {
1236 done = true;
1237 }
1238 }
1239
1240 *p_mdl_cfg_idx = older_mdl_cfg_idx;
1241
1242 } else {
1243 *p_mdl_cfg_idx = first_mdl_cfg_idx;
1244 }
1245
1246 } else {
1247 found = false;
1248 }
1249 }
1250
1251 #if (BTA_HL_DEBUG == TRUE)
1252 if (!found) {
1253 APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",
1254 found, *p_mdl_cfg_idx);
1255 }
1256 #endif
1257
1258 return found;
1259 }
1260
1261 /*******************************************************************************
1262 *
1263 * Function bta_hl_find_mdl_cfg_idx
1264 *
1265 * Description This function finds the MDL configuration index based on
1266 * the MDL ID
1267 *
1268 * Returns bool - true found
1269 * false not found
1270 *
1271 ******************************************************************************/
bta_hl_find_mdl_cfg_idx(uint8_t app_idx,uint8_t mcl_idx,tBTA_HL_MDL_ID mdl_id,uint8_t * p_mdl_cfg_idx)1272 bool bta_hl_find_mdl_cfg_idx(uint8_t app_idx, uint8_t mcl_idx,
1273 tBTA_HL_MDL_ID mdl_id, uint8_t* p_mdl_cfg_idx) {
1274 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1275 tBTA_HL_MDL_CFG* p_mdl;
1276 uint8_t i;
1277 bool found = false;
1278
1279 *p_mdl_cfg_idx = 0;
1280 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1281 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1282 if (p_mdl->active)
1283 APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",
1284 mdl_id, p_mdl->mdl_id);
1285 if (p_mdl->active && p_mcb->bd_addr == p_mdl->peer_bd_addr &&
1286 (p_mdl->mdl_id == mdl_id)) {
1287 found = true;
1288 *p_mdl_cfg_idx = i;
1289 break;
1290 }
1291 }
1292
1293 #if (BTA_HL_DEBUG == TRUE)
1294 if (!found) {
1295 APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx found=%d mdl_cfg_idx=%d ", found,
1296 i);
1297 }
1298 #endif
1299
1300 return found;
1301 }
1302
1303 /*******************************************************************************
1304 *
1305 * Function bta_hl_get_cur_time
1306 *
1307 * Description This function get the cuurent time value
1308 *
1309 * Returns bool - true found
1310 * false not found
1311 *
1312 ******************************************************************************/
bta_hl_get_cur_time(uint8_t app_idx,uint8_t * p_cur_time)1313 bool bta_hl_get_cur_time(uint8_t app_idx, uint8_t* p_cur_time) {
1314 tBTA_HL_MDL_CFG* p_mdl;
1315 uint8_t i, j, time_latest, time;
1316 bool found = false, result = true;
1317
1318 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1319 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1320 if (p_mdl->active) {
1321 found = true;
1322 time_latest = p_mdl->time;
1323 for (j = (i + 1); j < BTA_HL_NUM_MDL_CFGS; j++) {
1324 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, j);
1325 if (p_mdl->active) {
1326 time = p_mdl->time;
1327 if (time > time_latest) {
1328 time_latest = time;
1329 }
1330 }
1331 }
1332 break;
1333 }
1334 }
1335
1336 if (found) {
1337 if (time_latest < BTA_HL_MAX_TIME) {
1338 *p_cur_time = time_latest + 1;
1339 } else {
1340 /* need to wrap around */
1341 result = false;
1342 }
1343 } else {
1344 *p_cur_time = BTA_HL_MIN_TIME;
1345 }
1346
1347 #if (BTA_HL_DEBUG == TRUE)
1348 if (!result) {
1349 APPL_TRACE_DEBUG("bta_hl_get_cur_time result=%s cur_time=%d",
1350 (result ? "OK" : "FAIL"), *p_cur_time);
1351 }
1352 #endif
1353
1354 return result;
1355 }
1356
1357 /*******************************************************************************
1358 *
1359 * Function bta_hl_sort_cfg_time_idx
1360 *
1361 * Description This function sort the mdl configuration idx stored in array a
1362 * based on decending time value
1363 *
1364 * Returns bool - true found
1365 * false not found
1366 *
1367 ******************************************************************************/
bta_hl_sort_cfg_time_idx(uint8_t app_idx,uint8_t * a,uint8_t n)1368 void bta_hl_sort_cfg_time_idx(uint8_t app_idx, uint8_t* a, uint8_t n) {
1369 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1370 uint8_t temp_time, temp_idx;
1371 int16_t i, j;
1372 for (i = 1; i < n; ++i) {
1373 temp_idx = a[i];
1374 temp_time = p_acb->mdl_cfg[temp_idx].time;
1375 j = i - 1;
1376 while ((j >= 0) && (temp_time < p_acb->mdl_cfg[a[j]].time)) {
1377 a[j + 1] = a[j];
1378 --j;
1379 }
1380 a[j + 1] = temp_idx;
1381 }
1382 }
1383
1384 /*******************************************************************************
1385 *
1386 * Function bta_hl_compact_mdl_cfg_time
1387 *
1388 * Description This function finds the MDL configuration index based on
1389 * the MDL ID
1390 *
1391 * Returns bool - true found
1392 * false not found
1393 *
1394 ******************************************************************************/
bta_hl_compact_mdl_cfg_time(uint8_t app_idx,uint8_t mdep_id)1395 void bta_hl_compact_mdl_cfg_time(uint8_t app_idx, uint8_t mdep_id) {
1396 tBTA_HL_MDL_CFG* p_mdl;
1397 uint8_t i, time_min, cnt = 0;
1398 uint8_t s_arr[BTA_HL_NUM_MDL_CFGS];
1399
1400 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1401 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1402 if (p_mdl->active) {
1403 s_arr[cnt] = i;
1404 cnt++;
1405 }
1406 }
1407
1408 #if (BTA_HL_DEBUG == TRUE)
1409 APPL_TRACE_DEBUG("bta_hl_compact_mdl_cfg_time cnt=%d ", cnt);
1410 #endif
1411
1412 if (cnt) {
1413 bta_hl_sort_cfg_time_idx(app_idx, s_arr, cnt);
1414 time_min = BTA_HL_MIN_TIME;
1415 for (i = 0; i < cnt; i++) {
1416 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, s_arr[i]);
1417 p_mdl->time = time_min + i;
1418 bta_hl_co_save_mdl(mdep_id, s_arr[i], p_mdl);
1419 }
1420 }
1421 }
1422
1423 /*******************************************************************************
1424 *
1425 * Function bta_hl_is_mdl_exsit_in_mcl
1426 *
1427 * Description This function checks whether the MDL ID
1428 * has already existed in teh MCL or not
1429 *
1430 * Returns bool - true exist
1431 * false does not exist
1432 *
1433 ******************************************************************************/
bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx,const RawAddress & bd_addr,tBTA_HL_MDL_ID mdl_id)1434 bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, const RawAddress& bd_addr,
1435 tBTA_HL_MDL_ID mdl_id) {
1436 tBTA_HL_MDL_CFG* p_mdl;
1437 bool found = false;
1438 uint8_t i;
1439
1440 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1441 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1442 if (p_mdl->active && p_mdl->peer_bd_addr == bd_addr) {
1443 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
1444 if (p_mdl->mdl_id == mdl_id) {
1445 found = true;
1446 break;
1447 }
1448 } else {
1449 found = true;
1450 break;
1451 }
1452 }
1453 }
1454
1455 return found;
1456 }
1457
1458 /*******************************************************************************
1459 *
1460 * Function bta_hl_delete_mdl_cfg
1461 *
1462 * Description This function delete the specified MDL ID
1463 *
1464 * Returns bool - true Success
1465 * false Failed
1466 *
1467 ******************************************************************************/
bta_hl_delete_mdl_cfg(uint8_t app_idx,const RawAddress & bd_addr,tBTA_HL_MDL_ID mdl_id)1468 bool bta_hl_delete_mdl_cfg(uint8_t app_idx, const RawAddress& bd_addr,
1469 tBTA_HL_MDL_ID mdl_id) {
1470 tBTA_HL_MDL_CFG* p_mdl;
1471 bool success = false;
1472 uint8_t i;
1473
1474 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1475 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1476 if (p_mdl->active && p_mdl->peer_bd_addr == bd_addr) {
1477 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
1478 if (p_mdl->mdl_id == mdl_id) {
1479 bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
1480 memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
1481 success = true;
1482 break;
1483 }
1484 } else {
1485 bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
1486 memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
1487 success = true;
1488 }
1489 }
1490 }
1491
1492 return success;
1493 }
1494
1495 /*******************************************************************************
1496 *
1497 * Function bta_hl_is_mdl_value_valid
1498 *
1499 *
1500 * Description This function checks the specified MDL ID is in valid range.
1501 *
1502 * Returns bool - true Success
1503 * false Failed
1504 *
1505 * note: mdl_id range 0x0000 reserved,
1506 * 0x0001-oxFEFF dynamic range,
1507 * 0xFF00-0xFFFE reserved,
1508 * 0xFFFF indicates all MDLs (for delete operation only)
1509 *
1510 ******************************************************************************/
bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id)1511 bool bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id) {
1512 bool status = true;
1513
1514 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
1515 if (mdl_id != 0) {
1516 if (mdl_id > BTA_HL_MAX_MDL_VAL) {
1517 status = false;
1518 }
1519 } else {
1520 status = false;
1521 }
1522 }
1523
1524 return status;
1525 }
1526
1527 /*******************************************************************************
1528 *
1529 * Function bta_hl_find_mdep_cfg_idx
1530 *
1531 * Description This function finds the MDEP configuration index based
1532 * on the local MDEP ID
1533 *
1534 * Returns bool - true found
1535 * false not found
1536 *
1537 ******************************************************************************/
bta_hl_find_mdep_cfg_idx(uint8_t app_idx,tBTA_HL_MDEP_ID local_mdep_id,uint8_t * p_mdep_cfg_idx)1538 bool bta_hl_find_mdep_cfg_idx(uint8_t app_idx, tBTA_HL_MDEP_ID local_mdep_id,
1539 uint8_t* p_mdep_cfg_idx) {
1540 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1541 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
1542 bool found = false;
1543 uint8_t i;
1544
1545 for (i = 0; i < p_sup_feature->num_of_mdeps; i++) {
1546 if (p_sup_feature->mdep[i].mdep_id == local_mdep_id) {
1547 found = true;
1548 *p_mdep_cfg_idx = i;
1549 break;
1550 }
1551 }
1552
1553 #if (BTA_HL_DEBUG == TRUE)
1554 if (!found) {
1555 APPL_TRACE_DEBUG(
1556 "bta_hl_find_mdep_cfg_idx found=%d mdep_idx=%d local_mdep_id=%d ",
1557 found, i, local_mdep_id);
1558 }
1559 #endif
1560 return found;
1561 }
1562
1563 /*******************************************************************************
1564 *
1565 * Function bta_hl_find_rxtx_apdu_size
1566 *
1567 * Description This function finds the maximum APDU rx and tx sizes based on
1568 * the MDEP configuration data
1569 *
1570 * Returns void
1571 *
1572 ******************************************************************************/
bta_hl_find_rxtx_apdu_size(uint8_t app_idx,uint8_t mdep_cfg_idx,uint16_t * p_rx_apu_size,uint16_t * p_tx_apu_size)1573 void bta_hl_find_rxtx_apdu_size(uint8_t app_idx, uint8_t mdep_cfg_idx,
1574 uint16_t* p_rx_apu_size,
1575 uint16_t* p_tx_apu_size) {
1576 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1577 tBTA_HL_MDEP_CFG* p_mdep_cfg;
1578 uint8_t i;
1579 uint16_t max_rx_apdu_size = 0, max_tx_apdu_size = 0;
1580
1581 p_mdep_cfg = &p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg;
1582
1583 for (i = 0; i < p_mdep_cfg->num_of_mdep_data_types; i++) {
1584 if (max_rx_apdu_size < p_mdep_cfg->data_cfg[i].max_rx_apdu_size) {
1585 max_rx_apdu_size = p_mdep_cfg->data_cfg[i].max_rx_apdu_size;
1586 }
1587
1588 if (max_tx_apdu_size < p_mdep_cfg->data_cfg[i].max_tx_apdu_size) {
1589 max_tx_apdu_size = p_mdep_cfg->data_cfg[i].max_tx_apdu_size;
1590 }
1591 }
1592
1593 *p_rx_apu_size = max_rx_apdu_size;
1594 *p_tx_apu_size = max_tx_apdu_size;
1595
1596 #if (BTA_HL_DEBUG == TRUE)
1597 APPL_TRACE_DEBUG(
1598 "bta_hl_find_rxtx_apdu_size max_rx_apdu_size=%d max_tx_apdu_size=%d ",
1599 max_rx_apdu_size, max_tx_apdu_size);
1600 #endif
1601 }
1602
1603 /*******************************************************************************
1604 *
1605 * Function bta_hl_validate_peer_cfg
1606 *
1607 * Description This function validates the peer DCH configuration
1608 *
1609 * Returns bool - true validation is successful
1610 * false validation failed
1611 *
1612 ******************************************************************************/
bta_hl_validate_peer_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx,tBTA_HL_MDEP_ID peer_mdep_id,tBTA_HL_MDEP_ROLE peer_mdep_role,uint8_t sdp_idx)1613 bool bta_hl_validate_peer_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
1614 tBTA_HL_MDEP_ID peer_mdep_id,
1615 tBTA_HL_MDEP_ROLE peer_mdep_role,
1616 uint8_t sdp_idx) {
1617 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1618 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1619 tBTA_HL_SDP_REC* p_rec;
1620 bool peer_found = false;
1621 uint8_t i;
1622
1623 APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg sdp_idx=%d app_idx %d", sdp_idx,
1624 app_idx);
1625
1626 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
1627 return true;
1628 }
1629
1630 p_rec = &p_mcb->sdp.sdp_rec[sdp_idx];
1631 for (i = 0; i < p_rec->num_mdeps; i++) {
1632 APPL_TRACE_DEBUG("mdep_id %d peer_mdep_id %d", p_rec->mdep_cfg[i].mdep_id,
1633 peer_mdep_id);
1634 APPL_TRACE_DEBUG("mdep_role %d peer_mdep_role %d",
1635 p_rec->mdep_cfg[i].mdep_role, peer_mdep_role)
1636 if ((p_rec->mdep_cfg[i].mdep_id == peer_mdep_id) &&
1637 (p_rec->mdep_cfg[i].mdep_role == peer_mdep_role)) {
1638 peer_found = true;
1639
1640 break;
1641 }
1642 }
1643
1644 #if (BTA_HL_DEBUG == TRUE)
1645 if (!peer_found) {
1646 APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg failed num_mdeps=%d",
1647 p_rec->num_mdeps);
1648 }
1649 #endif
1650 return peer_found;
1651 }
1652
1653 /*******************************************************************************
1654 *
1655 * Function bta_hl_chk_local_cfg
1656 *
1657 * Description This function check whether the local DCH configuration is OK.
1658 *
1659 * Returns tBTA_HL_STATUS - OK - local DCH configuration is OK
1660 * NO_FIRST_RELIABLE - the streaming DCH
1661 * configuration is not OK and
1662 * it needs to use reliable
1663 * DCH configuration
1664 *
1665 ******************************************************************************/
bta_hl_chk_local_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdep_cfg_idx,tBTA_HL_DCH_CFG local_cfg)1666 tBTA_HL_STATUS bta_hl_chk_local_cfg(uint8_t app_idx, uint8_t mcl_idx,
1667 uint8_t mdep_cfg_idx,
1668 tBTA_HL_DCH_CFG local_cfg) {
1669 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1670 tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
1671
1672 if (mdep_cfg_idx &&
1673 (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role ==
1674 BTA_HL_MDEP_ROLE_SOURCE) &&
1675 (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) &&
1676 (local_cfg != BTA_HL_DCH_CFG_RELIABLE)) {
1677 status = BTA_HL_STATUS_NO_FIRST_RELIABLE;
1678 APPL_TRACE_ERROR("BTA_HL_STATUS_INVALID_DCH_CFG");
1679 }
1680
1681 return status;
1682 }
1683
1684 /*******************************************************************************
1685 *
1686 * Function bta_hl_validate_reconnect_params
1687 *
1688 * Description This function validates the reconnect parameters
1689 *
1690 * Returns bool - true validation is successful
1691 * false validation failed
1692 ******************************************************************************/
bta_hl_validate_reconnect_params(uint8_t app_idx,uint8_t mcl_idx,tBTA_HL_API_DCH_RECONNECT * p_reconnect,uint8_t * p_mdep_cfg_idx,uint8_t * p_mdl_cfg_idx)1693 bool bta_hl_validate_reconnect_params(uint8_t app_idx, uint8_t mcl_idx,
1694 tBTA_HL_API_DCH_RECONNECT* p_reconnect,
1695 uint8_t* p_mdep_cfg_idx,
1696 uint8_t* p_mdl_cfg_idx) {
1697 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1698 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
1699 uint8_t num_mdeps;
1700 uint8_t mdl_cfg_idx;
1701 bool local_mdep_id_found = false;
1702 bool mdl_cfg_found = false;
1703 bool status = false;
1704 uint8_t i, in_use_mdl_idx = 0;
1705
1706 #if (BTA_HL_DEBUG == TRUE)
1707 APPL_TRACE_DEBUG("bta_hl_validate_reconnect_params mdl_id=%d app_idx=%d",
1708 p_reconnect->mdl_id, app_idx);
1709 #endif
1710 if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
1711 &mdl_cfg_idx)) {
1712 mdl_cfg_found = true;
1713 }
1714
1715 #if (BTA_HL_DEBUG == TRUE)
1716 if (!mdl_cfg_found) {
1717 APPL_TRACE_DEBUG("mdl_cfg_found not found");
1718 }
1719 #endif
1720
1721 if (mdl_cfg_found) {
1722 num_mdeps = p_sup_feature->num_of_mdeps;
1723 for (i = 0; i < num_mdeps; i++) {
1724 if (p_sup_feature->mdep[i].mdep_id ==
1725 p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id) {
1726 local_mdep_id_found = true;
1727 *p_mdep_cfg_idx = i;
1728 *p_mdl_cfg_idx = mdl_cfg_idx;
1729 break;
1730 }
1731 }
1732 }
1733
1734 #if (BTA_HL_DEBUG == TRUE)
1735 if (!local_mdep_id_found) {
1736 APPL_TRACE_DEBUG("local_mdep_id not found");
1737 }
1738 #endif
1739
1740 if (local_mdep_id_found) {
1741 if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
1742 &in_use_mdl_idx)) {
1743 status = true;
1744 } else {
1745 APPL_TRACE_ERROR("mdl_id=%d is curreltly in use", p_reconnect->mdl_id);
1746 }
1747 }
1748
1749 #if (BTA_HL_DEBUG == TRUE)
1750 if (!status) {
1751 APPL_TRACE_DEBUG(
1752 "Reconnect validation failed local_mdep_id found=%d mdl_cfg_idx "
1753 "found=%d in_use_mdl_idx=%d ",
1754 local_mdep_id_found, mdl_cfg_found, in_use_mdl_idx);
1755 }
1756 #endif
1757 return status;
1758 }
1759
1760 /*******************************************************************************
1761 *
1762 * Function bta_hl_find_avail_mcl_idx
1763 *
1764 * Returns bool - true found
1765 * false not found
1766 *
1767 ******************************************************************************/
bta_hl_find_avail_mcl_idx(uint8_t app_idx,uint8_t * p_mcl_idx)1768 bool bta_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
1769 bool found = false;
1770 uint8_t i;
1771
1772 for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
1773 if (!bta_hl_cb.acb[app_idx].mcb[i].in_use) {
1774 found = true;
1775 *p_mcl_idx = i;
1776 break;
1777 }
1778 }
1779
1780 #if (BTA_HL_DEBUG == TRUE)
1781 if (!found) {
1782 APPL_TRACE_DEBUG("bta_hl_find_avail_mcl_idx found=%d idx=%d", found, i);
1783 }
1784 #endif
1785 return found;
1786 }
1787
1788 /*******************************************************************************
1789 *
1790 * Function bta_hl_find_avail_mdl_idx
1791 *
1792 * Description This function finds an available MDL control block index
1793 *
1794 * Returns bool - true found
1795 * false not found
1796 *
1797 ******************************************************************************/
bta_hl_find_avail_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint8_t * p_mdl_idx)1798 bool bta_hl_find_avail_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
1799 uint8_t* p_mdl_idx) {
1800 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1801 bool found = false;
1802 uint8_t i;
1803
1804 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
1805 if (!p_mcb->mdl[i].in_use) {
1806 memset((void*)&p_mcb->mdl[i], 0, sizeof(tBTA_HL_MDL_CB));
1807 found = true;
1808 *p_mdl_idx = i;
1809 break;
1810 }
1811 }
1812
1813 #if (BTA_HL_DEBUG == TRUE)
1814 if (!found) {
1815 APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_idx found=%d idx=%d", found, i);
1816 }
1817 #endif
1818 return found;
1819 }
1820
1821 /*******************************************************************************
1822 *
1823 * Function bta_hl_is_a_duplicate_id
1824 *
1825 * Description This function finds the application has been used or not
1826 *
1827 * Returns bool - true the app_id is a duplicate ID
1828 * false not a duplicate ID
1829 ******************************************************************************/
bta_hl_is_a_duplicate_id(uint8_t app_id)1830 bool bta_hl_is_a_duplicate_id(uint8_t app_id) {
1831 bool is_duplicate = false;
1832 uint8_t i;
1833
1834 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1835 if (bta_hl_cb.acb[i].in_use && (bta_hl_cb.acb[i].app_id == app_id)) {
1836 is_duplicate = true;
1837
1838 break;
1839 }
1840 }
1841
1842 #if (BTA_HL_DEBUG == TRUE)
1843 if (is_duplicate) {
1844 APPL_TRACE_DEBUG("bta_hl_is_a_duplicate_id app_id=%d is_duplicate=%d",
1845 app_id, is_duplicate);
1846 }
1847 #endif
1848
1849 return is_duplicate;
1850 }
1851
1852 /*******************************************************************************
1853 *
1854 * Function bta_hl_find_avail_app_idx
1855 *
1856 * Description This function finds an available application control block index
1857 *
1858 * Returns bool - true found
1859 * false not found
1860 *
1861 ******************************************************************************/
bta_hl_find_avail_app_idx(uint8_t * p_idx)1862 bool bta_hl_find_avail_app_idx(uint8_t* p_idx) {
1863 bool found = false;
1864 uint8_t i;
1865
1866 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1867 if (!bta_hl_cb.acb[i].in_use) {
1868 found = true;
1869 *p_idx = i;
1870 break;
1871 }
1872 }
1873
1874 #if (BTA_HL_DEBUG == TRUE)
1875 if (!found) {
1876 APPL_TRACE_DEBUG("bta_hl_find_avail_app_idx found=%d app_idx=%d", found, i);
1877 }
1878 #endif
1879 return found;
1880 }
1881
1882 /*******************************************************************************
1883 *
1884 * Function bta_hl_app_update
1885 *
1886 * Description This function registers an HDP application MCAP and DP
1887 *
1888 * Returns tBTA_HL_STATUS -registration status
1889 *
1890 ******************************************************************************/
bta_hl_app_update(uint8_t app_id,bool is_register)1891 tBTA_HL_STATUS bta_hl_app_update(uint8_t app_id, bool is_register) {
1892 tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
1893 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(0);
1894 tMCA_CS mca_cs;
1895 uint8_t i, mdep_idx, num_of_mdeps;
1896 uint8_t mdep_counter = 0;
1897
1898 #if (BTA_HL_DEBUG == TRUE)
1899 APPL_TRACE_DEBUG("bta_hl_app_update app_id=%d", app_id);
1900 #endif
1901
1902 if (is_register) {
1903 if ((status == BTA_HL_STATUS_OK) &&
1904 bta_hl_co_get_num_of_mdep(app_id, &num_of_mdeps)) {
1905 for (i = 0; i < num_of_mdeps; i++) {
1906 mca_cs.type = MCA_TDEP_DATA;
1907 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
1908 mca_cs.p_data_cback = bta_hl_mcap_data_cback;
1909 /* Find the first available mdep index, and create a MDL Endpoint */
1910 // make a function later if needed
1911 for (mdep_idx = 1; mdep_idx < BTA_HL_NUM_MDEPS; mdep_idx++) {
1912 if (p_acb->sup_feature.mdep[mdep_idx].mdep_id == 0) {
1913 break; /* We found an available index */
1914 } else {
1915 mdep_counter++;
1916 }
1917 }
1918 /* If no available MDEPs, return error */
1919 if (mdep_idx == BTA_HL_NUM_MDEPS) {
1920 APPL_TRACE_ERROR("bta_hl_app_update: Out of MDEP IDs");
1921 status = BTA_HL_STATUS_MCAP_REG_FAIL;
1922 break;
1923 }
1924 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
1925 &(p_acb->sup_feature.mdep[mdep_idx].mdep_id),
1926 &mca_cs) == MCA_SUCCESS) {
1927 if (bta_hl_co_get_mdep_config(
1928 app_id, mdep_idx, mdep_counter,
1929 p_acb->sup_feature.mdep[mdep_idx].mdep_id,
1930 &p_acb->sup_feature.mdep[mdep_idx].mdep_cfg)) {
1931 p_acb->sup_feature.mdep[mdep_idx].ori_app_id = app_id;
1932 APPL_TRACE_DEBUG("mdep idx %d id %d ori_app_id %d num data type %d",
1933 mdep_idx,
1934 p_acb->sup_feature.mdep[mdep_idx].mdep_id,
1935 p_acb->sup_feature.mdep[mdep_idx].ori_app_id,
1936 p_acb->sup_feature.mdep[mdep_idx]
1937 .mdep_cfg.num_of_mdep_data_types);
1938 if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
1939 BTA_HL_MDEP_ROLE_SOURCE) {
1940 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
1941 } else if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
1942 BTA_HL_MDEP_ROLE_SINK) {
1943 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
1944 } else {
1945 APPL_TRACE_ERROR(
1946 "bta_hl_app_registration: Invalid Role %d",
1947 p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role);
1948 status = BTA_HL_STATUS_MDEP_CO_FAIL;
1949 break;
1950 }
1951 } else {
1952 APPL_TRACE_ERROR("bta_hl_app_registration: Cfg callout failed");
1953 status = BTA_HL_STATUS_MDEP_CO_FAIL;
1954 break;
1955 }
1956 } else {
1957 APPL_TRACE_ERROR("bta_hl_app_registration: MCA_CreateDep failed");
1958 status = BTA_HL_STATUS_MCAP_REG_FAIL;
1959 break;
1960 }
1961 }
1962 p_acb->sup_feature.num_of_mdeps += num_of_mdeps;
1963 APPL_TRACE_DEBUG("num_of_mdeps %d", p_acb->sup_feature.num_of_mdeps);
1964
1965 if ((status == BTA_HL_STATUS_OK) &&
1966 (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
1967 p_acb->sup_feature.advertize_source_sdp =
1968 bta_hl_co_advrtise_source_sdp(app_id);
1969 }
1970
1971 if ((status == BTA_HL_STATUS_OK) &&
1972 (!bta_hl_co_get_echo_config(app_id, &p_acb->sup_feature.echo_cfg))) {
1973 status = BTA_HL_STATUS_ECHO_CO_FAIL;
1974 }
1975
1976 if ((status == BTA_HL_STATUS_OK) &&
1977 (!bta_hl_co_load_mdl_config(app_id, BTA_HL_NUM_MDL_CFGS,
1978 &p_acb->mdl_cfg[0]))) {
1979 status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
1980 }
1981 } else {
1982 status = BTA_HL_STATUS_MDEP_CO_FAIL;
1983 }
1984 } else {
1985 for (i = 1; i < BTA_HL_NUM_MDEPS; i++) {
1986 if (p_acb->sup_feature.mdep[i].ori_app_id == app_id) {
1987 APPL_TRACE_DEBUG("Found index %", i);
1988
1989 if (MCA_DeleteDep((tMCA_HANDLE)p_acb->app_handle,
1990 (p_acb->sup_feature.mdep[i].mdep_id)) !=
1991 MCA_SUCCESS) {
1992 APPL_TRACE_ERROR("Error deregistering");
1993 status = BTA_HL_STATUS_MCAP_REG_FAIL;
1994 return status;
1995 }
1996 memset(&p_acb->sup_feature.mdep[i], 0, sizeof(tBTA_HL_MDEP));
1997 }
1998 }
1999 }
2000
2001 if (status == BTA_HL_STATUS_OK) {
2002 /* Register/Update MDEP(s) in SDP Record */
2003 status = bta_hl_sdp_update(app_id);
2004 }
2005 /* else do cleanup */
2006
2007 return status;
2008 }
2009
2010 /*******************************************************************************
2011 *
2012 * Function bta_hl_app_registration
2013 *
2014 * Description This function registers an HDP application MCAP and DP
2015 *
2016 * Returns tBTA_HL_STATUS -registration status
2017 *
2018 ******************************************************************************/
bta_hl_app_registration(uint8_t app_idx)2019 tBTA_HL_STATUS bta_hl_app_registration(uint8_t app_idx) {
2020 tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
2021 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2022 tMCA_REG reg;
2023 tMCA_CS mca_cs;
2024 uint8_t i, num_of_mdeps;
2025 uint8_t mdep_counter = 0;
2026
2027 #if (BTA_HL_DEBUG == TRUE)
2028 APPL_TRACE_DEBUG("bta_hl_app_registration app_idx=%d", app_idx);
2029 #endif
2030
2031 reg.ctrl_psm = p_acb->ctrl_psm;
2032 reg.data_psm = p_acb->data_psm;
2033 reg.sec_mask = p_acb->sec_mask;
2034 reg.rsp_tout = BTA_HL_MCAP_RSP_TOUT;
2035
2036 p_acb->app_handle =
2037 (tBTA_HL_APP_HANDLE)MCA_Register(®, bta_hl_mcap_ctrl_cback);
2038 if (p_acb->app_handle != 0) {
2039 mca_cs.type = MCA_TDEP_ECHO;
2040 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2041 mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2042
2043 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2044 &(p_acb->sup_feature.mdep[0].mdep_id),
2045 &mca_cs) == MCA_SUCCESS) {
2046 if (p_acb->sup_feature.mdep[0].mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
2047 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2048 APPL_TRACE_ERROR("BAD MDEP ID for echo test mdep_id=%d",
2049 p_acb->sup_feature.mdep[0].mdep_id);
2050 }
2051 } else {
2052 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2053 APPL_TRACE_ERROR("MCA_CreateDep for echo test(mdep_id=0) failed");
2054 }
2055
2056 if ((status == BTA_HL_STATUS_OK) &&
2057 bta_hl_co_get_num_of_mdep(p_acb->app_id, &num_of_mdeps)) {
2058 p_acb->sup_feature.num_of_mdeps = num_of_mdeps + 1;
2059
2060 for (i = 1; i < p_acb->sup_feature.num_of_mdeps; i++) {
2061 mca_cs.type = MCA_TDEP_DATA;
2062 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2063 mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2064
2065 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2066 &(p_acb->sup_feature.mdep[i].mdep_id),
2067 &mca_cs) == MCA_SUCCESS) {
2068 if (bta_hl_co_get_mdep_config(p_acb->app_id, i, mdep_counter,
2069 p_acb->sup_feature.mdep[i].mdep_id,
2070 &p_acb->sup_feature.mdep[i].mdep_cfg)) {
2071 if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
2072 BTA_HL_MDEP_ROLE_SOURCE) {
2073 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
2074 } else if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
2075 BTA_HL_MDEP_ROLE_SINK) {
2076 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
2077 } else {
2078 status = BTA_HL_STATUS_MDEP_CO_FAIL;
2079 break;
2080 }
2081 p_acb->sup_feature.mdep[i].ori_app_id = p_acb->app_id;
2082 APPL_TRACE_DEBUG("index %d ori_app_id %d", i,
2083 p_acb->sup_feature.mdep[i].ori_app_id);
2084 } else {
2085 status = BTA_HL_STATUS_MDEP_CO_FAIL;
2086 break;
2087 }
2088 } else {
2089 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2090 break;
2091 }
2092 }
2093
2094 if ((status == BTA_HL_STATUS_OK) &&
2095 (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
2096 /* this is a source only applciation */
2097 p_acb->sup_feature.advertize_source_sdp =
2098 bta_hl_co_advrtise_source_sdp(p_acb->app_id);
2099 }
2100
2101 if ((status == BTA_HL_STATUS_OK) &&
2102 (!bta_hl_co_get_echo_config(p_acb->app_id,
2103 &p_acb->sup_feature.echo_cfg))) {
2104 status = BTA_HL_STATUS_ECHO_CO_FAIL;
2105 }
2106
2107 if ((status == BTA_HL_STATUS_OK) &&
2108 (!bta_hl_co_load_mdl_config(p_acb->app_id, BTA_HL_NUM_MDL_CFGS,
2109 &p_acb->mdl_cfg[0]))) {
2110 status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
2111 }
2112 } else {
2113 status = BTA_HL_STATUS_MDEP_CO_FAIL;
2114 }
2115 } else {
2116 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2117 }
2118
2119 if (status == BTA_HL_STATUS_OK) {
2120 status = bta_hl_sdp_register(app_idx);
2121 }
2122
2123 return status;
2124 }
2125
2126 /*******************************************************************************
2127 *
2128 * Function bta_hl_discard_data
2129 *
2130 * Description This function discard an HDP event
2131 *
2132 * Returns void
2133 *
2134 ******************************************************************************/
bta_hl_discard_data(uint16_t event,tBTA_HL_DATA * p_data)2135 void bta_hl_discard_data(uint16_t event, tBTA_HL_DATA* p_data) {
2136 #if (BTA_HL_DEBUG == TRUE)
2137 APPL_TRACE_ERROR("BTA HL Discard event=%s", bta_hl_evt_code(event));
2138
2139 #endif
2140
2141 switch (event) {
2142 case BTA_HL_API_SEND_DATA_EVT:
2143 break;
2144
2145 case BTA_HL_MCA_RCV_DATA_EVT:
2146 osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt);
2147 break;
2148
2149 default:
2150 /*Nothing to free*/
2151 break;
2152 }
2153 }
2154
2155 /*******************************************************************************
2156 *
2157 * Function bta_hl_save_mdl_cfg
2158 *
2159 * Description This function saves the MDL configuration
2160 *
2161 * Returns void
2162 *
2163 ******************************************************************************/
bta_hl_save_mdl_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)2164 void bta_hl_save_mdl_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
2165 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2166 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2167 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2168 uint8_t mdl_cfg_idx;
2169 tBTA_HL_MDL_ID mdl_id;
2170 bool found = true;
2171 tBTA_HL_MDL_CFG mdl_cfg;
2172 tBTA_HL_MDEP* p_mdep_cfg;
2173 tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
2174 uint8_t time_val = 0;
2175 mdl_id = p_dcb->mdl_id;
2176 if (!bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) {
2177 if (!bta_hl_find_avail_mdl_cfg_idx(app_idx, mcl_idx, &mdl_cfg_idx)) {
2178 APPL_TRACE_ERROR("No space to save the MDL config");
2179 found = false; /*no space available*/
2180 }
2181 }
2182
2183 if (found) {
2184 bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
2185 if (!bta_hl_get_cur_time(app_idx, &time_val)) {
2186 bta_hl_compact_mdl_cfg_time(app_idx, p_dcb->local_mdep_id);
2187 bta_hl_get_cur_time(app_idx, &time_val);
2188 }
2189 mdl_cfg.active = true;
2190 mdl_cfg.time = time_val;
2191 mdl_cfg.mdl_id = p_dcb->mdl_id;
2192 mdl_cfg.dch_mode = p_dcb->dch_mode;
2193 mdl_cfg.mtu = l2cap_cfg.mtu;
2194 mdl_cfg.fcs = l2cap_cfg.fcs;
2195
2196 mdl_cfg.peer_bd_addr = p_mcb->bd_addr;
2197 mdl_cfg.local_mdep_id = p_dcb->local_mdep_id;
2198 p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx];
2199 mdl_cfg.local_mdep_role = p_mdep_cfg->mdep_cfg.mdep_role;
2200 memcpy(&p_acb->mdl_cfg[mdl_cfg_idx], &mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
2201 bta_hl_co_save_mdl(mdl_cfg.local_mdep_id, mdl_cfg_idx, &mdl_cfg);
2202 }
2203
2204 #if (BTA_HL_DEBUG == TRUE)
2205 if (found) {
2206 if (p_dcb->mtu != l2cap_cfg.mtu) {
2207 APPL_TRACE_WARNING(
2208 "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from "
2209 "l2cap mtu=%d",
2210 p_dcb->mtu, l2cap_cfg.mtu);
2211 }
2212 APPL_TRACE_DEBUG("bta_hl_save_mdl_cfg saved=%d", found);
2213 APPL_TRACE_DEBUG("Saved. L2cap cfg mdl_id=%d mtu=%d fcs=%d dch_mode=%d",
2214 mdl_cfg.mdl_id, mdl_cfg.mtu, mdl_cfg.fcs,
2215 mdl_cfg.dch_mode);
2216 }
2217 #endif
2218 }
2219
2220 /*******************************************************************************
2221 *
2222 * Function bta_hl_set_dch_chan_cfg
2223 *
2224 * Description This function setups the L2CAP DCH channel configuration
2225 *
2226 * Returns void
2227 ******************************************************************************/
bta_hl_set_dch_chan_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx,tBTA_HL_DATA * p_data)2228 void bta_hl_set_dch_chan_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
2229 tBTA_HL_DATA* p_data) {
2230 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2231 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2232 uint8_t l2cap_mode = L2CAP_FCR_ERTM_MODE;
2233 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
2234 uint8_t local_mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
2235
2236 switch (p_dcb->dch_oper) {
2237 case BTA_HL_DCH_OP_LOCAL_RECONNECT:
2238 case BTA_HL_DCH_OP_REMOTE_RECONNECT:
2239 if (p_dcb->dch_mode == BTA_HL_DCH_MODE_STREAMING)
2240 l2cap_mode = L2CAP_FCR_STREAM_MODE;
2241 break;
2242 case BTA_HL_DCH_OP_LOCAL_OPEN:
2243 if (p_data->mca_evt.mca_data.create_cfm.cfg == BTA_HL_DCH_CFG_STREAMING)
2244 l2cap_mode = L2CAP_FCR_STREAM_MODE;
2245 break;
2246 case BTA_HL_DCH_OP_REMOTE_OPEN:
2247 if (p_dcb->local_cfg == BTA_HL_DCH_CFG_STREAMING)
2248 l2cap_mode = L2CAP_FCR_STREAM_MODE;
2249 break;
2250 default:
2251 APPL_TRACE_ERROR("Invalid dch oper=%d for set dch chan cfg",
2252 p_dcb->dch_oper);
2253 break;
2254 }
2255 p_dcb->chnl_cfg.fcr_opt.mode = l2cap_mode;
2256 p_dcb->chnl_cfg.fcr_opt.mps = bta_hl_set_mps(p_dcb->max_rx_apdu_size);
2257 p_dcb->chnl_cfg.fcr_opt.tx_win_sz = bta_hl_set_tx_win_size(
2258 p_dcb->max_rx_apdu_size, p_dcb->chnl_cfg.fcr_opt.mps);
2259 p_dcb->chnl_cfg.fcr_opt.max_transmit = BTA_HL_L2C_MAX_TRANSMIT;
2260 p_dcb->chnl_cfg.fcr_opt.rtrans_tout = BTA_HL_L2C_RTRANS_TOUT;
2261 p_dcb->chnl_cfg.fcr_opt.mon_tout = BTA_HL_L2C_MON_TOUT;
2262
2263 p_dcb->chnl_cfg.user_rx_buf_size =
2264 bta_hl_set_user_rx_buf_size(p_dcb->max_rx_apdu_size);
2265 p_dcb->chnl_cfg.user_tx_buf_size =
2266 bta_hl_set_user_tx_buf_size(p_dcb->max_tx_apdu_size);
2267 p_dcb->chnl_cfg.fcr_rx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
2268 p_dcb->chnl_cfg.fcr_tx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
2269 p_dcb->chnl_cfg.data_mtu = p_dcb->max_rx_apdu_size;
2270
2271 p_dcb->chnl_cfg.fcs = BTA_HL_MCA_NO_FCS;
2272 if (local_mdep_cfg_idx != BTA_HL_ECHO_TEST_MDEP_CFG_IDX) {
2273 if (p_sup_feature->mdep[local_mdep_cfg_idx].mdep_cfg.mdep_role ==
2274 BTA_HL_MDEP_ROLE_SOURCE) {
2275 p_dcb->chnl_cfg.fcs = BTA_HL_DEFAULT_SOURCE_FCS;
2276 }
2277 } else {
2278 p_dcb->chnl_cfg.fcs = BTA_HL_MCA_USE_FCS;
2279 }
2280
2281 #if (BTA_HL_DEBUG == TRUE)
2282 APPL_TRACE_DEBUG("L2CAP Params l2cap_mode[3-ERTM 4-STREAM]=%d", l2cap_mode);
2283 APPL_TRACE_DEBUG("Use FCS =%s mtu=%d",
2284 ((p_dcb->chnl_cfg.fcs & 1) ? "YES" : "NO"),
2285 p_dcb->chnl_cfg.data_mtu);
2286 APPL_TRACE_DEBUG(
2287 "tx_win_sz=%d, max_transmit=%d, rtrans_tout=%d, mon_tout=%d, mps=%d",
2288 p_dcb->chnl_cfg.fcr_opt.tx_win_sz, p_dcb->chnl_cfg.fcr_opt.max_transmit,
2289 p_dcb->chnl_cfg.fcr_opt.rtrans_tout, p_dcb->chnl_cfg.fcr_opt.mon_tout,
2290 p_dcb->chnl_cfg.fcr_opt.mps);
2291
2292 APPL_TRACE_DEBUG(
2293 "USER rx_buf_size=%d, tx_buf_size=%d, FCR rx_buf_size=%d, tx_buf_size=%d",
2294 p_dcb->chnl_cfg.user_rx_buf_size, p_dcb->chnl_cfg.user_tx_buf_size,
2295 p_dcb->chnl_cfg.fcr_rx_buf_size, p_dcb->chnl_cfg.fcr_tx_buf_size);
2296
2297 #endif
2298 }
2299
2300 /*******************************************************************************
2301 *
2302 * Function bta_hl_get_l2cap_cfg
2303 *
2304 * Description This function get the current L2CAP channel configuration
2305 *
2306 * Returns bool - true - operation is successful
2307 ******************************************************************************/
bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd,tBTA_HL_L2CAP_CFG_INFO * p_cfg)2308 bool bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd,
2309 tBTA_HL_L2CAP_CFG_INFO* p_cfg) {
2310 bool success = false;
2311 uint16_t lcid;
2312 tL2CAP_CFG_INFO* p_our_cfg;
2313 tL2CAP_CH_CFG_BITS our_cfg_bits;
2314 tL2CAP_CFG_INFO* p_peer_cfg;
2315 tL2CAP_CH_CFG_BITS peer_cfg_bits;
2316
2317 lcid = MCA_GetL2CapChannel((tMCA_DL)mdl_hnd);
2318 if (lcid && L2CA_GetCurrentConfig(lcid, &p_our_cfg, &our_cfg_bits,
2319 &p_peer_cfg, &peer_cfg_bits)) {
2320 p_cfg->fcs = BTA_HL_MCA_NO_FCS;
2321 if (our_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
2322 p_cfg->fcs |= p_our_cfg->fcs;
2323 } else {
2324 p_cfg->fcs = BTA_HL_MCA_USE_FCS;
2325 }
2326
2327 if (p_cfg->fcs != BTA_HL_MCA_USE_FCS) {
2328 if (peer_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
2329 p_cfg->fcs |= p_peer_cfg->fcs;
2330 } else {
2331 p_cfg->fcs = BTA_HL_MCA_USE_FCS;
2332 }
2333 }
2334
2335 p_cfg->mtu = 0;
2336 if (peer_cfg_bits & L2CAP_CH_CFG_MASK_MTU) {
2337 p_cfg->mtu = p_peer_cfg->mtu;
2338 } else {
2339 p_cfg->mtu = L2CAP_DEFAULT_MTU;
2340 }
2341 success = true;
2342 } else {
2343 p_cfg->mtu = L2CAP_DEFAULT_MTU;
2344 p_cfg->fcs = BTA_HL_L2C_NO_FCS;
2345 }
2346
2347 #if (BTA_HL_DEBUG == TRUE)
2348 if (!success) {
2349 APPL_TRACE_DEBUG("bta_hl_get_l2cap_cfg success=%d mdl=%d lcid=%d", success,
2350 mdl_hnd, lcid);
2351 APPL_TRACE_DEBUG("l2cap mtu=%d fcs=%d", p_cfg->mtu, p_cfg->fcs);
2352 }
2353 #endif
2354
2355 return success;
2356 }
2357
2358 /*******************************************************************************
2359 *
2360 * Function bta_hl_validate_chan_cfg
2361 *
2362 * Description This function validates the L2CAP channel configuration
2363 *
2364 * Returns bool - true - validation is successful
2365 ******************************************************************************/
bta_hl_validate_chan_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)2366 bool bta_hl_validate_chan_cfg(uint8_t app_idx, uint8_t mcl_idx,
2367 uint8_t mdl_idx) {
2368 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2369 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2370 bool success = false;
2371 uint8_t mdl_cfg_idx = 0;
2372 tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
2373 bool get_l2cap_result, get_mdl_result;
2374
2375 get_l2cap_result = bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
2376 get_mdl_result =
2377 bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_dcb->mdl_id, &mdl_cfg_idx);
2378
2379 if (get_l2cap_result && get_mdl_result) {
2380 if ((p_acb->mdl_cfg[mdl_cfg_idx].mtu <= l2cap_cfg.mtu) &&
2381 (p_acb->mdl_cfg[mdl_cfg_idx].fcs == l2cap_cfg.fcs) &&
2382 (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode == p_dcb->dch_mode)) {
2383 success = true;
2384 }
2385 }
2386
2387 #if (BTA_HL_DEBUG == TRUE)
2388
2389 if (p_dcb->mtu != l2cap_cfg.mtu) {
2390 APPL_TRACE_WARNING(
2391 "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap "
2392 "mtu=%d",
2393 p_dcb->mtu, l2cap_cfg.mtu);
2394 }
2395
2396 if (!success) {
2397 APPL_TRACE_DEBUG(
2398 "bta_hl_validate_chan_cfg success=%d app_idx=%d mcl_idx=%d mdl_idx=%d",
2399 success, app_idx, mcl_idx, mdl_idx);
2400 APPL_TRACE_DEBUG("Cur. L2cap cfg mtu=%d fcs=%d dch_mode=%d", l2cap_cfg.mtu,
2401 l2cap_cfg.fcs, p_dcb->dch_mode);
2402 APPL_TRACE_DEBUG("From saved: L2cap cfg mtu=%d fcs=%d dch_mode=%d",
2403 p_acb->mdl_cfg[mdl_cfg_idx].mtu,
2404 p_acb->mdl_cfg[mdl_cfg_idx].fcs,
2405 p_acb->mdl_cfg[mdl_cfg_idx].dch_mode);
2406 }
2407 #endif
2408
2409 return success;
2410 }
2411
2412 /*******************************************************************************
2413 *
2414 * Function bta_hl_is_cong_on
2415 *
2416 * Description This function checks whether the congestion condition is on.
2417 *
2418 * Returns bool - true DCH is congested
2419 * false not congested
2420 *
2421 ******************************************************************************/
bta_hl_is_cong_on(uint8_t app_id,const RawAddress & bd_addr,tBTA_HL_MDL_ID mdl_id)2422 bool bta_hl_is_cong_on(uint8_t app_id, const RawAddress& bd_addr,
2423 tBTA_HL_MDL_ID mdl_id)
2424
2425 {
2426 tBTA_HL_MDL_CB* p_dcb;
2427 uint8_t app_idx = 0, mcl_idx, mdl_idx;
2428 bool cong_status = true;
2429
2430 if (bta_hl_find_app_idx(app_id, &app_idx)) {
2431 if (bta_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
2432 if (bta_hl_find_mdl_idx(app_idx, mcl_idx, mdl_id, &mdl_idx)) {
2433 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2434 cong_status = p_dcb->cong;
2435 }
2436 }
2437 }
2438
2439 return cong_status;
2440 }
2441
2442 /*******************************************************************************
2443 *
2444 * Function bta_hl_check_cch_close
2445 *
2446 * Description This function checks whether there is a pending CCH close
2447 * request or not
2448 *
2449 * Returns void
2450 ******************************************************************************/
bta_hl_check_cch_close(uint8_t app_idx,uint8_t mcl_idx,tBTA_HL_DATA * p_data,bool check_dch_setup)2451 void bta_hl_check_cch_close(uint8_t app_idx, uint8_t mcl_idx,
2452 tBTA_HL_DATA* p_data, bool check_dch_setup) {
2453 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2454 tBTA_HL_MDL_CB* p_dcb;
2455 uint8_t mdl_idx;
2456
2457 #if (BTA_HL_DEBUG == TRUE)
2458 APPL_TRACE_DEBUG("bta_hl_check_cch_close cch_close_dch_oper=%d",
2459 p_mcb->cch_close_dch_oper);
2460 #endif
2461
2462 if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) {
2463 if (check_dch_setup &&
2464 bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2465 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2466 if (!p_mcb->rsp_tout) {
2467 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_ABORT;
2468
2469 if (!p_dcb->abort_oper) {
2470 p_dcb->abort_oper |= BTA_HL_ABORT_CCH_CLOSE_MASK;
2471 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT,
2472 p_data);
2473 }
2474 } else {
2475 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
2476 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
2477 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
2478 }
2479 } else if (bta_hl_find_an_active_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2480 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
2481 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT,
2482 p_data);
2483 } else {
2484 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_NONE;
2485 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_EVT, p_data);
2486 }
2487 }
2488 }
2489
2490 /*******************************************************************************
2491 *
2492 * Function bta_hl_clean_app
2493 *
2494 * Description Cleans up the HDP application resources and control block
2495 *
2496 * Returns void
2497 *
2498 ******************************************************************************/
bta_hl_clean_app(uint8_t app_idx)2499 void bta_hl_clean_app(uint8_t app_idx) {
2500 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2501 int i, num_act_apps = 0;
2502
2503 #if (BTA_HL_DEBUG == TRUE)
2504 APPL_TRACE_DEBUG("bta_hl_clean_app");
2505 #endif
2506 MCA_Deregister((tMCA_HANDLE)p_acb->app_handle);
2507
2508 if (p_acb->sdp_handle) SDP_DeleteRecord(p_acb->sdp_handle);
2509
2510 memset((void*)p_acb, 0, sizeof(tBTA_HL_APP_CB));
2511
2512 /* check any application is still active */
2513 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
2514 p_acb = BTA_HL_GET_APP_CB_PTR(i);
2515 if (p_acb->in_use) num_act_apps++;
2516 }
2517
2518 if (!num_act_apps) {
2519 bta_sys_remove_uuid(UUID_SERVCLASS_HDP_PROFILE);
2520 }
2521 }
2522
2523 /*******************************************************************************
2524 *
2525 * Function bta_hl_check_deregistration
2526 *
2527 * Description This function checks whether there is a pending deregistration
2528 * request or not
2529 *
2530 * Returns void
2531 ******************************************************************************/
bta_hl_check_deregistration(uint8_t app_idx,tBTA_HL_DATA * p_data)2532 void bta_hl_check_deregistration(uint8_t app_idx, tBTA_HL_DATA* p_data) {
2533 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2534 tBTA_HL_MCL_CB* p_mcb;
2535 uint8_t mcl_idx;
2536 tBTA_HL evt_data;
2537
2538 #if (BTA_HL_DEBUG == TRUE)
2539 APPL_TRACE_DEBUG("bta_hl_check_deregistration");
2540 #endif
2541
2542 if (p_acb->deregistering) {
2543 if (bta_hl_find_an_in_use_mcl_idx(app_idx, &mcl_idx)) {
2544 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2545 if (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) {
2546 if (p_mcb->cch_state == BTA_HL_CCH_OPENING_ST)
2547 p_mcb->force_close_local_cch_opening = true;
2548 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
2549 APPL_TRACE_DEBUG("p_mcb->force_close_local_cch_opening=%d",
2550 p_mcb->force_close_local_cch_opening);
2551 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, true);
2552 }
2553 } else {
2554 /* all cchs are closed */
2555 evt_data.dereg_cfm.app_handle = p_acb->app_handle;
2556 evt_data.dereg_cfm.app_id = p_data->api_dereg.app_id;
2557 evt_data.dereg_cfm.status = BTA_HL_STATUS_OK;
2558 p_acb->p_cback(BTA_HL_DEREGISTER_CFM_EVT, (tBTA_HL*)&evt_data);
2559 bta_hl_clean_app(app_idx);
2560 bta_hl_check_disable(p_data);
2561 }
2562 }
2563 }
2564
2565 /*******************************************************************************
2566 *
2567 * Function bta_hl_check_disable
2568 *
2569 * Description This function checks whether there is a pending disable
2570 * request or not
2571 *
2572 * Returns void
2573 *
2574 ******************************************************************************/
bta_hl_check_disable(tBTA_HL_DATA * p_data)2575 void bta_hl_check_disable(tBTA_HL_DATA* p_data) {
2576 tBTA_HL_CB* p_cb = &bta_hl_cb;
2577 tBTA_HL_APP_CB* p_acb;
2578 uint8_t app_idx;
2579 tBTA_HL_CTRL evt_data;
2580
2581 #if (BTA_HL_DEBUG == TRUE)
2582 APPL_TRACE_DEBUG("bta_hl_check_disable");
2583 #endif
2584
2585 if (bta_hl_cb.disabling) {
2586 if (bta_hl_find_an_in_use_app_idx(&app_idx)) {
2587 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2588 if (!p_acb->deregistering) {
2589 p_acb->deregistering = true;
2590 bta_hl_check_deregistration(app_idx, p_data);
2591 }
2592 } else {
2593 /* all apps are deregistered */
2594 bta_sys_deregister(BTA_ID_HL);
2595 evt_data.disable_cfm.status = BTA_HL_STATUS_OK;
2596 if (p_cb->p_ctrl_cback)
2597 p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT,
2598 (tBTA_HL_CTRL*)&evt_data);
2599 memset((void*)p_cb, 0, sizeof(tBTA_HL_CB));
2600 }
2601 }
2602 }
2603
2604 /*******************************************************************************
2605 *
2606 * Function bta_hl_build_abort_cfm
2607 *
2608 * Description This function builds the abort confirmation event data
2609 *
2610 * Returns None
2611 *
2612 ******************************************************************************/
bta_hl_build_abort_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_STATUS status)2613 void bta_hl_build_abort_cfm(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
2614 tBTA_HL_MCL_HANDLE mcl_handle,
2615 tBTA_HL_STATUS status) {
2616 p_evt_data->dch_abort_cfm.status = status;
2617 p_evt_data->dch_abort_cfm.mcl_handle = mcl_handle;
2618 p_evt_data->dch_abort_cfm.app_handle = app_handle;
2619 }
2620
2621 /*******************************************************************************
2622 *
2623 * Function bta_hl_build_abort_ind
2624 *
2625 * Description This function builds the abort indication event data
2626 *
2627 * Returns None
2628 *
2629 ******************************************************************************/
bta_hl_build_abort_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle)2630 void bta_hl_build_abort_ind(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
2631 tBTA_HL_MCL_HANDLE mcl_handle) {
2632 p_evt_data->dch_abort_ind.mcl_handle = mcl_handle;
2633 p_evt_data->dch_abort_ind.app_handle = app_handle;
2634 }
2635 /*******************************************************************************
2636 *
2637 * Function bta_hl_build_close_cfm
2638 *
2639 * Description This function builds the close confirmation event data
2640 *
2641 * Returns None
2642 *
2643 ******************************************************************************/
bta_hl_build_dch_close_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_MDL_HANDLE mdl_handle,tBTA_HL_STATUS status)2644 void bta_hl_build_dch_close_cfm(tBTA_HL* p_evt_data,
2645 tBTA_HL_APP_HANDLE app_handle,
2646 tBTA_HL_MCL_HANDLE mcl_handle,
2647 tBTA_HL_MDL_HANDLE mdl_handle,
2648 tBTA_HL_STATUS status) {
2649 p_evt_data->dch_close_cfm.status = status;
2650 p_evt_data->dch_close_cfm.mdl_handle = mdl_handle;
2651 p_evt_data->dch_close_cfm.mcl_handle = mcl_handle;
2652 p_evt_data->dch_close_cfm.app_handle = app_handle;
2653 }
2654
2655 /*******************************************************************************
2656 *
2657 * Function bta_hl_build_dch_close_ind
2658 *
2659 * Description This function builds the close indication event data
2660 *
2661 * Returns None
2662 *
2663 ******************************************************************************/
bta_hl_build_dch_close_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_MDL_HANDLE mdl_handle,bool intentional)2664 void bta_hl_build_dch_close_ind(tBTA_HL* p_evt_data,
2665 tBTA_HL_APP_HANDLE app_handle,
2666 tBTA_HL_MCL_HANDLE mcl_handle,
2667 tBTA_HL_MDL_HANDLE mdl_handle,
2668 bool intentional) {
2669 p_evt_data->dch_close_ind.mdl_handle = mdl_handle;
2670 p_evt_data->dch_close_ind.mcl_handle = mcl_handle;
2671 p_evt_data->dch_close_ind.app_handle = app_handle;
2672 p_evt_data->dch_close_ind.intentional = intentional;
2673 }
2674
2675 /*******************************************************************************
2676 *
2677 * Function bta_hl_build_send_data_cfm
2678 *
2679 * Description This function builds the send data confirmation event data
2680 *
2681 * Returns None
2682 *
2683 ******************************************************************************/
bta_hl_build_send_data_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_MDL_HANDLE mdl_handle,tBTA_HL_STATUS status)2684 void bta_hl_build_send_data_cfm(tBTA_HL* p_evt_data,
2685 tBTA_HL_APP_HANDLE app_handle,
2686 tBTA_HL_MCL_HANDLE mcl_handle,
2687 tBTA_HL_MDL_HANDLE mdl_handle,
2688 tBTA_HL_STATUS status) {
2689 p_evt_data->dch_send_data_cfm.mdl_handle = mdl_handle;
2690 p_evt_data->dch_send_data_cfm.mcl_handle = mcl_handle;
2691 p_evt_data->dch_send_data_cfm.app_handle = app_handle;
2692 p_evt_data->dch_send_data_cfm.status = status;
2693 }
2694
2695 /*******************************************************************************
2696 *
2697 * Function bta_hl_build_rcv_data_ind
2698 *
2699 * Description This function builds the received data indication event data
2700 *
2701 * Returns None
2702 *
2703 ******************************************************************************/
bta_hl_build_rcv_data_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_MDL_HANDLE mdl_handle)2704 void bta_hl_build_rcv_data_ind(tBTA_HL* p_evt_data,
2705 tBTA_HL_APP_HANDLE app_handle,
2706 tBTA_HL_MCL_HANDLE mcl_handle,
2707 tBTA_HL_MDL_HANDLE mdl_handle) {
2708 p_evt_data->dch_rcv_data_ind.mdl_handle = mdl_handle;
2709 p_evt_data->dch_rcv_data_ind.mcl_handle = mcl_handle;
2710 p_evt_data->dch_rcv_data_ind.app_handle = app_handle;
2711 }
2712
2713 /*******************************************************************************
2714 *
2715 * Function bta_hl_build_cch_open_cfm
2716 *
2717 * Description This function builds the CCH open confirmation event data
2718 *
2719 * Returns None
2720 *
2721 ******************************************************************************/
bta_hl_build_cch_open_cfm(tBTA_HL * p_evt_data,uint8_t app_id,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,const RawAddress & bd_addr,tBTA_HL_STATUS status)2722 void bta_hl_build_cch_open_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
2723 tBTA_HL_APP_HANDLE app_handle,
2724 tBTA_HL_MCL_HANDLE mcl_handle,
2725 const RawAddress& bd_addr,
2726 tBTA_HL_STATUS status) {
2727 p_evt_data->cch_open_cfm.app_id = app_id;
2728 p_evt_data->cch_open_cfm.app_handle = app_handle;
2729 p_evt_data->cch_open_cfm.mcl_handle = mcl_handle;
2730 p_evt_data->cch_open_cfm.bd_addr = bd_addr;
2731 p_evt_data->cch_open_cfm.status = status;
2732 APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d", status);
2733 }
2734
2735 /*******************************************************************************
2736 *
2737 * Function bta_hl_build_cch_open_ind
2738 *
2739 * Description This function builds the CCH open indication event data
2740 *
2741 * Returns None
2742 *
2743 ******************************************************************************/
bta_hl_build_cch_open_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,const RawAddress & bd_addr)2744 void bta_hl_build_cch_open_ind(tBTA_HL* p_evt_data,
2745 tBTA_HL_APP_HANDLE app_handle,
2746 tBTA_HL_MCL_HANDLE mcl_handle,
2747 const RawAddress& bd_addr) {
2748 p_evt_data->cch_open_ind.app_handle = app_handle;
2749 p_evt_data->cch_open_ind.mcl_handle = mcl_handle;
2750 p_evt_data->cch_open_ind.bd_addr = bd_addr;
2751 }
2752
2753 /*******************************************************************************
2754 *
2755 * Function bta_hl_build_cch_close_cfm
2756 *
2757 * Description This function builds the CCH close confirmation event data
2758 *
2759 * Returns None
2760 *
2761 ******************************************************************************/
bta_hl_build_cch_close_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_STATUS status)2762 void bta_hl_build_cch_close_cfm(tBTA_HL* p_evt_data,
2763 tBTA_HL_APP_HANDLE app_handle,
2764 tBTA_HL_MCL_HANDLE mcl_handle,
2765 tBTA_HL_STATUS status) {
2766 p_evt_data->cch_close_cfm.mcl_handle = mcl_handle;
2767 p_evt_data->cch_close_cfm.app_handle = app_handle;
2768 p_evt_data->cch_close_cfm.status = status;
2769 }
2770
2771 /*******************************************************************************
2772 *
2773 * Function bta_hl_build_cch_close_ind
2774 *
2775 * Description This function builds the CCH colse indication event data
2776 *
2777 * Returns None
2778 *
2779 ******************************************************************************/
bta_hl_build_cch_close_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,bool intentional)2780 void bta_hl_build_cch_close_ind(tBTA_HL* p_evt_data,
2781 tBTA_HL_APP_HANDLE app_handle,
2782 tBTA_HL_MCL_HANDLE mcl_handle,
2783 bool intentional) {
2784 p_evt_data->cch_close_ind.mcl_handle = mcl_handle;
2785 p_evt_data->cch_close_ind.app_handle = app_handle;
2786 p_evt_data->cch_close_ind.intentional = intentional;
2787 }
2788
2789 /*******************************************************************************
2790 *
2791 * Function bta_hl_build_dch_open_cfm
2792 *
2793 * Description This function builds the DCH open confirmation event data
2794 *
2795 * Returns None
2796 *
2797 ******************************************************************************/
bta_hl_build_dch_open_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_MDL_HANDLE mdl_handle,tBTA_HL_MDEP_ID local_mdep_id,tBTA_HL_MDL_ID mdl_id,tBTA_HL_DCH_MODE dch_mode,bool first_reliable,uint16_t mtu,tBTA_HL_STATUS status)2798 void bta_hl_build_dch_open_cfm(tBTA_HL* p_evt_data,
2799 tBTA_HL_APP_HANDLE app_handle,
2800 tBTA_HL_MCL_HANDLE mcl_handle,
2801 tBTA_HL_MDL_HANDLE mdl_handle,
2802 tBTA_HL_MDEP_ID local_mdep_id,
2803 tBTA_HL_MDL_ID mdl_id, tBTA_HL_DCH_MODE dch_mode,
2804 bool first_reliable, uint16_t mtu,
2805 tBTA_HL_STATUS status)
2806
2807 {
2808 p_evt_data->dch_open_cfm.mdl_handle = mdl_handle;
2809 p_evt_data->dch_open_cfm.mcl_handle = mcl_handle;
2810 p_evt_data->dch_open_cfm.app_handle = app_handle;
2811 p_evt_data->dch_open_cfm.local_mdep_id = local_mdep_id;
2812 p_evt_data->dch_open_cfm.mdl_id = mdl_id;
2813 p_evt_data->dch_open_cfm.dch_mode = dch_mode;
2814 p_evt_data->dch_open_cfm.first_reliable = first_reliable;
2815 p_evt_data->dch_open_cfm.mtu = mtu;
2816 p_evt_data->dch_open_cfm.status = status;
2817 }
2818
2819 /*******************************************************************************
2820 *
2821 * Function bta_hl_build_sdp_query_cfm
2822 *
2823 * Description This function builds the SDP query indication event data
2824 *
2825 * Returns None
2826 *
2827 ******************************************************************************/
bta_hl_build_sdp_query_cfm(tBTA_HL * p_evt_data,uint8_t app_id,tBTA_HL_APP_HANDLE app_handle,const RawAddress & bd_addr,tBTA_HL_SDP * p_sdp,tBTA_HL_STATUS status)2828 void bta_hl_build_sdp_query_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
2829 tBTA_HL_APP_HANDLE app_handle,
2830 const RawAddress& bd_addr, tBTA_HL_SDP* p_sdp,
2831 tBTA_HL_STATUS status)
2832
2833 {
2834 APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d",
2835 app_id, app_handle);
2836 p_evt_data->sdp_query_cfm.app_id = app_id;
2837 p_evt_data->sdp_query_cfm.app_handle = app_handle;
2838 p_evt_data->sdp_query_cfm.bd_addr = bd_addr;
2839 p_evt_data->sdp_query_cfm.p_sdp = p_sdp;
2840 p_evt_data->sdp_query_cfm.status = status;
2841 }
2842
2843 /*******************************************************************************
2844 *
2845 * Function bta_hl_build_delete_mdl_cfm
2846 *
2847 * Description This function builds the delete MDL confirmation event data
2848 *
2849 * Returns None
2850 *
2851 ******************************************************************************/
bta_hl_build_delete_mdl_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_MDL_ID mdl_id,tBTA_HL_STATUS status)2852 void bta_hl_build_delete_mdl_cfm(tBTA_HL* p_evt_data,
2853 tBTA_HL_APP_HANDLE app_handle,
2854 tBTA_HL_MCL_HANDLE mcl_handle,
2855 tBTA_HL_MDL_ID mdl_id, tBTA_HL_STATUS status)
2856
2857 {
2858 p_evt_data->delete_mdl_cfm.mcl_handle = mcl_handle;
2859 p_evt_data->delete_mdl_cfm.app_handle = app_handle;
2860 p_evt_data->delete_mdl_cfm.mdl_id = mdl_id;
2861 p_evt_data->delete_mdl_cfm.status = status;
2862 }
2863
2864 /*******************************************************************************
2865 *
2866 * Function bta_hl_build_echo_test_cfm
2867 *
2868 * Description This function builds the echo test confirmation event data
2869 *
2870 * Returns None
2871 *
2872 ******************************************************************************/
bta_hl_build_echo_test_cfm(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,tBTA_HL_STATUS status)2873 void bta_hl_build_echo_test_cfm(tBTA_HL* p_evt_data,
2874 tBTA_HL_APP_HANDLE app_handle,
2875 tBTA_HL_MCL_HANDLE mcl_handle,
2876 tBTA_HL_STATUS status) {
2877 p_evt_data->echo_test_cfm.mcl_handle = mcl_handle;
2878 p_evt_data->echo_test_cfm.app_handle = app_handle;
2879 p_evt_data->echo_test_cfm.status = status;
2880 }
2881
2882 /*****************************************************************************
2883 * Debug Functions
2884 ****************************************************************************/
2885 #if (BTA_HL_DEBUG == TRUE)
2886
2887 /*******************************************************************************
2888 *
2889 * Function bta_hl_status_code
2890 *
2891 * Description get the status string pointer
2892 *
2893 * Returns char * - status string pointer
2894 *
2895 ******************************************************************************/
bta_hl_status_code(tBTA_HL_STATUS status)2896 const char* bta_hl_status_code(tBTA_HL_STATUS status) {
2897 switch (status) {
2898 case BTA_HL_STATUS_OK:
2899 return "BTA_HL_STATUS_OK";
2900 case BTA_HL_STATUS_FAIL:
2901 return "BTA_HL_STATUS_FAIL";
2902 case BTA_HL_STATUS_ABORTED:
2903 return "BTA_HL_STATUS_ABORTED";
2904 case BTA_HL_STATUS_NO_RESOURCE:
2905 return "BTA_HL_STATUS_NO_RESOURCE";
2906 case BTA_HL_STATUS_LAST_ITEM:
2907 return "BTA_HL_STATUS_LAST_ITEM";
2908 case BTA_HL_STATUS_DUPLICATE_APP_ID:
2909 return "BTA_HL_STATUS_DUPLICATE_APP_ID";
2910 case BTA_HL_STATUS_INVALID_APP_HANDLE:
2911 return "BTA_HL_STATUS_INVALID_APP_HANDLE";
2912 case BTA_HL_STATUS_INVALID_MCL_HANDLE:
2913 return "BTA_HL_STATUS_INVALID_MCL_HANDLE";
2914 case BTA_HL_STATUS_MCAP_REG_FAIL:
2915 return "BTA_HL_STATUS_MCAP_REG_FAIL";
2916 case BTA_HL_STATUS_MDEP_CO_FAIL:
2917 return "BTA_HL_STATUS_MDEP_CO_FAIL";
2918 case BTA_HL_STATUS_ECHO_CO_FAIL:
2919 return "BTA_HL_STATUS_ECHO_CO_FAIL";
2920 case BTA_HL_STATUS_MDL_CFG_CO_FAIL:
2921 return "BTA_HL_STATUS_MDL_CFG_CO_FAIL";
2922 case BTA_HL_STATUS_SDP_NO_RESOURCE:
2923 return "BTA_HL_STATUS_SDP_NO_RESOURCE";
2924 case BTA_HL_STATUS_SDP_FAIL:
2925 return "BTA_HL_STATUS_SDP_FAIL";
2926 case BTA_HL_STATUS_NO_CCH:
2927 return "BTA_HL_STATUS_NO_CCH";
2928 case BTA_HL_STATUS_NO_MCL:
2929 return "BTA_HL_STATUS_NO_MCL";
2930
2931 case BTA_HL_STATUS_NO_FIRST_RELIABLE:
2932 return "BTA_HL_STATUS_NO_FIRST_RELIABLE";
2933 case BTA_HL_STATUS_INVALID_DCH_CFG:
2934 return "BTA_HL_STATUS_INVALID_DCH_CFG";
2935 case BTA_HL_STATUS_INVALID_BD_ADDR:
2936 return "BTA_HL_STATUS_INVALID_BD_ADDR";
2937 case BTA_HL_STATUS_INVALID_RECONNECT_CFG:
2938 return "BTA_HL_STATUS_INVALID_RECONNECT_CFG";
2939 case BTA_HL_STATUS_ECHO_TEST_BUSY:
2940 return "BTA_HL_STATUS_ECHO_TEST_BUSY";
2941 case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID:
2942 return "BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID";
2943 case BTA_HL_STATUS_INVALID_MDL_ID:
2944 return "BTA_HL_STATUS_INVALID_MDL_ID";
2945 case BTA_HL_STATUS_NO_MDL_ID_FOUND:
2946 return "BTA_HL_STATUS_NO_MDL_ID_FOUND";
2947 case BTA_HL_STATUS_DCH_BUSY:
2948 return "BTA_HL_STATUS_DCH_BUSY";
2949 default:
2950 return "Unknown status code";
2951 }
2952 }
2953 /*******************************************************************************
2954 *
2955 * Function bta_hl_evt_code
2956 *
2957 * Description Maps HL event code to the corresponding event string
2958 *
2959 * Returns string pointer for the associated event name
2960 *
2961 ******************************************************************************/
bta_hl_evt_code(tBTA_HL_INT_EVT evt_code)2962 const char* bta_hl_evt_code(tBTA_HL_INT_EVT evt_code) {
2963 switch (evt_code) {
2964 case BTA_HL_CCH_OPEN_EVT:
2965 return "BTA_HL_CCH_OPEN_EVT";
2966 case BTA_HL_CCH_SDP_OK_EVT:
2967 return "BTA_HL_CCH_SDP_OK_EVT";
2968 case BTA_HL_CCH_SDP_FAIL_EVT:
2969 return "BTA_HL_CCH_SDP_FAIL_EVT";
2970 case BTA_HL_MCA_CONNECT_IND_EVT:
2971 return "BTA_HL_MCA_CONNECT_IND_EVT";
2972 case BTA_HL_MCA_DISCONNECT_IND_EVT:
2973 return "BTA_HL_MCA_DISCONNECT_IND_EVT";
2974
2975 case BTA_HL_CCH_CLOSE_EVT:
2976 return "BTA_HL_CCH_CLOSE_EVT";
2977 case BTA_HL_CCH_CLOSE_CMPL_EVT:
2978 return "BTA_HL_CCH_CLOSE_CMPL_EVT";
2979 case BTA_HL_DCH_OPEN_EVT:
2980 return "BTA_HL_DCH_OPEN_EVT";
2981 case BTA_HL_MCA_CREATE_IND_EVT:
2982 return "BTA_HL_MCA_CREATE_IND_EVT";
2983 case BTA_HL_MCA_CREATE_CFM_EVT:
2984 return "BTA_HL_MCA_CREATE_CFM_EVT";
2985 case BTA_HL_MCA_OPEN_IND_EVT:
2986 return "BTA_HL_MCA_OPEN_IND_EVT";
2987 case BTA_HL_MCA_OPEN_CFM_EVT:
2988 return "BTA_HL_MCA_OPEN_CFM_EVT";
2989 case BTA_HL_DCH_CLOSE_EVT:
2990 return "BTA_HL_DCH_CLOSE_EVT";
2991 case BTA_HL_MCA_CLOSE_IND_EVT:
2992 return "BTA_HL_MCA_CLOSE_IND_EVT";
2993 case BTA_HL_MCA_CLOSE_CFM_EVT:
2994 return "BTA_HL_MCA_CLOSE_CFM_EVT";
2995 case BTA_HL_API_SEND_DATA_EVT:
2996 return "BTA_HL_API_SEND_DATA_EVT";
2997 case BTA_HL_MCA_RCV_DATA_EVT:
2998 return "BTA_HL_MCA_RCV_DATA_EVT";
2999 case BTA_HL_DCH_CLOSE_CMPL_EVT:
3000 return "BTA_HL_DCH_CLOSE_CMPL_EVT";
3001
3002 case BTA_HL_API_ENABLE_EVT:
3003 return "BTA_HL_API_ENABLE_EVT";
3004 case BTA_HL_API_DISABLE_EVT:
3005 return "BTA_HL_API_DISABLE_EVT";
3006 case BTA_HL_API_UPDATE_EVT:
3007 return "BTA_HL_API_UPDATE_EVT";
3008 case BTA_HL_API_REGISTER_EVT:
3009 return "BTA_HL_API_REGISTER_EVT";
3010 case BTA_HL_API_DEREGISTER_EVT:
3011 return "BTA_HL_API_DEREGISTER_EVT";
3012
3013 case BTA_HL_API_CCH_OPEN_EVT:
3014 return "BTA_HL_API_CCH_OPEN_EVT";
3015
3016 case BTA_HL_API_CCH_CLOSE_EVT:
3017 return "BTA_HL_API_CCH_CLOSE_EVT";
3018 case BTA_HL_API_DCH_OPEN_EVT:
3019 return "BTA_HL_API_DCH_OPEN_EVT";
3020
3021 case BTA_HL_API_DCH_RECONNECT_EVT:
3022 return "BTA_HL_API_DCH_RECONNECT_EVT";
3023 case BTA_HL_API_DCH_CLOSE_EVT:
3024 return "BTA_HL_API_DCH_CLOSE_EVT";
3025 case BTA_HL_API_DELETE_MDL_EVT:
3026 return "BTA_HL_API_DELETE_MDL_EVT";
3027 case BTA_HL_API_DCH_ABORT_EVT:
3028 return "BTA_HL_API_DCH_ABORT_EVT";
3029
3030 case BTA_HL_DCH_RECONNECT_EVT:
3031 return "BTA_HL_DCH_RECONNECT_EVT";
3032 case BTA_HL_DCH_SDP_INIT_EVT:
3033 return "BTA_HL_DCH_SDP_INIT_EVT";
3034 case BTA_HL_DCH_SDP_FAIL_EVT:
3035 return "BTA_HL_DCH_SDP_FAIL_EVT";
3036 case BTA_HL_API_DCH_ECHO_TEST_EVT:
3037 return "BTA_HL_API_DCH_ECHO_TEST_EVT";
3038 case BTA_HL_DCH_CLOSE_ECHO_TEST_EVT:
3039 return "BTA_HL_DCH_CLOSE_ECHO_TEST_EVT";
3040 case BTA_HL_MCA_RECONNECT_IND_EVT:
3041 return "BTA_HL_MCA_RECONNECT_IND_EVT";
3042 case BTA_HL_MCA_RECONNECT_CFM_EVT:
3043 return "BTA_HL_MCA_RECONNECT_CFM_EVT";
3044 case BTA_HL_API_DCH_CREATE_RSP_EVT:
3045 return "BTA_HL_API_DCH_CREATE_RSP_EVT";
3046 case BTA_HL_DCH_ABORT_EVT:
3047 return "BTA_HL_DCH_ABORT_EVT";
3048 case BTA_HL_MCA_ABORT_IND_EVT:
3049 return "BTA_HL_MCA_ABORT_IND_EVT";
3050 case BTA_HL_MCA_ABORT_CFM_EVT:
3051 return "BTA_HL_MCA_ABORT_CFM_EVT";
3052 case BTA_HL_MCA_DELETE_IND_EVT:
3053 return "BTA_HL_MCA_DELETE_IND_EVT";
3054 case BTA_HL_MCA_DELETE_CFM_EVT:
3055 return "BTA_HL_MCA_DELETE_CFM_EVT";
3056 case BTA_HL_MCA_CONG_CHG_EVT:
3057 return "BTA_HL_MCA_CONG_CHG_EVT";
3058 case BTA_HL_CI_GET_TX_DATA_EVT:
3059 return "BTA_HL_CI_GET_TX_DATA_EVT";
3060 case BTA_HL_CI_PUT_RX_DATA_EVT:
3061 return "BTA_HL_CI_PUT_RX_DATA_EVT";
3062 case BTA_HL_CI_GET_ECHO_DATA_EVT:
3063 return "BTA_HL_CI_GET_ECHO_DATA_EVT";
3064 case BTA_HL_DCH_ECHO_TEST_EVT:
3065 return "BTA_HL_DCH_ECHO_TEST_EVT";
3066 case BTA_HL_CI_PUT_ECHO_DATA_EVT:
3067 return "BTA_HL_CI_PUT_ECHO_DATA_EVT";
3068 case BTA_HL_API_SDP_QUERY_EVT:
3069 return "BTA_HL_API_SDP_QUERY_EVT";
3070 case BTA_HL_SDP_QUERY_OK_EVT:
3071 return "BTA_HL_SDP_QUERY_OK_EVT";
3072 case BTA_HL_SDP_QUERY_FAIL_EVT:
3073 return "BTA_HL_SDP_QUERY_FAIL_EVT";
3074 case BTA_HL_MCA_RSP_TOUT_IND_EVT:
3075 return "BTA_HL_MCA_RSP_TOUT_IND_EVT";
3076
3077 default:
3078 return "Unknown HL event code";
3079 }
3080 }
3081
3082 #endif /* Debug Functions */
3083 #endif // HL_INCLUDED
3084