1 /******************************************************************************
2 *
3 * Copyright (C) 2003-2012 Broadcom Corporation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 ******************************************************************************/
18
19 /******************************************************************************
20 *
21 * This file 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,BD_ADDR p_bd_addr,uint8_t * p_mcl_idx)1029 bool bta_hl_find_mcl_idx(uint8_t app_idx, BD_ADDR 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 (!memcmp(bta_hl_cb.acb[app_idx].mcb[i].bd_addr, p_bd_addr,
1037 BD_ADDR_LEN))) {
1038 found = true;
1039 *p_mcl_idx = i;
1040 break;
1041 }
1042 }
1043
1044 #if (BTA_HL_DEBUG == TRUE)
1045 if (!found) {
1046 APPL_TRACE_DEBUG("bta_hl_find_mcl_idx found=%d idx=%d", found, i);
1047 }
1048 #endif
1049 return found;
1050 }
1051
1052 /*******************************************************************************
1053 *
1054 * Function bta_hl_find_mdl_idx_using_handle
1055 *
1056 * Description This function finds the MDL control block index based on
1057 * the MDL handle
1058 *
1059 * Returns bool true-found
1060 *
1061 ******************************************************************************/
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)1062 bool bta_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
1063 uint8_t* p_app_idx, uint8_t* p_mcl_idx,
1064 uint8_t* p_mdl_idx) {
1065 tBTA_HL_APP_CB* p_acb;
1066 tBTA_HL_MCL_CB* p_mcb;
1067 tBTA_HL_MDL_CB* p_dcb;
1068 bool found = false;
1069 uint8_t i, j, k;
1070
1071 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1072 p_acb = BTA_HL_GET_APP_CB_PTR(i);
1073 if (p_acb->in_use) {
1074 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1075 p_mcb = BTA_HL_GET_MCL_CB_PTR(i, j);
1076 if (p_mcb->in_use) {
1077 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
1078 p_dcb = BTA_HL_GET_MDL_CB_PTR(i, j, k);
1079 if (p_dcb->in_use) {
1080 if (p_dcb->mdl_handle == mdl_handle) {
1081 found = true;
1082 *p_app_idx = i;
1083 *p_mcl_idx = j;
1084 *p_mdl_idx = k;
1085 break;
1086 }
1087 }
1088 }
1089 }
1090 }
1091 }
1092 }
1093
1094 #if (BTA_HL_DEBUG == TRUE)
1095 if (!found) {
1096 APPL_TRACE_DEBUG(
1097 "bta_hl_find_mdl_idx_using_handle found=%d mdl_handle=%d ", found,
1098 mdl_handle);
1099 }
1100 #endif
1101 return found;
1102 }
1103 /*******************************************************************************
1104 *
1105 * Function bta_hl_is_the_first_reliable_existed
1106 *
1107 * Description This function checks whether the first reliable DCH channel
1108 * has been setup on the MCL or not
1109 *
1110 * Returns bool - true exist
1111 * false does not exist
1112 *
1113 ******************************************************************************/
bta_hl_is_the_first_reliable_existed(uint8_t app_idx,uint8_t mcl_idx)1114 bool bta_hl_is_the_first_reliable_existed(uint8_t app_idx, uint8_t mcl_idx) {
1115 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1116 bool is_existed = false;
1117 uint8_t i;
1118
1119 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
1120 if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) {
1121 is_existed = true;
1122 break;
1123 }
1124 }
1125
1126 #if (BTA_HL_DEBUG == TRUE)
1127 APPL_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d ",
1128 is_existed);
1129 #endif
1130 return is_existed;
1131 }
1132
1133 /*******************************************************************************
1134 *
1135 * Function bta_hl_find_non_active_mdl_cfg
1136 *
1137 * Description This function finds a valid MDL configiration index and this
1138 * MDL ID is not active
1139 *
1140 * Returns bool - true found
1141 * false not found
1142 *
1143 ******************************************************************************/
bta_hl_find_non_active_mdl_cfg(uint8_t app_idx,uint8_t start_mdl_cfg_idx,uint8_t * p_mdl_cfg_idx)1144 bool bta_hl_find_non_active_mdl_cfg(uint8_t app_idx, uint8_t start_mdl_cfg_idx,
1145 uint8_t* p_mdl_cfg_idx) {
1146 tBTA_HL_MCL_CB* p_mcb;
1147 tBTA_HL_MDL_CB* p_dcb;
1148 tBTA_HL_MDL_CFG* p_mdl;
1149 bool mdl_in_use;
1150 bool found = false;
1151 uint8_t i, j, k;
1152
1153 for (i = start_mdl_cfg_idx; i < BTA_HL_NUM_MDL_CFGS; i++) {
1154 mdl_in_use = false;
1155 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1156 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1157 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, j);
1158 if (p_mcb->in_use &&
1159 !memcmp(p_mdl->peer_bd_addr, p_mcb->bd_addr, BD_ADDR_LEN)) {
1160 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
1161 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, j, k);
1162
1163 if (p_dcb->in_use && p_mdl->mdl_id == p_dcb->mdl_id) {
1164 mdl_in_use = true;
1165 break;
1166 }
1167 }
1168 }
1169
1170 if (mdl_in_use) {
1171 break;
1172 }
1173 }
1174
1175 if (!mdl_in_use) {
1176 *p_mdl_cfg_idx = i;
1177 found = true;
1178 break;
1179 }
1180 }
1181
1182 return found;
1183 }
1184
1185 /*******************************************************************************
1186 *
1187 * Function bta_hl_find_mdl_cfg_idx
1188 *
1189 * Description This function finds an available MDL configuration index
1190 *
1191 * Returns bool - true found
1192 * false not found
1193 *
1194 ******************************************************************************/
bta_hl_find_avail_mdl_cfg_idx(uint8_t app_idx,UNUSED_ATTR uint8_t mcl_idx,uint8_t * p_mdl_cfg_idx)1195 bool bta_hl_find_avail_mdl_cfg_idx(uint8_t app_idx, UNUSED_ATTR uint8_t mcl_idx,
1196 uint8_t* p_mdl_cfg_idx) {
1197 tBTA_HL_MDL_CFG *p_mdl, *p_mdl1, *p_mdl2;
1198 uint8_t i;
1199 bool found = false;
1200 uint8_t first_mdl_cfg_idx, second_mdl_cfg_idx, older_mdl_cfg_idx;
1201 bool done;
1202
1203 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1204 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1205 if (!p_mdl->active) {
1206 /* found an unused space to store mdl cfg*/
1207 found = true;
1208 *p_mdl_cfg_idx = i;
1209 break;
1210 }
1211 }
1212
1213 if (!found) {
1214 /* all available mdl cfg spaces are in use so we need to find the mdl cfg
1215 which is
1216 not currently in use and has the the oldest time stamp to remove*/
1217
1218 found = true;
1219 if (bta_hl_find_non_active_mdl_cfg(app_idx, 0, &first_mdl_cfg_idx)) {
1220 if (bta_hl_find_non_active_mdl_cfg(
1221 app_idx, (uint8_t)(first_mdl_cfg_idx + 1), &second_mdl_cfg_idx)) {
1222 done = false;
1223 while (!done) {
1224 p_mdl1 = BTA_HL_GET_MDL_CFG_PTR(app_idx, first_mdl_cfg_idx);
1225 p_mdl2 = BTA_HL_GET_MDL_CFG_PTR(app_idx, second_mdl_cfg_idx);
1226
1227 if (p_mdl1->time < p_mdl2->time) {
1228 older_mdl_cfg_idx = first_mdl_cfg_idx;
1229 } else {
1230 older_mdl_cfg_idx = second_mdl_cfg_idx;
1231 }
1232
1233 if (bta_hl_find_non_active_mdl_cfg(app_idx,
1234 (uint8_t)(second_mdl_cfg_idx + 1),
1235 &second_mdl_cfg_idx)) {
1236 first_mdl_cfg_idx = older_mdl_cfg_idx;
1237 } else {
1238 done = true;
1239 }
1240 }
1241
1242 *p_mdl_cfg_idx = older_mdl_cfg_idx;
1243
1244 } else {
1245 *p_mdl_cfg_idx = first_mdl_cfg_idx;
1246 }
1247
1248 } else {
1249 found = false;
1250 }
1251 }
1252
1253 #if (BTA_HL_DEBUG == TRUE)
1254 if (!found) {
1255 APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_cfg_idx found=%d mdl_cfg_idx=%d ",
1256 found, *p_mdl_cfg_idx);
1257 }
1258 #endif
1259
1260 return found;
1261 }
1262
1263 /*******************************************************************************
1264 *
1265 * Function bta_hl_find_mdl_cfg_idx
1266 *
1267 * Description This function finds the MDL configuration index based on
1268 * the MDL ID
1269 *
1270 * Returns bool - true found
1271 * false not found
1272 *
1273 ******************************************************************************/
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)1274 bool bta_hl_find_mdl_cfg_idx(uint8_t app_idx, uint8_t mcl_idx,
1275 tBTA_HL_MDL_ID mdl_id, uint8_t* p_mdl_cfg_idx) {
1276 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1277 tBTA_HL_MDL_CFG* p_mdl;
1278 uint8_t i;
1279 bool found = false;
1280
1281 *p_mdl_cfg_idx = 0;
1282 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1283 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1284 if (p_mdl->active)
1285 APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx: mdl_id =%d, p_mdl->mdl_id=%d",
1286 mdl_id, p_mdl->mdl_id);
1287 if (p_mdl->active &&
1288 (!memcmp(p_mcb->bd_addr, p_mdl->peer_bd_addr, BD_ADDR_LEN)) &&
1289 (p_mdl->mdl_id == mdl_id)) {
1290 found = true;
1291 *p_mdl_cfg_idx = i;
1292 break;
1293 }
1294 }
1295
1296 #if (BTA_HL_DEBUG == TRUE)
1297 if (!found) {
1298 APPL_TRACE_DEBUG("bta_hl_find_mdl_cfg_idx found=%d mdl_cfg_idx=%d ", found,
1299 i);
1300 }
1301 #endif
1302
1303 return found;
1304 }
1305
1306 /*******************************************************************************
1307 *
1308 * Function bta_hl_get_cur_time
1309 *
1310 * Description This function get the cuurent time value
1311 *
1312 * Returns bool - true found
1313 * false not found
1314 *
1315 ******************************************************************************/
bta_hl_get_cur_time(uint8_t app_idx,uint8_t * p_cur_time)1316 bool bta_hl_get_cur_time(uint8_t app_idx, uint8_t* p_cur_time) {
1317 tBTA_HL_MDL_CFG* p_mdl;
1318 uint8_t i, j, time_latest, time;
1319 bool found = false, result = true;
1320
1321 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1322 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1323 if (p_mdl->active) {
1324 found = true;
1325 time_latest = p_mdl->time;
1326 for (j = (i + 1); j < BTA_HL_NUM_MDL_CFGS; j++) {
1327 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, j);
1328 if (p_mdl->active) {
1329 time = p_mdl->time;
1330 if (time > time_latest) {
1331 time_latest = time;
1332 }
1333 }
1334 }
1335 break;
1336 }
1337 }
1338
1339 if (found) {
1340 if (time_latest < BTA_HL_MAX_TIME) {
1341 *p_cur_time = time_latest + 1;
1342 } else {
1343 /* need to wrap around */
1344 result = false;
1345 }
1346 } else {
1347 *p_cur_time = BTA_HL_MIN_TIME;
1348 }
1349
1350 #if (BTA_HL_DEBUG == TRUE)
1351 if (!result) {
1352 APPL_TRACE_DEBUG("bta_hl_get_cur_time result=%s cur_time=%d",
1353 (result ? "OK" : "FAIL"), *p_cur_time);
1354 }
1355 #endif
1356
1357 return result;
1358 }
1359
1360 /*******************************************************************************
1361 *
1362 * Function bta_hl_sort_cfg_time_idx
1363 *
1364 * Description This function sort the mdl configuration idx stored in array a
1365 * based on decending time value
1366 *
1367 * Returns bool - true found
1368 * false not found
1369 *
1370 ******************************************************************************/
bta_hl_sort_cfg_time_idx(uint8_t app_idx,uint8_t * a,uint8_t n)1371 void bta_hl_sort_cfg_time_idx(uint8_t app_idx, uint8_t* a, uint8_t n) {
1372 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1373 uint8_t temp_time, temp_idx;
1374 int16_t i, j;
1375 for (i = 1; i < n; ++i) {
1376 temp_idx = a[i];
1377 temp_time = p_acb->mdl_cfg[temp_idx].time;
1378 j = i - 1;
1379 while ((j >= 0) && (temp_time < p_acb->mdl_cfg[a[j]].time)) {
1380 a[j + 1] = a[j];
1381 --j;
1382 }
1383 a[j + 1] = temp_idx;
1384 }
1385 }
1386
1387 /*******************************************************************************
1388 *
1389 * Function bta_hl_compact_mdl_cfg_time
1390 *
1391 * Description This function finds the MDL configuration index based on
1392 * the MDL ID
1393 *
1394 * Returns bool - true found
1395 * false not found
1396 *
1397 ******************************************************************************/
bta_hl_compact_mdl_cfg_time(uint8_t app_idx,uint8_t mdep_id)1398 void bta_hl_compact_mdl_cfg_time(uint8_t app_idx, uint8_t mdep_id) {
1399 tBTA_HL_MDL_CFG* p_mdl;
1400 uint8_t i, time_min, cnt = 0;
1401 uint8_t s_arr[BTA_HL_NUM_MDL_CFGS];
1402
1403 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1404 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1405 if (p_mdl->active) {
1406 s_arr[cnt] = i;
1407 cnt++;
1408 }
1409 }
1410
1411 #if (BTA_HL_DEBUG == TRUE)
1412 APPL_TRACE_DEBUG("bta_hl_compact_mdl_cfg_time cnt=%d ", cnt);
1413 #endif
1414
1415 if (cnt) {
1416 bta_hl_sort_cfg_time_idx(app_idx, s_arr, cnt);
1417 time_min = BTA_HL_MIN_TIME;
1418 for (i = 0; i < cnt; i++) {
1419 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, s_arr[i]);
1420 p_mdl->time = time_min + i;
1421 bta_hl_co_save_mdl(mdep_id, s_arr[i], p_mdl);
1422 }
1423 }
1424 }
1425
1426 /*******************************************************************************
1427 *
1428 * Function bta_hl_is_mdl_exsit_in_mcl
1429 *
1430 * Description This function checks whether the MDL ID
1431 * has already existed in teh MCL or not
1432 *
1433 * Returns bool - true exist
1434 * false does not exist
1435 *
1436 ******************************************************************************/
bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx,BD_ADDR bd_addr,tBTA_HL_MDL_ID mdl_id)1437 bool bta_hl_is_mdl_exsit_in_mcl(uint8_t app_idx, BD_ADDR bd_addr,
1438 tBTA_HL_MDL_ID mdl_id) {
1439 tBTA_HL_MDL_CFG* p_mdl;
1440 bool found = false;
1441 uint8_t i;
1442
1443 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1444 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1445 if (p_mdl->active && !memcmp(p_mdl->peer_bd_addr, bd_addr, BD_ADDR_LEN)) {
1446 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
1447 if (p_mdl->mdl_id == mdl_id) {
1448 found = true;
1449 break;
1450 }
1451 } else {
1452 found = true;
1453 break;
1454 }
1455 }
1456 }
1457
1458 return found;
1459 }
1460
1461 /*******************************************************************************
1462 *
1463 * Function bta_hl_delete_mdl_cfg
1464 *
1465 * Description This function delete the specified MDL ID
1466 *
1467 * Returns bool - true Success
1468 * false Failed
1469 *
1470 ******************************************************************************/
bta_hl_delete_mdl_cfg(uint8_t app_idx,BD_ADDR bd_addr,tBTA_HL_MDL_ID mdl_id)1471 bool bta_hl_delete_mdl_cfg(uint8_t app_idx, BD_ADDR bd_addr,
1472 tBTA_HL_MDL_ID mdl_id) {
1473 tBTA_HL_MDL_CFG* p_mdl;
1474 bool success = false;
1475 uint8_t i;
1476
1477 for (i = 0; i < BTA_HL_NUM_MDL_CFGS; i++) {
1478 p_mdl = BTA_HL_GET_MDL_CFG_PTR(app_idx, i);
1479 if (p_mdl->active && !memcmp(p_mdl->peer_bd_addr, bd_addr, BD_ADDR_LEN)) {
1480 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
1481 if (p_mdl->mdl_id == mdl_id) {
1482 bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
1483 memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
1484 success = true;
1485 break;
1486 }
1487 } else {
1488 bta_hl_co_delete_mdl(p_mdl->local_mdep_id, i);
1489 memset(p_mdl, 0, sizeof(tBTA_HL_MDL_CFG));
1490 success = true;
1491 }
1492 }
1493 }
1494
1495 return success;
1496 }
1497
1498 /*******************************************************************************
1499 *
1500 * Function bta_hl_is_mdl_value_valid
1501 *
1502 *
1503 * Description This function checks the specified MDL ID is in valid range.
1504 *
1505 * Returns bool - true Success
1506 * false Failed
1507 *
1508 * note: mdl_id range 0x0000 reserved,
1509 * 0x0001-oxFEFF dynamic range,
1510 * 0xFF00-0xFFFE reserved,
1511 * 0xFFFF indicates all MDLs (for delete operation only)
1512 *
1513 ******************************************************************************/
bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id)1514 bool bta_hl_is_mdl_value_valid(tBTA_HL_MDL_ID mdl_id) {
1515 bool status = true;
1516
1517 if (mdl_id != BTA_HL_DELETE_ALL_MDL_IDS) {
1518 if (mdl_id != 0) {
1519 if (mdl_id > BTA_HL_MAX_MDL_VAL) {
1520 status = false;
1521 }
1522 } else {
1523 status = false;
1524 }
1525 }
1526
1527 return status;
1528 }
1529
1530 /*******************************************************************************
1531 *
1532 * Function bta_hl_find_mdep_cfg_idx
1533 *
1534 * Description This function finds the MDEP configuration index based
1535 * on the local MDEP ID
1536 *
1537 * Returns bool - true found
1538 * false not found
1539 *
1540 ******************************************************************************/
bta_hl_find_mdep_cfg_idx(uint8_t app_idx,tBTA_HL_MDEP_ID local_mdep_id,uint8_t * p_mdep_cfg_idx)1541 bool bta_hl_find_mdep_cfg_idx(uint8_t app_idx, tBTA_HL_MDEP_ID local_mdep_id,
1542 uint8_t* p_mdep_cfg_idx) {
1543 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1544 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
1545 bool found = false;
1546 uint8_t i;
1547
1548 for (i = 0; i < p_sup_feature->num_of_mdeps; i++) {
1549 if (p_sup_feature->mdep[i].mdep_id == local_mdep_id) {
1550 found = true;
1551 *p_mdep_cfg_idx = i;
1552 break;
1553 }
1554 }
1555
1556 #if (BTA_HL_DEBUG == TRUE)
1557 if (!found) {
1558 APPL_TRACE_DEBUG(
1559 "bta_hl_find_mdep_cfg_idx found=%d mdep_idx=%d local_mdep_id=%d ",
1560 found, i, local_mdep_id);
1561 }
1562 #endif
1563 return found;
1564 }
1565
1566 /*******************************************************************************
1567 *
1568 * Function bta_hl_find_rxtx_apdu_size
1569 *
1570 * Description This function finds the maximum APDU rx and tx sizes based on
1571 * the MDEP configuration data
1572 *
1573 * Returns void
1574 *
1575 ******************************************************************************/
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)1576 void bta_hl_find_rxtx_apdu_size(uint8_t app_idx, uint8_t mdep_cfg_idx,
1577 uint16_t* p_rx_apu_size,
1578 uint16_t* p_tx_apu_size) {
1579 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1580 tBTA_HL_MDEP_CFG* p_mdep_cfg;
1581 uint8_t i;
1582 uint16_t max_rx_apdu_size = 0, max_tx_apdu_size = 0;
1583
1584 p_mdep_cfg = &p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg;
1585
1586 for (i = 0; i < p_mdep_cfg->num_of_mdep_data_types; i++) {
1587 if (max_rx_apdu_size < p_mdep_cfg->data_cfg[i].max_rx_apdu_size) {
1588 max_rx_apdu_size = p_mdep_cfg->data_cfg[i].max_rx_apdu_size;
1589 }
1590
1591 if (max_tx_apdu_size < p_mdep_cfg->data_cfg[i].max_tx_apdu_size) {
1592 max_tx_apdu_size = p_mdep_cfg->data_cfg[i].max_tx_apdu_size;
1593 }
1594 }
1595
1596 *p_rx_apu_size = max_rx_apdu_size;
1597 *p_tx_apu_size = max_tx_apdu_size;
1598
1599 #if (BTA_HL_DEBUG == TRUE)
1600 APPL_TRACE_DEBUG(
1601 "bta_hl_find_rxtx_apdu_size max_rx_apdu_size=%d max_tx_apdu_size=%d ",
1602 max_rx_apdu_size, max_tx_apdu_size);
1603 #endif
1604 }
1605
1606 /*******************************************************************************
1607 *
1608 * Function bta_hl_validate_peer_cfg
1609 *
1610 * Description This function validates the peer DCH configuration
1611 *
1612 * Returns bool - true validation is successful
1613 * false validation failed
1614 *
1615 ******************************************************************************/
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)1616 bool bta_hl_validate_peer_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
1617 tBTA_HL_MDEP_ID peer_mdep_id,
1618 tBTA_HL_MDEP_ROLE peer_mdep_role,
1619 uint8_t sdp_idx) {
1620 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1621 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1622 tBTA_HL_SDP_REC* p_rec;
1623 bool peer_found = false;
1624 uint8_t i;
1625
1626 APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg sdp_idx=%d app_idx %d", sdp_idx,
1627 app_idx);
1628
1629 if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
1630 return true;
1631 }
1632
1633 p_rec = &p_mcb->sdp.sdp_rec[sdp_idx];
1634 for (i = 0; i < p_rec->num_mdeps; i++) {
1635 APPL_TRACE_DEBUG("mdep_id %d peer_mdep_id %d", p_rec->mdep_cfg[i].mdep_id,
1636 peer_mdep_id);
1637 APPL_TRACE_DEBUG("mdep_role %d peer_mdep_role %d",
1638 p_rec->mdep_cfg[i].mdep_role, peer_mdep_role)
1639 if ((p_rec->mdep_cfg[i].mdep_id == peer_mdep_id) &&
1640 (p_rec->mdep_cfg[i].mdep_role == peer_mdep_role)) {
1641 peer_found = true;
1642
1643 break;
1644 }
1645 }
1646
1647 #if (BTA_HL_DEBUG == TRUE)
1648 if (!peer_found) {
1649 APPL_TRACE_DEBUG("bta_hl_validate_peer_cfg failed num_mdeps=%d",
1650 p_rec->num_mdeps);
1651 }
1652 #endif
1653 return peer_found;
1654 }
1655
1656 /*******************************************************************************
1657 *
1658 * Function bta_hl_chk_local_cfg
1659 *
1660 * Description This function check whether the local DCH configuration is OK.
1661 *
1662 * Returns tBTA_HL_STATUS - OK - local DCH configuration is OK
1663 * NO_FIRST_RELIABLE - the streaming DCH
1664 * configuration is not OK and
1665 * it needs to use reliable
1666 * DCH configuration
1667 *
1668 ******************************************************************************/
bta_hl_chk_local_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdep_cfg_idx,tBTA_HL_DCH_CFG local_cfg)1669 tBTA_HL_STATUS bta_hl_chk_local_cfg(uint8_t app_idx, uint8_t mcl_idx,
1670 uint8_t mdep_cfg_idx,
1671 tBTA_HL_DCH_CFG local_cfg) {
1672 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1673 tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
1674
1675 if (mdep_cfg_idx &&
1676 (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role ==
1677 BTA_HL_MDEP_ROLE_SOURCE) &&
1678 (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) &&
1679 (local_cfg != BTA_HL_DCH_CFG_RELIABLE)) {
1680 status = BTA_HL_STATUS_NO_FIRST_RELIABLE;
1681 APPL_TRACE_ERROR("BTA_HL_STATUS_INVALID_DCH_CFG");
1682 }
1683
1684 return status;
1685 }
1686
1687 /*******************************************************************************
1688 *
1689 * Function bta_hl_validate_reconnect_params
1690 *
1691 * Description This function validates the reconnect parameters
1692 *
1693 * Returns bool - true validation is successful
1694 * false validation failed
1695 ******************************************************************************/
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)1696 bool bta_hl_validate_reconnect_params(uint8_t app_idx, uint8_t mcl_idx,
1697 tBTA_HL_API_DCH_RECONNECT* p_reconnect,
1698 uint8_t* p_mdep_cfg_idx,
1699 uint8_t* p_mdl_cfg_idx) {
1700 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1701 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
1702 uint8_t num_mdeps;
1703 uint8_t mdl_cfg_idx;
1704 bool local_mdep_id_found = false;
1705 bool mdl_cfg_found = false;
1706 bool status = false;
1707 uint8_t i, in_use_mdl_idx = 0;
1708
1709 #if (BTA_HL_DEBUG == TRUE)
1710 APPL_TRACE_DEBUG("bta_hl_validate_reconnect_params mdl_id=%d app_idx=%d",
1711 p_reconnect->mdl_id, app_idx);
1712 #endif
1713 if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
1714 &mdl_cfg_idx)) {
1715 mdl_cfg_found = true;
1716 }
1717
1718 #if (BTA_HL_DEBUG == TRUE)
1719 if (!mdl_cfg_found) {
1720 APPL_TRACE_DEBUG("mdl_cfg_found not found");
1721 }
1722 #endif
1723
1724 if (mdl_cfg_found) {
1725 num_mdeps = p_sup_feature->num_of_mdeps;
1726 for (i = 0; i < num_mdeps; i++) {
1727 if (p_sup_feature->mdep[i].mdep_id ==
1728 p_acb->mdl_cfg[mdl_cfg_idx].local_mdep_id) {
1729 local_mdep_id_found = true;
1730 *p_mdep_cfg_idx = i;
1731 *p_mdl_cfg_idx = mdl_cfg_idx;
1732 break;
1733 }
1734 }
1735 }
1736
1737 #if (BTA_HL_DEBUG == TRUE)
1738 if (!local_mdep_id_found) {
1739 APPL_TRACE_DEBUG("local_mdep_id not found");
1740 }
1741 #endif
1742
1743 if (local_mdep_id_found) {
1744 if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect->mdl_id,
1745 &in_use_mdl_idx)) {
1746 status = true;
1747 } else {
1748 APPL_TRACE_ERROR("mdl_id=%d is curreltly in use", p_reconnect->mdl_id);
1749 }
1750 }
1751
1752 #if (BTA_HL_DEBUG == TRUE)
1753 if (!status) {
1754 APPL_TRACE_DEBUG(
1755 "Reconnect validation failed local_mdep_id found=%d mdl_cfg_idx "
1756 "found=%d in_use_mdl_idx=%d ",
1757 local_mdep_id_found, mdl_cfg_found, in_use_mdl_idx);
1758 }
1759 #endif
1760 return status;
1761 }
1762
1763 /*******************************************************************************
1764 *
1765 * Function bta_hl_find_avail_mcl_idx
1766 *
1767 * Returns bool - true found
1768 * false not found
1769 *
1770 ******************************************************************************/
bta_hl_find_avail_mcl_idx(uint8_t app_idx,uint8_t * p_mcl_idx)1771 bool bta_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
1772 bool found = false;
1773 uint8_t i;
1774
1775 for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
1776 if (!bta_hl_cb.acb[app_idx].mcb[i].in_use) {
1777 found = true;
1778 *p_mcl_idx = i;
1779 break;
1780 }
1781 }
1782
1783 #if (BTA_HL_DEBUG == TRUE)
1784 if (!found) {
1785 APPL_TRACE_DEBUG("bta_hl_find_avail_mcl_idx found=%d idx=%d", found, i);
1786 }
1787 #endif
1788 return found;
1789 }
1790
1791 /*******************************************************************************
1792 *
1793 * Function bta_hl_find_avail_mdl_idx
1794 *
1795 * Description This function finds an available MDL control block index
1796 *
1797 * Returns bool - true found
1798 * false not found
1799 *
1800 ******************************************************************************/
bta_hl_find_avail_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint8_t * p_mdl_idx)1801 bool bta_hl_find_avail_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
1802 uint8_t* p_mdl_idx) {
1803 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1804 bool found = false;
1805 uint8_t i;
1806
1807 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
1808 if (!p_mcb->mdl[i].in_use) {
1809 memset((void*)&p_mcb->mdl[i], 0, sizeof(tBTA_HL_MDL_CB));
1810 found = true;
1811 *p_mdl_idx = i;
1812 break;
1813 }
1814 }
1815
1816 #if (BTA_HL_DEBUG == TRUE)
1817 if (!found) {
1818 APPL_TRACE_DEBUG("bta_hl_find_avail_mdl_idx found=%d idx=%d", found, i);
1819 }
1820 #endif
1821 return found;
1822 }
1823
1824 /*******************************************************************************
1825 *
1826 * Function bta_hl_is_a_duplicate_id
1827 *
1828 * Description This function finds the application has been used or not
1829 *
1830 * Returns bool - true the app_id is a duplicate ID
1831 * false not a duplicate ID
1832 ******************************************************************************/
bta_hl_is_a_duplicate_id(uint8_t app_id)1833 bool bta_hl_is_a_duplicate_id(uint8_t app_id) {
1834 bool is_duplicate = false;
1835 uint8_t i;
1836
1837 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1838 if (bta_hl_cb.acb[i].in_use && (bta_hl_cb.acb[i].app_id == app_id)) {
1839 is_duplicate = true;
1840
1841 break;
1842 }
1843 }
1844
1845 #if (BTA_HL_DEBUG == TRUE)
1846 if (is_duplicate) {
1847 APPL_TRACE_DEBUG("bta_hl_is_a_duplicate_id app_id=%d is_duplicate=%d",
1848 app_id, is_duplicate);
1849 }
1850 #endif
1851
1852 return is_duplicate;
1853 }
1854
1855 /*******************************************************************************
1856 *
1857 * Function bta_hl_find_avail_app_idx
1858 *
1859 * Description This function finds an available application control block index
1860 *
1861 * Returns bool - true found
1862 * false not found
1863 *
1864 ******************************************************************************/
bta_hl_find_avail_app_idx(uint8_t * p_idx)1865 bool bta_hl_find_avail_app_idx(uint8_t* p_idx) {
1866 bool found = false;
1867 uint8_t i;
1868
1869 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1870 if (!bta_hl_cb.acb[i].in_use) {
1871 found = true;
1872 *p_idx = i;
1873 break;
1874 }
1875 }
1876
1877 #if (BTA_HL_DEBUG == TRUE)
1878 if (!found) {
1879 APPL_TRACE_DEBUG("bta_hl_find_avail_app_idx found=%d app_idx=%d", found, i);
1880 }
1881 #endif
1882 return found;
1883 }
1884
1885 /*******************************************************************************
1886 *
1887 * Function bta_hl_app_update
1888 *
1889 * Description This function registers an HDP application MCAP and DP
1890 *
1891 * Returns tBTA_HL_STATUS -registration status
1892 *
1893 ******************************************************************************/
bta_hl_app_update(uint8_t app_id,bool is_register)1894 tBTA_HL_STATUS bta_hl_app_update(uint8_t app_id, bool is_register) {
1895 tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
1896 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(0);
1897 tMCA_CS mca_cs;
1898 uint8_t i, mdep_idx, num_of_mdeps;
1899 uint8_t mdep_counter = 0;
1900
1901 #if (BTA_HL_DEBUG == TRUE)
1902 APPL_TRACE_DEBUG("bta_hl_app_update app_id=%d", app_id);
1903 #endif
1904
1905 if (is_register) {
1906 if ((status == BTA_HL_STATUS_OK) &&
1907 bta_hl_co_get_num_of_mdep(app_id, &num_of_mdeps)) {
1908 for (i = 0; i < num_of_mdeps; i++) {
1909 mca_cs.type = MCA_TDEP_DATA;
1910 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
1911 mca_cs.p_data_cback = bta_hl_mcap_data_cback;
1912 /* Find the first available mdep index, and create a MDL Endpoint */
1913 // make a function later if needed
1914 for (mdep_idx = 1; mdep_idx < BTA_HL_NUM_MDEPS; mdep_idx++) {
1915 if (p_acb->sup_feature.mdep[mdep_idx].mdep_id == 0) {
1916 break; /* We found an available index */
1917 } else {
1918 mdep_counter++;
1919 }
1920 }
1921 /* If no available MDEPs, return error */
1922 if (mdep_idx == BTA_HL_NUM_MDEPS) {
1923 APPL_TRACE_ERROR("bta_hl_app_update: Out of MDEP IDs");
1924 status = BTA_HL_STATUS_MCAP_REG_FAIL;
1925 break;
1926 }
1927 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
1928 &(p_acb->sup_feature.mdep[mdep_idx].mdep_id),
1929 &mca_cs) == MCA_SUCCESS) {
1930 if (bta_hl_co_get_mdep_config(
1931 app_id, mdep_idx, mdep_counter,
1932 p_acb->sup_feature.mdep[mdep_idx].mdep_id,
1933 &p_acb->sup_feature.mdep[mdep_idx].mdep_cfg)) {
1934 p_acb->sup_feature.mdep[mdep_idx].ori_app_id = app_id;
1935 APPL_TRACE_DEBUG("mdep idx %d id %d ori_app_id %d num data type %d",
1936 mdep_idx,
1937 p_acb->sup_feature.mdep[mdep_idx].mdep_id,
1938 p_acb->sup_feature.mdep[mdep_idx].ori_app_id,
1939 p_acb->sup_feature.mdep[mdep_idx]
1940 .mdep_cfg.num_of_mdep_data_types);
1941 if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
1942 BTA_HL_MDEP_ROLE_SOURCE) {
1943 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
1944 } else if (p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role ==
1945 BTA_HL_MDEP_ROLE_SINK) {
1946 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
1947 } else {
1948 APPL_TRACE_ERROR(
1949 "bta_hl_app_registration: Invalid Role %d",
1950 p_acb->sup_feature.mdep[mdep_idx].mdep_cfg.mdep_role);
1951 status = BTA_HL_STATUS_MDEP_CO_FAIL;
1952 break;
1953 }
1954 } else {
1955 APPL_TRACE_ERROR("bta_hl_app_registration: Cfg callout failed");
1956 status = BTA_HL_STATUS_MDEP_CO_FAIL;
1957 break;
1958 }
1959 } else {
1960 APPL_TRACE_ERROR("bta_hl_app_registration: MCA_CreateDep failed");
1961 status = BTA_HL_STATUS_MCAP_REG_FAIL;
1962 break;
1963 }
1964 }
1965 p_acb->sup_feature.num_of_mdeps += num_of_mdeps;
1966 APPL_TRACE_DEBUG("num_of_mdeps %d", p_acb->sup_feature.num_of_mdeps);
1967
1968 if ((status == BTA_HL_STATUS_OK) &&
1969 (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
1970 p_acb->sup_feature.advertize_source_sdp =
1971 bta_hl_co_advrtise_source_sdp(app_id);
1972 }
1973
1974 if ((status == BTA_HL_STATUS_OK) &&
1975 (!bta_hl_co_get_echo_config(app_id, &p_acb->sup_feature.echo_cfg))) {
1976 status = BTA_HL_STATUS_ECHO_CO_FAIL;
1977 }
1978
1979 if ((status == BTA_HL_STATUS_OK) &&
1980 (!bta_hl_co_load_mdl_config(app_id, BTA_HL_NUM_MDL_CFGS,
1981 &p_acb->mdl_cfg[0]))) {
1982 status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
1983 }
1984 } else {
1985 status = BTA_HL_STATUS_MDEP_CO_FAIL;
1986 }
1987 } else {
1988 for (i = 1; i < BTA_HL_NUM_MDEPS; i++) {
1989 if (p_acb->sup_feature.mdep[i].ori_app_id == app_id) {
1990 APPL_TRACE_DEBUG("Found index %", i);
1991
1992 if (MCA_DeleteDep((tMCA_HANDLE)p_acb->app_handle,
1993 (p_acb->sup_feature.mdep[i].mdep_id)) !=
1994 MCA_SUCCESS) {
1995 APPL_TRACE_ERROR("Error deregistering");
1996 status = BTA_HL_STATUS_MCAP_REG_FAIL;
1997 return status;
1998 }
1999 memset(&p_acb->sup_feature.mdep[i], 0, sizeof(tBTA_HL_MDEP));
2000 }
2001 }
2002 }
2003
2004 if (status == BTA_HL_STATUS_OK) {
2005 /* Register/Update MDEP(s) in SDP Record */
2006 status = bta_hl_sdp_update(app_id);
2007 }
2008 /* else do cleanup */
2009
2010 return status;
2011 }
2012
2013 /*******************************************************************************
2014 *
2015 * Function bta_hl_app_registration
2016 *
2017 * Description This function registers an HDP application MCAP and DP
2018 *
2019 * Returns tBTA_HL_STATUS -registration status
2020 *
2021 ******************************************************************************/
bta_hl_app_registration(uint8_t app_idx)2022 tBTA_HL_STATUS bta_hl_app_registration(uint8_t app_idx) {
2023 tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
2024 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2025 tMCA_REG reg;
2026 tMCA_CS mca_cs;
2027 uint8_t i, num_of_mdeps;
2028 uint8_t mdep_counter = 0;
2029
2030 #if (BTA_HL_DEBUG == TRUE)
2031 APPL_TRACE_DEBUG("bta_hl_app_registration app_idx=%d", app_idx);
2032 #endif
2033
2034 reg.ctrl_psm = p_acb->ctrl_psm;
2035 reg.data_psm = p_acb->data_psm;
2036 reg.sec_mask = p_acb->sec_mask;
2037 reg.rsp_tout = BTA_HL_MCAP_RSP_TOUT;
2038
2039 p_acb->app_handle =
2040 (tBTA_HL_APP_HANDLE)MCA_Register(®, bta_hl_mcap_ctrl_cback);
2041 if (p_acb->app_handle != 0) {
2042 mca_cs.type = MCA_TDEP_ECHO;
2043 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2044 mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2045
2046 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2047 &(p_acb->sup_feature.mdep[0].mdep_id),
2048 &mca_cs) == MCA_SUCCESS) {
2049 if (p_acb->sup_feature.mdep[0].mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
2050 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2051 APPL_TRACE_ERROR("BAD MDEP ID for echo test mdep_id=%d",
2052 p_acb->sup_feature.mdep[0].mdep_id);
2053 }
2054 } else {
2055 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2056 APPL_TRACE_ERROR("MCA_CreateDep for echo test(mdep_id=0) failed");
2057 }
2058
2059 if ((status == BTA_HL_STATUS_OK) &&
2060 bta_hl_co_get_num_of_mdep(p_acb->app_id, &num_of_mdeps)) {
2061 p_acb->sup_feature.num_of_mdeps = num_of_mdeps + 1;
2062
2063 for (i = 1; i < p_acb->sup_feature.num_of_mdeps; i++) {
2064 mca_cs.type = MCA_TDEP_DATA;
2065 mca_cs.max_mdl = BTA_HL_NUM_MDLS_PER_MDEP;
2066 mca_cs.p_data_cback = bta_hl_mcap_data_cback;
2067
2068 if (MCA_CreateDep((tMCA_HANDLE)p_acb->app_handle,
2069 &(p_acb->sup_feature.mdep[i].mdep_id),
2070 &mca_cs) == MCA_SUCCESS) {
2071 if (bta_hl_co_get_mdep_config(p_acb->app_id, i, mdep_counter,
2072 p_acb->sup_feature.mdep[i].mdep_id,
2073 &p_acb->sup_feature.mdep[i].mdep_cfg)) {
2074 if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
2075 BTA_HL_MDEP_ROLE_SOURCE) {
2076 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
2077 } else if (p_acb->sup_feature.mdep[i].mdep_cfg.mdep_role ==
2078 BTA_HL_MDEP_ROLE_SINK) {
2079 p_acb->sup_feature.app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
2080 } else {
2081 status = BTA_HL_STATUS_MDEP_CO_FAIL;
2082 break;
2083 }
2084 p_acb->sup_feature.mdep[i].ori_app_id = p_acb->app_id;
2085 APPL_TRACE_DEBUG("index %d ori_app_id %d", i,
2086 p_acb->sup_feature.mdep[i].ori_app_id);
2087 } else {
2088 status = BTA_HL_STATUS_MDEP_CO_FAIL;
2089 break;
2090 }
2091 } else {
2092 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2093 break;
2094 }
2095 }
2096
2097 if ((status == BTA_HL_STATUS_OK) &&
2098 (p_acb->sup_feature.app_role_mask == BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
2099 /* this is a source only applciation */
2100 p_acb->sup_feature.advertize_source_sdp =
2101 bta_hl_co_advrtise_source_sdp(p_acb->app_id);
2102 }
2103
2104 if ((status == BTA_HL_STATUS_OK) &&
2105 (!bta_hl_co_get_echo_config(p_acb->app_id,
2106 &p_acb->sup_feature.echo_cfg))) {
2107 status = BTA_HL_STATUS_ECHO_CO_FAIL;
2108 }
2109
2110 if ((status == BTA_HL_STATUS_OK) &&
2111 (!bta_hl_co_load_mdl_config(p_acb->app_id, BTA_HL_NUM_MDL_CFGS,
2112 &p_acb->mdl_cfg[0]))) {
2113 status = BTA_HL_STATUS_MDL_CFG_CO_FAIL;
2114 }
2115 } else {
2116 status = BTA_HL_STATUS_MDEP_CO_FAIL;
2117 }
2118 } else {
2119 status = BTA_HL_STATUS_MCAP_REG_FAIL;
2120 }
2121
2122 if (status == BTA_HL_STATUS_OK) {
2123 status = bta_hl_sdp_register(app_idx);
2124 }
2125
2126 return status;
2127 }
2128
2129 /*******************************************************************************
2130 *
2131 * Function bta_hl_discard_data
2132 *
2133 * Description This function discard an HDP event
2134 *
2135 * Returns void
2136 *
2137 ******************************************************************************/
bta_hl_discard_data(uint16_t event,tBTA_HL_DATA * p_data)2138 void bta_hl_discard_data(uint16_t event, tBTA_HL_DATA* p_data) {
2139 #if (BTA_HL_DEBUG == TRUE)
2140 APPL_TRACE_ERROR("BTA HL Discard event=%s", bta_hl_evt_code(event));
2141
2142 #endif
2143
2144 switch (event) {
2145 case BTA_HL_API_SEND_DATA_EVT:
2146 break;
2147
2148 case BTA_HL_MCA_RCV_DATA_EVT:
2149 osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt);
2150 break;
2151
2152 default:
2153 /*Nothing to free*/
2154 break;
2155 }
2156 }
2157
2158 /*******************************************************************************
2159 *
2160 * Function bta_hl_save_mdl_cfg
2161 *
2162 * Description This function saves the MDL configuration
2163 *
2164 * Returns void
2165 *
2166 ******************************************************************************/
bta_hl_save_mdl_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)2167 void bta_hl_save_mdl_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
2168 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2169 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2170 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2171 uint8_t mdl_cfg_idx;
2172 tBTA_HL_MDL_ID mdl_id;
2173 bool found = true;
2174 tBTA_HL_MDL_CFG mdl_cfg;
2175 tBTA_HL_MDEP* p_mdep_cfg;
2176 tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
2177 uint8_t time_val = 0;
2178 mdl_id = p_dcb->mdl_id;
2179 if (!bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, mdl_id, &mdl_cfg_idx)) {
2180 if (!bta_hl_find_avail_mdl_cfg_idx(app_idx, mcl_idx, &mdl_cfg_idx)) {
2181 APPL_TRACE_ERROR("No space to save the MDL config");
2182 found = false; /*no space available*/
2183 }
2184 }
2185
2186 if (found) {
2187 bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
2188 if (!bta_hl_get_cur_time(app_idx, &time_val)) {
2189 bta_hl_compact_mdl_cfg_time(app_idx, p_dcb->local_mdep_id);
2190 bta_hl_get_cur_time(app_idx, &time_val);
2191 }
2192 mdl_cfg.active = true;
2193 mdl_cfg.time = time_val;
2194 mdl_cfg.mdl_id = p_dcb->mdl_id;
2195 mdl_cfg.dch_mode = p_dcb->dch_mode;
2196 mdl_cfg.mtu = l2cap_cfg.mtu;
2197 mdl_cfg.fcs = l2cap_cfg.fcs;
2198
2199 bdcpy(mdl_cfg.peer_bd_addr, p_mcb->bd_addr);
2200 mdl_cfg.local_mdep_id = p_dcb->local_mdep_id;
2201 p_mdep_cfg = &p_acb->sup_feature.mdep[p_dcb->local_mdep_cfg_idx];
2202 mdl_cfg.local_mdep_role = p_mdep_cfg->mdep_cfg.mdep_role;
2203 memcpy(&p_acb->mdl_cfg[mdl_cfg_idx], &mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
2204 bta_hl_co_save_mdl(mdl_cfg.local_mdep_id, mdl_cfg_idx, &mdl_cfg);
2205 }
2206
2207 #if (BTA_HL_DEBUG == TRUE)
2208 if (found) {
2209 if (p_dcb->mtu != l2cap_cfg.mtu) {
2210 APPL_TRACE_WARNING(
2211 "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from "
2212 "l2cap mtu=%d",
2213 p_dcb->mtu, l2cap_cfg.mtu);
2214 }
2215 APPL_TRACE_DEBUG("bta_hl_save_mdl_cfg saved=%d", found);
2216 APPL_TRACE_DEBUG("Saved. L2cap cfg mdl_id=%d mtu=%d fcs=%d dch_mode=%d",
2217 mdl_cfg.mdl_id, mdl_cfg.mtu, mdl_cfg.fcs,
2218 mdl_cfg.dch_mode);
2219 }
2220 #endif
2221 }
2222
2223 /*******************************************************************************
2224 *
2225 * Function bta_hl_set_dch_chan_cfg
2226 *
2227 * Description This function setups the L2CAP DCH channel configuration
2228 *
2229 * Returns void
2230 ******************************************************************************/
bta_hl_set_dch_chan_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx,tBTA_HL_DATA * p_data)2231 void bta_hl_set_dch_chan_cfg(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
2232 tBTA_HL_DATA* p_data) {
2233 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2234 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2235 uint8_t l2cap_mode = L2CAP_FCR_ERTM_MODE;
2236 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
2237 uint8_t local_mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
2238
2239 switch (p_dcb->dch_oper) {
2240 case BTA_HL_DCH_OP_LOCAL_RECONNECT:
2241 case BTA_HL_DCH_OP_REMOTE_RECONNECT:
2242 if (p_dcb->dch_mode == BTA_HL_DCH_MODE_STREAMING)
2243 l2cap_mode = L2CAP_FCR_STREAM_MODE;
2244 break;
2245 case BTA_HL_DCH_OP_LOCAL_OPEN:
2246 if (p_data->mca_evt.mca_data.create_cfm.cfg == BTA_HL_DCH_CFG_STREAMING)
2247 l2cap_mode = L2CAP_FCR_STREAM_MODE;
2248 break;
2249 case BTA_HL_DCH_OP_REMOTE_OPEN:
2250 if (p_dcb->local_cfg == BTA_HL_DCH_CFG_STREAMING)
2251 l2cap_mode = L2CAP_FCR_STREAM_MODE;
2252 break;
2253 default:
2254 APPL_TRACE_ERROR("Invalid dch oper=%d for set dch chan cfg",
2255 p_dcb->dch_oper);
2256 break;
2257 }
2258 p_dcb->chnl_cfg.fcr_opt.mode = l2cap_mode;
2259 p_dcb->chnl_cfg.fcr_opt.mps = bta_hl_set_mps(p_dcb->max_rx_apdu_size);
2260 p_dcb->chnl_cfg.fcr_opt.tx_win_sz = bta_hl_set_tx_win_size(
2261 p_dcb->max_rx_apdu_size, p_dcb->chnl_cfg.fcr_opt.mps);
2262 p_dcb->chnl_cfg.fcr_opt.max_transmit = BTA_HL_L2C_MAX_TRANSMIT;
2263 p_dcb->chnl_cfg.fcr_opt.rtrans_tout = BTA_HL_L2C_RTRANS_TOUT;
2264 p_dcb->chnl_cfg.fcr_opt.mon_tout = BTA_HL_L2C_MON_TOUT;
2265
2266 p_dcb->chnl_cfg.user_rx_buf_size =
2267 bta_hl_set_user_rx_buf_size(p_dcb->max_rx_apdu_size);
2268 p_dcb->chnl_cfg.user_tx_buf_size =
2269 bta_hl_set_user_tx_buf_size(p_dcb->max_tx_apdu_size);
2270 p_dcb->chnl_cfg.fcr_rx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
2271 p_dcb->chnl_cfg.fcr_tx_buf_size = L2CAP_INVALID_ERM_BUF_SIZE;
2272 p_dcb->chnl_cfg.data_mtu = p_dcb->max_rx_apdu_size;
2273
2274 p_dcb->chnl_cfg.fcs = BTA_HL_MCA_NO_FCS;
2275 if (local_mdep_cfg_idx != BTA_HL_ECHO_TEST_MDEP_CFG_IDX) {
2276 if (p_sup_feature->mdep[local_mdep_cfg_idx].mdep_cfg.mdep_role ==
2277 BTA_HL_MDEP_ROLE_SOURCE) {
2278 p_dcb->chnl_cfg.fcs = BTA_HL_DEFAULT_SOURCE_FCS;
2279 }
2280 } else {
2281 p_dcb->chnl_cfg.fcs = BTA_HL_MCA_USE_FCS;
2282 }
2283
2284 #if (BTA_HL_DEBUG == TRUE)
2285 APPL_TRACE_DEBUG("L2CAP Params l2cap_mode[3-ERTM 4-STREAM]=%d", l2cap_mode);
2286 APPL_TRACE_DEBUG("Use FCS =%s mtu=%d",
2287 ((p_dcb->chnl_cfg.fcs & 1) ? "YES" : "NO"),
2288 p_dcb->chnl_cfg.data_mtu);
2289 APPL_TRACE_DEBUG(
2290 "tx_win_sz=%d, max_transmit=%d, rtrans_tout=%d, mon_tout=%d, mps=%d",
2291 p_dcb->chnl_cfg.fcr_opt.tx_win_sz, p_dcb->chnl_cfg.fcr_opt.max_transmit,
2292 p_dcb->chnl_cfg.fcr_opt.rtrans_tout, p_dcb->chnl_cfg.fcr_opt.mon_tout,
2293 p_dcb->chnl_cfg.fcr_opt.mps);
2294
2295 APPL_TRACE_DEBUG(
2296 "USER rx_buf_size=%d, tx_buf_size=%d, FCR rx_buf_size=%d, tx_buf_size=%d",
2297 p_dcb->chnl_cfg.user_rx_buf_size, p_dcb->chnl_cfg.user_tx_buf_size,
2298 p_dcb->chnl_cfg.fcr_rx_buf_size, p_dcb->chnl_cfg.fcr_tx_buf_size);
2299
2300 #endif
2301 }
2302
2303 /*******************************************************************************
2304 *
2305 * Function bta_hl_get_l2cap_cfg
2306 *
2307 * Description This function get the current L2CAP channel configuration
2308 *
2309 * Returns bool - true - operation is successful
2310 ******************************************************************************/
bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd,tBTA_HL_L2CAP_CFG_INFO * p_cfg)2311 bool bta_hl_get_l2cap_cfg(tBTA_HL_MDL_HANDLE mdl_hnd,
2312 tBTA_HL_L2CAP_CFG_INFO* p_cfg) {
2313 bool success = false;
2314 uint16_t lcid;
2315 tL2CAP_CFG_INFO* p_our_cfg;
2316 tL2CAP_CH_CFG_BITS our_cfg_bits;
2317 tL2CAP_CFG_INFO* p_peer_cfg;
2318 tL2CAP_CH_CFG_BITS peer_cfg_bits;
2319
2320 lcid = MCA_GetL2CapChannel((tMCA_DL)mdl_hnd);
2321 if (lcid && L2CA_GetCurrentConfig(lcid, &p_our_cfg, &our_cfg_bits,
2322 &p_peer_cfg, &peer_cfg_bits)) {
2323 p_cfg->fcs = BTA_HL_MCA_NO_FCS;
2324 if (our_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
2325 p_cfg->fcs |= p_our_cfg->fcs;
2326 } else {
2327 p_cfg->fcs = BTA_HL_MCA_USE_FCS;
2328 }
2329
2330 if (p_cfg->fcs != BTA_HL_MCA_USE_FCS) {
2331 if (peer_cfg_bits & L2CAP_CH_CFG_MASK_FCS) {
2332 p_cfg->fcs |= p_peer_cfg->fcs;
2333 } else {
2334 p_cfg->fcs = BTA_HL_MCA_USE_FCS;
2335 }
2336 }
2337
2338 p_cfg->mtu = 0;
2339 if (peer_cfg_bits & L2CAP_CH_CFG_MASK_MTU) {
2340 p_cfg->mtu = p_peer_cfg->mtu;
2341 } else {
2342 p_cfg->mtu = L2CAP_DEFAULT_MTU;
2343 }
2344 success = true;
2345 } else {
2346 p_cfg->mtu = L2CAP_DEFAULT_MTU;
2347 p_cfg->fcs = BTA_HL_L2C_NO_FCS;
2348 }
2349
2350 #if (BTA_HL_DEBUG == TRUE)
2351 if (!success) {
2352 APPL_TRACE_DEBUG("bta_hl_get_l2cap_cfg success=%d mdl=%d lcid=%d", success,
2353 mdl_hnd, lcid);
2354 APPL_TRACE_DEBUG("l2cap mtu=%d fcs=%d", p_cfg->mtu, p_cfg->fcs);
2355 }
2356 #endif
2357
2358 return success;
2359 }
2360
2361 /*******************************************************************************
2362 *
2363 * Function bta_hl_validate_chan_cfg
2364 *
2365 * Description This function validates the L2CAP channel configuration
2366 *
2367 * Returns bool - true - validation is successful
2368 ******************************************************************************/
bta_hl_validate_chan_cfg(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)2369 bool bta_hl_validate_chan_cfg(uint8_t app_idx, uint8_t mcl_idx,
2370 uint8_t mdl_idx) {
2371 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2372 tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2373 bool success = false;
2374 uint8_t mdl_cfg_idx = 0;
2375 tBTA_HL_L2CAP_CFG_INFO l2cap_cfg;
2376 bool get_l2cap_result, get_mdl_result;
2377
2378 get_l2cap_result = bta_hl_get_l2cap_cfg(p_dcb->mdl_handle, &l2cap_cfg);
2379 get_mdl_result =
2380 bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_dcb->mdl_id, &mdl_cfg_idx);
2381
2382 if (get_l2cap_result && get_mdl_result) {
2383 if ((p_acb->mdl_cfg[mdl_cfg_idx].mtu <= l2cap_cfg.mtu) &&
2384 (p_acb->mdl_cfg[mdl_cfg_idx].fcs == l2cap_cfg.fcs) &&
2385 (p_acb->mdl_cfg[mdl_cfg_idx].dch_mode == p_dcb->dch_mode)) {
2386 success = true;
2387 }
2388 }
2389
2390 #if (BTA_HL_DEBUG == TRUE)
2391
2392 if (p_dcb->mtu != l2cap_cfg.mtu) {
2393 APPL_TRACE_WARNING(
2394 "MCAP and L2CAP peer mtu size out of sync from MCAP mtu=%d from l2cap "
2395 "mtu=%d",
2396 p_dcb->mtu, l2cap_cfg.mtu);
2397 }
2398
2399 if (!success) {
2400 APPL_TRACE_DEBUG(
2401 "bta_hl_validate_chan_cfg success=%d app_idx=%d mcl_idx=%d mdl_idx=%d",
2402 success, app_idx, mcl_idx, mdl_idx);
2403 APPL_TRACE_DEBUG("Cur. L2cap cfg mtu=%d fcs=%d dch_mode=%d", l2cap_cfg.mtu,
2404 l2cap_cfg.fcs, p_dcb->dch_mode);
2405 APPL_TRACE_DEBUG("From saved: L2cap cfg mtu=%d fcs=%d dch_mode=%d",
2406 p_acb->mdl_cfg[mdl_cfg_idx].mtu,
2407 p_acb->mdl_cfg[mdl_cfg_idx].fcs,
2408 p_acb->mdl_cfg[mdl_cfg_idx].dch_mode);
2409 }
2410 #endif
2411
2412 return success;
2413 }
2414
2415 /*******************************************************************************
2416 *
2417 * Function bta_hl_is_cong_on
2418 *
2419 * Description This function checks whether the congestion condition is on.
2420 *
2421 * Returns bool - true DCH is congested
2422 * false not congested
2423 *
2424 ******************************************************************************/
bta_hl_is_cong_on(uint8_t app_id,BD_ADDR bd_addr,tBTA_HL_MDL_ID mdl_id)2425 bool bta_hl_is_cong_on(uint8_t app_id, BD_ADDR bd_addr, tBTA_HL_MDL_ID mdl_id)
2426
2427 {
2428 tBTA_HL_MDL_CB* p_dcb;
2429 uint8_t app_idx = 0, mcl_idx, mdl_idx;
2430 bool cong_status = true;
2431
2432 if (bta_hl_find_app_idx(app_id, &app_idx)) {
2433 if (bta_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
2434 if (bta_hl_find_mdl_idx(app_idx, mcl_idx, mdl_id, &mdl_idx)) {
2435 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2436 cong_status = p_dcb->cong;
2437 }
2438 }
2439 }
2440
2441 return cong_status;
2442 }
2443
2444 /*******************************************************************************
2445 *
2446 * Function bta_hl_check_cch_close
2447 *
2448 * Description This function checks whether there is a pending CCH close
2449 * request or not
2450 *
2451 * Returns void
2452 ******************************************************************************/
bta_hl_check_cch_close(uint8_t app_idx,uint8_t mcl_idx,tBTA_HL_DATA * p_data,bool check_dch_setup)2453 void bta_hl_check_cch_close(uint8_t app_idx, uint8_t mcl_idx,
2454 tBTA_HL_DATA* p_data, bool check_dch_setup) {
2455 tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2456 tBTA_HL_MDL_CB* p_dcb;
2457 uint8_t mdl_idx;
2458
2459 #if (BTA_HL_DEBUG == TRUE)
2460 APPL_TRACE_DEBUG("bta_hl_check_cch_close cch_close_dch_oper=%d",
2461 p_mcb->cch_close_dch_oper);
2462 #endif
2463
2464 if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) {
2465 if (check_dch_setup &&
2466 bta_hl_find_dch_setup_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2467 p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2468 if (!p_mcb->rsp_tout) {
2469 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_ABORT;
2470
2471 if (!p_dcb->abort_oper) {
2472 p_dcb->abort_oper |= BTA_HL_ABORT_CCH_CLOSE_MASK;
2473 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT,
2474 p_data);
2475 }
2476 } else {
2477 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
2478 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
2479 BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
2480 }
2481 } else if (bta_hl_find_an_active_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2482 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_CLOSE;
2483 bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT,
2484 p_data);
2485 } else {
2486 p_mcb->cch_close_dch_oper = BTA_HL_CCH_CLOSE_OP_DCH_NONE;
2487 bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_EVT, p_data);
2488 }
2489 }
2490 }
2491
2492 /*******************************************************************************
2493 *
2494 * Function bta_hl_clean_app
2495 *
2496 * Description Cleans up the HDP application resources and control block
2497 *
2498 * Returns void
2499 *
2500 ******************************************************************************/
bta_hl_clean_app(uint8_t app_idx)2501 void bta_hl_clean_app(uint8_t app_idx) {
2502 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2503 int i, num_act_apps = 0;
2504
2505 #if (BTA_HL_DEBUG == TRUE)
2506 APPL_TRACE_DEBUG("bta_hl_clean_app");
2507 #endif
2508 MCA_Deregister((tMCA_HANDLE)p_acb->app_handle);
2509
2510 if (p_acb->sdp_handle) SDP_DeleteRecord(p_acb->sdp_handle);
2511
2512 memset((void*)p_acb, 0, sizeof(tBTA_HL_APP_CB));
2513
2514 /* check any application is still active */
2515 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
2516 p_acb = BTA_HL_GET_APP_CB_PTR(i);
2517 if (p_acb->in_use) num_act_apps++;
2518 }
2519
2520 if (!num_act_apps) {
2521 bta_sys_remove_uuid(UUID_SERVCLASS_HDP_PROFILE);
2522 }
2523 }
2524
2525 /*******************************************************************************
2526 *
2527 * Function bta_hl_check_deregistration
2528 *
2529 * Description This function checks whether there is a pending deregistration
2530 * request or not
2531 *
2532 * Returns void
2533 ******************************************************************************/
bta_hl_check_deregistration(uint8_t app_idx,tBTA_HL_DATA * p_data)2534 void bta_hl_check_deregistration(uint8_t app_idx, tBTA_HL_DATA* p_data) {
2535 tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2536 tBTA_HL_MCL_CB* p_mcb;
2537 uint8_t mcl_idx;
2538 tBTA_HL evt_data;
2539
2540 #if (BTA_HL_DEBUG == TRUE)
2541 APPL_TRACE_DEBUG("bta_hl_check_deregistration");
2542 #endif
2543
2544 if (p_acb->deregistering) {
2545 if (bta_hl_find_an_in_use_mcl_idx(app_idx, &mcl_idx)) {
2546 p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2547 if (p_mcb->cch_oper != BTA_HL_CCH_OP_LOCAL_CLOSE) {
2548 if (p_mcb->cch_state == BTA_HL_CCH_OPENING_ST)
2549 p_mcb->force_close_local_cch_opening = true;
2550 p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_CLOSE;
2551 APPL_TRACE_DEBUG("p_mcb->force_close_local_cch_opening=%d",
2552 p_mcb->force_close_local_cch_opening);
2553 bta_hl_check_cch_close(app_idx, mcl_idx, p_data, true);
2554 }
2555 } else {
2556 /* all cchs are closed */
2557 evt_data.dereg_cfm.app_handle = p_acb->app_handle;
2558 evt_data.dereg_cfm.app_id = p_data->api_dereg.app_id;
2559 evt_data.dereg_cfm.status = BTA_HL_STATUS_OK;
2560 p_acb->p_cback(BTA_HL_DEREGISTER_CFM_EVT, (tBTA_HL*)&evt_data);
2561 bta_hl_clean_app(app_idx);
2562 bta_hl_check_disable(p_data);
2563 }
2564 }
2565 }
2566
2567 /*******************************************************************************
2568 *
2569 * Function bta_hl_check_disable
2570 *
2571 * Description This function checks whether there is a pending disable
2572 * request or not
2573 *
2574 * Returns void
2575 *
2576 ******************************************************************************/
bta_hl_check_disable(tBTA_HL_DATA * p_data)2577 void bta_hl_check_disable(tBTA_HL_DATA* p_data) {
2578 tBTA_HL_CB* p_cb = &bta_hl_cb;
2579 tBTA_HL_APP_CB* p_acb;
2580 uint8_t app_idx;
2581 tBTA_HL_CTRL evt_data;
2582
2583 #if (BTA_HL_DEBUG == TRUE)
2584 APPL_TRACE_DEBUG("bta_hl_check_disable");
2585 #endif
2586
2587 if (bta_hl_cb.disabling) {
2588 if (bta_hl_find_an_in_use_app_idx(&app_idx)) {
2589 p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2590 if (!p_acb->deregistering) {
2591 p_acb->deregistering = true;
2592 bta_hl_check_deregistration(app_idx, p_data);
2593 }
2594 } else {
2595 /* all apps are deregistered */
2596 bta_sys_deregister(BTA_ID_HL);
2597 evt_data.disable_cfm.status = BTA_HL_STATUS_OK;
2598 if (p_cb->p_ctrl_cback)
2599 p_cb->p_ctrl_cback(BTA_HL_CTRL_DISABLE_CFM_EVT,
2600 (tBTA_HL_CTRL*)&evt_data);
2601 memset((void*)p_cb, 0, sizeof(tBTA_HL_CB));
2602 }
2603 }
2604 }
2605
2606 /*******************************************************************************
2607 *
2608 * Function bta_hl_build_abort_cfm
2609 *
2610 * Description This function builds the abort confirmation event data
2611 *
2612 * Returns None
2613 *
2614 ******************************************************************************/
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)2615 void bta_hl_build_abort_cfm(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
2616 tBTA_HL_MCL_HANDLE mcl_handle,
2617 tBTA_HL_STATUS status) {
2618 p_evt_data->dch_abort_cfm.status = status;
2619 p_evt_data->dch_abort_cfm.mcl_handle = mcl_handle;
2620 p_evt_data->dch_abort_cfm.app_handle = app_handle;
2621 }
2622
2623 /*******************************************************************************
2624 *
2625 * Function bta_hl_build_abort_ind
2626 *
2627 * Description This function builds the abort indication event data
2628 *
2629 * Returns None
2630 *
2631 ******************************************************************************/
bta_hl_build_abort_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle)2632 void bta_hl_build_abort_ind(tBTA_HL* p_evt_data, tBTA_HL_APP_HANDLE app_handle,
2633 tBTA_HL_MCL_HANDLE mcl_handle) {
2634 p_evt_data->dch_abort_ind.mcl_handle = mcl_handle;
2635 p_evt_data->dch_abort_ind.app_handle = app_handle;
2636 }
2637 /*******************************************************************************
2638 *
2639 * Function bta_hl_build_close_cfm
2640 *
2641 * Description This function builds the close confirmation event data
2642 *
2643 * Returns None
2644 *
2645 ******************************************************************************/
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)2646 void bta_hl_build_dch_close_cfm(tBTA_HL* p_evt_data,
2647 tBTA_HL_APP_HANDLE app_handle,
2648 tBTA_HL_MCL_HANDLE mcl_handle,
2649 tBTA_HL_MDL_HANDLE mdl_handle,
2650 tBTA_HL_STATUS status) {
2651 p_evt_data->dch_close_cfm.status = status;
2652 p_evt_data->dch_close_cfm.mdl_handle = mdl_handle;
2653 p_evt_data->dch_close_cfm.mcl_handle = mcl_handle;
2654 p_evt_data->dch_close_cfm.app_handle = app_handle;
2655 }
2656
2657 /*******************************************************************************
2658 *
2659 * Function bta_hl_build_dch_close_ind
2660 *
2661 * Description This function builds the close indication event data
2662 *
2663 * Returns None
2664 *
2665 ******************************************************************************/
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)2666 void bta_hl_build_dch_close_ind(tBTA_HL* p_evt_data,
2667 tBTA_HL_APP_HANDLE app_handle,
2668 tBTA_HL_MCL_HANDLE mcl_handle,
2669 tBTA_HL_MDL_HANDLE mdl_handle,
2670 bool intentional) {
2671 p_evt_data->dch_close_ind.mdl_handle = mdl_handle;
2672 p_evt_data->dch_close_ind.mcl_handle = mcl_handle;
2673 p_evt_data->dch_close_ind.app_handle = app_handle;
2674 p_evt_data->dch_close_ind.intentional = intentional;
2675 }
2676
2677 /*******************************************************************************
2678 *
2679 * Function bta_hl_build_send_data_cfm
2680 *
2681 * Description This function builds the send data confirmation event data
2682 *
2683 * Returns None
2684 *
2685 ******************************************************************************/
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)2686 void bta_hl_build_send_data_cfm(tBTA_HL* p_evt_data,
2687 tBTA_HL_APP_HANDLE app_handle,
2688 tBTA_HL_MCL_HANDLE mcl_handle,
2689 tBTA_HL_MDL_HANDLE mdl_handle,
2690 tBTA_HL_STATUS status) {
2691 p_evt_data->dch_send_data_cfm.mdl_handle = mdl_handle;
2692 p_evt_data->dch_send_data_cfm.mcl_handle = mcl_handle;
2693 p_evt_data->dch_send_data_cfm.app_handle = app_handle;
2694 p_evt_data->dch_send_data_cfm.status = status;
2695 }
2696
2697 /*******************************************************************************
2698 *
2699 * Function bta_hl_build_rcv_data_ind
2700 *
2701 * Description This function builds the received data indication event data
2702 *
2703 * Returns None
2704 *
2705 ******************************************************************************/
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)2706 void bta_hl_build_rcv_data_ind(tBTA_HL* p_evt_data,
2707 tBTA_HL_APP_HANDLE app_handle,
2708 tBTA_HL_MCL_HANDLE mcl_handle,
2709 tBTA_HL_MDL_HANDLE mdl_handle) {
2710 p_evt_data->dch_rcv_data_ind.mdl_handle = mdl_handle;
2711 p_evt_data->dch_rcv_data_ind.mcl_handle = mcl_handle;
2712 p_evt_data->dch_rcv_data_ind.app_handle = app_handle;
2713 }
2714
2715 /*******************************************************************************
2716 *
2717 * Function bta_hl_build_cch_open_cfm
2718 *
2719 * Description This function builds the CCH open confirmation event data
2720 *
2721 * Returns None
2722 *
2723 ******************************************************************************/
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,BD_ADDR bd_addr,tBTA_HL_STATUS status)2724 void bta_hl_build_cch_open_cfm(tBTA_HL* p_evt_data, uint8_t app_id,
2725 tBTA_HL_APP_HANDLE app_handle,
2726 tBTA_HL_MCL_HANDLE mcl_handle, BD_ADDR bd_addr,
2727 tBTA_HL_STATUS status) {
2728 p_evt_data->cch_open_cfm.app_id = app_id;
2729 p_evt_data->cch_open_cfm.app_handle = app_handle;
2730 p_evt_data->cch_open_cfm.mcl_handle = mcl_handle;
2731 bdcpy(p_evt_data->cch_open_cfm.bd_addr, bd_addr);
2732 p_evt_data->cch_open_cfm.status = status;
2733 APPL_TRACE_DEBUG("bta_hl_build_cch_open_cfm: status=%d", status);
2734 }
2735
2736 /*******************************************************************************
2737 *
2738 * Function bta_hl_build_cch_open_ind
2739 *
2740 * Description This function builds the CCH open indication event data
2741 *
2742 * Returns None
2743 *
2744 ******************************************************************************/
bta_hl_build_cch_open_ind(tBTA_HL * p_evt_data,tBTA_HL_APP_HANDLE app_handle,tBTA_HL_MCL_HANDLE mcl_handle,BD_ADDR bd_addr)2745 void bta_hl_build_cch_open_ind(tBTA_HL* p_evt_data,
2746 tBTA_HL_APP_HANDLE app_handle,
2747 tBTA_HL_MCL_HANDLE mcl_handle, BD_ADDR 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 bdcpy(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,BD_ADDR 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, BD_ADDR bd_addr,
2830 tBTA_HL_SDP* p_sdp, tBTA_HL_STATUS status)
2831
2832 {
2833 APPL_TRACE_DEBUG("bta_hl_build_sdp_query_cfm: app_id = %d, app_handle=%d",
2834 app_id, app_handle);
2835 p_evt_data->sdp_query_cfm.app_id = app_id;
2836 p_evt_data->sdp_query_cfm.app_handle = app_handle;
2837 bdcpy(p_evt_data->sdp_query_cfm.bd_addr, bd_addr);
2838 p_evt_data->sdp_query_cfm.p_sdp = p_sdp;
2839 p_evt_data->sdp_query_cfm.status = status;
2840 }
2841
2842 /*******************************************************************************
2843 *
2844 * Function bta_hl_build_delete_mdl_cfm
2845 *
2846 * Description This function builds the delete MDL confirmation event data
2847 *
2848 * Returns None
2849 *
2850 ******************************************************************************/
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)2851 void bta_hl_build_delete_mdl_cfm(tBTA_HL* p_evt_data,
2852 tBTA_HL_APP_HANDLE app_handle,
2853 tBTA_HL_MCL_HANDLE mcl_handle,
2854 tBTA_HL_MDL_ID mdl_id, tBTA_HL_STATUS status)
2855
2856 {
2857 p_evt_data->delete_mdl_cfm.mcl_handle = mcl_handle;
2858 p_evt_data->delete_mdl_cfm.app_handle = app_handle;
2859 p_evt_data->delete_mdl_cfm.mdl_id = mdl_id;
2860 p_evt_data->delete_mdl_cfm.status = status;
2861 }
2862
2863 /*******************************************************************************
2864 *
2865 * Function bta_hl_build_echo_test_cfm
2866 *
2867 * Description This function builds the echo test confirmation event data
2868 *
2869 * Returns None
2870 *
2871 ******************************************************************************/
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)2872 void bta_hl_build_echo_test_cfm(tBTA_HL* p_evt_data,
2873 tBTA_HL_APP_HANDLE app_handle,
2874 tBTA_HL_MCL_HANDLE mcl_handle,
2875 tBTA_HL_STATUS status) {
2876 p_evt_data->echo_test_cfm.mcl_handle = mcl_handle;
2877 p_evt_data->echo_test_cfm.app_handle = app_handle;
2878 p_evt_data->echo_test_cfm.status = status;
2879 }
2880
2881 /*****************************************************************************
2882 * Debug Functions
2883 ****************************************************************************/
2884 #if (BTA_HL_DEBUG == TRUE)
2885
2886 /*******************************************************************************
2887 *
2888 * Function bta_hl_status_code
2889 *
2890 * Description get the status string pointer
2891 *
2892 * Returns char * - status string pointer
2893 *
2894 ******************************************************************************/
bta_hl_status_code(tBTA_HL_STATUS status)2895 const char* bta_hl_status_code(tBTA_HL_STATUS status) {
2896 switch (status) {
2897 case BTA_HL_STATUS_OK:
2898 return "BTA_HL_STATUS_OK";
2899 case BTA_HL_STATUS_FAIL:
2900 return "BTA_HL_STATUS_FAIL";
2901 case BTA_HL_STATUS_ABORTED:
2902 return "BTA_HL_STATUS_ABORTED";
2903 case BTA_HL_STATUS_NO_RESOURCE:
2904 return "BTA_HL_STATUS_NO_RESOURCE";
2905 case BTA_HL_STATUS_LAST_ITEM:
2906 return "BTA_HL_STATUS_LAST_ITEM";
2907 case BTA_HL_STATUS_DUPLICATE_APP_ID:
2908 return "BTA_HL_STATUS_DUPLICATE_APP_ID";
2909 case BTA_HL_STATUS_INVALID_APP_HANDLE:
2910 return "BTA_HL_STATUS_INVALID_APP_HANDLE";
2911 case BTA_HL_STATUS_INVALID_MCL_HANDLE:
2912 return "BTA_HL_STATUS_INVALID_MCL_HANDLE";
2913 case BTA_HL_STATUS_MCAP_REG_FAIL:
2914 return "BTA_HL_STATUS_MCAP_REG_FAIL";
2915 case BTA_HL_STATUS_MDEP_CO_FAIL:
2916 return "BTA_HL_STATUS_MDEP_CO_FAIL";
2917 case BTA_HL_STATUS_ECHO_CO_FAIL:
2918 return "BTA_HL_STATUS_ECHO_CO_FAIL";
2919 case BTA_HL_STATUS_MDL_CFG_CO_FAIL:
2920 return "BTA_HL_STATUS_MDL_CFG_CO_FAIL";
2921 case BTA_HL_STATUS_SDP_NO_RESOURCE:
2922 return "BTA_HL_STATUS_SDP_NO_RESOURCE";
2923 case BTA_HL_STATUS_SDP_FAIL:
2924 return "BTA_HL_STATUS_SDP_FAIL";
2925 case BTA_HL_STATUS_NO_CCH:
2926 return "BTA_HL_STATUS_NO_CCH";
2927 case BTA_HL_STATUS_NO_MCL:
2928 return "BTA_HL_STATUS_NO_MCL";
2929
2930 case BTA_HL_STATUS_NO_FIRST_RELIABLE:
2931 return "BTA_HL_STATUS_NO_FIRST_RELIABLE";
2932 case BTA_HL_STATUS_INVALID_DCH_CFG:
2933 return "BTA_HL_STATUS_INVALID_DCH_CFG";
2934 case BTA_HL_STATUS_INVALID_BD_ADDR:
2935 return "BTA_HL_STATUS_INVALID_BD_ADDR";
2936 case BTA_HL_STATUS_INVALID_RECONNECT_CFG:
2937 return "BTA_HL_STATUS_INVALID_RECONNECT_CFG";
2938 case BTA_HL_STATUS_ECHO_TEST_BUSY:
2939 return "BTA_HL_STATUS_ECHO_TEST_BUSY";
2940 case BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID:
2941 return "BTA_HL_STATUS_INVALID_LOCAL_MDEP_ID";
2942 case BTA_HL_STATUS_INVALID_MDL_ID:
2943 return "BTA_HL_STATUS_INVALID_MDL_ID";
2944 case BTA_HL_STATUS_NO_MDL_ID_FOUND:
2945 return "BTA_HL_STATUS_NO_MDL_ID_FOUND";
2946 case BTA_HL_STATUS_DCH_BUSY:
2947 return "BTA_HL_STATUS_DCH_BUSY";
2948 default:
2949 return "Unknown status code";
2950 }
2951 }
2952 /*******************************************************************************
2953 *
2954 * Function bta_hl_evt_code
2955 *
2956 * Description Maps HL event code to the corresponding event string
2957 *
2958 * Returns string pointer for the associated event name
2959 *
2960 ******************************************************************************/
bta_hl_evt_code(tBTA_HL_INT_EVT evt_code)2961 const char* bta_hl_evt_code(tBTA_HL_INT_EVT evt_code) {
2962 switch (evt_code) {
2963 case BTA_HL_CCH_OPEN_EVT:
2964 return "BTA_HL_CCH_OPEN_EVT";
2965 case BTA_HL_CCH_SDP_OK_EVT:
2966 return "BTA_HL_CCH_SDP_OK_EVT";
2967 case BTA_HL_CCH_SDP_FAIL_EVT:
2968 return "BTA_HL_CCH_SDP_FAIL_EVT";
2969 case BTA_HL_MCA_CONNECT_IND_EVT:
2970 return "BTA_HL_MCA_CONNECT_IND_EVT";
2971 case BTA_HL_MCA_DISCONNECT_IND_EVT:
2972 return "BTA_HL_MCA_DISCONNECT_IND_EVT";
2973
2974 case BTA_HL_CCH_CLOSE_EVT:
2975 return "BTA_HL_CCH_CLOSE_EVT";
2976 case BTA_HL_CCH_CLOSE_CMPL_EVT:
2977 return "BTA_HL_CCH_CLOSE_CMPL_EVT";
2978 case BTA_HL_DCH_OPEN_EVT:
2979 return "BTA_HL_DCH_OPEN_EVT";
2980 case BTA_HL_MCA_CREATE_IND_EVT:
2981 return "BTA_HL_MCA_CREATE_IND_EVT";
2982 case BTA_HL_MCA_CREATE_CFM_EVT:
2983 return "BTA_HL_MCA_CREATE_CFM_EVT";
2984 case BTA_HL_MCA_OPEN_IND_EVT:
2985 return "BTA_HL_MCA_OPEN_IND_EVT";
2986 case BTA_HL_MCA_OPEN_CFM_EVT:
2987 return "BTA_HL_MCA_OPEN_CFM_EVT";
2988 case BTA_HL_DCH_CLOSE_EVT:
2989 return "BTA_HL_DCH_CLOSE_EVT";
2990 case BTA_HL_MCA_CLOSE_IND_EVT:
2991 return "BTA_HL_MCA_CLOSE_IND_EVT";
2992 case BTA_HL_MCA_CLOSE_CFM_EVT:
2993 return "BTA_HL_MCA_CLOSE_CFM_EVT";
2994 case BTA_HL_API_SEND_DATA_EVT:
2995 return "BTA_HL_API_SEND_DATA_EVT";
2996 case BTA_HL_MCA_RCV_DATA_EVT:
2997 return "BTA_HL_MCA_RCV_DATA_EVT";
2998 case BTA_HL_DCH_CLOSE_CMPL_EVT:
2999 return "BTA_HL_DCH_CLOSE_CMPL_EVT";
3000
3001 case BTA_HL_API_ENABLE_EVT:
3002 return "BTA_HL_API_ENABLE_EVT";
3003 case BTA_HL_API_DISABLE_EVT:
3004 return "BTA_HL_API_DISABLE_EVT";
3005 case BTA_HL_API_UPDATE_EVT:
3006 return "BTA_HL_API_UPDATE_EVT";
3007 case BTA_HL_API_REGISTER_EVT:
3008 return "BTA_HL_API_REGISTER_EVT";
3009 case BTA_HL_API_DEREGISTER_EVT:
3010 return "BTA_HL_API_DEREGISTER_EVT";
3011
3012 case BTA_HL_API_CCH_OPEN_EVT:
3013 return "BTA_HL_API_CCH_OPEN_EVT";
3014
3015 case BTA_HL_API_CCH_CLOSE_EVT:
3016 return "BTA_HL_API_CCH_CLOSE_EVT";
3017 case BTA_HL_API_DCH_OPEN_EVT:
3018 return "BTA_HL_API_DCH_OPEN_EVT";
3019
3020 case BTA_HL_API_DCH_RECONNECT_EVT:
3021 return "BTA_HL_API_DCH_RECONNECT_EVT";
3022 case BTA_HL_API_DCH_CLOSE_EVT:
3023 return "BTA_HL_API_DCH_CLOSE_EVT";
3024 case BTA_HL_API_DELETE_MDL_EVT:
3025 return "BTA_HL_API_DELETE_MDL_EVT";
3026 case BTA_HL_API_DCH_ABORT_EVT:
3027 return "BTA_HL_API_DCH_ABORT_EVT";
3028
3029 case BTA_HL_DCH_RECONNECT_EVT:
3030 return "BTA_HL_DCH_RECONNECT_EVT";
3031 case BTA_HL_DCH_SDP_INIT_EVT:
3032 return "BTA_HL_DCH_SDP_INIT_EVT";
3033 case BTA_HL_DCH_SDP_FAIL_EVT:
3034 return "BTA_HL_DCH_SDP_FAIL_EVT";
3035 case BTA_HL_API_DCH_ECHO_TEST_EVT:
3036 return "BTA_HL_API_DCH_ECHO_TEST_EVT";
3037 case BTA_HL_DCH_CLOSE_ECHO_TEST_EVT:
3038 return "BTA_HL_DCH_CLOSE_ECHO_TEST_EVT";
3039 case BTA_HL_MCA_RECONNECT_IND_EVT:
3040 return "BTA_HL_MCA_RECONNECT_IND_EVT";
3041 case BTA_HL_MCA_RECONNECT_CFM_EVT:
3042 return "BTA_HL_MCA_RECONNECT_CFM_EVT";
3043 case BTA_HL_API_DCH_CREATE_RSP_EVT:
3044 return "BTA_HL_API_DCH_CREATE_RSP_EVT";
3045 case BTA_HL_DCH_ABORT_EVT:
3046 return "BTA_HL_DCH_ABORT_EVT";
3047 case BTA_HL_MCA_ABORT_IND_EVT:
3048 return "BTA_HL_MCA_ABORT_IND_EVT";
3049 case BTA_HL_MCA_ABORT_CFM_EVT:
3050 return "BTA_HL_MCA_ABORT_CFM_EVT";
3051 case BTA_HL_MCA_DELETE_IND_EVT:
3052 return "BTA_HL_MCA_DELETE_IND_EVT";
3053 case BTA_HL_MCA_DELETE_CFM_EVT:
3054 return "BTA_HL_MCA_DELETE_CFM_EVT";
3055 case BTA_HL_MCA_CONG_CHG_EVT:
3056 return "BTA_HL_MCA_CONG_CHG_EVT";
3057 case BTA_HL_CI_GET_TX_DATA_EVT:
3058 return "BTA_HL_CI_GET_TX_DATA_EVT";
3059 case BTA_HL_CI_PUT_RX_DATA_EVT:
3060 return "BTA_HL_CI_PUT_RX_DATA_EVT";
3061 case BTA_HL_CI_GET_ECHO_DATA_EVT:
3062 return "BTA_HL_CI_GET_ECHO_DATA_EVT";
3063 case BTA_HL_DCH_ECHO_TEST_EVT:
3064 return "BTA_HL_DCH_ECHO_TEST_EVT";
3065 case BTA_HL_CI_PUT_ECHO_DATA_EVT:
3066 return "BTA_HL_CI_PUT_ECHO_DATA_EVT";
3067 case BTA_HL_API_SDP_QUERY_EVT:
3068 return "BTA_HL_API_SDP_QUERY_EVT";
3069 case BTA_HL_SDP_QUERY_OK_EVT:
3070 return "BTA_HL_SDP_QUERY_OK_EVT";
3071 case BTA_HL_SDP_QUERY_FAIL_EVT:
3072 return "BTA_HL_SDP_QUERY_FAIL_EVT";
3073 case BTA_HL_MCA_RSP_TOUT_IND_EVT:
3074 return "BTA_HL_MCA_RSP_TOUT_IND_EVT";
3075
3076 default:
3077 return "Unknown HL event code";
3078 }
3079 }
3080
3081 #endif /* Debug Functions */
3082 #endif // HL_INCLUDED
3083