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