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 contains the HeaLth device profile (HL) action functions for
22 *  the state machine.
23 *
24 ******************************************************************************/
25
26#include <string.h>
27
28#include "bt_target.h"
29#if (HL_INCLUDED == TRUE)
30
31#include "bt_common.h"
32#include "bta_hl_api.h"
33#include "bta_hl_int.h"
34#include "bta_sys.h"
35#include "mca_api.h"
36#include "mca_defs.h"
37#include "osi/include/osi.h"
38#include "port_api.h"
39#include "sdp_api.h"
40#include "utl.h"
41
42/*****************************************************************************
43 *  Local Function prototypes
44 ****************************************************************************/
45#if (BTA_HL_DEBUG == TRUE)
46static const char* bta_hl_mcap_evt_code(uint8_t evt_code);
47static const char* bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code);
48static const char* bta_hl_cback_evt_code(uint8_t evt_code);
49#endif
50static void bta_hl_sdp_cback(uint8_t sdp_op, uint8_t app_idx, uint8_t mcl_idx,
51                             uint8_t mdl_idx, uint16_t status);
52static void bta_hl_sdp_cback0(uint16_t status);
53static void bta_hl_sdp_cback1(uint16_t status);
54static void bta_hl_sdp_cback2(uint16_t status);
55static void bta_hl_sdp_cback3(uint16_t status);
56static void bta_hl_sdp_cback4(uint16_t status);
57static void bta_hl_sdp_cback5(uint16_t status);
58static void bta_hl_sdp_cback6(uint16_t status);
59
60static tSDP_DISC_CMPL_CB* const bta_hl_sdp_cback_arr[] = {
61    bta_hl_sdp_cback0, bta_hl_sdp_cback1, bta_hl_sdp_cback2, bta_hl_sdp_cback3,
62    bta_hl_sdp_cback4, bta_hl_sdp_cback5, bta_hl_sdp_cback6};
63
64/*******************************************************************************
65 *
66 * Function         bta_hl_dch_mca_cong_change
67 *
68 * Description      Action routine for processing congestion change notification
69 *
70 * Returns          void
71 *
72 ******************************************************************************/
73void bta_hl_dch_mca_cong_change(uint8_t app_idx, uint8_t mcl_idx,
74                                uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
75  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
76  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
77  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
78  tMCA_CONG_CHG* p_cong_chg = &p_data->mca_evt.mca_data.cong_chg;
79  tBTA_HL evt_data;
80
81#if (BTA_HL_DEBUG == TRUE)
82  APPL_TRACE_DEBUG("bta_hl_dch_mca_cong_change mdl_id=%d cong=%d",
83                   p_cong_chg->mdl_id, p_cong_chg->cong);
84#endif
85  evt_data.dch_cong_ind.cong = p_dcb->cong = p_cong_chg->cong;
86  evt_data.dch_cong_ind.mdl_handle = p_dcb->mdl_handle;
87  evt_data.dch_cong_ind.mcl_handle = p_mcb->mcl_handle;
88  evt_data.dch_cong_ind.app_handle = p_acb->app_handle;
89
90  p_acb->p_cback(BTA_HL_CONG_CHG_IND_EVT, (tBTA_HL*)&evt_data);
91}
92
93/*******************************************************************************
94 *
95 * Function         bta_hl_dch_echo_test
96 *
97 * Description      Action routine for processing echo test request
98 *
99 * Returns          void
100 *
101 ******************************************************************************/
102void bta_hl_dch_echo_test(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
103                          UNUSED_ATTR tBTA_HL_DATA* p_data) {
104  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
105  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
106  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
107
108#if (BTA_HL_DEBUG == TRUE)
109  APPL_TRACE_DEBUG("bta_hl_dch_echo_test");
110#endif
111
112  p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_GET_ECHO_DATA;
113  p_dcb->cout_oper |= BTA_HL_CO_GET_ECHO_DATA_MASK;
114
115  bta_hl_co_get_echo_data(
116      p_acb->app_id, p_mcb->mcl_handle, p_dcb->p_echo_tx_pkt->len,
117      BTA_HL_GET_BUF_PTR(p_dcb->p_echo_tx_pkt), BTA_HL_CI_GET_ECHO_DATA_EVT);
118}
119/*******************************************************************************
120 *
121 * Function         bta_hl_dch_sdp_init
122 *
123 * Description      Action routine for processing DCH SDP initiation
124 *
125 * Returns          void
126 *
127 ******************************************************************************/
128void bta_hl_dch_sdp_init(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
129                         tBTA_HL_DATA* p_data) {
130  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
131  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
132
133#if (BTA_HL_DEBUG == TRUE)
134  APPL_TRACE_DEBUG("bta_hl_dch_sdp_init");
135#endif
136  if (p_mcb->sdp_oper == BTA_HL_SDP_OP_NONE) {
137    p_mcb->sdp_mdl_idx = mdl_idx;
138    if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) {
139      p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_OPEN_INIT;
140
141    } else {
142      p_mcb->sdp_oper = BTA_HL_SDP_OP_DCH_RECONNECT_INIT;
143    }
144
145    if (bta_hl_init_sdp(p_mcb->sdp_oper, app_idx, mcl_idx, mdl_idx) !=
146        BTA_HL_STATUS_OK) {
147      APPL_TRACE_ERROR("SDP INIT failed");
148      p_mcb->sdp_oper = BTA_HL_SDP_OP_NONE;
149      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT,
150                            p_data);
151    }
152  } else {
153    APPL_TRACE_ERROR("SDP in use");
154    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_SDP_FAIL_EVT,
155                          p_data);
156  }
157}
158
159/*******************************************************************************
160 *
161 * Function         bta_hl_dch_close_echo_test
162 *
163 * Description      Action routine for processing the closing of echo test
164 *
165 * Returns          void
166 *
167 ******************************************************************************/
168void bta_hl_dch_close_echo_test(uint8_t app_idx, uint8_t mcl_idx,
169                                uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
170  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
171
172#if (BTA_HL_DEBUG == TRUE)
173  APPL_TRACE_DEBUG("bta_hl_dch_close_echo_test");
174#endif
175
176  switch (p_dcb->echo_oper) {
177    case BTA_HL_ECHO_OP_DCH_CLOSE_CFM:
178    case BTA_HL_ECHO_OP_OPEN_IND:
179    case BTA_HL_ECHO_OP_ECHO_PKT:
180      p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST;
181      break;
182    case BTA_HL_ECHO_OP_MDL_CREATE_CFM:
183    case BTA_HL_ECHO_OP_DCH_OPEN_CFM:
184    case BTA_HL_ECHO_OP_LOOP_BACK:
185    default:
186      break;
187  }
188
189  if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) != MCA_SUCCESS) {
190    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
191                          p_data);
192  }
193}
194
195/*******************************************************************************
196 *
197 * Function         bta_hl_dch_mca_rcv_data
198 *
199 * Description      Action routine for processing the received data
200 *
201 * Returns          void
202 *
203 ******************************************************************************/
204void bta_hl_dch_mca_rcv_data(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
205                             tBTA_HL_DATA* p_data) {
206  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
207  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
208  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
209
210#if (BTA_HL_DEBUG == TRUE)
211  APPL_TRACE_DEBUG("bta_hl_dch_mca_rcv_data");
212#endif
213
214  if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
215    switch (p_dcb->echo_oper) {
216      case BTA_HL_ECHO_OP_ECHO_PKT:
217
218        if (MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle,
219                         p_data->mca_rcv_data_evt.p_pkt) != MCA_SUCCESS) {
220          osi_free_and_reset((void**)&p_data->mca_rcv_data_evt.p_pkt);
221          bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
222                                BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data);
223        }
224        break;
225      case BTA_HL_ECHO_OP_LOOP_BACK:
226
227        p_dcb->p_echo_rx_pkt = p_data->mca_rcv_data_evt.p_pkt;
228        p_dcb->echo_oper = BTA_HL_ECHO_OP_CI_PUT_ECHO_DATA;
229        p_dcb->cout_oper |= BTA_HL_CO_PUT_ECHO_DATA_MASK;
230        p_dcb->ci_put_echo_data_status = BTA_HL_STATUS_FAIL;
231
232        bta_hl_co_put_echo_data(p_acb->app_id, p_mcb->mcl_handle,
233                                p_dcb->p_echo_rx_pkt->len,
234                                BTA_HL_GET_BUF_PTR(p_dcb->p_echo_rx_pkt),
235                                BTA_HL_CI_PUT_ECHO_DATA_EVT);
236        break;
237      default:
238        APPL_TRACE_ERROR("Unknonw echo_oper=%d", p_dcb->echo_oper);
239        break;
240    }
241
242  } else {
243    p_dcb->cout_oper |= BTA_HL_CO_PUT_RX_DATA_MASK;
244    p_dcb->p_rx_pkt = p_data->mca_rcv_data_evt.p_pkt;
245
246    bta_hl_co_put_rx_data(
247        p_acb->app_id, p_dcb->mdl_handle, p_dcb->p_rx_pkt->len,
248        BTA_HL_GET_BUF_PTR(p_dcb->p_rx_pkt), BTA_HL_CI_PUT_RX_DATA_EVT);
249  }
250}
251
252/*******************************************************************************
253 *
254 * Function         bta_hl_dch_ci_put_echo_data
255 *
256 * Description      Action routine for processing the call-in of the
257 *                  put echo data event
258 *
259 * Returns          void
260 *
261 ******************************************************************************/
262void bta_hl_dch_ci_put_echo_data(uint8_t app_idx, uint8_t mcl_idx,
263                                 uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
264  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
265
266#if (BTA_HL_DEBUG == TRUE)
267  APPL_TRACE_DEBUG("bta_hl_dch_ci_put_echo_data");
268#endif
269
270  p_dcb->cout_oper &= ~BTA_HL_CO_PUT_ECHO_DATA_MASK;
271  osi_free_and_reset((void**)&p_dcb->p_echo_rx_pkt);
272  p_dcb->ci_put_echo_data_status = p_data->ci_get_put_echo_data.status;
273
274  p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_CLOSE_CFM;
275  bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
276                        BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data);
277}
278
279/*******************************************************************************
280 *
281 * Function         bta_hl_dch_ci_get_echo_data
282 *
283 * Description      Action routine for processing the call-in of the
284 *                  get echo data event
285 *
286 * Returns          void
287 *
288 ******************************************************************************/
289void bta_hl_dch_ci_get_echo_data(uint8_t app_idx, uint8_t mcl_idx,
290                                 uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
291  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
292  tBTA_HL_STATUS status;
293
294#if (BTA_HL_DEBUG == TRUE)
295  APPL_TRACE_DEBUG("bta_hl_dch_ci_get_echo_data");
296#endif
297
298  p_dcb->cout_oper &= ~BTA_HL_CO_GET_ECHO_DATA_MASK;
299
300  if (!p_dcb->abort_oper) {
301    status = p_data->ci_get_put_echo_data.status;
302    if (status == BTA_HL_STATUS_OK) {
303      p_dcb->echo_oper = BTA_HL_ECHO_OP_MDL_CREATE_CFM;
304      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_OPEN_EVT,
305                            p_data);
306    } else {
307      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
308                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
309    }
310  } else {
311    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
312                          p_data);
313  }
314}
315
316/*******************************************************************************
317 *
318 * Function         bta_hl_dch_ci_put_rx_data
319 *
320 * Description      Action routine for processing the call-in of the
321 *                  put rx data event
322 *
323 * Returns          void
324 *
325 ******************************************************************************/
326void bta_hl_dch_ci_put_rx_data(uint8_t app_idx, uint8_t mcl_idx,
327                               uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
328  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
329  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
330  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
331  tBTA_HL evt_data;
332
333#if (BTA_HL_DEBUG == TRUE)
334  APPL_TRACE_DEBUG("bta_hl_dch_ci_put_rx_data");
335#endif
336
337  p_dcb->cout_oper &= ~BTA_HL_CO_PUT_RX_DATA_MASK;
338  osi_free_and_reset((void**)&p_dcb->p_rx_pkt);
339  bta_hl_build_rcv_data_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
340                            p_dcb->mdl_handle);
341  p_acb->p_cback(BTA_HL_DCH_RCV_DATA_IND_EVT, (tBTA_HL*)&evt_data);
342  if (p_dcb->close_pending) {
343    if (!p_dcb->cout_oper) {
344      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT,
345                            p_data);
346    }
347  }
348}
349
350/*******************************************************************************
351 *
352 * Function         bta_hl_dch_ci_get_tx_data
353 *
354 * Description      Action routine for processing the call-in of the
355 *                  get tx data event
356 *
357 * Returns          void
358 *
359 ******************************************************************************/
360void bta_hl_dch_ci_get_tx_data(uint8_t app_idx, uint8_t mcl_idx,
361                               uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
362  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
363  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
364  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
365  tMCA_RESULT result;
366  tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
367  bool free_buf = false;
368  bool close_dch = false;
369  tBTA_HL evt_data;
370
371#if (BTA_HL_DEBUG == TRUE)
372  APPL_TRACE_DEBUG("bta_hl_dch_ci_get_tx_data");
373#endif
374
375  if (p_data != NULL) {
376    status = p_data->ci_get_put_data.status;
377    APPL_TRACE_WARNING("%s: status=%d", __func__, status);
378  }
379
380  p_dcb->cout_oper &= ~BTA_HL_CO_GET_TX_DATA_MASK;
381
382  if (p_dcb->close_pending) {
383    status = BTA_HL_STATUS_FAIL;
384    free_buf = true;
385
386    if (!p_dcb->cout_oper) {
387      close_dch = true;
388    }
389  } else if (status == BTA_HL_STATUS_FAIL) {
390    free_buf = TRUE;
391  } else {
392    result = MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_tx_pkt);
393    if (result != MCA_SUCCESS) {
394      if (result == MCA_BUSY) {
395        status = BTA_HL_STATUS_DCH_BUSY;
396      } else {
397        status = BTA_HL_STATUS_FAIL;
398      }
399      free_buf = true;
400    } else {
401      p_dcb->p_tx_pkt = NULL;
402    }
403  }
404
405  if (free_buf) osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
406
407  bta_hl_build_send_data_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
408                             p_dcb->mdl_handle, status);
409  p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT, (tBTA_HL*)&evt_data);
410
411  if (close_dch) {
412    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_EVT,
413                          p_data);
414  }
415}
416
417/*******************************************************************************
418 *
419 * Function         bta_hl_dch_send_data
420 *
421 * Description      Action routine for processing api send data request
422 *
423 * Returns          void
424 *
425 ******************************************************************************/
426void bta_hl_dch_send_data(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
427                          tBTA_HL_DATA* p_data) {
428  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
429  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
430  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
431  tBTA_HL evt_data;
432  bool success = true;
433
434#if (BTA_HL_DEBUG == TRUE)
435  APPL_TRACE_DEBUG("bta_hl_dch_send_data");
436#endif
437
438  if (!(p_dcb->cout_oper & BTA_HL_CO_GET_TX_DATA_MASK)) {
439    // p_dcb->chnl_cfg.fcs may be BTA_HL_MCA_USE_FCS (0x11) or BTA_HL_MCA_NO_FCS
440    // (0x10) or BTA_HL_DEFAULT_SOURCE_FCS (1)
441    bool fcs_use = (bool)(p_dcb->chnl_cfg.fcs & BTA_HL_MCA_FCS_USE_MASK);
442    p_dcb->p_tx_pkt = bta_hl_get_buf(p_data->api_send_data.pkt_size, fcs_use);
443    if (p_dcb->p_tx_pkt != NULL) {
444      bta_hl_co_get_tx_data(
445          p_acb->app_id, p_dcb->mdl_handle, p_data->api_send_data.pkt_size,
446          BTA_HL_GET_BUF_PTR(p_dcb->p_tx_pkt), BTA_HL_CI_GET_TX_DATA_EVT);
447      p_dcb->cout_oper |= BTA_HL_CO_GET_TX_DATA_MASK;
448    } else {
449      success = false;
450    }
451  } else {
452    success = false;
453  }
454
455  if (!success) {
456    bta_hl_build_send_data_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
457                               p_dcb->mdl_handle, BTA_HL_STATUS_FAIL);
458    p_acb->p_cback(BTA_HL_DCH_SEND_DATA_CFM_EVT, (tBTA_HL*)&evt_data);
459  }
460}
461
462/*******************************************************************************
463 *
464 * Function         bta_hl_dch_close_cmpl
465 *
466 * Description      Action routine for processing the close complete event
467 *
468 * Returns          void
469 *
470 ******************************************************************************/
471void bta_hl_dch_close_cmpl(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
472                           tBTA_HL_DATA* p_data) {
473  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
474  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
475  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
476  tBTA_HL evt_data;
477  tBTA_HL_EVT event = 0;
478  bool send_evt = true;
479  tBTA_HL_STATUS status;
480
481#if (BTA_HL_DEBUG == TRUE)
482  APPL_TRACE_DEBUG("bta_hl_dch_close_cmpl dch oper=%s",
483                   bta_hl_dch_oper_code(p_dcb->dch_oper));
484#endif
485
486  switch (p_dcb->dch_oper) {
487    case BTA_HL_DCH_OP_LOCAL_OPEN:
488    case BTA_HL_DCH_OP_LOCAL_RECONNECT:
489
490      if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) {
491        bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
492                               BTA_HL_STATUS_OK);
493        event = BTA_HL_DCH_ABORT_CFM_EVT;
494      } else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK) {
495        bta_hl_build_abort_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle);
496        event = BTA_HL_DCH_ABORT_IND_EVT;
497      } else {
498        bta_hl_build_dch_open_cfm(&evt_data, p_acb->app_handle,
499                                  p_mcb->mcl_handle, BTA_HL_INVALID_MDL_HANDLE,
500                                  0, 0, 0, 0, 0, BTA_HL_STATUS_FAIL);
501        event = BTA_HL_DCH_OPEN_CFM_EVT;
502        if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT) {
503          event = BTA_HL_DCH_RECONNECT_CFM_EVT;
504        }
505      }
506      break;
507
508    case BTA_HL_DCH_OP_LOCAL_CLOSE:
509    case BTA_HL_DCH_OP_REMOTE_DELETE:
510    case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT:
511    case BTA_HL_DCH_OP_NONE:
512
513      bta_hl_build_dch_close_cfm(&evt_data, p_acb->app_handle,
514                                 p_mcb->mcl_handle, p_dcb->mdl_handle,
515                                 BTA_HL_STATUS_OK);
516      event = BTA_HL_DCH_CLOSE_CFM_EVT;
517      break;
518
519    case BTA_HL_DCH_OP_REMOTE_CLOSE:
520      bta_hl_build_dch_close_ind(&evt_data, p_acb->app_handle,
521                                 p_mcb->mcl_handle, p_dcb->mdl_handle,
522                                 p_dcb->intentional_close);
523      event = BTA_HL_DCH_CLOSE_IND_EVT;
524      break;
525
526    case BTA_HL_DCH_OP_REMOTE_OPEN:
527
528      if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) {
529        bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
530                               BTA_HL_STATUS_OK);
531        event = BTA_HL_DCH_ABORT_CFM_EVT;
532      } else if (p_dcb->abort_oper & BTA_HL_ABORT_REMOTE_MASK) {
533        bta_hl_build_abort_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle);
534        event = BTA_HL_DCH_ABORT_IND_EVT;
535      } else {
536        bta_hl_build_dch_close_ind(&evt_data, p_acb->app_handle,
537                                   p_mcb->mcl_handle, p_dcb->mdl_handle,
538                                   p_dcb->intentional_close);
539        event = BTA_HL_DCH_CLOSE_IND_EVT;
540      }
541      break;
542
543    case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST:
544    /* this is normal echo test close */
545    case BTA_HL_DCH_OP_REMOTE_CREATE:
546    case BTA_HL_DCH_OP_REMOTE_RECONNECT:
547      send_evt = false;
548      break;
549
550    default:
551#if (BTA_HL_DEBUG == TRUE)
552      APPL_TRACE_ERROR("DCH operation not found oper=%s",
553                       bta_hl_dch_oper_code(p_dcb->dch_oper));
554#endif
555      send_evt = false;
556      break;
557  }
558
559  if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
560    p_mcb->echo_test = false;
561    send_evt = false;
562
563    if (p_dcb->dch_oper != BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST) {
564      switch (p_dcb->echo_oper) {
565        case BTA_HL_ECHO_OP_CI_GET_ECHO_DATA:
566        case BTA_HL_ECHO_OP_SDP_INIT:
567        case BTA_HL_ECHO_OP_MDL_CREATE_CFM:
568        case BTA_HL_ECHO_OP_DCH_OPEN_CFM:
569        case BTA_HL_ECHO_OP_LOOP_BACK:
570
571          status = BTA_HL_STATUS_FAIL;
572          send_evt = true;
573          break;
574        case BTA_HL_ECHO_OP_OPEN_IND:
575        case BTA_HL_ECHO_OP_ECHO_PKT:
576          break;
577        default:
578          APPL_TRACE_ERROR("Invalid echo_oper=%d", p_dcb->echo_oper);
579          break;
580      }
581    } else {
582      status = p_dcb->ci_put_echo_data_status;
583      send_evt = true;
584    }
585
586    if (send_evt) {
587      bta_hl_build_echo_test_cfm(&evt_data, p_acb->app_handle,
588                                 p_mcb->mcl_handle, status);
589      event = BTA_HL_DCH_ECHO_TEST_CFM_EVT;
590    }
591  }
592
593  bta_hl_clean_mdl_cb(app_idx, mcl_idx, mdl_idx);
594
595  if (send_evt) {
596    if (p_acb->p_cback) {
597#if (BTA_HL_DEBUG == TRUE)
598      APPL_TRACE_DEBUG("Send Event: %s", bta_hl_cback_evt_code(event));
599#endif
600      p_acb->p_cback(event, (tBTA_HL*)&evt_data);
601    }
602  }
603  /* check cch close is in progress or not */
604  bta_hl_check_cch_close(app_idx, mcl_idx, p_data, false);
605}
606/*******************************************************************************
607 *
608 * Function         bta_hl_dch_mca_close_ind
609 *
610 * Description      Action routine for processing the close indication
611 *
612 * Returns          void
613 *
614 ******************************************************************************/
615void bta_hl_dch_mca_close_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
616                              tBTA_HL_DATA* p_data) {
617  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
618
619#if (BTA_HL_DEBUG == TRUE)
620  APPL_TRACE_DEBUG("bta_hl_dch_mca_close_ind dch oper=%s",
621                   bta_hl_dch_oper_code(p_dcb->dch_oper));
622#endif
623
624  p_dcb->intentional_close = false;
625  if (p_data->mca_evt.mca_data.close_ind.reason == L2CAP_DISC_OK) {
626    p_dcb->intentional_close = true;
627  }
628
629  if (!p_dcb->cout_oper) {
630    if ((p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_OPEN) &&
631        (p_dcb->dch_oper != BTA_HL_DCH_OP_REMOTE_RECONNECT)) {
632      p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CLOSE;
633    }
634    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
635                          p_data);
636  } else {
637    p_dcb->close_pending = true;
638  }
639}
640
641/*******************************************************************************
642 *
643 * Function         bta_hl_dch_mca_close_cfm
644 *
645 * Description      Action routine for processing the close confirmation
646 *
647 * Returns          void
648 *
649 ******************************************************************************/
650void bta_hl_dch_mca_close_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
651                              tBTA_HL_DATA* p_data) {
652  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
653
654#if (BTA_HL_DEBUG == TRUE)
655  APPL_TRACE_DEBUG("bta_hl_dch_mca_close_cfm dch_oper=%s",
656                   bta_hl_dch_oper_code(p_dcb->dch_oper));
657#endif
658
659  switch (p_dcb->dch_oper) {
660    case BTA_HL_DCH_OP_LOCAL_CLOSE:
661    case BTA_HL_DCH_OP_LOCAL_OPEN:
662    case BTA_HL_DCH_OP_LOCAL_RECONNECT:
663    case BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST:
664    case BTA_HL_DCH_OP_REMOTE_DELETE:
665    case BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT:
666    case BTA_HL_DCH_OP_NONE:
667      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
668                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
669      break;
670    default:
671#if (BTA_HL_DEBUG == TRUE)
672      APPL_TRACE_ERROR("Invalid dch_oper=%s for close cfm",
673                       bta_hl_dch_oper_code(p_dcb->dch_oper));
674#endif
675      break;
676  }
677}
678
679/*******************************************************************************
680 *
681 * Function         bta_hl_dch_mca_close
682 *
683 * Description      Action routine for processing the DCH close request
684 *
685 * Returns          void
686 *
687 ******************************************************************************/
688void bta_hl_dch_mca_close(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
689                          tBTA_HL_DATA* p_data) {
690  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
691  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
692  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
693  tBTA_HL_STATUS status = BTA_HL_STATUS_OK;
694  tBTA_HL evt_data;
695
696#if (BTA_HL_DEBUG == TRUE)
697  APPL_TRACE_DEBUG("bta_hl_dch_mca_close");
698#endif
699  if (!p_dcb->cout_oper) {
700    p_dcb->close_pending = false;
701    if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) {
702      p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE;
703    } else {
704      status = BTA_HL_STATUS_FAIL;
705    }
706
707    if ((status != BTA_HL_STATUS_OK) &&
708        (p_mcb->cch_close_dch_oper != BTA_HL_CCH_CLOSE_OP_DCH_CLOSE)) {
709      bta_hl_build_dch_close_cfm(&evt_data, p_acb->app_handle,
710                                 p_mcb->mcl_handle,
711                                 p_data->api_dch_close.mdl_handle, status);
712      p_acb->p_cback(BTA_HL_DCH_CLOSE_CFM_EVT, (tBTA_HL*)&evt_data);
713    }
714  } else {
715    p_dcb->close_pending = true;
716  }
717}
718
719/*******************************************************************************
720 *
721 * Function         bta_hl_dch_mca_open_ind
722 *
723 * Description      Action routine for processing the open indication
724 *
725 * Returns          void
726 *
727 ******************************************************************************/
728void bta_hl_dch_mca_open_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
729                             tBTA_HL_DATA* p_data) {
730  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
731  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
732  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
733  tMCA_DL_OPEN* p_open_ind = &p_data->mca_evt.mca_data.open_ind;
734  tBTA_HL evt_data;
735  tBTA_HL_EVT event;
736  uint8_t old_dch_oper = BTA_HL_DCH_OP_NONE;
737  bool send_event = false;
738
739#if (BTA_HL_DEBUG == TRUE)
740  APPL_TRACE_DEBUG("bta_hl_dch_mca_open_ind");
741#endif
742  if ((p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_OPEN) ||
743      (p_dcb->dch_oper == BTA_HL_DCH_OP_REMOTE_RECONNECT)) {
744    p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE)p_open_ind->mdl;
745    p_dcb->mtu = p_open_ind->mtu;
746
747    evt_data.dch_open_ind.mdl_handle = p_dcb->mdl_handle;
748    evt_data.dch_open_ind.mcl_handle = p_mcb->mcl_handle;
749    evt_data.dch_open_ind.app_handle = p_acb->app_handle;
750
751    evt_data.dch_open_ind.local_mdep_id = p_dcb->local_mdep_id;
752    evt_data.dch_open_ind.mdl_id = p_dcb->mdl_id;
753    evt_data.dch_open_ind.mtu = p_dcb->mtu;
754
755    if (p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE) {
756      evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_RELIABLE;
757      if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) {
758        p_dcb->is_the_first_reliable = true;
759      }
760    } else {
761      evt_data.dch_open_ind.dch_mode = BTA_HL_DCH_MODE_STREAMING;
762    }
763    evt_data.dch_open_ind.first_reliable = p_dcb->is_the_first_reliable;
764
765    old_dch_oper = p_dcb->dch_oper;
766    p_dcb->dch_oper = BTA_HL_DCH_OP_NONE;
767  }
768
769  switch (old_dch_oper) {
770    case BTA_HL_DCH_OP_REMOTE_OPEN:
771
772      p_dcb->dch_mode = evt_data.dch_open_ind.dch_mode;
773      if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
774        bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx);
775        event = BTA_HL_DCH_OPEN_IND_EVT;
776        send_event = true;
777      } else {
778        p_dcb->echo_oper = BTA_HL_ECHO_OP_ECHO_PKT;
779      }
780
781      break;
782
783    case BTA_HL_DCH_OP_REMOTE_RECONNECT:
784
785      if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx)) {
786        bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx);
787        event = BTA_HL_DCH_RECONNECT_IND_EVT;
788        send_event = true;
789      } else {
790        if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) {
791          p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT;
792        } else {
793          APPL_TRACE_ERROR("Unabel to close DCH for reconnect cfg mismatch");
794        }
795      }
796      break;
797    default:
798      break;
799  }
800
801  if (send_event) {
802    p_acb->p_cback(event, (tBTA_HL*)&evt_data);
803  }
804}
805
806/*******************************************************************************
807 *
808 * Function         bta_hl_dch_mca_open_cfm
809 *
810 * Description      Action routine for processing the open confirmation
811 *
812 * Returns          void
813 *
814 ******************************************************************************/
815void bta_hl_dch_mca_open_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
816                             tBTA_HL_DATA* p_data) {
817  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
818  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
819  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
820  tMCA_DL_OPEN* p_open_cfm = &p_data->mca_evt.mca_data.open_cfm;
821  tBTA_HL evt_data;
822  tBTA_HL_EVT event;
823  uint8_t old_dch_oper = BTA_HL_DCH_OP_NONE;
824  tBTA_HL_DCH_MODE dch_mode = BTA_HL_DCH_MODE_STREAMING;
825  bool send_event = false;
826
827#if (BTA_HL_DEBUG == TRUE)
828  APPL_TRACE_DEBUG("bta_hl_dch_mca_open_cfm");
829#endif
830  if ((p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) ||
831      (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT)) {
832    p_dcb->mdl_handle = (tBTA_HL_MDL_HANDLE)p_open_cfm->mdl;
833    p_dcb->mtu = p_open_cfm->mtu;
834
835    /*todo verify dch_mode, mtu and fcs for reconnect */
836    if (p_dcb->chnl_cfg.fcr_opt.mode == L2CAP_FCR_ERTM_MODE) {
837      dch_mode = BTA_HL_DCH_MODE_RELIABLE;
838    }
839
840    if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
841      if (dch_mode == BTA_HL_DCH_MODE_RELIABLE) {
842        if (!bta_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) {
843          p_dcb->is_the_first_reliable = true;
844        }
845      }
846    }
847
848    bta_hl_build_dch_open_cfm(
849        &evt_data, p_acb->app_handle, p_mcb->mcl_handle, p_dcb->mdl_handle,
850        p_dcb->local_mdep_id, p_dcb->mdl_id, dch_mode,
851        p_dcb->is_the_first_reliable, p_dcb->mtu, BTA_HL_STATUS_OK);
852
853    old_dch_oper = p_dcb->dch_oper;
854    p_dcb->dch_oper = BTA_HL_DCH_OP_NONE;
855  } else {
856    APPL_TRACE_ERROR("Error dch oper =%d", p_dcb->dch_oper);
857    return;
858  }
859
860  switch (old_dch_oper) {
861    case BTA_HL_DCH_OP_LOCAL_OPEN:
862
863      p_dcb->dch_mode = dch_mode;
864      if (p_dcb->local_mdep_id != BTA_HL_ECHO_TEST_MDEP_ID) {
865        bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx);
866        event = BTA_HL_DCH_OPEN_CFM_EVT;
867        send_event = true;
868      } else {
869        p_dcb->echo_oper = BTA_HL_ECHO_OP_LOOP_BACK;
870        if (MCA_WriteReq((tMCA_DL)p_dcb->mdl_handle, p_dcb->p_echo_tx_pkt) !=
871            MCA_SUCCESS) {
872          bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
873                                BTA_HL_DCH_CLOSE_ECHO_TEST_EVT, p_data);
874        } else {
875          p_dcb->p_echo_tx_pkt = NULL;
876        }
877      }
878      break;
879
880    case BTA_HL_DCH_OP_LOCAL_RECONNECT:
881
882      if (bta_hl_validate_chan_cfg(app_idx, mcl_idx, mdl_idx)) {
883        bta_hl_save_mdl_cfg(app_idx, mcl_idx, mdl_idx);
884        event = BTA_HL_DCH_RECONNECT_CFM_EVT;
885        send_event = true;
886      } else {
887        if (MCA_CloseReq((tMCA_DL)p_dcb->mdl_handle) == MCA_SUCCESS) {
888          p_dcb->dch_oper = BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT;
889        } else {
890          APPL_TRACE_ERROR("Unabel to close DCH for reconnect cfg mismatch");
891        }
892      }
893      break;
894    default:
895      break;
896  }
897
898  if (send_event) p_acb->p_cback(event, (tBTA_HL*)&evt_data);
899}
900
901/*******************************************************************************
902 *
903 * Function         bta_hl_dch_mca_abort_ind
904 *
905 * Description      Action routine for processing the abort indication
906 *
907 * Returns          void
908 *
909 ******************************************************************************/
910void bta_hl_dch_mca_abort_ind(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
911                              tBTA_HL_DATA* p_data) {
912  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
913
914#if (BTA_HL_DEBUG == TRUE)
915  APPL_TRACE_DEBUG("bta_hl_dch_mca_abort_ind");
916#endif
917
918  p_dcb->abort_oper |= BTA_HL_ABORT_REMOTE_MASK;
919  bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
920                        p_data);
921}
922
923/*******************************************************************************
924 *
925 * Function         bta_hl_dch_mca_abort_cfm
926 *
927 * Description      Action routine for processing the abort confirmation
928 *
929 * Returns          void
930 *
931 ******************************************************************************/
932void bta_hl_dch_mca_abort_cfm(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
933                              tBTA_HL_DATA* p_data) {
934  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
935  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
936  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
937  tBTA_HL evt_data;
938
939#if (BTA_HL_DEBUG == TRUE)
940  APPL_TRACE_DEBUG("bta_hl_dch_mca_abort_cfm");
941#endif
942
943  if (p_dcb->abort_oper) {
944    if (p_data->mca_evt.mca_data.abort_cfm.rsp_code != MCA_RSP_SUCCESS) {
945      if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) {
946        bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
947                               BTA_HL_STATUS_FAIL);
948        p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT, (tBTA_HL*)&evt_data);
949      }
950    } else {
951      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
952                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
953    }
954  } else {
955    APPL_TRACE_ERROR("Not expecting Abort CFM ");
956  }
957}
958
959/*******************************************************************************
960 *
961 * Function         bta_hl_dch_mca_abort
962 *
963 * Description      Action routine for processing the abort request
964 *
965 * Returns          void
966 *
967 ******************************************************************************/
968void bta_hl_dch_mca_abort(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
969                          tBTA_HL_DATA* p_data) {
970  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
971  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
972  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
973  tMCA_RESULT mca_result;
974  tBTA_HL evt_data;
975
976  if (((p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) ||
977       (p_mcb->sdp_oper == BTA_HL_SDP_OP_DCH_RECONNECT_INIT)) &&
978      (p_mcb->sdp_mdl_idx == mdl_idx)) {
979    p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK;
980    return;
981  } else if (p_dcb->echo_oper == BTA_HL_ECHO_OP_CI_GET_ECHO_DATA) {
982    p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK;
983    return;
984  }
985
986  p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
987
988  mca_result = MCA_Abort((tMCA_CL)p_mcb->mcl_handle);
989  if (mca_result != MCA_SUCCESS) {
990    if (mca_result == MCA_NO_RESOURCES) {
991      p_dcb->abort_oper |= BTA_HL_ABORT_PENDING_MASK;
992    } else {
993      if (p_dcb->abort_oper & BTA_HL_ABORT_LOCAL_MASK) {
994        bta_hl_build_abort_cfm(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
995                               BTA_HL_STATUS_FAIL);
996        p_acb->p_cback(BTA_HL_DCH_ABORT_CFM_EVT, (tBTA_HL*)&evt_data);
997      }
998      bta_hl_check_cch_close(app_idx, mcl_idx, p_data, false);
999    }
1000  }
1001
1002#if (BTA_HL_DEBUG == TRUE)
1003  APPL_TRACE_DEBUG("bta_hl_dch_mca_abort abort_oper=0x%x", p_dcb->abort_oper);
1004#endif
1005}
1006
1007/*******************************************************************************
1008 *
1009 * Function         bta_hl_dch_mca_reconnect_ind
1010 *
1011 * Description      Action routine for processing the reconnect indication
1012 *
1013 * Returns          void
1014 *
1015 ******************************************************************************/
1016void bta_hl_dch_mca_reconnect_ind(uint8_t app_idx, uint8_t mcl_idx,
1017                                  uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
1018  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1019  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1020  tBTA_HL_MDL_CFG* p_mdl_cfg;
1021  tMCA_EVT_HDR* p_reconnect_ind = &p_data->mca_evt.mca_data.reconnect_ind;
1022  uint8_t mdl_cfg_idx, in_use_mdl_idx, mdep_cfg_idx;
1023  uint8_t rsp_code = MCA_RSP_SUCCESS;
1024
1025#if (BTA_HL_DEBUG == TRUE)
1026  APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect_ind mdl_id=%d",
1027                   p_reconnect_ind->mdl_id);
1028#endif
1029
1030  if (bta_hl_find_mdl_cfg_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id,
1031                              &mdl_cfg_idx)) {
1032    if (!bta_hl_find_mdl_idx(app_idx, mcl_idx, p_reconnect_ind->mdl_id,
1033                             &in_use_mdl_idx)) {
1034      p_mdl_cfg = BTA_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx);
1035
1036      if (bta_hl_find_mdep_cfg_idx(app_idx, p_mdl_cfg->local_mdep_id,
1037                                   &mdep_cfg_idx)) {
1038        p_dcb->in_use = true;
1039        p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_RECONNECT;
1040        p_dcb->sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
1041        p_dcb->peer_mdep_id = 0xFF;
1042        p_dcb->local_mdep_id = p_mdl_cfg->local_mdep_id;
1043        p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
1044        p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN;
1045        p_dcb->mdl_id = p_reconnect_ind->mdl_id;
1046        p_dcb->mdl_cfg_idx_included = true;
1047        p_dcb->mdl_cfg_idx = mdl_cfg_idx;
1048        p_dcb->dch_mode = p_mdl_cfg->dch_mode;
1049        bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx,
1050                                   &p_dcb->max_rx_apdu_size,
1051                                   &p_dcb->max_tx_apdu_size);
1052        bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
1053      } else {
1054        rsp_code = MCA_RSP_BAD_MDL;
1055      }
1056    } else {
1057      rsp_code = MCA_RSP_BAD_MDL;
1058    }
1059  } else {
1060    rsp_code = MCA_RSP_BAD_MDL;
1061  }
1062
1063  if (MCA_ReconnectMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id,
1064                          p_dcb->mdl_id, rsp_code,
1065                          &p_dcb->chnl_cfg) != MCA_SUCCESS) {
1066    MCA_Abort((tMCA_CL)p_mcb->mcl_handle);
1067    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
1068                          p_data);
1069  }
1070}
1071
1072/*******************************************************************************
1073 *
1074 * Function         bta_hl_dch_mca_reconnect_cfm
1075 *
1076 * Description      Action routine for processing the reconenct confirmation
1077 *
1078 * Returns          void
1079 *
1080 ******************************************************************************/
1081void bta_hl_dch_mca_reconnect_cfm(uint8_t app_idx, uint8_t mcl_idx,
1082                                  uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
1083  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1084  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1085  tMCA_RSP_EVT* p_reconnect_cfm = &p_data->mca_evt.mca_data.reconnect_cfm;
1086
1087#if (BTA_HL_DEBUG == TRUE)
1088  APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect_cfm");
1089#endif
1090  if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) {
1091    p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
1092    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT,
1093                          p_data);
1094    return;
1095  }
1096
1097  if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_RECONNECT) {
1098    if (p_reconnect_cfm->rsp_code == MCA_RSP_SUCCESS) {
1099      bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
1100
1101      if (MCA_DataChnlCfg((tMCA_CL)p_mcb->mcl_handle, &p_dcb->chnl_cfg) !=
1102          MCA_SUCCESS) {
1103        /* should be able to abort so no checking of the return code */
1104        MCA_Abort((tMCA_CL)p_mcb->mcl_handle);
1105        bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1106                              BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1107      }
1108    } else {
1109      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1110                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1111    }
1112  }
1113}
1114
1115/*******************************************************************************
1116 *
1117 * Function         bta_hl_dch_mca_reconnect
1118 *
1119 * Description      Action routine for processing the reconnect request
1120 *
1121 * Returns          void
1122 *
1123 ******************************************************************************/
1124void bta_hl_dch_mca_reconnect(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
1125                              tBTA_HL_DATA* p_data) {
1126  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1127  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1128  tMCA_CHNL_CFG* p_chnl_cfg = NULL;
1129  uint8_t sdp_idx;
1130
1131#if (BTA_HL_DEBUG == TRUE)
1132  APPL_TRACE_DEBUG("bta_hl_dch_mca_reconnect");
1133#endif
1134  if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm,
1135                                         &sdp_idx)) {
1136    p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm;
1137    if (MCA_ReconnectMdl((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id,
1138                         p_mcb->data_psm, p_dcb->mdl_id,
1139                         p_chnl_cfg) != MCA_SUCCESS) {
1140      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1141                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1142    }
1143  } else {
1144    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
1145                          p_data);
1146  }
1147}
1148
1149/*******************************************************************************
1150 *
1151 * Function         bta_hl_dch_create_rsp
1152 *
1153 * Description      Action routine for processing BTA_HL_API_DCH_CREATE_RSP_EVT
1154 *
1155 * Returns          void
1156 *
1157 ******************************************************************************/
1158void bta_hl_dch_create_rsp(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
1159                           tBTA_HL_DATA* p_data) {
1160  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1161  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1162  tBTA_HL_API_DCH_CREATE_RSP* p_create_rsp = &p_data->api_dch_create_rsp;
1163  uint8_t mca_rsp_code = MCA_RSP_SUCCESS;
1164
1165#if (BTA_HL_DEBUG == TRUE)
1166  APPL_TRACE_DEBUG("bta_hl_dch_create_rsp");
1167#endif
1168  if (p_create_rsp->rsp_code == BTA_HL_DCH_CREATE_RSP_SUCCESS) {
1169    p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN;
1170    p_dcb->local_cfg = p_create_rsp->cfg_rsp;
1171
1172    bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
1173  } else {
1174    mca_rsp_code = MCA_RSP_CFG_REJ;
1175  }
1176
1177  if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id,
1178                       p_dcb->mdl_id, p_dcb->local_cfg, mca_rsp_code,
1179                       &p_dcb->chnl_cfg) != MCA_SUCCESS) {
1180    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
1181                          p_data);
1182  }
1183}
1184
1185/*******************************************************************************
1186 *
1187 * Function         bta_hl_dch_mca_create_ind
1188 *
1189 * Description      Action routine for processing
1190 *
1191 * Returns          void
1192 *
1193 ******************************************************************************/
1194void bta_hl_dch_mca_create_ind(uint8_t app_idx, uint8_t mcl_idx,
1195                               uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
1196  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1197  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1198  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1199  tMCA_CREATE_IND* p_create_ind = &p_data->mca_evt.mca_data.create_ind;
1200  uint8_t mdep_cfg_idx;
1201  uint8_t cfg_rsp;
1202  uint8_t rsp_code = MCA_RSP_SUCCESS;
1203  bool send_create_ind_evt = false;
1204  tBTA_HL evt_data;
1205  tBTA_HL_ECHO_CFG* p_echo_cfg;
1206
1207#if (BTA_HL_DEBUG == TRUE)
1208  APPL_TRACE_DEBUG("bta_hl_dch_mca_create_ind");
1209#endif
1210
1211  if (bta_hl_find_mdep_cfg_idx(app_idx, p_create_ind->dep_id, &mdep_cfg_idx)) {
1212    if (p_create_ind->dep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
1213      if (bta_hl_find_echo_cfg_rsp(app_idx, mcl_idx, mdep_cfg_idx,
1214                                   p_create_ind->cfg, &cfg_rsp)) {
1215        p_dcb->in_use = true;
1216        p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_OPEN;
1217        p_dcb->local_mdep_id = p_create_ind->dep_id;
1218        p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
1219        p_dcb->local_cfg = cfg_rsp;
1220        p_dcb->remote_cfg = p_create_ind->cfg;
1221        p_dcb->mdl_id = p_create_ind->mdl_id;
1222        p_dcb->mdl_cfg_idx_included = false;
1223        p_echo_cfg = BTA_HL_GET_ECHO_CFG_PTR(app_idx);
1224        p_dcb->max_rx_apdu_size = p_echo_cfg->max_rx_apdu_size;
1225        p_dcb->max_tx_apdu_size = p_echo_cfg->max_tx_apdu_size;
1226
1227        bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
1228      } else {
1229        rsp_code = MCA_RSP_CFG_REJ;
1230      }
1231    } else
1232
1233    {
1234      p_dcb->in_use = true;
1235      p_dcb->dch_oper = BTA_HL_DCH_OP_REMOTE_CREATE;
1236      p_dcb->local_mdep_id = p_create_ind->dep_id;
1237      p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
1238      p_dcb->local_cfg = BTA_HL_DCH_CFG_UNKNOWN;
1239      p_dcb->remote_cfg = p_create_ind->cfg;
1240      p_dcb->mdl_id = p_create_ind->mdl_id;
1241      p_dcb->mdl_cfg_idx_included = false;
1242      bta_hl_find_rxtx_apdu_size(app_idx, mdep_cfg_idx,
1243                                 &p_dcb->max_rx_apdu_size,
1244                                 &p_dcb->max_tx_apdu_size);
1245      send_create_ind_evt = true;
1246    }
1247  } else {
1248    rsp_code = MCA_RSP_BAD_MDEP;
1249  }
1250
1251  if (send_create_ind_evt) {
1252    evt_data.dch_create_ind.mcl_handle = p_mcb->mcl_handle;
1253    evt_data.dch_create_ind.app_handle = p_acb->app_handle;
1254    evt_data.dch_create_ind.local_mdep_id = p_dcb->local_mdep_id;
1255    evt_data.dch_create_ind.mdl_id = p_dcb->mdl_id;
1256    evt_data.dch_create_ind.cfg = p_dcb->remote_cfg;
1257    evt_data.dch_create_ind.bd_addr = p_mcb->bd_addr;
1258    p_acb->p_cback(BTA_HL_DCH_CREATE_IND_EVT, (tBTA_HL*)&evt_data);
1259  } else {
1260    if (MCA_CreateMdlRsp((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id,
1261                         p_dcb->mdl_id, p_dcb->local_cfg, rsp_code,
1262                         &p_dcb->chnl_cfg) != MCA_SUCCESS) {
1263      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1264                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1265    } else {
1266      if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
1267        p_mcb->echo_test = true;
1268        p_dcb->echo_oper = BTA_HL_ECHO_OP_OPEN_IND;
1269      }
1270    }
1271  }
1272}
1273
1274/*******************************************************************************
1275 *
1276 * Function         bta_hl_dch_mca_create_cfm
1277 *
1278 * Description      Action routine for processing
1279 *
1280 * Returns          void
1281 *
1282 ******************************************************************************/
1283void bta_hl_dch_mca_create_cfm(uint8_t app_idx, uint8_t mcl_idx,
1284                               uint8_t mdl_idx, tBTA_HL_DATA* p_data) {
1285  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1286  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1287  tMCA_CREATE_CFM* p_create_cfm = &p_data->mca_evt.mca_data.create_cfm;
1288
1289#if (BTA_HL_DEBUG == TRUE)
1290  APPL_TRACE_DEBUG("bta_hl_dch_mca_create_cfm");
1291#endif
1292
1293  if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) {
1294    p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
1295    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_ABORT_EVT,
1296                          p_data);
1297    return;
1298  }
1299
1300  if (p_dcb->dch_oper == BTA_HL_DCH_OP_LOCAL_OPEN) {
1301    if (p_create_cfm->rsp_code == MCA_RSP_SUCCESS) {
1302      if (bta_hl_validate_cfg(app_idx, mcl_idx, mdl_idx, p_create_cfm->cfg)) {
1303        bta_hl_set_dch_chan_cfg(app_idx, mcl_idx, mdl_idx, p_data);
1304
1305        if (MCA_DataChnlCfg((tMCA_CL)p_mcb->mcl_handle, &p_dcb->chnl_cfg) !=
1306            MCA_SUCCESS) {
1307          /* this should not happen */
1308          APPL_TRACE_ERROR("Unable to create data channel");
1309          MCA_Abort((tMCA_CL)p_mcb->mcl_handle);
1310          bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1311                                BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1312        } else {
1313          if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
1314            p_dcb->echo_oper = BTA_HL_ECHO_OP_DCH_OPEN_CFM;
1315          }
1316        }
1317      } else {
1318        MCA_Abort((tMCA_CL)p_mcb->mcl_handle);
1319        bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1320                              BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1321      }
1322    } else {
1323      APPL_TRACE_ERROR("MCA Create- failed");
1324      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1325                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1326    }
1327  }
1328}
1329
1330/*******************************************************************************
1331 *
1332 * Function         bta_hl_dch_mca_create
1333 *
1334 * Description      Action routine for processing the MDL create request
1335 *
1336 * Returns          void
1337 *
1338 ******************************************************************************/
1339void bta_hl_dch_mca_create(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
1340                           tBTA_HL_DATA* p_data) {
1341  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1342  tBTA_HL_MDL_CB* p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1343  tMCA_RESULT result;
1344  uint8_t sdp_idx;
1345
1346#if (BTA_HL_DEBUG == TRUE)
1347  APPL_TRACE_DEBUG("bta_hl_dch_mca_create");
1348#endif
1349
1350  if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->ctrl_psm,
1351                                         &sdp_idx) &&
1352      bta_hl_validate_peer_cfg(app_idx, mcl_idx, mdl_idx, p_dcb->peer_mdep_id,
1353                               p_dcb->peer_mdep_role, sdp_idx)) {
1354    p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm;
1355    result = MCA_CreateMdl((tMCA_CL)p_mcb->mcl_handle, p_dcb->local_mdep_id,
1356                           p_mcb->data_psm, p_dcb->mdl_id, p_dcb->peer_mdep_id,
1357                           p_dcb->local_cfg, NULL);
1358    if (result != MCA_SUCCESS) {
1359      APPL_TRACE_ERROR("MCA_CreateMdl FAIL mca_result=%d", result);
1360      bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx,
1361                            BTA_HL_DCH_CLOSE_CMPL_EVT, p_data);
1362    }
1363  } else {
1364    APPL_TRACE_ERROR("MCA Create- SDP idx or peer MDEP cfg not found");
1365    bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
1366                          p_data);
1367  }
1368}
1369
1370/*******************************************************************************
1371 *
1372 * Function         bta_hl_dch_sdp_fail
1373 *
1374 * Description      Action routine for processing the SDP failed event
1375 *
1376 * Returns          void
1377 *
1378 ******************************************************************************/
1379void bta_hl_dch_sdp_fail(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx,
1380                         tBTA_HL_DATA* p_data) {
1381#if (BTA_HL_DEBUG == TRUE)
1382  APPL_TRACE_DEBUG("bta_hl_dch_sdp_fail");
1383#endif
1384  bta_hl_dch_sm_execute(app_idx, mcl_idx, mdl_idx, BTA_HL_DCH_CLOSE_CMPL_EVT,
1385                        p_data);
1386}
1387
1388/******************************************************************************
1389 *
1390 * Function         bta_hl_sdp_cback
1391 *
1392 * Description      This is the SDP callback function used by HL.
1393 *                  This function will be executed by SDP when the service
1394 *                  search is completed.  If the search is successful, it
1395 *                  finds the first record in the database that matches the
1396 *                  UUID of the search.  Then retrieves the scn from the
1397 *                  record.
1398 *
1399 * Returns          void.
1400 *
1401 *****************************************************************************/
1402static void bta_hl_sdp_cback(uint8_t sdp_oper, uint8_t app_idx, uint8_t mcl_idx,
1403                             uint8_t mdl_idx, uint16_t status) {
1404  tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1405  tBTA_HL_SDP_REC* p_hdp_rec;
1406  tBTA_HL_CCH_SDP* p_cch_buf;
1407  tBTA_HL_DCH_SDP* p_dch_buf;
1408  tSDP_DISC_REC* p_rec = NULL;
1409  tSDP_PROTOCOL_ELEM pe;
1410  tSDP_DISC_ATTR* p_attr;
1411  uint8_t i, rec_cnt;
1412  tBTA_HL_SUP_FEATURE_LIST_ELEM sup_feature;
1413  bool sdp_parsing_ok = false, result = false;
1414  uint16_t event;
1415  tBTA_HL_MDL_CB* p_dcb;
1416  uint16_t service_uuid;
1417  uint16_t name_len;
1418
1419#if (BTA_HL_DEBUG == TRUE)
1420  APPL_TRACE_DEBUG(
1421      "bta_hl_sdp_cback status:%d sdp_oper=%d app_idx=%d, mcl_idx=%d,   "
1422      "mdl_idx=%d",
1423      status, sdp_oper, app_idx, mcl_idx, mdl_idx);
1424#endif
1425
1426  rec_cnt = 0;
1427  service_uuid = bta_hl_get_service_uuids(sdp_oper, app_idx, mcl_idx, mdl_idx);
1428
1429  if (status == SDP_SUCCESS || status == SDP_DB_FULL) {
1430    memset(&p_cb->sdp, 0, sizeof(tBTA_HL_SDP));
1431    do {
1432      if (bta_hl_find_service_in_db(app_idx, mcl_idx, service_uuid, &p_rec)) {
1433        p_hdp_rec = &p_cb->sdp.sdp_rec[rec_cnt];
1434        p_cb->sdp.num_recs = rec_cnt + 1;
1435      } else {
1436        break;
1437      }
1438
1439      if (SDP_FindProtocolListElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe)) {
1440        p_hdp_rec->ctrl_psm = (uint16_t)pe.params[0];
1441      } else {
1442        APPL_TRACE_WARNING("Control PSM not found");
1443        break;
1444      }
1445      if (SDP_FindAddProtoListsElemInRec(p_rec, UUID_PROTOCOL_L2CAP, &pe)) {
1446        p_hdp_rec->data_psm = (uint16_t)pe.params[0];
1447      } else {
1448        APPL_TRACE_WARNING("Data PSM not found");
1449        break;
1450      }
1451
1452      p_hdp_rec->srv_name[0] = '\0';
1453      p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_NAME);
1454      if (p_attr != NULL) {
1455        if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN)
1456          name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
1457        else
1458          name_len = BT_MAX_SERVICE_NAME_LEN;
1459        memcpy(p_hdp_rec->srv_name, p_attr->attr_value.v.array, name_len);
1460      }
1461
1462      p_hdp_rec->srv_desp[0] = '\0';
1463      p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_SERVICE_DESCRIPTION);
1464      if (p_attr != NULL) {
1465        if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN)
1466          name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
1467        else
1468          name_len = BT_MAX_SERVICE_NAME_LEN;
1469        memcpy(p_hdp_rec->srv_desp, p_attr->attr_value.v.array, name_len);
1470      }
1471
1472      p_hdp_rec->provider_name[0] = '\0';
1473      p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_PROVIDER_NAME);
1474      if (p_attr != NULL) {
1475        if (SDP_DISC_ATTR_LEN(p_attr->attr_len_type) < BT_MAX_SERVICE_NAME_LEN)
1476          name_len = (uint16_t)SDP_DISC_ATTR_LEN(p_attr->attr_len_type);
1477        else
1478          name_len = BT_MAX_SERVICE_NAME_LEN;
1479        memcpy(p_hdp_rec->provider_name, p_attr->attr_value.v.array, name_len);
1480      }
1481
1482      p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_MCAP_SUP_PROC);
1483      if (p_attr != NULL) {
1484        p_hdp_rec->mcap_sup_proc = p_attr->attr_value.v.u8;
1485      } else {
1486        APPL_TRACE_WARNING("MCAP SUP PROC not found");
1487        break;
1488      }
1489
1490      p_attr = SDP_FindAttributeInRec(p_rec, ATTR_ID_HDP_SUP_FEAT_LIST);
1491      if (p_attr != NULL) {
1492        if (bta_hl_fill_sup_feature_list(p_attr, &sup_feature)) {
1493          p_hdp_rec->num_mdeps = (uint8_t)sup_feature.num_elems;
1494          APPL_TRACE_WARNING("bta_hl_sdp_cback num_mdeps %d",
1495                             sup_feature.num_elems);
1496          for (i = 0; i < sup_feature.num_elems; i++) {
1497            p_hdp_rec->mdep_cfg[i].data_type =
1498                sup_feature.list_elem[i].data_type;
1499            p_hdp_rec->mdep_cfg[i].mdep_id = sup_feature.list_elem[i].mdep_id;
1500            p_hdp_rec->mdep_cfg[i].mdep_role =
1501                sup_feature.list_elem[i].mdep_role;
1502            /* Check MDEP Description pointer to prevent crash due to null
1503             * pointer */
1504            if (sup_feature.list_elem[i].p_mdep_desp != NULL) {
1505              strlcpy(p_hdp_rec->mdep_cfg[i].mdep_desp,
1506                      sup_feature.list_elem[i].p_mdep_desp,
1507                      BTA_HL_MDEP_DESP_LEN);
1508            } else {
1509              APPL_TRACE_ERROR(
1510                  "bta_hl_sdp_cback Incorrect Mdep[%d] Description (Null ptr)",
1511                  i);
1512            }
1513          }
1514
1515          sdp_parsing_ok = true;
1516        } else {
1517          APPL_TRACE_WARNING("HDP supported feature list fill failed");
1518          break;
1519        }
1520      } else {
1521        APPL_TRACE_WARNING("HDP supported feature list not found");
1522        break;
1523      }
1524#if (BTA_HL_DEBUG == TRUE)
1525      APPL_TRACE_DEBUG("record=%d ctrl_psm=%0x data_psm=%x", rec_cnt + 1,
1526                       p_hdp_rec->ctrl_psm, p_hdp_rec->data_psm);
1527      APPL_TRACE_DEBUG("srv_name=[%s]", (p_hdp_rec->srv_name[0] != '\0')
1528                                            ? p_hdp_rec->srv_name
1529                                            : "NULL");
1530      APPL_TRACE_DEBUG("srv_desp=[%s]", (p_hdp_rec->srv_desp[0] != '\0')
1531                                            ? p_hdp_rec->srv_desp
1532                                            : "NULL");
1533      for (i = 0; i < sup_feature.num_elems; i++) {
1534        APPL_TRACE_DEBUG(
1535            "index=0x%02x mdep_id=0x%04x data type=0x%04x mdep role=%s(0x%02x)",
1536            (i + 1), p_hdp_rec->mdep_cfg[i].mdep_id,
1537            p_hdp_rec->mdep_cfg[i].data_type,
1538            (p_hdp_rec->mdep_cfg[i].mdep_role == BTA_HL_MDEP_ROLE_SOURCE)
1539                ? "Src"
1540                : "Snk",
1541            p_hdp_rec->mdep_cfg[i].mdep_role);
1542      }
1543      APPL_TRACE_DEBUG("provider_name=[%s]",
1544                       (p_hdp_rec->provider_name[0] != '\0')
1545                           ? p_hdp_rec->provider_name
1546                           : "NULL");
1547      APPL_TRACE_DEBUG("found MCAP sup procedure=%d",
1548                       p_cb->sdp.sdp_rec[rec_cnt].mcap_sup_proc);
1549#endif
1550      rec_cnt++;
1551      if (rec_cnt >= BTA_HL_NUM_SDP_RECS) {
1552        APPL_TRACE_WARNING("No more spaces for SDP recs max_rec_cnt=%d",
1553                           BTA_HL_NUM_SDP_RECS);
1554        break;
1555      }
1556
1557    } while (true);
1558  }
1559
1560  osi_free_and_reset((void**)&p_cb->p_db);
1561
1562  if ((status == SDP_SUCCESS || status == SDP_DB_FULL) && p_cb->sdp.num_recs &&
1563      sdp_parsing_ok) {
1564    result = true;
1565  } else {
1566    APPL_TRACE_WARNING(
1567        "SDP Failed sdp_status=%d num_recs=%d sdp_parsing_ok=%d ", status,
1568        p_cb->sdp.num_recs, sdp_parsing_ok);
1569  }
1570
1571  p_cb->sdp_oper = BTA_HL_SDP_OP_NONE;
1572
1573  switch (sdp_oper) {
1574    case BTA_HL_SDP_OP_CCH_INIT:
1575    case BTA_HL_SDP_OP_SDP_QUERY_NEW:
1576    case BTA_HL_SDP_OP_SDP_QUERY_CURRENT:
1577
1578      /* send result in event back to BTA */
1579      p_cch_buf = (tBTA_HL_CCH_SDP*)osi_malloc(sizeof(tBTA_HL_CCH_SDP));
1580      if (result) {
1581        if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT) {
1582          event = BTA_HL_CCH_SDP_OK_EVT;
1583          if (p_cb->close_pending) event = BTA_HL_CCH_SDP_FAIL_EVT;
1584        } else {
1585          event = BTA_HL_SDP_QUERY_OK_EVT;
1586        }
1587      } else {
1588        if (sdp_oper == BTA_HL_SDP_OP_CCH_INIT)
1589          event = BTA_HL_CCH_SDP_FAIL_EVT;
1590        else
1591          event = BTA_HL_SDP_QUERY_FAIL_EVT;
1592      }
1593      p_cch_buf->hdr.event = event;
1594
1595      p_cch_buf->app_idx = app_idx;
1596      p_cch_buf->mcl_idx = mcl_idx;
1597      p_cch_buf->release_mcl_cb = false;
1598      if (sdp_oper == BTA_HL_SDP_OP_SDP_QUERY_NEW)
1599        p_cch_buf->release_mcl_cb = true;
1600
1601      bta_sys_sendmsg(p_cch_buf);
1602      break;
1603    case BTA_HL_SDP_OP_DCH_OPEN_INIT:
1604    case BTA_HL_SDP_OP_DCH_RECONNECT_INIT:
1605      p_dch_buf = (tBTA_HL_DCH_SDP*)osi_malloc(sizeof(tBTA_HL_DCH_SDP));
1606      p_dch_buf->hdr.event = BTA_HL_DCH_SDP_FAIL_EVT;
1607      p_dch_buf->app_idx = app_idx;
1608      p_dch_buf->mcl_idx = mcl_idx;
1609      p_dch_buf->mdl_idx = mdl_idx;
1610      p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1611      if (p_dcb->abort_oper & BTA_HL_ABORT_PENDING_MASK) {
1612        p_dcb->abort_oper &= ~BTA_HL_ABORT_PENDING_MASK;
1613        result = false;
1614      }
1615      if (result) {
1616        if (sdp_oper == BTA_HL_SDP_OP_DCH_OPEN_INIT) {
1617          if (p_dcb->local_mdep_id == BTA_HL_ECHO_TEST_MDEP_ID) {
1618            p_dch_buf->hdr.event = BTA_HL_DCH_ECHO_TEST_EVT;
1619          } else {
1620            p_dch_buf->hdr.event = BTA_HL_DCH_OPEN_EVT;
1621          }
1622        } else {
1623          p_dch_buf->hdr.event = BTA_HL_DCH_RECONNECT_EVT;
1624        }
1625      }
1626      bta_sys_sendmsg(p_dch_buf);
1627      break;
1628    default:
1629      break;
1630  }
1631}
1632
1633/******************************************************************************
1634 *
1635 * Function         bta_hl_sdp_cback0
1636 *
1637 * Description      This is the SDP callback function used by index = 0
1638 *
1639 * Returns          void.
1640 *
1641 *****************************************************************************/
1642static void bta_hl_sdp_cback0(uint16_t status) {
1643  bta_hl_sdp_cback(bta_hl_cb.scb[0].sdp_oper, bta_hl_cb.scb[0].app_idx,
1644                   bta_hl_cb.scb[0].mcl_idx, bta_hl_cb.scb[0].mdl_idx, status);
1645  bta_hl_deallocate_spd_cback(0);
1646}
1647
1648/******************************************************************************
1649 *
1650 * Function         bta_hl_sdp_cback1
1651 *
1652 * Description      This is the SDP callback function used by index = 1
1653 *
1654 * Parameters       status  - status of the SDP callabck
1655 *
1656 * Returns          void.
1657 *
1658 *****************************************************************************/
1659static void bta_hl_sdp_cback1(uint16_t status) {
1660  bta_hl_sdp_cback(bta_hl_cb.scb[1].sdp_oper, bta_hl_cb.scb[1].app_idx,
1661                   bta_hl_cb.scb[1].mcl_idx, bta_hl_cb.scb[1].mdl_idx, status);
1662  bta_hl_deallocate_spd_cback(1);
1663}
1664
1665/******************************************************************************
1666 *
1667 * Function         bta_hl_sdp_cback2
1668 *
1669 * Description      This is the SDP callback function used by index = 2
1670 *
1671 * Returns          void.
1672 *
1673 *****************************************************************************/
1674static void bta_hl_sdp_cback2(uint16_t status) {
1675  bta_hl_sdp_cback(bta_hl_cb.scb[2].sdp_oper, bta_hl_cb.scb[2].app_idx,
1676                   bta_hl_cb.scb[2].mcl_idx, bta_hl_cb.scb[2].mdl_idx, status);
1677  bta_hl_deallocate_spd_cback(2);
1678}
1679
1680/******************************************************************************
1681 *
1682 * Function         bta_hl_sdp_cback3
1683 *
1684 * Description      This is the SDP callback function used by index = 3
1685 *
1686 * Returns          void.
1687 *
1688 *****************************************************************************/
1689static void bta_hl_sdp_cback3(uint16_t status) {
1690  bta_hl_sdp_cback(bta_hl_cb.scb[3].sdp_oper, bta_hl_cb.scb[3].app_idx,
1691                   bta_hl_cb.scb[3].mcl_idx, bta_hl_cb.scb[3].mdl_idx, status);
1692  bta_hl_deallocate_spd_cback(3);
1693}
1694
1695/******************************************************************************
1696 *
1697 * Function         bta_hl_sdp_cback4
1698 *
1699 * Description      This is the SDP callback function used by index = 4
1700 *
1701 * Parameters       status  - status of the SDP callabck
1702 *
1703 * Returns          void.
1704 *
1705 *****************************************************************************/
1706static void bta_hl_sdp_cback4(uint16_t status) {
1707  bta_hl_sdp_cback(bta_hl_cb.scb[4].sdp_oper, bta_hl_cb.scb[4].app_idx,
1708                   bta_hl_cb.scb[4].mcl_idx, bta_hl_cb.scb[4].mdl_idx, status);
1709  bta_hl_deallocate_spd_cback(4);
1710}
1711
1712/******************************************************************************
1713 *
1714 * Function         bta_hl_sdp_cback5
1715 *
1716 * Description      This is the SDP callback function used by index = 5
1717 *
1718 * Parameters       status  - status of the SDP callabck
1719 *
1720 * Returns          void.
1721 *
1722 *****************************************************************************/
1723static void bta_hl_sdp_cback5(uint16_t status) {
1724  bta_hl_sdp_cback(bta_hl_cb.scb[5].sdp_oper, bta_hl_cb.scb[5].app_idx,
1725                   bta_hl_cb.scb[5].mcl_idx, bta_hl_cb.scb[5].mdl_idx, status);
1726  bta_hl_deallocate_spd_cback(5);
1727}
1728
1729/******************************************************************************
1730 *
1731 * Function         bta_hl_sdp_cback6
1732 *
1733 * Description      This is the SDP callback function used by index = 6
1734 *
1735 * Returns          void.
1736 *
1737 *****************************************************************************/
1738static void bta_hl_sdp_cback6(uint16_t status) {
1739  bta_hl_sdp_cback(bta_hl_cb.scb[6].sdp_oper, bta_hl_cb.scb[6].app_idx,
1740                   bta_hl_cb.scb[6].mcl_idx, bta_hl_cb.scb[6].mdl_idx, status);
1741  bta_hl_deallocate_spd_cback(6);
1742}
1743
1744/*******************************************************************************
1745 *
1746 * Function      bta_hl_deallocate_spd_cback
1747 *
1748 * Description   Deallocate a SDP control block
1749 *
1750 * Returns      bool - true found
1751 *                        false not found
1752 *
1753 ******************************************************************************/
1754void bta_hl_deallocate_spd_cback(uint8_t sdp_cback_idx) {
1755  tBTA_HL_SDP_CB* p_spd_cb = &bta_hl_cb.scb[sdp_cback_idx];
1756
1757  memset(p_spd_cb, 0, sizeof(tBTA_HL_SDP_CB));
1758
1759#if (BTA_HL_DEBUG == TRUE)
1760  APPL_TRACE_DEBUG("bta_hl_deallocate_spd_cback index=%d", sdp_cback_idx);
1761#endif
1762}
1763
1764/*******************************************************************************
1765 *
1766 * Function      bta_hl_allocate_spd_cback
1767 *
1768 * Description   Finds a not in used SDP control block index
1769 *
1770 *
1771 * Returns      bool - true found
1772 *                        false not found
1773 *
1774 ******************************************************************************/
1775tSDP_DISC_CMPL_CB* bta_hl_allocate_spd_cback(tBTA_HL_SDP_OPER sdp_oper,
1776                                             uint8_t app_idx, uint8_t mcl_idx,
1777                                             uint8_t mdl_idx,
1778                                             uint8_t* p_sdp_cback_idx) {
1779  uint8_t i;
1780  tSDP_DISC_CMPL_CB* p_cbcak = NULL;
1781
1782  for (i = 0; i < BTA_HL_NUM_SDP_CBACKS; i++) {
1783    if (!bta_hl_cb.scb[i].in_use) {
1784      p_cbcak = bta_hl_sdp_cback_arr[i];
1785      bta_hl_cb.scb[i].in_use = true;
1786      bta_hl_cb.scb[i].sdp_oper = sdp_oper;
1787      bta_hl_cb.scb[i].app_idx = app_idx;
1788      bta_hl_cb.scb[i].mcl_idx = mcl_idx;
1789      bta_hl_cb.scb[i].mdl_idx = mdl_idx;
1790      *p_sdp_cback_idx = i;
1791      break;
1792    }
1793  }
1794
1795  if (i == BTA_HL_NUM_SDP_CBACKS) {
1796    APPL_TRACE_WARNING("No scb is available to allocate")
1797  } else {
1798#if (BTA_HL_DEBUG == TRUE)
1799    APPL_TRACE_DEBUG("bta_hl_allocate_spd_cback cback_idx=%d ", i);
1800    APPL_TRACE_DEBUG("sdp_oper=%d, app_idx=%d, mcl_idx=%d,  mdl_idx=%d",
1801                     bta_hl_cb.scb[i].sdp_oper, bta_hl_cb.scb[i].app_idx,
1802                     bta_hl_cb.scb[i].mcl_idx, bta_hl_cb.scb[i].mdl_idx);
1803#endif
1804  }
1805  return p_cbcak;
1806}
1807
1808/*******************************************************************************
1809 *
1810 * Function         bta_hl_init_sdp
1811 *
1812 * Description      Action routine for processing the SDP initiattion request
1813 *
1814 * Returns          void
1815 *
1816 ******************************************************************************/
1817tBTA_HL_STATUS bta_hl_init_sdp(tBTA_HL_SDP_OPER sdp_oper, uint8_t app_idx,
1818                               uint8_t mcl_idx, uint8_t mdl_idx) {
1819  tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1820  tSDP_UUID uuid_list;
1821  uint16_t attr_list[BTA_HL_NUM_SRCH_ATTR];
1822  uint16_t num_attrs = BTA_HL_NUM_SRCH_ATTR;
1823  tBTA_HL_STATUS status;
1824  uint8_t sdp_cback_idx;
1825#if (BTA_HL_DEBUG == TRUE)
1826  APPL_TRACE_DEBUG(
1827      "bta_hl_init_sdp sdp_oper=%d app_idx=%d mcl_idx=%d, mdl_idx=%d", sdp_oper,
1828      app_idx, mcl_idx, mdl_idx);
1829#endif
1830  p_cb->sdp_cback = bta_hl_allocate_spd_cback(sdp_oper, app_idx, mcl_idx,
1831                                              mdl_idx, &sdp_cback_idx);
1832  if (p_cb->sdp_cback != NULL) {
1833    if (p_cb->p_db == NULL)
1834      (p_cb->p_db = (tSDP_DISCOVERY_DB*)osi_malloc(BTA_HL_DISC_SIZE));
1835    attr_list[0] = ATTR_ID_SERVICE_CLASS_ID_LIST;
1836    attr_list[1] = ATTR_ID_PROTOCOL_DESC_LIST;
1837    attr_list[2] = ATTR_ID_BT_PROFILE_DESC_LIST;
1838    attr_list[3] = ATTR_ID_ADDITION_PROTO_DESC_LISTS;
1839    attr_list[4] = ATTR_ID_SERVICE_NAME;
1840    attr_list[5] = ATTR_ID_SERVICE_DESCRIPTION;
1841    attr_list[6] = ATTR_ID_PROVIDER_NAME;
1842    attr_list[7] = ATTR_ID_HDP_SUP_FEAT_LIST;
1843    attr_list[8] = ATTR_ID_HDP_DATA_EXCH_SPEC;
1844    attr_list[9] = ATTR_ID_HDP_MCAP_SUP_PROC;
1845
1846    uuid_list.len = LEN_UUID_16;
1847    uuid_list.uu.uuid16 = UUID_SERVCLASS_HDP_PROFILE;
1848    SDP_InitDiscoveryDb(p_cb->p_db, BTA_HL_DISC_SIZE, 1, &uuid_list, num_attrs,
1849                        attr_list);
1850
1851    if (!SDP_ServiceSearchAttributeRequest(p_cb->bd_addr, p_cb->p_db,
1852                                           p_cb->sdp_cback)) {
1853      status = BTA_HL_STATUS_FAIL;
1854    } else {
1855      status = BTA_HL_STATUS_OK;
1856    }
1857  } else {
1858    status = BTA_HL_STATUS_SDP_NO_RESOURCE;
1859  }
1860
1861  if (status != BTA_HL_STATUS_OK) {
1862    osi_free_and_reset((void**)&p_cb->p_db);
1863    if (status != BTA_HL_STATUS_SDP_NO_RESOURCE)
1864      bta_hl_deallocate_spd_cback(sdp_cback_idx);
1865  }
1866
1867  return status;
1868}
1869
1870/*******************************************************************************
1871 *
1872 * Function         bta_hl_cch_sdp_init
1873 *
1874 * Description      Action routine for processing the CCH SDP init event
1875 *
1876 * Returns          void
1877 *
1878 ******************************************************************************/
1879void bta_hl_cch_sdp_init(uint8_t app_idx, uint8_t mcl_idx,
1880                         tBTA_HL_DATA* p_data) {
1881  tBTA_HL_MCL_CB* p_cb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1882#if (BTA_HL_DEBUG == TRUE)
1883  APPL_TRACE_DEBUG("bta_hl_cch_init_sdp");
1884#endif
1885  if (p_cb->sdp_oper == BTA_HL_SDP_OP_NONE) {
1886    p_cb->app_id = p_data->api_cch_open.app_id;
1887    p_cb->sdp_oper = BTA_HL_SDP_OP_CCH_INIT;
1888
1889    if (bta_hl_init_sdp(p_cb->sdp_oper, app_idx, mcl_idx, 0xFF) !=
1890        BTA_HL_STATUS_OK) {
1891      p_cb->sdp_oper = BTA_HL_SDP_OP_NONE;
1892      bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_SDP_FAIL_EVT, p_data);
1893    }
1894  } else {
1895    APPL_TRACE_ERROR("SDP in use");
1896    bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_SDP_FAIL_EVT, p_data);
1897  }
1898}
1899
1900/*******************************************************************************
1901 *
1902 * Function         bta_hl_cch_mca_open
1903 *
1904 * Description      Action routine for processing the CCH open request
1905 *
1906 * Returns          void
1907 *
1908 ******************************************************************************/
1909void bta_hl_cch_mca_open(uint8_t app_idx, uint8_t mcl_idx,
1910                         tBTA_HL_DATA* p_data) {
1911  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1912  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1913  uint8_t sdp_idx;
1914
1915#if (BTA_HL_DEBUG == TRUE)
1916  APPL_TRACE_DEBUG("bta_hl_cch_mca_open");
1917#endif
1918
1919  if (bta_hl_find_sdp_idx_using_ctrl_psm(&p_mcb->sdp, p_mcb->req_ctrl_psm,
1920                                         &sdp_idx)) {
1921    p_mcb->ctrl_psm = p_mcb->sdp.sdp_rec[sdp_idx].ctrl_psm;
1922    p_mcb->data_psm = p_mcb->sdp.sdp_rec[sdp_idx].data_psm;
1923    if (MCA_ConnectReq((tMCA_HANDLE)p_acb->app_handle, p_mcb->bd_addr,
1924                       p_mcb->ctrl_psm, p_mcb->sec_mask) != MCA_SUCCESS) {
1925      bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT,
1926                            p_data);
1927    }
1928  } else {
1929    bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data);
1930  }
1931}
1932
1933/*******************************************************************************
1934 *
1935 * Function         bta_hl_cch_mca_close
1936 *
1937 * Description      Action routine for processing the CCH close request
1938 *
1939 * Returns          void
1940 *
1941 ******************************************************************************/
1942void bta_hl_cch_mca_close(uint8_t app_idx, uint8_t mcl_idx,
1943                          tBTA_HL_DATA* p_data) {
1944  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1945
1946#if (BTA_HL_DEBUG == TRUE)
1947  APPL_TRACE_DEBUG("bta_hl_cch_mca_close mcl_handle=%d", p_mcb->mcl_handle);
1948#endif
1949  if (p_mcb->sdp_oper != BTA_HL_SDP_OP_CCH_INIT) {
1950    if (p_mcb->mcl_handle) {
1951      if (MCA_DisconnectReq((tMCA_HANDLE)p_mcb->mcl_handle) != MCA_SUCCESS) {
1952        bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT,
1953                              p_data);
1954      }
1955    } else {
1956      p_mcb->close_pending = true;
1957      APPL_TRACE_DEBUG(
1958          "No valid mcl_handle to stop the CCH setup now so wait until CCH is "
1959          "up then close it");
1960    }
1961  } else {
1962    p_mcb->close_pending = true;
1963    APPL_TRACE_DEBUG(
1964        "can not stop the CCH setup becasue SDP is in progress so wait until "
1965        "it is done");
1966  }
1967}
1968
1969/*******************************************************************************
1970 *
1971 * Function         bta_hl_cch_close_cmpl
1972 *
1973 * Description      Action routine for processing the CCH close complete event
1974 *
1975 * Returns          void
1976 *
1977 ******************************************************************************/
1978void bta_hl_cch_close_cmpl(uint8_t app_idx, uint8_t mcl_idx,
1979                           tBTA_HL_DATA* p_data) {
1980  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
1981  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1982
1983  tBTA_HL evt_data;
1984  tBTA_HL_EVT event;
1985  bool send_evt = true;
1986#if (BTA_HL_DEBUG == TRUE)
1987  APPL_TRACE_DEBUG("bta_hl_cch_close_cmpl");
1988#endif
1989  bta_sys_conn_close(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr);
1990
1991  if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE &&
1992      p_mcb->force_close_local_cch_opening) {
1993    p_mcb->cch_oper = BTA_HL_CCH_OP_LOCAL_OPEN;
1994    APPL_TRACE_DEBUG(
1995        "change cch_oper from BTA_HL_CCH_OP_LOCAL_CLOSE to "
1996        "BTA_HL_CCH_OP_LOCAL_OPEN");
1997  }
1998
1999  switch (p_mcb->cch_oper) {
2000    case BTA_HL_CCH_OP_LOCAL_OPEN:
2001      bta_hl_build_cch_open_cfm(&evt_data, p_mcb->app_id, p_acb->app_handle,
2002                                p_mcb->mcl_handle, p_mcb->bd_addr,
2003                                BTA_HL_STATUS_FAIL);
2004      event = BTA_HL_CCH_OPEN_CFM_EVT;
2005      break;
2006    case BTA_HL_CCH_OP_LOCAL_CLOSE:
2007      bta_hl_build_cch_close_cfm(&evt_data, p_acb->app_handle,
2008                                 p_mcb->mcl_handle, BTA_HL_STATUS_OK);
2009      event = BTA_HL_CCH_CLOSE_CFM_EVT;
2010      break;
2011    case BTA_HL_CCH_OP_REMOTE_CLOSE:
2012      bta_hl_build_cch_close_ind(&evt_data, p_acb->app_handle,
2013                                 p_mcb->mcl_handle, p_mcb->intentional_close);
2014      event = BTA_HL_CCH_CLOSE_IND_EVT;
2015      break;
2016    default:
2017      send_evt = false;
2018      break;
2019  }
2020
2021  memset(p_mcb, 0, sizeof(tBTA_HL_MCL_CB));
2022
2023  if (send_evt) p_acb->p_cback(event, (tBTA_HL*)&evt_data);
2024
2025  bta_hl_check_deregistration(app_idx, p_data);
2026}
2027
2028/*******************************************************************************
2029 *
2030 * Function         bta_hl_cch_mca_disconnect
2031 *
2032 * Description      Action routine for processing the CCH disconnect indication
2033 *
2034 * Returns          void
2035 *
2036 ******************************************************************************/
2037void bta_hl_cch_mca_disconnect(uint8_t app_idx, uint8_t mcl_idx,
2038                               tBTA_HL_DATA* p_data) {
2039  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2040  tBTA_HL_MDL_CB* p_dcb;
2041  uint8_t i;
2042#if (BTA_HL_DEBUG == TRUE)
2043  APPL_TRACE_DEBUG("bta_hl_cch_mca_disconnect");
2044#endif
2045
2046  p_mcb->intentional_close = false;
2047  if (p_data->mca_evt.mca_data.disconnect_ind.reason == L2CAP_DISC_OK) {
2048    p_mcb->intentional_close = true;
2049  }
2050
2051  for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
2052    p_dcb = BTA_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, i);
2053    if (p_dcb->in_use && (p_dcb->dch_state != BTA_HL_DCH_IDLE_ST)) {
2054      if (p_mcb->cch_oper == BTA_HL_CCH_OP_LOCAL_CLOSE) {
2055        bta_hl_dch_sm_execute(app_idx, mcl_idx, i, BTA_HL_DCH_CLOSE_CMPL_EVT,
2056                              p_data);
2057      } else {
2058        bta_hl_dch_sm_execute(app_idx, mcl_idx, i, BTA_HL_MCA_CLOSE_IND_EVT,
2059                              p_data);
2060      }
2061    }
2062  }
2063  bta_hl_cch_sm_execute(app_idx, mcl_idx, BTA_HL_CCH_CLOSE_CMPL_EVT, p_data);
2064}
2065
2066/*******************************************************************************
2067 *
2068 * Function         bta_hl_cch_mca_disc_open
2069 *
2070 * Description      Action routine for disconnect the just opened Control
2071 *                  channel
2072 *
2073 * Returns          void
2074 *
2075 ******************************************************************************/
2076void bta_hl_cch_mca_disc_open(uint8_t app_idx, uint8_t mcl_idx,
2077                              tBTA_HL_DATA* p_data) {
2078  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2079
2080#if (BTA_HL_DEBUG == TRUE)
2081  APPL_TRACE_DEBUG("bta_hl_cch_mca_disc_open mcl_handle=0x%x close_pending=%d",
2082                   p_data->mca_evt.mcl_handle, p_mcb->close_pending);
2083#endif
2084
2085  p_mcb->close_pending = false;
2086  p_mcb->mcl_handle = p_data->mca_evt.mcl_handle;
2087  bta_hl_cch_mca_close(app_idx, mcl_idx, p_data);
2088}
2089
2090/*******************************************************************************
2091 *
2092 * Function         bta_hl_cch_mca_rsp_tout
2093 *
2094 * Description      Action routine for processing the MCAP response timeout
2095 *
2096 * Returns          void
2097 *
2098 ******************************************************************************/
2099void bta_hl_cch_mca_rsp_tout(uint8_t app_idx, uint8_t mcl_idx,
2100                             tBTA_HL_DATA* p_data) {
2101  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2102#if (BTA_HL_DEBUG == TRUE)
2103  APPL_TRACE_DEBUG("bta_hl_cch_mca_rsp_tout");
2104#endif
2105
2106  p_mcb->rsp_tout = true;
2107
2108  bta_hl_check_cch_close(app_idx, mcl_idx, p_data, true);
2109}
2110
2111/*******************************************************************************
2112 *
2113 * Function         bta_hl_cch_mca_connect
2114 *
2115 * Description      Action routine for processing the CCH connect indication
2116 *
2117 * Returns          void
2118 *
2119 ******************************************************************************/
2120void bta_hl_cch_mca_connect(uint8_t app_idx, uint8_t mcl_idx,
2121                            tBTA_HL_DATA* p_data) {
2122  tBTA_HL_APP_CB* p_acb = BTA_HL_GET_APP_CB_PTR(app_idx);
2123  tBTA_HL_MCL_CB* p_mcb = BTA_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2124  tBTA_HL evt_data;
2125  tBTA_HL_EVT event;
2126  bool send_event = true;
2127
2128#if (BTA_HL_DEBUG == TRUE)
2129  APPL_TRACE_DEBUG("bta_hl_cch_mca_connect mcl_handle=%d ",
2130                   p_data->mca_evt.mcl_handle);
2131#endif
2132
2133  p_mcb->mcl_handle = p_data->mca_evt.mcl_handle;
2134  p_mcb->bd_addr = p_data->mca_evt.mca_data.connect_ind.bd_addr;
2135  p_mcb->cch_mtu = p_data->mca_evt.mca_data.connect_ind.mtu;
2136
2137  bta_sys_conn_open(BTA_ID_HL, p_acb->app_id, p_mcb->bd_addr);
2138  switch (p_mcb->cch_oper) {
2139    case BTA_HL_CCH_OP_LOCAL_OPEN:
2140      bta_hl_build_cch_open_cfm(&evt_data, p_mcb->app_id, p_acb->app_handle,
2141                                p_mcb->mcl_handle, p_mcb->bd_addr,
2142                                BTA_HL_STATUS_OK);
2143      event = BTA_HL_CCH_OPEN_CFM_EVT;
2144      break;
2145    case BTA_HL_CCH_OP_REMOTE_OPEN:
2146      bta_hl_build_cch_open_ind(&evt_data, p_acb->app_handle, p_mcb->mcl_handle,
2147                                p_mcb->bd_addr);
2148      event = BTA_HL_CCH_OPEN_IND_EVT;
2149      break;
2150    default:
2151      send_event = false;
2152      break;
2153  }
2154
2155  p_mcb->cch_oper = BTA_HL_CCH_OP_NONE;
2156  if (send_event) p_acb->p_cback(event, (tBTA_HL*)&evt_data);
2157}
2158
2159/*******************************************************************************
2160 *
2161 * Function         bta_hl_mcap_ctrl_cback
2162 *
2163 * Description      MCAP control callback function for HL.
2164 *
2165 * Returns          void
2166 *
2167 ******************************************************************************/
2168void bta_hl_mcap_ctrl_cback(tMCA_HANDLE handle, tMCA_CL mcl, uint8_t event,
2169                            tMCA_CTRL* p_data) {
2170  bool send_event = true;
2171  uint16_t mca_event;
2172
2173#if (BTA_HL_DEBUG == TRUE)
2174  APPL_TRACE_EVENT("bta_hl_mcap_ctrl_cback event[%s]",
2175                   bta_hl_mcap_evt_code(event));
2176#endif
2177
2178  switch (event) {
2179    case MCA_CREATE_IND_EVT:
2180      mca_event = (uint16_t)BTA_HL_MCA_CREATE_IND_EVT;
2181      break;
2182    case MCA_CREATE_CFM_EVT:
2183      mca_event = (uint16_t)BTA_HL_MCA_CREATE_CFM_EVT;
2184      break;
2185    case MCA_RECONNECT_IND_EVT:
2186      mca_event = (uint16_t)BTA_HL_MCA_RECONNECT_IND_EVT;
2187      break;
2188    case MCA_RECONNECT_CFM_EVT:
2189      mca_event = (uint16_t)BTA_HL_MCA_RECONNECT_CFM_EVT;
2190      break;
2191    case MCA_ABORT_IND_EVT:
2192      mca_event = (uint16_t)BTA_HL_MCA_ABORT_IND_EVT;
2193      break;
2194    case MCA_ABORT_CFM_EVT:
2195      mca_event = (uint16_t)BTA_HL_MCA_ABORT_CFM_EVT;
2196      break;
2197    case MCA_DELETE_IND_EVT:
2198      mca_event = (uint16_t)BTA_HL_MCA_DELETE_IND_EVT;
2199      break;
2200    case MCA_DELETE_CFM_EVT:
2201      mca_event = (uint16_t)BTA_HL_MCA_DELETE_CFM_EVT;
2202      break;
2203    case MCA_CONNECT_IND_EVT:
2204      mca_event = (uint16_t)BTA_HL_MCA_CONNECT_IND_EVT;
2205      break;
2206    case MCA_DISCONNECT_IND_EVT:
2207      mca_event = (uint16_t)BTA_HL_MCA_DISCONNECT_IND_EVT;
2208      break;
2209    case MCA_OPEN_IND_EVT:
2210      mca_event = (uint16_t)BTA_HL_MCA_OPEN_IND_EVT;
2211      break;
2212    case MCA_OPEN_CFM_EVT:
2213      mca_event = (uint16_t)BTA_HL_MCA_OPEN_CFM_EVT;
2214      break;
2215    case MCA_CLOSE_IND_EVT:
2216      mca_event = (uint16_t)BTA_HL_MCA_CLOSE_IND_EVT;
2217      break;
2218    case MCA_CLOSE_CFM_EVT:
2219      mca_event = (uint16_t)BTA_HL_MCA_CLOSE_CFM_EVT;
2220      break;
2221    case MCA_CONG_CHG_EVT:
2222      mca_event = (uint16_t)BTA_HL_MCA_CONG_CHG_EVT;
2223      break;
2224    case MCA_RSP_TOUT_IND_EVT:
2225      mca_event = (uint16_t)BTA_HL_MCA_RSP_TOUT_IND_EVT;
2226      break;
2227    case MCA_ERROR_RSP_EVT:
2228
2229    default:
2230      send_event = false;
2231      break;
2232  }
2233
2234  if (send_event) {
2235    tBTA_HL_MCA_EVT* p_msg =
2236        (tBTA_HL_MCA_EVT*)osi_malloc(sizeof(tBTA_HL_MCA_EVT));
2237    p_msg->hdr.event = mca_event;
2238    p_msg->app_handle = (tBTA_HL_APP_HANDLE)handle;
2239    p_msg->mcl_handle = (tBTA_HL_MCL_HANDLE)mcl;
2240    memcpy(&p_msg->mca_data, p_data, sizeof(tMCA_CTRL));
2241    bta_sys_sendmsg(p_msg);
2242  }
2243}
2244
2245/*******************************************************************************
2246 *
2247 * Function         bta_hl_mcap_data_cback
2248 *
2249 * Description      MCAP data callback function for HL.
2250 *
2251 * Returns          void
2252 *
2253 ******************************************************************************/
2254void bta_hl_mcap_data_cback(tMCA_DL mdl, BT_HDR* p_pkt) {
2255  uint8_t app_idx, mcl_idx, mdl_idx;
2256  if (bta_hl_find_mdl_idx_using_handle((tBTA_HL_MDL_HANDLE)mdl, &app_idx,
2257                                       &mcl_idx, &mdl_idx)) {
2258    tBTA_HL_MCA_RCV_DATA_EVT* p_msg =
2259        (tBTA_HL_MCA_RCV_DATA_EVT*)osi_malloc(sizeof(tBTA_HL_MCA_RCV_DATA_EVT));
2260    p_msg->hdr.event = BTA_HL_MCA_RCV_DATA_EVT;
2261    p_msg->app_idx = app_idx;
2262    p_msg->mcl_idx = mcl_idx;
2263    p_msg->mdl_idx = mdl_idx;
2264    p_msg->p_pkt = p_pkt;
2265    bta_sys_sendmsg(p_msg);
2266  }
2267}
2268
2269/*****************************************************************************
2270 *  Debug Functions
2271 ****************************************************************************/
2272#if (BTA_HL_DEBUG == TRUE)
2273
2274#define CASE_RETURN_STR(const) \
2275  case const:                  \
2276    return #const;
2277
2278/*******************************************************************************
2279 *
2280 * Function         bta_hl_mcap_evt_code
2281 *
2282 * Description      get the MCAP event string pointer
2283 *
2284 * Returns          char * - event string pointer
2285 *
2286 ******************************************************************************/
2287static const char* bta_hl_mcap_evt_code(uint8_t evt_code) {
2288  switch (evt_code) {
2289    CASE_RETURN_STR(MCA_ERROR_RSP_EVT)
2290    CASE_RETURN_STR(MCA_CREATE_IND_EVT)
2291    CASE_RETURN_STR(MCA_CREATE_CFM_EVT)
2292    CASE_RETURN_STR(MCA_RECONNECT_IND_EVT)
2293    CASE_RETURN_STR(MCA_RECONNECT_CFM_EVT)
2294    CASE_RETURN_STR(MCA_ABORT_IND_EVT)
2295    CASE_RETURN_STR(MCA_ABORT_CFM_EVT)
2296    CASE_RETURN_STR(MCA_DELETE_IND_EVT)
2297    CASE_RETURN_STR(MCA_DELETE_CFM_EVT)
2298    CASE_RETURN_STR(MCA_CONNECT_IND_EVT)
2299    CASE_RETURN_STR(MCA_DISCONNECT_IND_EVT)
2300    CASE_RETURN_STR(MCA_OPEN_IND_EVT)
2301    CASE_RETURN_STR(MCA_OPEN_CFM_EVT)
2302    CASE_RETURN_STR(MCA_CLOSE_IND_EVT)
2303    CASE_RETURN_STR(MCA_CLOSE_CFM_EVT)
2304    CASE_RETURN_STR(MCA_CONG_CHG_EVT)
2305    CASE_RETURN_STR(MCA_RSP_TOUT_IND_EVT)
2306    default:
2307      return "Unknown MCAP event code";
2308  }
2309}
2310
2311/*******************************************************************************
2312 *
2313 * Function         bta_hl_cback_evt_code
2314 *
2315 * Description      get the HDP event string pointer
2316 *
2317 * Returns          char * - event string pointer
2318 *
2319 ******************************************************************************/
2320static const char* bta_hl_cback_evt_code(uint8_t evt_code) {
2321  switch (evt_code) {
2322    CASE_RETURN_STR(BTA_HL_CCH_OPEN_IND_EVT)
2323    CASE_RETURN_STR(BTA_HL_CCH_OPEN_CFM_EVT)
2324    CASE_RETURN_STR(BTA_HL_CCH_CLOSE_IND_EVT)
2325    CASE_RETURN_STR(BTA_HL_CCH_CLOSE_CFM_EVT)
2326    CASE_RETURN_STR(BTA_HL_DCH_OPEN_IND_EVT)
2327    CASE_RETURN_STR(BTA_HL_DCH_OPEN_CFM_EVT)
2328    CASE_RETURN_STR(BTA_HL_DCH_CLOSE_IND_EVT)
2329    CASE_RETURN_STR(BTA_HL_DCH_CLOSE_CFM_EVT)
2330    CASE_RETURN_STR(BTA_HL_DCH_RCV_DATA_IND_EVT)
2331    CASE_RETURN_STR(BTA_HL_REGISTER_CFM_EVT)
2332    CASE_RETURN_STR(BTA_HL_DEREGISTER_CFM_EVT)
2333    CASE_RETURN_STR(BTA_HL_DCH_RECONNECT_CFM_EVT)
2334    CASE_RETURN_STR(BTA_HL_DCH_RECONNECT_IND_EVT)
2335    CASE_RETURN_STR(BTA_HL_DCH_ECHO_TEST_CFM_EVT)
2336    CASE_RETURN_STR(BTA_HL_SDP_QUERY_CFM_EVT)
2337    CASE_RETURN_STR(BTA_HL_CONG_CHG_IND_EVT)
2338    CASE_RETURN_STR(BTA_HL_DCH_CREATE_IND_EVT)
2339    CASE_RETURN_STR(BTA_HL_DELETE_MDL_IND_EVT)
2340    CASE_RETURN_STR(BTA_HL_DELETE_MDL_CFM_EVT)
2341    CASE_RETURN_STR(BTA_HL_DCH_ABORT_IND_EVT)
2342    CASE_RETURN_STR(BTA_HL_DCH_ABORT_CFM_EVT)
2343    default:
2344      return "Unknown HDP event code";
2345  }
2346}
2347
2348/*******************************************************************************
2349 *
2350 * Function         bta_hl_dch_oper_code
2351 *
2352 * Description      Get the DCH operation string
2353 *
2354 * Returns          char * - DCH operation string pointer
2355 *
2356 ******************************************************************************/
2357static const char* bta_hl_dch_oper_code(tBTA_HL_DCH_OPER oper_code) {
2358  switch (oper_code) {
2359    CASE_RETURN_STR(BTA_HL_DCH_OP_NONE)
2360    CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_CREATE)
2361    CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_OPEN)
2362    CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_OPEN)
2363    CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_CLOSE)
2364    CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_CLOSE)
2365    CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_DELETE)
2366    CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_DELETE)
2367    CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_RECONNECT)
2368    CASE_RETURN_STR(BTA_HL_DCH_OP_REMOTE_RECONNECT)
2369    CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_CLOSE_ECHO_TEST)
2370    CASE_RETURN_STR(BTA_HL_DCH_OP_LOCAL_CLOSE_RECONNECT)
2371    default:
2372      return "Unknown DCH oper code";
2373  }
2374}
2375
2376#endif /* Debug Functions */
2377#endif /* HL_INCLUDED */
2378