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