1 /******************************************************************************
2 *
3 * Copyright 2009-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 * Filename: btif_hl.c
22 *
23 * Description: Health Device Profile Bluetooth Interface
24 *
25 *
26 ******************************************************************************/
27 #define LOG_TAG "bt_btif_hl"
28
29 #include "btif_hl.h"
30
31 #include <base/logging.h>
32 #include <ctype.h>
33 #include <errno.h>
34 #include <fcntl.h>
35 #include <pthread.h>
36 #include <signal.h>
37 #include <stdio.h>
38 #include <stdlib.h>
39 #include <string.h>
40 #include <sys/poll.h>
41 #include <sys/prctl.h>
42 #include <sys/select.h>
43 #include <sys/socket.h>
44 #include <sys/types.h>
45 #include <sys/un.h>
46 #include <time.h>
47 #include <unistd.h>
48
49 #include <hardware/bt_hl.h>
50
51 #include "bta_api.h"
52 #include "btif_common.h"
53 #include "btif_storage.h"
54 #include "btif_util.h"
55 #include "btu.h"
56 #include "mca_api.h"
57 #include "osi/include/list.h"
58 #include "osi/include/log.h"
59 #include "osi/include/osi.h"
60
61 #define MAX_DATATYPE_SUPPORTED 8
62
63 extern int btif_hl_update_maxfd(int max_org_s);
64 extern void btif_hl_select_monitor_callback(fd_set* p_cur_set,
65 UNUSED_ATTR fd_set* p_org_set);
66 extern void btif_hl_select_wakeup_callback(fd_set* p_org_set,
67 int wakeup_signal);
68 extern int btif_hl_update_maxfd(int max_org_s);
69 extern void btif_hl_select_monitor_callback(fd_set* p_cur_set,
70 UNUSED_ATTR fd_set* p_org_set);
71 extern void btif_hl_select_wakeup_callback(fd_set* p_org_set,
72 int wakeup_signal);
73 extern void btif_hl_soc_thread_init(void);
74 extern void btif_hl_release_mcl_sockets(uint8_t app_idx, uint8_t mcl_idx);
75 extern bool btif_hl_create_socket(uint8_t app_idx, uint8_t mcl_idx,
76 uint8_t mdl_idx);
77 extern void btif_hl_release_socket(uint8_t app_idx, uint8_t mcl_idx,
78 uint8_t mdl_idx);
79
80 btif_hl_cb_t btif_hl_cb;
81 btif_hl_cb_t* p_btif_hl_cb = &btif_hl_cb;
82
83 /*******************************************************************************
84 * Static variables
85 ******************************************************************************/
86 static bthl_callbacks_t bt_hl_callbacks_cb;
87 static bthl_callbacks_t* bt_hl_callbacks = NULL;
88
89 /* signal socketpair to wake up select loop */
90
91 const int btif_hl_signal_select_wakeup = 1;
92 const int btif_hl_signal_select_exit = 2;
93 const int btif_hl_signal_select_close_connected = 3;
94
95 static int listen_s = -1;
96 static int connected_s = -1;
97 static pthread_t select_thread_id = -1;
98 static int signal_fds[2] = {-1, -1};
99 static list_t* soc_queue;
100 static int reg_counter;
101
102 static inline int btif_hl_select_wakeup(void);
103 static inline int btif_hl_select_close_connected(void);
104 static inline int btif_hl_close_select_thread(void);
105 static uint8_t btif_hl_get_next_app_id(void);
106 static int btif_hl_get_next_channel_id(uint8_t app_id);
107 static void btif_hl_init_next_app_id(void);
108 static void btif_hl_init_next_channel_id(void);
109 static void btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event, tBTA_HL_CTRL* p_data);
110 static void btif_hl_set_state(btif_hl_state_t state);
111 static btif_hl_state_t btif_hl_get_state(void);
112 static void btif_hl_cback(tBTA_HL_EVT event, tBTA_HL* p_data);
113 static void btif_hl_proc_cb_evt(uint16_t event, char* p_param);
114
115 #define CHECK_CALL_CBACK(P_CB, P_CBACK, ...) \
116 do { \
117 if ((P_CB) && (P_CB)->P_CBACK) { \
118 (P_CB)->P_CBACK(__VA_ARGS__); \
119 } else { \
120 ASSERTC(0, "Callback is NULL", 0); \
121 } \
122 } while (0)
123
124 #define BTIF_HL_CALL_CBACK(P_CB, P_CBACK, ...) \
125 do { \
126 if ((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) && \
127 (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED)) { \
128 if ((P_CB) && (P_CB)->P_CBACK) { \
129 (P_CB)->P_CBACK(__VA_ARGS__); \
130 } else { \
131 ASSERTC(0, "Callback is NULL", 0); \
132 } \
133 } \
134 } while (0)
135
136 #define CHECK_BTHL_INIT() \
137 do { \
138 if (bt_hl_callbacks == NULL) { \
139 BTIF_TRACE_WARNING("BTHL: %s: BTHL not initialized", __func__); \
140 return BT_STATUS_NOT_READY; \
141 } \
142 } while (0)
143
144 static const btif_hl_data_type_cfg_t data_type_table[] = {
145 /* Data Specilization Ntx Nrx (from Bluetooth SIG's
146 HDP whitepaper)*/
147 {BTIF_HL_DATA_TYPE_PULSE_OXIMETER, 9216, 256},
148 {BTIF_HL_DATA_TYPE_BLOOD_PRESSURE_MON, 896, 224},
149 {BTIF_HL_DATA_TYPE_BODY_THERMOMETER, 896, 224},
150 {BTIF_HL_DATA_TYPE_BODY_WEIGHT_SCALE, 896, 224},
151 {BTIF_HL_DATA_TYPE_GLUCOSE_METER, 896, 224},
152 {BTIF_HL_DATA_TYPE_STEP_COUNTER, 6624, 224},
153 {BTIF_HL_DATA_TYPE_BCA, 7730, 1230},
154 {BTIF_HL_DATA_TYPE_PEAK_FLOW, 2030, 224},
155 {BTIF_HL_DATA_TYPE_ACTIVITY_HUB, 5120, 224},
156 {BTIF_HL_DATA_TYPE_AMM, 1024, 64}};
157
158 #define BTIF_HL_DATA_TABLE_SIZE \
159 (sizeof(data_type_table) / sizeof(btif_hl_data_type_cfg_t))
160 #define BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE \
161 10240 /* use this size if the data type is not \
162 defined in the table; for future proof */
163 #define BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE \
164 512 /* use this size if the data type is not \
165 defined in the table; for future proof */
166
167 #define BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE 1024
168
169 /*******************************************************************************
170 * Static utility functions
171 ******************************************************************************/
172
173 #define BTIF_IF_GET_NAME 16
btif_hl_display_calling_process_name(void)174 void btif_hl_display_calling_process_name(void) {
175 char name[16];
176 prctl(BTIF_IF_GET_NAME, name, 0, 0, 0);
177 BTIF_TRACE_DEBUG("Process name (%s)", name);
178 }
179 #define BTIF_TIMEOUT_CCH_NO_DCH_MS (30 * 1000)
180
181 /*******************************************************************************
182 *
183 * Function btif_hl_if_channel_setup_pending
184 *
185 * Description check whether channel id is in setup pending state or not
186 *
187 * Returns bool
188 *
189 ******************************************************************************/
btif_hl_if_channel_setup_pending(int channel_id,uint8_t * p_app_idx,uint8_t * p_mcl_idx)190 bool btif_hl_if_channel_setup_pending(int channel_id, uint8_t* p_app_idx,
191 uint8_t* p_mcl_idx) {
192 btif_hl_app_cb_t* p_acb;
193 btif_hl_mcl_cb_t* p_mcb;
194 uint8_t i, j;
195 bool found = false;
196
197 *p_app_idx = 0;
198 *p_mcl_idx = 0;
199 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
200 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
201 if (p_acb->in_use) {
202 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
203 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j);
204 if (p_mcb->in_use && p_mcb->is_connected &&
205 p_mcb->pcb.channel_id == channel_id) {
206 found = true;
207 *p_app_idx = i;
208 *p_mcl_idx = j;
209 break;
210 }
211 }
212 }
213 if (found) break;
214 }
215 BTIF_TRACE_DEBUG("%s found=%d channel_id=0x%08x", __func__, found, channel_id,
216 *p_app_idx, *p_mcl_idx);
217 return found;
218 }
219 /*******************************************************************************
220 *
221 * Function btif_hl_num_dchs_in_use
222 *
223 * Description find number of DCHs in use
224 *
225 * Returns uint8_t
226 ******************************************************************************/
btif_hl_num_dchs_in_use(uint8_t mcl_handle)227 uint8_t btif_hl_num_dchs_in_use(uint8_t mcl_handle) {
228 btif_hl_app_cb_t* p_acb;
229 btif_hl_mcl_cb_t* p_mcb;
230 uint8_t i, j, x;
231 uint8_t cnt = 0;
232
233 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
234 BTIF_TRACE_DEBUG("btif_hl_num_dchs:i = %d", i);
235 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
236 if (p_acb && p_acb->in_use) {
237 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
238 if (p_acb->mcb[j].in_use)
239 BTIF_TRACE_DEBUG(
240 "btif_hl_num_dchs:mcb in use j=%d, mcl_handle=%d,mcb handle=%d",
241 j, mcl_handle, p_acb->mcb[j].mcl_handle);
242 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
243 p_mcb = &p_acb->mcb[j];
244 BTIF_TRACE_DEBUG("btif_hl_num_dchs: mcl handle found j =%d", j);
245 for (x = 0; x < BTA_HL_NUM_MDLS_PER_MCL; x++) {
246 if (p_mcb->mdl[x].in_use) {
247 BTIF_TRACE_DEBUG("btif_hl_num_dchs_in_use:found x =%d", x);
248 cnt++;
249 }
250 }
251 }
252 }
253 }
254 }
255
256 BTIF_TRACE_DEBUG("%s dch in use count=%d", __func__, cnt);
257 return cnt;
258 }
259 /*******************************************************************************
260 *
261 * Function btif_hl_timer_timeout
262 *
263 * Description Process timer timeout
264 *
265 * Returns void
266 ******************************************************************************/
btif_hl_timer_timeout(void * data)267 void btif_hl_timer_timeout(void* data) {
268 btif_hl_mcl_cb_t* p_mcb = (btif_hl_mcl_cb_t*)data;
269
270 BTIF_TRACE_DEBUG("%s", __func__);
271 if (p_mcb->is_connected) {
272 BTIF_TRACE_DEBUG("Idle timeout Close CCH mcl_handle=%d", p_mcb->mcl_handle);
273 BTA_HlCchClose(p_mcb->mcl_handle);
274 } else {
275 BTIF_TRACE_DEBUG("CCH idle timeout But CCH not connected");
276 }
277 }
278
279 /*******************************************************************************
280 *
281 * Function btif_hl_stop_cch_timer
282 *
283 * Description stop CCH timer
284 *
285 * Returns void
286 ******************************************************************************/
btif_hl_stop_cch_timer(uint8_t app_idx,uint8_t mcl_idx)287 void btif_hl_stop_cch_timer(uint8_t app_idx, uint8_t mcl_idx) {
288 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
289
290 BTIF_TRACE_DEBUG("%s app_idx=%d, mcl_idx=%d", __func__, app_idx, mcl_idx);
291 alarm_cancel(p_mcb->cch_timer);
292 }
293
294 /*******************************************************************************
295 *
296 * Function btif_hl_start_cch_timer
297 *
298 * Description start CCH timer
299 *
300 * Returns void
301 ******************************************************************************/
btif_hl_start_cch_timer(uint8_t app_idx,uint8_t mcl_idx)302 void btif_hl_start_cch_timer(uint8_t app_idx, uint8_t mcl_idx) {
303 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
304 BTIF_TRACE_DEBUG("%s app_idx=%d, mcl_idx=%d", __func__, app_idx, mcl_idx);
305
306 alarm_free(p_mcb->cch_timer);
307 p_mcb->cch_timer = alarm_new("btif_hl.mcl_cch_timer");
308 alarm_set_on_mloop(p_mcb->cch_timer, BTIF_TIMEOUT_CCH_NO_DCH_MS,
309 btif_hl_timer_timeout, p_mcb);
310 }
311
312 /*******************************************************************************
313 *
314 * Function btif_hl_find_mdl_idx
315 *
316 * Description Find the MDL index using MDL ID
317 *
318 * Returns bool
319 *
320 ******************************************************************************/
btif_hl_find_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint16_t mdl_id,uint8_t * p_mdl_idx)321 static bool btif_hl_find_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
322 uint16_t mdl_id, uint8_t* p_mdl_idx) {
323 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
324 bool found = false;
325 uint8_t i;
326
327 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
328 if (p_mcb->mdl[i].in_use && (mdl_id != 0) &&
329 (p_mcb->mdl[i].mdl_id == mdl_id)) {
330 found = true;
331 *p_mdl_idx = i;
332 break;
333 }
334 }
335
336 BTIF_TRACE_DEBUG("%s found=%d mdl_id=%d mdl_idx=%d ", __func__, found, mdl_id,
337 i);
338
339 return found;
340 }
341
342 /*******************************************************************************
343 *
344 * Function btif_hl_is_the_first_reliable_existed
345 *
346 * Description This function checks whether the first reliable DCH channel
347 * has been setup on the MCL or not
348 *
349 * Returns bool - true exist
350 * false does not exist
351 *
352 ******************************************************************************/
btif_hl_is_the_first_reliable_existed(uint8_t app_idx,uint8_t mcl_idx)353 bool btif_hl_is_the_first_reliable_existed(uint8_t app_idx, uint8_t mcl_idx) {
354 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
355 bool is_existed = false;
356 uint8_t i;
357
358 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
359 if (p_mcb->mdl[i].in_use && p_mcb->mdl[i].is_the_first_reliable) {
360 is_existed = true;
361 break;
362 }
363 }
364
365 BTIF_TRACE_DEBUG("bta_hl_is_the_first_reliable_existed is_existed=%d ",
366 is_existed);
367 return is_existed;
368 }
369 /*******************************************************************************
370 *
371 * Function btif_hl_clean_delete_mdl
372 *
373 * Description Cleanup the delete mdl control block
374 *
375 * Returns Nothing
376 *
377 ******************************************************************************/
btif_hl_clean_delete_mdl(btif_hl_delete_mdl_t * p_cb)378 static void btif_hl_clean_delete_mdl(btif_hl_delete_mdl_t* p_cb) {
379 BTIF_TRACE_DEBUG("%s", __func__);
380 memset(p_cb, 0, sizeof(btif_hl_delete_mdl_t));
381 }
382
383 /*******************************************************************************
384 *
385 * Function btif_hl_clean_pcb
386 *
387 * Description Cleanup the pending chan control block
388 *
389 * Returns Nothing
390 *
391 ******************************************************************************/
btif_hl_clean_pcb(btif_hl_pending_chan_cb_t * p_pcb)392 static void btif_hl_clean_pcb(btif_hl_pending_chan_cb_t* p_pcb) {
393 BTIF_TRACE_DEBUG("%s", __func__);
394 memset(p_pcb, 0, sizeof(btif_hl_pending_chan_cb_t));
395 }
396
397 /*******************************************************************************
398 *
399 * Function btif_hl_clean_mdl_cb
400 *
401 * Description Cleanup the MDL control block
402 *
403 * Returns Nothing
404 *
405 ******************************************************************************/
btif_hl_clean_mdl_cb(btif_hl_mdl_cb_t * p_dcb)406 static void btif_hl_clean_mdl_cb(btif_hl_mdl_cb_t* p_dcb) {
407 BTIF_TRACE_DEBUG("%s", __func__);
408 osi_free_and_reset((void**)&p_dcb->p_rx_pkt);
409 osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
410 memset(p_dcb, 0, sizeof(btif_hl_mdl_cb_t));
411 }
412
413 /*******************************************************************************
414 *
415 * Function btif_hl_reset_mcb
416 *
417 * Description Reset MCL control block
418 *
419 * Returns bool
420 *
421 ******************************************************************************/
btif_hl_clean_mcl_cb(uint8_t app_idx,uint8_t mcl_idx)422 static void btif_hl_clean_mcl_cb(uint8_t app_idx, uint8_t mcl_idx) {
423 btif_hl_mcl_cb_t* p_mcb;
424 BTIF_TRACE_DEBUG("%s app_idx=%d, mcl_idx=%d", __func__, app_idx, mcl_idx);
425 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
426 alarm_free(p_mcb->cch_timer);
427 memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
428 }
429
430 /*******************************************************************************
431 *
432 * Function btif_hl_find_sdp_idx_using_mdep_filter
433 *
434 * Description This function finds the SDP record index using MDEP filter
435 * parameters
436 *
437 * Returns bool
438 *
439 ******************************************************************************/
btif_hl_reset_mdep_filter(uint8_t app_idx)440 static void btif_hl_reset_mdep_filter(uint8_t app_idx) {
441 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
442 p_acb->filter.num_elems = 0;
443 }
444
445 /*******************************************************************************
446 *
447 * Function btif_hl_find_sdp_idx_using_mdep_filter
448 *
449 * Description This function finds the SDP record index using MDEP filter
450 * parameters
451 *
452 * Returns bool
453 *
454 ******************************************************************************/
btif_hl_find_sdp_idx_using_mdep_filter(uint8_t app_idx,uint8_t mcl_idx,uint8_t * p_sdp_idx)455 static bool btif_hl_find_sdp_idx_using_mdep_filter(uint8_t app_idx,
456 uint8_t mcl_idx,
457 uint8_t* p_sdp_idx) {
458 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
459 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
460 uint8_t i, j, num_recs, num_elems, num_mdeps, mdep_idx;
461 tBTA_HL_MDEP_ROLE peer_mdep_role;
462 uint16_t data_type;
463 tBTA_HL_SDP_MDEP_CFG* p_mdep;
464 bool found = false;
465 bool elem_found;
466
467 BTIF_TRACE_DEBUG("btif_hl_find_sdp_idx_using_mdep_filter");
468 num_recs = p_mcb->sdp.num_recs;
469 num_elems = p_acb->filter.num_elems;
470 if (!num_elems) {
471 BTIF_TRACE_DEBUG("btif_hl_find_sdp_idx_using_mdep_filter num_elem=0");
472 *p_sdp_idx = 0;
473 found = true;
474 return found;
475 }
476
477 for (i = 0; i < num_recs; i++) {
478 num_mdeps = p_mcb->sdp.sdp_rec[i].num_mdeps;
479 for (j = 0; j < num_elems; j++) {
480 data_type = p_acb->filter.elem[j].data_type;
481 peer_mdep_role = p_acb->filter.elem[j].peer_mdep_role;
482 elem_found = false;
483 mdep_idx = 0;
484 while (!elem_found && mdep_idx < num_mdeps) {
485 p_mdep = &(p_mcb->sdp.sdp_rec[i].mdep_cfg[mdep_idx]);
486 if ((p_mdep->data_type == data_type) &&
487 (p_mdep->mdep_role == peer_mdep_role)) {
488 elem_found = true;
489 } else {
490 mdep_idx++;
491 }
492 }
493
494 if (!elem_found) {
495 found = false;
496 break;
497 } else {
498 found = true;
499 }
500 }
501
502 if (found) {
503 BTIF_TRACE_DEBUG("btif_hl_find_sdp_idx_using_mdep_filter found idx=%d",
504 i);
505 *p_sdp_idx = i;
506 break;
507 }
508 }
509
510 BTIF_TRACE_DEBUG("%s found=%d sdp_idx=%d", __func__, found, *p_sdp_idx);
511
512 btif_hl_reset_mdep_filter(app_idx);
513
514 return found;
515 }
516 /*******************************************************************************
517 *
518 * Function btif_hl_is_reconnect_possible
519 *
520 * Description check reconnect is possible or not
521 *
522 * Returns bool
523 *
524 ******************************************************************************/
btif_hl_is_reconnect_possible(uint8_t app_idx,uint8_t mcl_idx,int mdep_cfg_idx,tBTA_HL_DCH_OPEN_PARAM * p_dch_open_api,tBTA_HL_MDL_ID * p_mdl_id)525 bool btif_hl_is_reconnect_possible(uint8_t app_idx, uint8_t mcl_idx,
526 int mdep_cfg_idx,
527 tBTA_HL_DCH_OPEN_PARAM* p_dch_open_api,
528 tBTA_HL_MDL_ID* p_mdl_id) {
529 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
530 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
531 tBTA_HL_DCH_CFG local_cfg = p_dch_open_api->local_cfg;
532 tBTA_HL_DCH_MODE dch_mode = BTA_HL_DCH_MODE_RELIABLE;
533 bool use_mdl_dch_mode = false;
534 btif_hl_mdl_cfg_t* p_mdl;
535 btif_hl_mdl_cfg_t* p_mdl1;
536 uint8_t i, j;
537 bool is_reconnect_ok = false;
538 bool stream_mode_avail = false;
539 uint16_t data_type =
540 p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.data_cfg[0].data_type;
541 tBTA_HL_MDEP_ID peer_mdep_id = p_dch_open_api->peer_mdep_id;
542 uint8_t mdl_idx;
543
544 BTIF_TRACE_DEBUG("%s app_idx=%d mcl_idx=%d mdep_cfg_idx=%d", __func__,
545 app_idx, mcl_idx, mdep_cfg_idx);
546 switch (local_cfg) {
547 case BTA_HL_DCH_CFG_NO_PREF:
548 if (!btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) {
549 dch_mode = BTA_HL_DCH_MODE_RELIABLE;
550 } else {
551 use_mdl_dch_mode = true;
552 }
553 break;
554 case BTA_HL_DCH_CFG_RELIABLE:
555 dch_mode = BTA_HL_DCH_MODE_RELIABLE;
556 break;
557 case BTA_HL_DCH_CFG_STREAMING:
558 dch_mode = BTA_HL_DCH_MODE_STREAMING;
559 break;
560 default:
561 BTIF_TRACE_ERROR("Invalid local_cfg=%d", local_cfg);
562 return is_reconnect_ok;
563 break;
564 }
565
566 BTIF_TRACE_DEBUG("local_cfg=%d use_mdl_dch_mode=%d dch_mode=%d ", local_cfg,
567 use_mdl_dch_mode, dch_mode);
568
569 for (i = 0, p_mdl = &p_acb->mdl_cfg[0]; i < BTA_HL_NUM_MDL_CFGS;
570 i++, p_mdl++) {
571 if (p_mdl->base.active && p_mdl->extra.data_type == data_type &&
572 (p_mdl->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID &&
573 p_mdl->extra.peer_mdep_id == peer_mdep_id) &&
574 p_mdl->base.peer_bd_addr != p_mcb->bd_addr && p_mdl->base.mdl_id &&
575 !btif_hl_find_mdl_idx(app_idx, mcl_idx, p_mdl->base.mdl_id, &mdl_idx)) {
576 BTIF_TRACE_DEBUG("i=%d Matched active=%d mdl_id =%d, mdl_dch_mode=%d",
577 i, p_mdl->base.active, p_mdl->base.mdl_id,
578 p_mdl->base.dch_mode);
579 if (!use_mdl_dch_mode) {
580 if (p_mdl->base.dch_mode == dch_mode) {
581 is_reconnect_ok = true;
582 *p_mdl_id = p_mdl->base.mdl_id;
583 BTIF_TRACE_DEBUG("reconnect is possible dch_mode=%d mdl_id=%d",
584 dch_mode, p_mdl->base.mdl_id);
585 break;
586 }
587 } else {
588 is_reconnect_ok = true;
589 for (j = i, p_mdl1 = &p_acb->mdl_cfg[i]; j < BTA_HL_NUM_MDL_CFGS;
590 j++, p_mdl1++) {
591 if (p_mdl1->base.active && p_mdl1->extra.data_type == data_type &&
592 (p_mdl1->extra.peer_mdep_id != BTA_HL_INVALID_MDEP_ID &&
593 p_mdl1->extra.peer_mdep_id == peer_mdep_id) &&
594 p_mdl1->base.peer_bd_addr != p_mcb->bd_addr &&
595 p_mdl1->base.dch_mode == BTA_HL_DCH_MODE_STREAMING) {
596 stream_mode_avail = true;
597 BTIF_TRACE_DEBUG("found streaming mode mdl index=%d", j);
598 break;
599 }
600 }
601
602 if (stream_mode_avail) {
603 dch_mode = BTA_HL_DCH_MODE_STREAMING;
604 *p_mdl_id = p_mdl1->base.mdl_id;
605 BTIF_TRACE_DEBUG(
606 "reconnect is ok index=%d dch_mode=streaming mdl_id=%d", j,
607 *p_mdl_id);
608 break;
609 } else {
610 dch_mode = p_mdl->base.dch_mode;
611 *p_mdl_id = p_mdl->base.mdl_id;
612 BTIF_TRACE_DEBUG("reconnect is ok index=%d dch_mode=%d mdl_id=%d", i,
613 p_mdl->base.dch_mode, *p_mdl_id);
614 break;
615 }
616 }
617 }
618 }
619
620 BTIF_TRACE_DEBUG("is_reconnect_ok dch_mode=%d mdl_id=%d", is_reconnect_ok,
621 dch_mode, *p_mdl_id);
622 return is_reconnect_ok;
623 }
624
625 /*******************************************************************************
626 *
627 * Function btif_hl_dch_open
628 *
629 * Description Process DCH open request using the DCH Open API parameters
630 *
631 * Returns bool
632 *
633 ******************************************************************************/
btif_hl_dch_open(uint8_t app_id,const RawAddress & bd_addr,tBTA_HL_DCH_OPEN_PARAM * p_dch_open_api,int mdep_cfg_idx,btif_hl_pend_dch_op_t op,int * channel_id)634 bool btif_hl_dch_open(uint8_t app_id, const RawAddress& bd_addr,
635 tBTA_HL_DCH_OPEN_PARAM* p_dch_open_api, int mdep_cfg_idx,
636 btif_hl_pend_dch_op_t op, int* channel_id) {
637 btif_hl_app_cb_t* p_acb;
638 btif_hl_mcl_cb_t* p_mcb;
639 btif_hl_pending_chan_cb_t* p_pcb;
640 uint8_t app_idx, mcl_idx;
641 bool status = false;
642 tBTA_HL_MDL_ID mdl_id;
643 tBTA_HL_DCH_RECONNECT_PARAM reconnect_param;
644
645 BTIF_TRACE_DEBUG("%s app_id=%d ", __func__, app_id);
646 VLOG(0) << "DB " << bd_addr;
647
648 if (btif_hl_find_app_idx(app_id, &app_idx)) {
649 if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
650 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
651
652 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
653 if (!p_pcb->in_use) {
654 p_mcb->req_ctrl_psm = p_dch_open_api->ctrl_psm;
655
656 p_pcb->in_use = true;
657 *channel_id = p_pcb->channel_id =
658 (int)btif_hl_get_next_channel_id(app_id);
659 p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING;
660 p_pcb->mdep_cfg_idx = mdep_cfg_idx;
661 p_pcb->bd_addr = bd_addr;
662 p_pcb->op = op;
663
664 if (p_mcb->sdp.num_recs) {
665 if (p_mcb->valid_sdp_idx) {
666 p_dch_open_api->ctrl_psm = p_mcb->ctrl_psm;
667 }
668
669 if (!btif_hl_is_reconnect_possible(app_idx, mcl_idx, mdep_cfg_idx,
670 p_dch_open_api, &mdl_id)) {
671 BTIF_TRACE_DEBUG("Issue DCH open");
672 BTA_HlDchOpen(p_mcb->mcl_handle, p_dch_open_api);
673 } else {
674 reconnect_param.ctrl_psm = p_mcb->ctrl_psm;
675 reconnect_param.mdl_id = mdl_id;
676 ;
677 BTIF_TRACE_DEBUG("Issue Reconnect ctrl_psm=0x%x mdl_id=0x%x",
678 reconnect_param.ctrl_psm, reconnect_param.mdl_id);
679 BTA_HlDchReconnect(p_mcb->mcl_handle, &reconnect_param);
680 }
681
682 status = true;
683 } else {
684 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
685 p_mcb->cch_oper = BTIF_HL_CCH_OP_DCH_OPEN;
686 BTA_HlSdpQuery(app_id, p_acb->app_handle, bd_addr);
687 status = true;
688 }
689 }
690 }
691 }
692
693 BTIF_TRACE_DEBUG("status=%d ", status);
694 return status;
695 }
696
697 /*******************************************************************************
698 *
699 * Function btif_hl_dch_abort
700 *
701 * Description Process DCH abort request
702 *
703 * Returns Nothing
704 *
705 ******************************************************************************/
btif_hl_dch_abort(uint8_t app_idx,uint8_t mcl_idx)706 void btif_hl_dch_abort(uint8_t app_idx, uint8_t mcl_idx) {
707 btif_hl_mcl_cb_t* p_mcb;
708
709 BTIF_TRACE_DEBUG("%s app_idx=%d mcl_idx=%d", __func__, app_idx, mcl_idx);
710 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
711 if (p_mcb->is_connected) {
712 BTA_HlDchAbort(p_mcb->mcl_handle);
713 } else {
714 p_mcb->pcb.abort_pending = true;
715 }
716 }
717 /*******************************************************************************
718 *
719 * Function btif_hl_cch_open
720 *
721 * Description Process CCH open request
722 *
723 * Returns Nothing
724 *
725 ******************************************************************************/
btif_hl_cch_open(uint8_t app_id,const RawAddress & bd_addr,uint16_t ctrl_psm,int mdep_cfg_idx,btif_hl_pend_dch_op_t op,int * channel_id)726 bool btif_hl_cch_open(uint8_t app_id, const RawAddress& bd_addr,
727 uint16_t ctrl_psm, int mdep_cfg_idx,
728 btif_hl_pend_dch_op_t op, int* channel_id) {
729 btif_hl_app_cb_t* p_acb;
730 btif_hl_mcl_cb_t* p_mcb;
731 btif_hl_pending_chan_cb_t* p_pcb;
732 uint8_t app_idx, mcl_idx;
733 bool status = true;
734
735 BTIF_TRACE_DEBUG("%s app_id=%d ctrl_psm=%d mdep_cfg_idx=%d op=%d", __func__,
736 app_id, ctrl_psm, mdep_cfg_idx, op);
737 VLOG(1) << "DB " << bd_addr;
738
739 if (btif_hl_find_app_idx(app_id, &app_idx)) {
740 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
741
742 if (!btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
743 if (btif_hl_find_avail_mcl_idx(app_idx, &mcl_idx)) {
744 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
745 alarm_free(p_mcb->cch_timer);
746 memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
747 p_mcb->in_use = true;
748 p_mcb->bd_addr = bd_addr;
749
750 if (!ctrl_psm) {
751 p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING;
752 } else {
753 p_mcb->cch_oper = BTIF_HL_CCH_OP_MATCHED_CTRL_PSM;
754 p_mcb->req_ctrl_psm = ctrl_psm;
755 }
756
757 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
758 p_pcb->in_use = true;
759 p_pcb->mdep_cfg_idx = mdep_cfg_idx;
760 p_pcb->bd_addr = bd_addr;
761 p_pcb->op = op;
762
763 switch (op) {
764 case BTIF_HL_PEND_DCH_OP_OPEN:
765 *channel_id = p_pcb->channel_id =
766 (int)btif_hl_get_next_channel_id(app_id);
767 p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING;
768 break;
769 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
770 p_pcb->channel_id = p_acb->delete_mdl.channel_id;
771 p_pcb->cb_state = BTIF_HL_CHAN_CB_STATE_DESTROYED_PENDING;
772 break;
773 default:
774 break;
775 }
776 BTA_HlSdpQuery(app_id, p_acb->app_handle, bd_addr);
777 } else {
778 status = false;
779 BTIF_TRACE_ERROR("Open CCH request discarded- No mcl cb");
780 }
781 } else {
782 status = false;
783 BTIF_TRACE_ERROR("Open CCH request discarded- already in USE");
784 }
785 } else {
786 status = false;
787 BTIF_TRACE_ERROR("Invalid app_id=%d", app_id);
788 }
789
790 if (channel_id) {
791 BTIF_TRACE_DEBUG("status=%d channel_id=0x%08x", status, *channel_id);
792 } else {
793 BTIF_TRACE_DEBUG("status=%d ", status);
794 }
795 return status;
796 }
797
798 /*******************************************************************************
799 *
800 * Function btif_hl_find_mdl_idx_using_handle
801 *
802 * Description Find the MDL index using channel id
803 *
804 * Returns bool
805 *
806 ******************************************************************************/
btif_hl_find_mdl_cfg_idx_using_channel_id(int channel_id,uint8_t * p_app_idx,uint8_t * p_mdl_cfg_idx)807 bool btif_hl_find_mdl_cfg_idx_using_channel_id(int channel_id,
808 uint8_t* p_app_idx,
809 uint8_t* p_mdl_cfg_idx) {
810 btif_hl_app_cb_t* p_acb;
811 btif_hl_mdl_cfg_t* p_mdl;
812 bool found = false;
813 uint8_t i, j;
814 int mdl_cfg_channel_id;
815
816 *p_app_idx = 0;
817 *p_mdl_cfg_idx = 0;
818 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
819 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
820 for (j = 0; j < BTA_HL_NUM_MDL_CFGS; j++) {
821 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(i, j);
822 mdl_cfg_channel_id = *(BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(i, j));
823 if (p_acb->in_use && p_mdl->base.active &&
824 (mdl_cfg_channel_id == channel_id)) {
825 found = true;
826 *p_app_idx = i;
827 *p_mdl_cfg_idx = j;
828 break;
829 }
830 }
831 }
832
833 BTIF_TRACE_EVENT("%s found=%d channel_id=0x%08x, app_idx=%d mdl_cfg_idx=%d ",
834 __func__, found, channel_id, i, j);
835 return found;
836 }
837 /*******************************************************************************
838 *
839 * Function btif_hl_find_mdl_idx_using_handle
840 *
841 * Description Find the MDL index using channel id
842 *
843 * Returns bool
844 *
845 ******************************************************************************/
btif_hl_find_mdl_idx_using_channel_id(int channel_id,uint8_t * p_app_idx,uint8_t * p_mcl_idx,uint8_t * p_mdl_idx)846 bool btif_hl_find_mdl_idx_using_channel_id(int channel_id, uint8_t* p_app_idx,
847 uint8_t* p_mcl_idx,
848 uint8_t* p_mdl_idx) {
849 btif_hl_app_cb_t* p_acb;
850 btif_hl_mcl_cb_t* p_mcb;
851 btif_hl_mdl_cb_t* p_dcb;
852 bool found = false;
853 uint8_t i, j, k;
854
855 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
856 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
857 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
858 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j);
859 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
860 p_dcb = BTIF_HL_GET_MDL_CB_PTR(i, j, k);
861 if (p_acb->in_use && p_mcb->in_use && p_dcb->in_use &&
862 (p_dcb->channel_id == channel_id)) {
863 found = true;
864 *p_app_idx = i;
865 *p_mcl_idx = j;
866 *p_mdl_idx = k;
867 break;
868 }
869 }
870 }
871 }
872 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d ", __func__,
873 found, i, j, k);
874 return found;
875 }
876
877 /*******************************************************************************
878 *
879 * Function btif_hl_find_channel_id_using_mdl_id
880 *
881 * Description Find channel id using mdl_id'
882 *
883 * Returns bool
884 ******************************************************************************/
btif_hl_find_channel_id_using_mdl_id(uint8_t app_idx,tBTA_HL_MDL_ID mdl_id,int * p_channel_id)885 bool btif_hl_find_channel_id_using_mdl_id(uint8_t app_idx,
886 tBTA_HL_MDL_ID mdl_id,
887 int* p_channel_id) {
888 btif_hl_app_cb_t* p_acb;
889 btif_hl_mdl_cfg_t* p_mdl;
890 bool found = false;
891 uint8_t j = 0;
892 int mdl_cfg_channel_id;
893 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
894 if (p_acb && p_acb->in_use) {
895 for (j = 0; j < BTA_HL_NUM_MDL_CFGS; j++) {
896 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, j);
897 mdl_cfg_channel_id = *(BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(app_idx, j));
898 if (p_mdl->base.active && (p_mdl->base.mdl_id == mdl_id)) {
899 found = true;
900 *p_channel_id = mdl_cfg_channel_id;
901 break;
902 }
903 }
904 }
905 BTIF_TRACE_EVENT(
906 "%s found=%d channel_id=0x%08x, mdl_id=0x%x app_idx=%d mdl_cfg_idx=%d ",
907 __func__, found, *p_channel_id, mdl_id, app_idx, j);
908 return found;
909 }
910
911 /*******************************************************************************
912 *
913 * Function btif_hl_find_mdl_idx_using_handle
914 *
915 * Description Find the MDL index using handle
916 *
917 * Returns bool
918 *
919 ******************************************************************************/
btif_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,uint8_t * p_app_idx,uint8_t * p_mcl_idx,uint8_t * p_mdl_idx)920 bool btif_hl_find_mdl_idx_using_handle(tBTA_HL_MDL_HANDLE mdl_handle,
921 uint8_t* p_app_idx, uint8_t* p_mcl_idx,
922 uint8_t* p_mdl_idx) {
923 btif_hl_app_cb_t* p_acb;
924 btif_hl_mcl_cb_t* p_mcb;
925 btif_hl_mdl_cb_t* p_dcb;
926 bool found = false;
927 uint8_t i, j, k;
928
929 *p_app_idx = 0;
930 *p_mcl_idx = 0;
931 *p_mdl_idx = 0;
932 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
933 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
934 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
935 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, j);
936 for (k = 0; k < BTA_HL_NUM_MDLS_PER_MCL; k++) {
937 p_dcb = BTIF_HL_GET_MDL_CB_PTR(i, j, k);
938 if (p_acb->in_use && p_mcb->in_use && p_dcb->in_use &&
939 (p_dcb->mdl_handle == mdl_handle)) {
940 found = true;
941 *p_app_idx = i;
942 *p_mcl_idx = j;
943 *p_mdl_idx = k;
944 break;
945 }
946 }
947 }
948 }
949
950 BTIF_TRACE_EVENT("%s found=%d app_idx=%d mcl_idx=%d mdl_idx=%d ", __func__,
951 found, i, j, k);
952 return found;
953 }
954 /*******************************************************************************
955 *
956 * Function btif_hl_find_peer_mdep_id
957 *
958 * Description Find the peer MDEP ID from the received SPD records
959 *
960 * Returns bool
961 *
962 ******************************************************************************/
btif_hl_find_peer_mdep_id(uint8_t app_id,const RawAddress & bd_addr,tBTA_HL_MDEP_ROLE local_mdep_role,uint16_t data_type,tBTA_HL_MDEP_ID * p_peer_mdep_id)963 static bool btif_hl_find_peer_mdep_id(uint8_t app_id, const RawAddress& bd_addr,
964 tBTA_HL_MDEP_ROLE local_mdep_role,
965 uint16_t data_type,
966 tBTA_HL_MDEP_ID* p_peer_mdep_id) {
967 uint8_t app_idx, mcl_idx;
968 btif_hl_mcl_cb_t* p_mcb;
969 tBTA_HL_SDP_REC* p_rec;
970 uint8_t i, num_mdeps;
971 bool found = false;
972 tBTA_HL_MDEP_ROLE peer_mdep_role;
973
974 BTIF_TRACE_DEBUG("%s app_id=%d local_mdep_role=%d, data_type=%d", __func__,
975 app_id, local_mdep_role, data_type);
976 VLOG(1) << "DB " << bd_addr;
977
978 BTIF_TRACE_DEBUG("local_mdep_role=%d", local_mdep_role);
979 BTIF_TRACE_DEBUG("data_type=%d", data_type);
980
981 if (local_mdep_role == BTA_HL_MDEP_ROLE_SINK)
982 peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE;
983 else
984 peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
985
986 if (btif_hl_find_app_idx(app_id, &app_idx)) {
987 if (btif_hl_find_mcl_idx(app_idx, bd_addr, &mcl_idx)) {
988 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
989
990 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d", app_idx, mcl_idx);
991 BTIF_TRACE_DEBUG("valid_spd_idx=%d sdp_idx=%d", p_mcb->valid_sdp_idx,
992 p_mcb->sdp_idx);
993 if (p_mcb->valid_sdp_idx) {
994 p_rec = &p_mcb->sdp.sdp_rec[p_mcb->sdp_idx];
995 num_mdeps = p_rec->num_mdeps;
996 BTIF_TRACE_DEBUG("num_mdeps=%d", num_mdeps);
997
998 for (i = 0; i < num_mdeps; i++) {
999 BTIF_TRACE_DEBUG("p_rec->mdep_cfg[%d].mdep_role=%d", i,
1000 p_rec->mdep_cfg[i].mdep_role);
1001 BTIF_TRACE_DEBUG("p_rec->mdep_cfg[%d].data_type =%d", i,
1002 p_rec->mdep_cfg[i].data_type);
1003 if ((p_rec->mdep_cfg[i].mdep_role == peer_mdep_role) &&
1004 (p_rec->mdep_cfg[i].data_type == data_type)) {
1005 found = true;
1006 *p_peer_mdep_id = p_rec->mdep_cfg[i].mdep_id;
1007 break;
1008 }
1009 }
1010 }
1011 }
1012 }
1013
1014 BTIF_TRACE_DEBUG("found =%d *p_peer_mdep_id=%d", found, *p_peer_mdep_id);
1015
1016 return found;
1017 }
1018
1019 /*******************************************************************************
1020 *
1021 * Function btif_hl_find_mdep_cfg_idx
1022 *
1023 * Description Find the MDEP configuration index using local MDEP_ID
1024 *
1025 * Returns bool
1026 *
1027 ******************************************************************************/
btif_hl_find_mdep_cfg_idx(uint8_t app_idx,tBTA_HL_MDEP_ID local_mdep_id,uint8_t * p_mdep_cfg_idx)1028 static bool btif_hl_find_mdep_cfg_idx(uint8_t app_idx,
1029 tBTA_HL_MDEP_ID local_mdep_id,
1030 uint8_t* p_mdep_cfg_idx) {
1031 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
1032 tBTA_HL_SUP_FEATURE* p_sup_feature = &p_acb->sup_feature;
1033 bool found = false;
1034 uint8_t i;
1035
1036 for (i = 0; i < p_sup_feature->num_of_mdeps; i++) {
1037 BTIF_TRACE_DEBUG("btif_hl_find_mdep_cfg_idx: mdep_id=%d app_idx = %d",
1038 p_sup_feature->mdep[i].mdep_id, app_idx);
1039 if (p_sup_feature->mdep[i].mdep_id == local_mdep_id) {
1040 found = true;
1041 *p_mdep_cfg_idx = i;
1042 break;
1043 }
1044 }
1045
1046 BTIF_TRACE_DEBUG("%s found=%d mdep_idx=%d local_mdep_id=%d app_idx=%d ",
1047 __func__, found, i, local_mdep_id, app_idx);
1048 return found;
1049 }
1050
1051 /*******************************************************************************
1052 *
1053 * Function btif_hl_find_mcl_idx
1054 *
1055 * Description Find the MCL index using BD address
1056 *
1057 * Returns bool
1058 *
1059 ******************************************************************************/
btif_hl_find_mcl_idx(uint8_t app_idx,const RawAddress & p_bd_addr,uint8_t * p_mcl_idx)1060 bool btif_hl_find_mcl_idx(uint8_t app_idx, const RawAddress& p_bd_addr,
1061 uint8_t* p_mcl_idx) {
1062 bool found = false;
1063 uint8_t i;
1064 btif_hl_mcl_cb_t* p_mcb;
1065
1066 *p_mcl_idx = 0;
1067 for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
1068 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, i);
1069 if (p_mcb->in_use && p_mcb->bd_addr == p_bd_addr) {
1070 found = true;
1071 *p_mcl_idx = i;
1072 break;
1073 }
1074 }
1075
1076 BTIF_TRACE_DEBUG("%s found=%d idx=%d", __func__, found, i);
1077 return found;
1078 }
1079 /*******************************************************************************
1080 *
1081 * Function btif_hl_init
1082 *
1083 * Description HL initialization function.
1084 *
1085 * Returns void
1086 *
1087 ******************************************************************************/
btif_hl_init(void)1088 static void btif_hl_init(void) {
1089 BTIF_TRACE_DEBUG("%s", __func__);
1090 memset(p_btif_hl_cb, 0, sizeof(btif_hl_cb_t));
1091 btif_hl_init_next_app_id();
1092 btif_hl_init_next_channel_id();
1093 }
1094 /*******************************************************************************
1095 *
1096 * Function btif_hl_disable
1097 *
1098 * Description Disable initialization function.
1099 *
1100 * Returns void
1101 *
1102 ******************************************************************************/
btif_hl_disable(void)1103 static void btif_hl_disable(void) {
1104 BTIF_TRACE_DEBUG("%s", __func__);
1105
1106 if ((p_btif_hl_cb->state != BTIF_HL_STATE_DISABLING) &&
1107 (p_btif_hl_cb->state != BTIF_HL_STATE_DISABLED)) {
1108 btif_hl_set_state(BTIF_HL_STATE_DISABLING);
1109 BTA_HlDisable();
1110 }
1111 }
1112 /*******************************************************************************
1113 *
1114 * Function btif_hl_is_no_active_app
1115 *
1116 * Description Find whether or not any APP is still in use
1117 *
1118 * Returns bool
1119 *
1120 ******************************************************************************/
btif_hl_is_no_active_app(void)1121 static bool btif_hl_is_no_active_app(void) {
1122 bool no_active_app = true;
1123 uint8_t i;
1124
1125 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1126 if (btif_hl_cb.acb[i].in_use) {
1127 no_active_app = false;
1128 break;
1129 }
1130 }
1131
1132 BTIF_TRACE_DEBUG("%s no_active_app=%d ", __func__, no_active_app);
1133 return no_active_app;
1134 }
1135
1136 /*******************************************************************************
1137 *
1138 * Function btif_hl_free_app_idx
1139 *
1140 * Description free an application control block
1141 *
1142 * Returns void
1143 *
1144 ******************************************************************************/
btif_hl_free_app_idx(uint8_t app_idx)1145 static void btif_hl_free_app_idx(uint8_t app_idx) {
1146 if ((app_idx < BTA_HL_NUM_APPS) && btif_hl_cb.acb[app_idx].in_use) {
1147 btif_hl_cb.acb[app_idx].in_use = false;
1148 for (size_t i = 0; i < BTA_HL_NUM_MCLS; i++)
1149 alarm_free(btif_hl_cb.acb[app_idx].mcb[i].cch_timer);
1150 memset(&btif_hl_cb.acb[app_idx], 0, sizeof(btif_hl_app_cb_t));
1151 }
1152 }
1153 /*******************************************************************************
1154 *
1155 * Function btif_hl_set_state
1156 *
1157 * Description set HL state
1158 *
1159 * Returns void
1160 *
1161 ******************************************************************************/
btif_hl_set_state(btif_hl_state_t state)1162 static void btif_hl_set_state(btif_hl_state_t state) {
1163 BTIF_TRACE_DEBUG("btif_hl_set_state: %d ---> %d ", p_btif_hl_cb->state,
1164 state);
1165 p_btif_hl_cb->state = state;
1166 }
1167
1168 /*******************************************************************************
1169 *
1170 * Function btif_hl_set_state
1171 *
1172 * Description get HL state
1173 *
1174 * Returns btif_hl_state_t
1175 *
1176 ******************************************************************************/
1177
btif_hl_get_state(void)1178 static btif_hl_state_t btif_hl_get_state(void) {
1179 BTIF_TRACE_DEBUG("btif_hl_get_state: %d ", p_btif_hl_cb->state);
1180 return p_btif_hl_cb->state;
1181 }
1182
1183 /*******************************************************************************
1184 *
1185 * Function btif_hl_find_data_type_idx
1186 *
1187 * Description Find the index in the data type table
1188 *
1189 * Returns bool
1190 *
1191 ******************************************************************************/
btif_hl_find_data_type_idx(uint16_t data_type,uint8_t * p_idx)1192 static bool btif_hl_find_data_type_idx(uint16_t data_type, uint8_t* p_idx) {
1193 bool found = false;
1194 uint8_t i;
1195
1196 for (i = 0; i < BTIF_HL_DATA_TABLE_SIZE; i++) {
1197 if (data_type_table[i].data_type == data_type) {
1198 found = true;
1199 *p_idx = i;
1200 break;
1201 }
1202 }
1203
1204 BTIF_TRACE_DEBUG("%s found=%d, data_type=0x%x idx=%d", __func__, found,
1205 data_type, i);
1206 return found;
1207 }
1208
1209 /*******************************************************************************
1210 *
1211 * Function btif_hl_get_max_tx_apdu_size
1212 *
1213 * Description Find the maximum TX APDU size for the specified data type and
1214 * MDEP role
1215 *
1216 * Returns uint16_t
1217 *
1218 ******************************************************************************/
btif_hl_get_max_tx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,uint16_t data_type)1219 uint16_t btif_hl_get_max_tx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
1220 uint16_t data_type) {
1221 uint8_t idx;
1222 uint16_t max_tx_apdu_size = 0;
1223
1224 if (btif_hl_find_data_type_idx(data_type, &idx)) {
1225 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) {
1226 max_tx_apdu_size = data_type_table[idx].max_tx_apdu_size;
1227 } else {
1228 max_tx_apdu_size = data_type_table[idx].max_rx_apdu_size;
1229 }
1230 } else {
1231 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) {
1232 max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE;
1233 } else {
1234 max_tx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE;
1235 }
1236 }
1237
1238 BTIF_TRACE_DEBUG("%s mdep_role=%d data_type=0x%4x size=%d", __func__,
1239 mdep_role, data_type, max_tx_apdu_size);
1240 return max_tx_apdu_size;
1241 }
1242
1243 /*******************************************************************************
1244 *
1245 * Function btif_hl_get_max_rx_apdu_size
1246 *
1247 * Description Find the maximum RX APDU size for the specified data type and
1248 * MDEP role
1249 *
1250 * Returns uint16_t
1251 *
1252 ******************************************************************************/
btif_hl_get_max_rx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,uint16_t data_type)1253 uint16_t btif_hl_get_max_rx_apdu_size(tBTA_HL_MDEP_ROLE mdep_role,
1254 uint16_t data_type) {
1255 uint8_t idx;
1256 uint16_t max_rx_apdu_size = 0;
1257
1258 if (btif_hl_find_data_type_idx(data_type, &idx)) {
1259 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) {
1260 max_rx_apdu_size = data_type_table[idx].max_rx_apdu_size;
1261 } else {
1262 max_rx_apdu_size = data_type_table[idx].max_tx_apdu_size;
1263 }
1264 } else {
1265 if (mdep_role == BTA_HL_MDEP_ROLE_SOURCE) {
1266 max_rx_apdu_size = BTIF_HL_DEFAULT_SRC_RX_APDU_SIZE;
1267 } else {
1268 max_rx_apdu_size = BTIF_HL_DEFAULT_SRC_TX_APDU_SIZE;
1269 }
1270 }
1271
1272 BTIF_TRACE_DEBUG("%s mdep_role=%d data_type=0x%4x size=%d", __func__,
1273 mdep_role, data_type, max_rx_apdu_size);
1274
1275 return max_rx_apdu_size;
1276 }
1277
1278 /*******************************************************************************
1279 *
1280 * Function btif_hl_if_channel_setup_pending
1281 *
1282 * Description
1283 *
1284 * Returns bool
1285 *
1286 ******************************************************************************/
1287
btif_hl_get_bta_mdep_role(bthl_mdep_role_t mdep,tBTA_HL_MDEP_ROLE * p)1288 static bool btif_hl_get_bta_mdep_role(bthl_mdep_role_t mdep,
1289 tBTA_HL_MDEP_ROLE* p) {
1290 bool status = true;
1291 switch (mdep) {
1292 case BTHL_MDEP_ROLE_SOURCE:
1293 *p = BTA_HL_MDEP_ROLE_SOURCE;
1294 break;
1295 case BTHL_MDEP_ROLE_SINK:
1296 *p = BTA_HL_MDEP_ROLE_SINK;
1297 break;
1298 default:
1299 *p = BTA_HL_MDEP_ROLE_SOURCE;
1300 status = false;
1301 break;
1302 }
1303
1304 BTIF_TRACE_DEBUG("%s status=%d bta_mdep_role=%d (%d:btif)", __func__, status,
1305 *p, mdep);
1306 return status;
1307 }
1308 /*******************************************************************************
1309 *
1310 * Function btif_hl_get_bta_channel_type
1311 *
1312 * Description convert bthl channel type to BTA DCH channel type
1313 *
1314 * Returns bool
1315 *
1316 ******************************************************************************/
1317
btif_hl_get_bta_channel_type(bthl_channel_type_t channel_type,tBTA_HL_DCH_CFG * p)1318 static bool btif_hl_get_bta_channel_type(bthl_channel_type_t channel_type,
1319 tBTA_HL_DCH_CFG* p) {
1320 bool status = true;
1321 switch (channel_type) {
1322 case BTHL_CHANNEL_TYPE_RELIABLE:
1323 *p = BTA_HL_DCH_CFG_RELIABLE;
1324 break;
1325 case BTHL_CHANNEL_TYPE_STREAMING:
1326 *p = BTA_HL_DCH_CFG_STREAMING;
1327 break;
1328 case BTHL_CHANNEL_TYPE_ANY:
1329 *p = BTA_HL_DCH_CFG_NO_PREF;
1330 break;
1331 default:
1332 status = false;
1333 break;
1334 }
1335 BTIF_TRACE_DEBUG("%s status = %d BTA DCH CFG=%d (1-rel 2-strm", __func__,
1336 status, *p);
1337 return status;
1338 }
1339 /*******************************************************************************
1340 *
1341 * Function btif_hl_get_next_app_id
1342 *
1343 * Description get next applcation id
1344 *
1345 * Returns uint8_t
1346 *
1347 ******************************************************************************/
1348
btif_hl_get_next_app_id()1349 static uint8_t btif_hl_get_next_app_id() {
1350 uint8_t next_app_id = btif_hl_cb.next_app_id;
1351
1352 btif_hl_cb.next_app_id++;
1353 return next_app_id;
1354 }
1355 /*******************************************************************************
1356 *
1357 * Function btif_hl_get_next_channel_id
1358 *
1359 * Description get next channel id
1360 *
1361 * Returns int
1362 *
1363 ******************************************************************************/
btif_hl_get_next_channel_id(uint8_t app_id)1364 static int btif_hl_get_next_channel_id(uint8_t app_id) {
1365 uint16_t next_channel_id = btif_hl_cb.next_channel_id;
1366 int channel_id;
1367 btif_hl_cb.next_channel_id++;
1368 channel_id = (app_id << 16) + next_channel_id;
1369 BTIF_TRACE_DEBUG("%s channel_id=0x%08x, app_id=0x%02x next_channel_id=0x%04x",
1370 __func__, channel_id, app_id, next_channel_id);
1371 return channel_id;
1372 }
1373 /*******************************************************************************
1374 *
1375 * Function btif_hl_get_app_id
1376 *
1377 * Description get the applicaiton id associated with the channel id
1378 *
1379 * Returns uint8_t
1380 *
1381 ******************************************************************************/
1382
btif_hl_get_app_id(int channel_id)1383 static uint8_t btif_hl_get_app_id(int channel_id) {
1384 uint8_t app_id = (uint8_t)(channel_id >> 16);
1385 BTIF_TRACE_DEBUG("%s channel_id=0x%08x, app_id=0x%02x ", __func__, channel_id,
1386 app_id);
1387 return app_id;
1388 }
1389 /*******************************************************************************
1390 *
1391 * Function btif_hl_init_next_app_id
1392 *
1393 * Description initialize the application id
1394 *
1395 * Returns void
1396 *
1397 ******************************************************************************/
btif_hl_init_next_app_id(void)1398 static void btif_hl_init_next_app_id(void) { btif_hl_cb.next_app_id = 1; }
1399 /*******************************************************************************
1400 *
1401 * Function btif_hl_init_next_channel_id
1402 *
1403 * Description initialize the channel id
1404 *
1405 * Returns void
1406 *
1407 ******************************************************************************/
btif_hl_init_next_channel_id(void)1408 static void btif_hl_init_next_channel_id(void) {
1409 btif_hl_cb.next_channel_id = 1;
1410 }
1411
1412 /*******************************************************************************
1413 *
1414 * Function btif_hl_find_app_idx_using_handle
1415 *
1416 * Description Find the applicaiton index using handle
1417 *
1418 * Returns bool
1419 *
1420 ******************************************************************************/
btif_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle,uint8_t * p_app_idx)1421 bool btif_hl_find_app_idx_using_handle(tBTA_HL_APP_HANDLE app_handle,
1422 uint8_t* p_app_idx) {
1423 bool found = false;
1424 uint8_t i;
1425
1426 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1427 if (btif_hl_cb.acb[i].in_use &&
1428 (btif_hl_cb.acb[i].app_handle == app_handle)) {
1429 found = true;
1430 *p_app_idx = i;
1431 break;
1432 }
1433 }
1434
1435 BTIF_TRACE_EVENT("%s status=%d handle=%d app_idx=%d ", __func__, found,
1436 app_handle, i);
1437
1438 return found;
1439 }
1440
1441 /*******************************************************************************
1442 *
1443 * Function btif_hl_find_app_idx_using_app_id
1444 *
1445 * Description Find the applicaiton index using app_id
1446 *
1447 * Returns bool
1448 *
1449 ******************************************************************************/
btif_hl_find_app_idx_using_app_id(uint8_t app_id,uint8_t * p_app_idx)1450 bool btif_hl_find_app_idx_using_app_id(uint8_t app_id, uint8_t* p_app_idx) {
1451 bool found = false;
1452 uint8_t i;
1453
1454 *p_app_idx = 0;
1455 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1456 if (btif_hl_cb.acb[i].in_use && (btif_hl_cb.acb[i].app_id == app_id)) {
1457 found = true;
1458 *p_app_idx = i;
1459 break;
1460 }
1461 }
1462
1463 BTIF_TRACE_EVENT("%s found=%d app_id=%d app_idx=%d ", __func__, found, app_id,
1464 i);
1465
1466 return found;
1467 }
1468
1469 /*******************************************************************************
1470 *
1471 * Function btif_hl_find_mcl_idx_using_handle
1472 *
1473 * Description Find the MCL index using handle
1474 *
1475 * Returns bool
1476 *
1477 ******************************************************************************/
btif_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle,uint8_t * p_app_idx,uint8_t * p_mcl_idx)1478 bool btif_hl_find_mcl_idx_using_handle(tBTA_HL_MCL_HANDLE mcl_handle,
1479 uint8_t* p_app_idx, uint8_t* p_mcl_idx) {
1480 btif_hl_app_cb_t* p_acb;
1481 bool found = false;
1482 uint8_t i, j;
1483
1484 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1485 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
1486 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1487 if (p_acb->mcb[j].in_use)
1488 BTIF_TRACE_DEBUG(
1489 "btif_hl_find_mcl_idx_using_handle:app_idx=%d,"
1490 "mcl_idx =%d mcl_handle=%d",
1491 i, j, p_acb->mcb[j].mcl_handle);
1492 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
1493 found = true;
1494 *p_app_idx = i;
1495 *p_mcl_idx = j;
1496 break;
1497 }
1498 }
1499 }
1500 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d mcl_idx=%d", __func__, found, i, j);
1501 return found;
1502 }
1503
1504 /*******************************************************************************
1505 *
1506 * Function btif_hl_find_mdl_idx_using_mdl_id
1507 *
1508 * Description Find the mdl index using mdl_id
1509 *
1510 * Returns bool
1511 *
1512 ******************************************************************************/
btif_hl_find_mcl_idx_using_mdl_id(uint8_t mdl_id,uint8_t mcl_handle,uint8_t * p_app_idx,uint8_t * p_mcl_idx)1513 bool btif_hl_find_mcl_idx_using_mdl_id(uint8_t mdl_id, uint8_t mcl_handle,
1514 uint8_t* p_app_idx, uint8_t* p_mcl_idx) {
1515 btif_hl_app_cb_t* p_acb;
1516 btif_hl_mcl_cb_t* p_mcb;
1517 bool found = false;
1518 uint8_t i, j, x;
1519
1520 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1521 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
1522 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1523 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
1524 p_mcb = &p_acb->mcb[j];
1525 BTIF_TRACE_DEBUG(
1526 "btif_hl_find_mcl_idx_using_mdl_id: mcl handle found j =%d", j);
1527 for (x = 0; x < BTA_HL_NUM_MDLS_PER_MCL; x++) {
1528 if (p_mcb->mdl[x].in_use && p_mcb->mdl[x].mdl_id == mdl_id) {
1529 BTIF_TRACE_DEBUG("btif_hl_find_mcl_idx_using_mdl_id:found x =%d",
1530 x);
1531 found = true;
1532 *p_app_idx = i;
1533 *p_mcl_idx = j;
1534 break;
1535 }
1536 }
1537 }
1538 }
1539 }
1540 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d mcl_idx=%d", __func__, found, i, j);
1541 return found;
1542 }
1543
1544 /*******************************************************************************
1545 *
1546 * Function btif_hl_find_mcl_idx_using_deleted_mdl_id
1547 *
1548 * Description Find the app index deleted_mdl_id
1549 *
1550 * Returns bool
1551 *
1552 ******************************************************************************/
btif_hl_find_app_idx_using_deleted_mdl_id(uint8_t mdl_id,uint8_t * p_app_idx)1553 bool btif_hl_find_app_idx_using_deleted_mdl_id(uint8_t mdl_id,
1554 uint8_t* p_app_idx) {
1555 btif_hl_app_cb_t* p_acb;
1556 bool found = false;
1557 uint8_t i;
1558
1559 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1560 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
1561 if (p_acb->delete_mdl.active) {
1562 BTIF_TRACE_DEBUG("%s: app_idx=%d, mdl_id=%d", __func__, i, mdl_id);
1563 }
1564 if (p_acb->delete_mdl.active && (p_acb->delete_mdl.mdl_id == mdl_id)) {
1565 found = true;
1566 *p_app_idx = i;
1567 break;
1568 }
1569 }
1570 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i);
1571 return found;
1572 }
1573
1574 /*******************************************************************************
1575 *
1576 * Function btif_hl_stop_timer_using_handle
1577 *
1578 * Description clean control channel cb using handle
1579 *
1580 * Returns void
1581 *
1582 ******************************************************************************/
btif_hl_stop_timer_using_handle(tBTA_HL_MCL_HANDLE mcl_handle)1583 static void btif_hl_stop_timer_using_handle(tBTA_HL_MCL_HANDLE mcl_handle) {
1584 btif_hl_app_cb_t* p_acb;
1585 uint8_t i, j;
1586
1587 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1588 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
1589 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1590 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
1591 btif_hl_stop_cch_timer(i, j);
1592 }
1593 }
1594 }
1595 }
1596
1597 /*******************************************************************************
1598 *
1599 * Function btif_hl_find_mcl_idx_using_app_idx
1600 *
1601 * Description Find the MCL index using handle
1602 *
1603 * Returns bool
1604 *
1605 ******************************************************************************/
btif_hl_find_mcl_idx_using_app_idx(tBTA_HL_MCL_HANDLE mcl_handle,uint8_t p_app_idx,uint8_t * p_mcl_idx)1606 bool btif_hl_find_mcl_idx_using_app_idx(tBTA_HL_MCL_HANDLE mcl_handle,
1607 uint8_t p_app_idx, uint8_t* p_mcl_idx) {
1608 btif_hl_app_cb_t* p_acb;
1609 bool found = false;
1610 uint8_t j;
1611
1612 p_acb = BTIF_HL_GET_APP_CB_PTR(p_app_idx);
1613 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1614 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
1615 found = true;
1616 *p_mcl_idx = j;
1617 break;
1618 }
1619 }
1620 BTIF_TRACE_DEBUG("%s found=%dmcl_idx=%d", __func__, found, j);
1621 return found;
1622 }
1623
1624 /*******************************************************************************
1625 *
1626 * Function btif_hl_clean_mdls_using_app_idx
1627 *
1628 * Description clean dch cpntrol bloack using app_idx
1629 *
1630 * Returns void
1631 *
1632 ******************************************************************************/
btif_hl_clean_mdls_using_app_idx(uint8_t app_idx)1633 void btif_hl_clean_mdls_using_app_idx(uint8_t app_idx) {
1634 btif_hl_app_cb_t* p_acb;
1635 btif_hl_mcl_cb_t* p_mcb;
1636 btif_hl_mdl_cb_t* p_dcb;
1637 uint8_t j, x;
1638 RawAddress bd_addr;
1639
1640 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
1641 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
1642 if (p_acb->mcb[j].in_use) {
1643 p_mcb = &p_acb->mcb[j];
1644 BTIF_TRACE_DEBUG(
1645 "btif_hl_find_mcl_idx_using_mdl_id: mcl handle found j =%d", j);
1646 for (x = 0; x < BTA_HL_NUM_MDLS_PER_MCL; x++) {
1647 if (p_mcb->mdl[x].in_use) {
1648 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, j, x);
1649 btif_hl_release_socket(app_idx, j, x);
1650 bd_addr = p_mcb->bd_addr;
1651 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, p_acb->app_id,
1652 &bd_addr, p_dcb->local_mdep_cfg_idx,
1653 p_dcb->channel_id, BTHL_CONN_STATE_DISCONNECTED,
1654 0);
1655 btif_hl_clean_mdl_cb(p_dcb);
1656 if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle))
1657 BTA_HlCchClose(p_mcb->mcl_handle);
1658 BTIF_TRACE_DEBUG("remote DCH close success mdl_idx=%d", x);
1659 }
1660 }
1661 }
1662 }
1663 }
1664
1665 /*******************************************************************************
1666 *
1667 * Function btif_hl_find_app_idx
1668 *
1669 * Description Find the application index using application ID
1670 *
1671 * Returns bool
1672 *
1673 ******************************************************************************/
btif_hl_find_app_idx(uint8_t app_id,uint8_t * p_app_idx)1674 bool btif_hl_find_app_idx(uint8_t app_id, uint8_t* p_app_idx) {
1675 bool found = false;
1676 uint8_t i;
1677
1678 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1679 if (btif_hl_cb.acb[i].in_use && (btif_hl_cb.acb[i].app_id == app_id)) {
1680 found = true;
1681 *p_app_idx = i;
1682 break;
1683 }
1684 }
1685 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i);
1686
1687 return found;
1688 }
1689
1690 /*******************************************************************************
1691 *
1692 * Function btif_hl_find_app_idx
1693 *
1694 * Description Find the application index using application ID
1695 *
1696 * Returns bool
1697 *
1698 ******************************************************************************/
btif_hl_find_app_idx_using_mdepId(uint8_t mdep_id,uint8_t * p_app_idx)1699 bool btif_hl_find_app_idx_using_mdepId(uint8_t mdep_id, uint8_t* p_app_idx) {
1700 bool found = false;
1701 uint8_t i;
1702
1703 *p_app_idx = 0;
1704 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1705 BTIF_TRACE_DEBUG("btif_hl_find_app_idx_using_mdepId: MDEP-ID = %d",
1706 btif_hl_cb.acb[i].sup_feature.mdep[0].mdep_id);
1707 if (btif_hl_cb.acb[i].in_use &&
1708 (btif_hl_cb.acb[i].sup_feature.mdep[0].mdep_id == mdep_id)) {
1709 found = true;
1710 *p_app_idx = i;
1711 break;
1712 }
1713 }
1714 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i);
1715
1716 return found;
1717 }
1718
1719 /*******************************************************************************
1720 *
1721 * Function btif_hl_find_avail_mdl_idx
1722 *
1723 * Description Find a not in-use MDL index
1724 *
1725 * Returns bool
1726 *
1727 ******************************************************************************/
btif_hl_find_avail_mdl_idx(uint8_t app_idx,uint8_t mcl_idx,uint8_t * p_mdl_idx)1728 bool btif_hl_find_avail_mdl_idx(uint8_t app_idx, uint8_t mcl_idx,
1729 uint8_t* p_mdl_idx) {
1730 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
1731 bool found = false;
1732 uint8_t i;
1733
1734 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
1735 if (!p_mcb->mdl[i].in_use) {
1736 btif_hl_clean_mdl_cb(&p_mcb->mdl[i]);
1737 found = true;
1738 *p_mdl_idx = i;
1739 break;
1740 }
1741 }
1742
1743 BTIF_TRACE_DEBUG("%s found=%d idx=%d", __func__, found, i);
1744 return found;
1745 }
1746
1747 /*******************************************************************************
1748 *
1749 * Function btif_hl_find_avail_mcl_idx
1750 *
1751 * Description Find a not in-use MDL index
1752 *
1753 * Returns bool
1754 *
1755 ******************************************************************************/
btif_hl_find_avail_mcl_idx(uint8_t app_idx,uint8_t * p_mcl_idx)1756 bool btif_hl_find_avail_mcl_idx(uint8_t app_idx, uint8_t* p_mcl_idx) {
1757 bool found = false;
1758 uint8_t i;
1759
1760 for (i = 0; i < BTA_HL_NUM_MCLS; i++) {
1761 if (!btif_hl_cb.acb[app_idx].mcb[i].in_use) {
1762 found = true;
1763 *p_mcl_idx = i;
1764 break;
1765 }
1766 }
1767 BTIF_TRACE_DEBUG("%s found=%d mcl_idx=%d", __func__, found, i);
1768 return found;
1769 }
1770
1771 /*******************************************************************************
1772 *
1773 * Function btif_hl_find_avail_app_idx
1774 *
1775 * Description Find a not in-use APP index
1776 *
1777 * Returns bool
1778 *
1779 ******************************************************************************/
btif_hl_find_avail_app_idx(uint8_t * p_idx)1780 static bool btif_hl_find_avail_app_idx(uint8_t* p_idx) {
1781 bool found = false;
1782 uint8_t i;
1783
1784 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
1785 if (!btif_hl_cb.acb[i].in_use) {
1786 found = true;
1787 *p_idx = i;
1788 break;
1789 }
1790 }
1791
1792 BTIF_TRACE_DEBUG("%s found=%d app_idx=%d", __func__, found, i);
1793 return found;
1794 }
1795
1796 /*******************************************************************************
1797 *
1798 * Function btif_hl_proc_dereg_cfm
1799 *
1800 * Description Process the de-registration confirmation
1801 *
1802 * Returns Nothing
1803 *
1804 ******************************************************************************/
btif_hl_proc_dereg_cfm(tBTA_HL * p_data)1805 static void btif_hl_proc_dereg_cfm(tBTA_HL* p_data)
1806
1807 {
1808 btif_hl_app_cb_t* p_acb;
1809 uint8_t app_idx;
1810 int app_id = 0;
1811 bthl_app_reg_state_t state = BTHL_APP_REG_STATE_DEREG_SUCCESS;
1812
1813 BTIF_TRACE_DEBUG("%s de-reg status=%d app_handle=%d", __func__,
1814 p_data->dereg_cfm.status, p_data->dereg_cfm.app_handle);
1815
1816 if (btif_hl_find_app_idx_using_app_id(p_data->dereg_cfm.app_id, &app_idx)) {
1817 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
1818 app_id = (int)p_acb->app_id;
1819 if (p_data->dereg_cfm.status == BTA_HL_STATUS_OK) {
1820 btif_hl_clean_mdls_using_app_idx(app_idx);
1821 for (size_t i = 0; i < BTA_HL_NUM_MCLS; i++)
1822 alarm_free(p_acb->mcb[i].cch_timer);
1823 memset(p_acb, 0, sizeof(btif_hl_app_cb_t));
1824 } else
1825 state = BTHL_APP_REG_STATE_DEREG_FAILED;
1826
1827 BTIF_TRACE_DEBUG("call reg state callback app_id=%d state=%d", app_id,
1828 state);
1829 BTIF_HL_CALL_CBACK(bt_hl_callbacks, app_reg_state_cb, app_id, state);
1830
1831 if (btif_hl_is_no_active_app()) {
1832 btif_hl_disable();
1833 }
1834 }
1835 }
1836
1837 /*******************************************************************************
1838 *
1839 * Function btif_hl_proc_reg_cfm
1840 *
1841 * Description Process the registration confirmation
1842 *
1843 * Returns Nothing
1844 *
1845 ******************************************************************************/
btif_hl_proc_reg_cfm(tBTA_HL * p_data)1846 static void btif_hl_proc_reg_cfm(tBTA_HL* p_data) {
1847 btif_hl_app_cb_t* p_acb;
1848 uint8_t app_idx;
1849 bthl_app_reg_state_t state = BTHL_APP_REG_STATE_REG_SUCCESS;
1850
1851 BTIF_TRACE_DEBUG("%s reg status=%d app_handle=%d", __func__,
1852 p_data->reg_cfm.status, p_data->reg_cfm.app_handle);
1853
1854 if (btif_hl_find_app_idx(p_data->reg_cfm.app_id, &app_idx)) {
1855 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
1856 if (p_data->reg_cfm.status == BTA_HL_STATUS_OK) {
1857 p_acb->app_handle = p_data->reg_cfm.app_handle;
1858 } else {
1859 btif_hl_free_app_idx(app_idx);
1860 state = BTHL_APP_REG_STATE_REG_FAILED;
1861 }
1862
1863 BTIF_TRACE_DEBUG("%s call reg state callback app_id=%d reg state=%d",
1864 __func__, p_data->reg_cfm.app_id, state);
1865 BTIF_HL_CALL_CBACK(bt_hl_callbacks, app_reg_state_cb,
1866 ((int)p_data->reg_cfm.app_id), state);
1867 }
1868 }
1869
1870 /*******************************************************************************
1871 *
1872 * Function btif_hl_set_chan_cb_state
1873 *
1874 * Description set the channel callback state
1875 *
1876 * Returns void
1877 *
1878 ******************************************************************************/
btif_hl_set_chan_cb_state(uint8_t app_idx,uint8_t mcl_idx,btif_hl_chan_cb_state_t state)1879 void btif_hl_set_chan_cb_state(uint8_t app_idx, uint8_t mcl_idx,
1880 btif_hl_chan_cb_state_t state) {
1881 btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
1882 btif_hl_chan_cb_state_t cur_state = p_pcb->cb_state;
1883
1884 if (cur_state != state) {
1885 p_pcb->cb_state = state;
1886 BTIF_TRACE_DEBUG("%s state %d--->%d", __func__, cur_state, state);
1887 }
1888 }
1889 /*******************************************************************************
1890 *
1891 * Function btif_hl_send_destroyed_cb
1892 *
1893 * Description send the channel destroyed callback
1894 *
1895 * Returns void
1896 *
1897 ******************************************************************************/
btif_hl_send_destroyed_cb(btif_hl_app_cb_t * p_acb)1898 void btif_hl_send_destroyed_cb(btif_hl_app_cb_t* p_acb) {
1899 int app_id = (int)btif_hl_get_app_id(p_acb->delete_mdl.channel_id);
1900
1901 RawAddress bd_addr = p_acb->delete_mdl.bd_addr;
1902 BTIF_TRACE_DEBUG("%s", __func__);
1903 BTIF_TRACE_DEBUG(
1904 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d, state=%d "
1905 "fd=%d",
1906 p_acb->delete_mdl.channel_id, p_acb->delete_mdl.mdep_cfg_idx,
1907 BTHL_CONN_STATE_DESTROYED, 0);
1908 VLOG(1) << "BD " << bd_addr;
1909
1910 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
1911 p_acb->delete_mdl.mdep_cfg_idx,
1912 p_acb->delete_mdl.channel_id, BTHL_CONN_STATE_DESTROYED,
1913 0);
1914 }
1915 /*******************************************************************************
1916 *
1917 * Function btif_hl_send_disconnecting_cb
1918 *
1919 * Description send a channel disconnecting callback
1920 *
1921 * Returns void
1922 *
1923 ******************************************************************************/
btif_hl_send_disconnecting_cb(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)1924 void btif_hl_send_disconnecting_cb(uint8_t app_idx, uint8_t mcl_idx,
1925 uint8_t mdl_idx) {
1926 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
1927 btif_hl_soc_cb_t* p_scb = p_dcb->p_scb;
1928 int app_id = (int)btif_hl_get_app_id(p_scb->channel_id);
1929
1930 RawAddress bd_addr = p_scb->bd_addr;
1931
1932 BTIF_TRACE_DEBUG("%s", __func__);
1933 BTIF_TRACE_DEBUG(
1934 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d, "
1935 "state=%d fd=%d",
1936 p_scb->channel_id, p_scb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTING,
1937 p_scb->socket_id[0]);
1938 VLOG(1) << "BD " << bd_addr;
1939 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
1940 p_scb->mdep_cfg_idx, p_scb->channel_id,
1941 BTHL_CONN_STATE_DISCONNECTING, p_scb->socket_id[0]);
1942 }
1943 /*******************************************************************************
1944 *
1945 * Function btif_hl_send_setup_connecting_cb
1946 *
1947 * Description send a channel connecting callback
1948 *
1949 * Returns void
1950 *
1951 ******************************************************************************/
btif_hl_send_setup_connecting_cb(uint8_t app_idx,uint8_t mcl_idx)1952 void btif_hl_send_setup_connecting_cb(uint8_t app_idx, uint8_t mcl_idx) {
1953 btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
1954 int app_id = (int)btif_hl_get_app_id(p_pcb->channel_id);
1955
1956 RawAddress bd_addr = p_pcb->bd_addr;
1957
1958 if (p_pcb->in_use &&
1959 p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING) {
1960 BTIF_TRACE_DEBUG("%s", __func__);
1961 BTIF_TRACE_DEBUG(
1962 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d "
1963 "state=%d fd=%d",
1964 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING, 0);
1965 VLOG(1) << "BD " << bd_addr;
1966
1967 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
1968 p_pcb->mdep_cfg_idx, p_pcb->channel_id,
1969 BTHL_CONN_STATE_CONNECTING, 0);
1970 btif_hl_set_chan_cb_state(app_idx, mcl_idx,
1971 BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING);
1972 }
1973 }
1974 /*******************************************************************************
1975 *
1976 * Function btif_hl_send_setup_disconnected_cb
1977 *
1978 * Description send a channel disconnected callback
1979 *
1980 * Returns void
1981 *
1982 ******************************************************************************/
btif_hl_send_setup_disconnected_cb(uint8_t app_idx,uint8_t mcl_idx)1983 void btif_hl_send_setup_disconnected_cb(uint8_t app_idx, uint8_t mcl_idx) {
1984 btif_hl_pending_chan_cb_t* p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
1985 int app_id = (int)btif_hl_get_app_id(p_pcb->channel_id);
1986
1987 RawAddress bd_addr = p_pcb->bd_addr;
1988
1989 BTIF_TRACE_DEBUG("%s p_pcb->in_use=%d", __func__, p_pcb->in_use);
1990 if (p_pcb->in_use) {
1991 BTIF_TRACE_DEBUG("%p_pcb->cb_state=%d", p_pcb->cb_state);
1992 if (p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTING_PENDING) {
1993 BTIF_TRACE_DEBUG(
1994 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d "
1995 "state=%d fd=%d",
1996 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_CONNECTING,
1997 0);
1998 VLOG(1) << "BD " << bd_addr;
1999 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
2000 p_pcb->mdep_cfg_idx, p_pcb->channel_id,
2001 BTHL_CONN_STATE_CONNECTING, 0);
2002
2003 BTIF_TRACE_DEBUG(
2004 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d "
2005 "state=%d fd=%d",
2006 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED,
2007 0);
2008 VLOG(1) << "BD " << bd_addr;
2009 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
2010 p_pcb->mdep_cfg_idx, p_pcb->channel_id,
2011 BTHL_CONN_STATE_DISCONNECTED, 0);
2012 } else if (p_pcb->cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING) {
2013 BTIF_TRACE_DEBUG(
2014 "call channel state callback channel_id=0x%08x mdep_cfg_idx=%d "
2015 "state=%d fd=%d",
2016 p_pcb->channel_id, p_pcb->mdep_cfg_idx, BTHL_CONN_STATE_DISCONNECTED,
2017 0);
2018 VLOG(1) << "BD " << bd_addr;
2019 BTIF_HL_CALL_CBACK(bt_hl_callbacks, channel_state_cb, app_id, &bd_addr,
2020 p_pcb->mdep_cfg_idx, p_pcb->channel_id,
2021 BTHL_CONN_STATE_DISCONNECTED, 0);
2022 }
2023 btif_hl_clean_pcb(p_pcb);
2024 }
2025 }
2026 /*******************************************************************************
2027 *
2028 * Function btif_hl_proc_sdp_query_cfm
2029 *
2030 * Description Process the SDP query confirmation
2031 *
2032 * Returns Nothing
2033 *
2034 ******************************************************************************/
btif_hl_proc_sdp_query_cfm(tBTA_HL * p_data)2035 static bool btif_hl_proc_sdp_query_cfm(tBTA_HL* p_data) {
2036 btif_hl_app_cb_t* p_acb;
2037 btif_hl_mcl_cb_t* p_mcb;
2038 tBTA_HL_SDP* p_sdp;
2039 tBTA_HL_CCH_OPEN_PARAM open_param;
2040 uint8_t app_idx, mcl_idx, sdp_idx = 0;
2041 uint8_t num_recs, i, num_mdeps, j;
2042 btif_hl_cch_op_t old_cch_oper;
2043 bool status = false;
2044 btif_hl_pending_chan_cb_t* p_pcb;
2045
2046 BTIF_TRACE_DEBUG("%s", __func__);
2047
2048 p_sdp = p_data->sdp_query_cfm.p_sdp;
2049 num_recs = p_sdp->num_recs;
2050
2051 BTIF_TRACE_DEBUG("num of SDP records=%d", num_recs);
2052 for (i = 0; i < num_recs; i++) {
2053 BTIF_TRACE_DEBUG("rec_idx=%d ctrl_psm=0x%x data_psm=0x%x", (i + 1),
2054 p_sdp->sdp_rec[i].ctrl_psm, p_sdp->sdp_rec[i].data_psm);
2055 BTIF_TRACE_DEBUG("MCAP supported procedures=0x%x",
2056 p_sdp->sdp_rec[i].mcap_sup_proc);
2057 num_mdeps = p_sdp->sdp_rec[i].num_mdeps;
2058 BTIF_TRACE_DEBUG("num of mdeps =%d", num_mdeps);
2059 for (j = 0; j < num_mdeps; j++) {
2060 BTIF_TRACE_DEBUG("mdep_idx=%d mdep_id=0x%x data_type=0x%x mdep_role=0x%x",
2061 (j + 1), p_sdp->sdp_rec[i].mdep_cfg[j].mdep_id,
2062 p_sdp->sdp_rec[i].mdep_cfg[j].data_type,
2063 p_sdp->sdp_rec[i].mdep_cfg[j].mdep_role);
2064 }
2065 }
2066
2067 if (btif_hl_find_app_idx_using_app_id(p_data->sdp_query_cfm.app_id,
2068 &app_idx)) {
2069 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2070
2071 if (btif_hl_find_mcl_idx(app_idx, p_data->sdp_query_cfm.bd_addr,
2072 &mcl_idx)) {
2073 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2074 if (p_mcb->cch_oper != BTIF_HL_CCH_OP_NONE) {
2075 memcpy(&p_mcb->sdp, p_sdp, sizeof(tBTA_HL_SDP));
2076 old_cch_oper = p_mcb->cch_oper;
2077 p_mcb->cch_oper = BTIF_HL_CCH_OP_NONE;
2078
2079 switch (old_cch_oper) {
2080 case BTIF_HL_CCH_OP_MDEP_FILTERING:
2081 status = btif_hl_find_sdp_idx_using_mdep_filter(app_idx, mcl_idx,
2082 &sdp_idx);
2083 break;
2084 default:
2085 break;
2086 }
2087
2088 if (status) {
2089 p_mcb->sdp_idx = sdp_idx;
2090 p_mcb->valid_sdp_idx = true;
2091 p_mcb->ctrl_psm = p_mcb->sdp.sdp_rec[sdp_idx].ctrl_psm;
2092
2093 switch (old_cch_oper) {
2094 case BTIF_HL_CCH_OP_MDEP_FILTERING:
2095 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2096 if (p_pcb->in_use) {
2097 if (!p_pcb->abort_pending) {
2098 switch (p_pcb->op) {
2099 case BTIF_HL_PEND_DCH_OP_OPEN:
2100 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
2101 break;
2102 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
2103 default:
2104 break;
2105 }
2106 open_param.ctrl_psm = p_mcb->ctrl_psm;
2107 open_param.bd_addr = p_mcb->bd_addr;
2108 open_param.sec_mask =
2109 (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
2110 BTA_HlCchOpen(p_acb->app_id, p_acb->app_handle, &open_param);
2111 } else {
2112 BTIF_TRACE_DEBUG("channel abort pending");
2113 }
2114 }
2115 break;
2116
2117 case BTIF_HL_CCH_OP_DCH_OPEN:
2118 status = btif_hl_proc_pending_op(app_idx, mcl_idx);
2119 break;
2120
2121 default:
2122 BTIF_TRACE_ERROR("Invalid CCH oper %d", old_cch_oper);
2123 break;
2124 }
2125 } else {
2126 BTIF_TRACE_ERROR("Can not find SDP idx discard CCH Open request");
2127 }
2128 }
2129 }
2130 }
2131
2132 // this was allocated in bta_hl_sdp_query_results
2133 osi_free_and_reset((void**)&p_data->sdp_query_cfm.p_sdp);
2134
2135 return status;
2136 }
2137
2138 /*******************************************************************************
2139 *
2140 * Function btif_hl_proc_cch_open_ind
2141 *
2142 * Description Process the CCH open indication
2143 *
2144 * Returns Nothing
2145 *
2146 ******************************************************************************/
btif_hl_proc_cch_open_ind(tBTA_HL * p_data)2147 static void btif_hl_proc_cch_open_ind(tBTA_HL* p_data)
2148
2149 {
2150 btif_hl_mcl_cb_t* p_mcb;
2151 uint8_t mcl_idx;
2152 int i;
2153
2154 BTIF_TRACE_DEBUG("%s", __func__);
2155 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
2156 if (btif_hl_cb.acb[i].in_use) {
2157 if (!btif_hl_find_mcl_idx(i, p_data->cch_open_ind.bd_addr, &mcl_idx)) {
2158 if (btif_hl_find_avail_mcl_idx(i, &mcl_idx)) {
2159 p_mcb = BTIF_HL_GET_MCL_CB_PTR(i, mcl_idx);
2160 alarm_free(p_mcb->cch_timer);
2161 memset(p_mcb, 0, sizeof(btif_hl_mcl_cb_t));
2162 p_mcb->in_use = true;
2163 p_mcb->is_connected = true;
2164 p_mcb->mcl_handle = p_data->cch_open_ind.mcl_handle;
2165 p_mcb->bd_addr = p_data->cch_open_ind.bd_addr;
2166 btif_hl_start_cch_timer(i, mcl_idx);
2167 }
2168 } else {
2169 BTIF_TRACE_ERROR("The MCL already exist for cch_open_ind");
2170 }
2171 }
2172 }
2173 }
2174
2175 /*******************************************************************************
2176 *
2177 * Function btif_hl_proc_pending_op
2178 *
2179 * Description Process the pending dch operation.
2180 *
2181 * Returns Nothing
2182 *
2183 ******************************************************************************/
btif_hl_proc_pending_op(uint8_t app_idx,uint8_t mcl_idx)2184 bool btif_hl_proc_pending_op(uint8_t app_idx, uint8_t mcl_idx)
2185
2186 {
2187 btif_hl_app_cb_t* p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2188 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2189 btif_hl_pending_chan_cb_t* p_pcb;
2190 bool status = false;
2191 tBTA_HL_DCH_OPEN_PARAM dch_open;
2192 tBTA_HL_MDL_ID mdl_id;
2193 tBTA_HL_DCH_RECONNECT_PARAM reconnect_param;
2194
2195 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2196 if (p_pcb->in_use) {
2197 switch (p_pcb->op) {
2198 case BTIF_HL_PEND_DCH_OP_OPEN:
2199 if (!p_pcb->abort_pending) {
2200 BTIF_TRACE_DEBUG("op BTIF_HL_PEND_DCH_OP_OPEN");
2201 dch_open.ctrl_psm = p_mcb->ctrl_psm;
2202 dch_open.local_mdep_id =
2203 p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx].mdep_id;
2204 if (btif_hl_find_peer_mdep_id(
2205 p_acb->app_id, p_mcb->bd_addr,
2206 p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx]
2207 .mdep_cfg.mdep_role,
2208 p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx]
2209 .mdep_cfg.data_cfg[0]
2210 .data_type,
2211 &dch_open.peer_mdep_id)) {
2212 dch_open.local_cfg = p_acb->channel_type[p_pcb->mdep_cfg_idx];
2213 if ((p_acb->sup_feature.mdep[p_pcb->mdep_cfg_idx]
2214 .mdep_cfg.mdep_role == BTA_HL_MDEP_ROLE_SOURCE) &&
2215 !btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) {
2216 dch_open.local_cfg = BTA_HL_DCH_CFG_RELIABLE;
2217 }
2218 dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
2219 BTIF_TRACE_DEBUG("dch_open.local_cfg=%d ", dch_open.local_cfg);
2220 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
2221
2222 if (!btif_hl_is_reconnect_possible(app_idx, mcl_idx,
2223 p_pcb->mdep_cfg_idx, &dch_open,
2224 &mdl_id)) {
2225 BTIF_TRACE_DEBUG("Issue DCH open, mcl_handle=%d",
2226 p_mcb->mcl_handle);
2227 BTA_HlDchOpen(p_mcb->mcl_handle, &dch_open);
2228 } else {
2229 reconnect_param.ctrl_psm = p_mcb->ctrl_psm;
2230 reconnect_param.mdl_id = mdl_id;
2231 ;
2232 BTIF_TRACE_DEBUG("Issue Reconnect ctrl_psm=0x%x mdl_id=0x%x",
2233 reconnect_param.ctrl_psm,
2234 reconnect_param.mdl_id);
2235 BTA_HlDchReconnect(p_mcb->mcl_handle, &reconnect_param);
2236 }
2237 status = true;
2238 }
2239 } else {
2240 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
2241 status = true;
2242 }
2243 break;
2244 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
2245 BTA_HlDeleteMdl(p_mcb->mcl_handle, p_acb->delete_mdl.mdl_id);
2246 status = true;
2247 break;
2248
2249 default:
2250 break;
2251 }
2252 }
2253 return status;
2254 }
2255
2256 /*******************************************************************************
2257 *
2258 * Function btif_hl_proc_cch_open_cfm
2259 *
2260 * Description Process the CCH open confirmation
2261 *
2262 * Returns Nothing
2263 *
2264 ******************************************************************************/
btif_hl_proc_cch_open_cfm(tBTA_HL * p_data)2265 static bool btif_hl_proc_cch_open_cfm(tBTA_HL* p_data)
2266
2267 {
2268 btif_hl_mcl_cb_t* p_mcb;
2269 uint8_t app_idx, mcl_idx;
2270 bool status = false;
2271
2272 BTIF_TRACE_DEBUG("%s", __func__);
2273
2274 if (btif_hl_find_app_idx_using_app_id(p_data->cch_open_cfm.app_id,
2275 &app_idx)) {
2276 BTIF_TRACE_DEBUG("app_idx=%d", app_idx);
2277 if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr, &mcl_idx)) {
2278 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2279 BTIF_TRACE_DEBUG("mcl_idx=%d, mcl_handle=%d", mcl_idx,
2280 p_data->cch_open_cfm.mcl_handle);
2281 p_mcb->mcl_handle = p_data->cch_open_cfm.mcl_handle;
2282 p_mcb->is_connected = true;
2283 status = btif_hl_proc_pending_op(app_idx, mcl_idx);
2284 if (status) btif_hl_start_cch_timer(app_idx, mcl_idx);
2285 }
2286 }
2287
2288 return status;
2289 }
2290
2291 /*******************************************************************************
2292 *
2293 * Function btif_hl_clean_mcb_using_handle
2294 *
2295 * Description clean control channel cb using handle
2296 *
2297 * Returns void
2298 *
2299 ******************************************************************************/
btif_hl_clean_mcb_using_handle(tBTA_HL_MCL_HANDLE mcl_handle)2300 static void btif_hl_clean_mcb_using_handle(tBTA_HL_MCL_HANDLE mcl_handle) {
2301 btif_hl_app_cb_t* p_acb;
2302 uint8_t i, j;
2303
2304 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
2305 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
2306 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
2307 if (p_acb->mcb[j].in_use)
2308 BTIF_TRACE_DEBUG(
2309 "btif_hl_find_mcl_idx_using_handle: app_idx=%d,"
2310 "mcl_idx =%d mcl_handle=%d",
2311 i, j, p_acb->mcb[j].mcl_handle);
2312 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
2313 btif_hl_stop_cch_timer(i, j);
2314 btif_hl_release_mcl_sockets(i, j);
2315 btif_hl_send_setup_disconnected_cb(i, j);
2316 btif_hl_clean_mcl_cb(i, j);
2317 }
2318 }
2319 }
2320 }
2321
2322 /*******************************************************************************
2323 *
2324 * Function btif_hl_proc_cch_close_ind
2325 *
2326 * Description Process the CCH close indication
2327 *
2328 * Returns Nothing
2329 *
2330 ******************************************************************************/
btif_hl_proc_cch_close_ind(tBTA_HL * p_data)2331 static void btif_hl_proc_cch_close_ind(tBTA_HL* p_data)
2332
2333 {
2334 BTIF_TRACE_DEBUG("%s", __func__);
2335
2336 btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle);
2337 }
2338
2339 /*******************************************************************************
2340 *
2341 * Function btif_hl_proc_cch_close_cfm
2342 *
2343 * Description Process the CCH close confirmation
2344 *
2345 * Returns Nothing
2346 *
2347 ******************************************************************************/
btif_hl_proc_cch_close_cfm(tBTA_HL * p_data)2348 static void btif_hl_proc_cch_close_cfm(tBTA_HL* p_data) {
2349 BTIF_TRACE_DEBUG("%s", __func__);
2350
2351 btif_hl_clean_mcb_using_handle(p_data->cch_close_ind.mcl_handle);
2352 }
2353
2354 /*******************************************************************************
2355 *
2356 * Function btif_hl_proc_create_ind
2357 *
2358 * Description Process the MDL create indication
2359 *
2360 * Returns Nothing
2361 *
2362 ******************************************************************************/
btif_hl_proc_create_ind(tBTA_HL * p_data)2363 static void btif_hl_proc_create_ind(tBTA_HL* p_data) {
2364 btif_hl_app_cb_t* p_acb;
2365 btif_hl_mcl_cb_t* p_mcb;
2366 tBTA_HL_MDEP* p_mdep;
2367 uint8_t orig_app_idx, mcl_idx, mdep_cfg_idx;
2368 bool first_reliable_exist;
2369 bool success = true;
2370 tBTA_HL_DCH_CFG rsp_cfg = BTA_HL_DCH_CFG_UNKNOWN;
2371 tBTA_HL_DCH_CREATE_RSP rsp_code = BTA_HL_DCH_CREATE_RSP_CFG_REJ;
2372 tBTA_HL_DCH_CREATE_RSP_PARAM create_rsp_param;
2373
2374 BTIF_TRACE_DEBUG("%s", __func__);
2375
2376 // Find the correct app_idx based on the mdep_id;
2377 btif_hl_find_app_idx_using_mdepId(p_data->dch_create_ind.local_mdep_id,
2378 &orig_app_idx);
2379 if (btif_hl_find_mcl_idx(orig_app_idx, p_data->dch_create_ind.bd_addr,
2380 &mcl_idx)) {
2381 p_acb = BTIF_HL_GET_APP_CB_PTR(orig_app_idx);
2382 p_mcb = BTIF_HL_GET_MCL_CB_PTR(orig_app_idx, mcl_idx);
2383
2384 if (btif_hl_find_mdep_cfg_idx(orig_app_idx,
2385 p_data->dch_create_ind.local_mdep_id,
2386 &mdep_cfg_idx)) {
2387 p_mdep = &(p_acb->sup_feature.mdep[mdep_cfg_idx]);
2388 first_reliable_exist =
2389 btif_hl_is_the_first_reliable_existed(orig_app_idx, mcl_idx);
2390 switch (p_mdep->mdep_cfg.mdep_role) {
2391 case BTA_HL_MDEP_ROLE_SOURCE:
2392 if (p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_NO_PREF) {
2393 if (first_reliable_exist) {
2394 rsp_cfg = p_acb->channel_type[mdep_cfg_idx];
2395 } else {
2396 rsp_cfg = BTA_HL_DCH_CFG_RELIABLE;
2397 }
2398 rsp_code = BTA_HL_DCH_CREATE_RSP_SUCCESS;
2399 }
2400
2401 break;
2402 case BTA_HL_MDEP_ROLE_SINK:
2403
2404 BTIF_TRACE_DEBUG("btif_hl_proc_create_ind:BTA_HL_MDEP_ROLE_SINK");
2405 if ((p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_RELIABLE) ||
2406 (first_reliable_exist &&
2407 (p_data->dch_create_ind.cfg == BTA_HL_DCH_CFG_STREAMING))) {
2408 rsp_code = BTA_HL_DCH_CREATE_RSP_SUCCESS;
2409 rsp_cfg = p_data->dch_create_ind.cfg;
2410 BTIF_TRACE_DEBUG(
2411 "btif_hl_proc_create_ind:BTA_HL_MDEP_ROLE_SINK cfg = %d",
2412 rsp_cfg);
2413 }
2414 break;
2415 default:
2416 break;
2417 }
2418 }
2419 } else {
2420 success = false;
2421 }
2422
2423 if (success) {
2424 BTIF_TRACE_DEBUG("create response rsp_code=%d rsp_cfg=%d", rsp_code,
2425 rsp_cfg);
2426 create_rsp_param.local_mdep_id = p_data->dch_create_ind.local_mdep_id;
2427 create_rsp_param.mdl_id = p_data->dch_create_ind.mdl_id;
2428 create_rsp_param.rsp_code = rsp_code;
2429 create_rsp_param.cfg_rsp = rsp_cfg;
2430 BTA_HlDchCreateRsp(p_mcb->mcl_handle, &create_rsp_param);
2431 }
2432 }
2433
2434 /*******************************************************************************
2435 *
2436 * Function btif_hl_proc_dch_open_ind
2437 *
2438 * Description Process the DCH open indication
2439 *
2440 * Returns Nothing
2441 *
2442 ******************************************************************************/
btif_hl_proc_dch_open_ind(tBTA_HL * p_data)2443 static void btif_hl_proc_dch_open_ind(tBTA_HL* p_data)
2444
2445 {
2446 btif_hl_mdl_cb_t* p_dcb;
2447 uint8_t orig_app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2448 bool close_dch = false;
2449
2450 BTIF_TRACE_DEBUG("%s", __func__);
2451
2452 // Find the correct app_idx based on the mdep_id;
2453 btif_hl_find_app_idx_using_mdepId(p_data->dch_open_ind.local_mdep_id,
2454 &orig_app_idx);
2455
2456 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_ind.mcl_handle,
2457 orig_app_idx, &mcl_idx)) {
2458 if (btif_hl_find_avail_mdl_idx(orig_app_idx, mcl_idx, &mdl_idx)) {
2459 p_dcb = BTIF_HL_GET_MDL_CB_PTR(orig_app_idx, mcl_idx, mdl_idx);
2460
2461 if (btif_hl_find_mdep_cfg_idx(orig_app_idx,
2462 p_data->dch_open_ind.local_mdep_id,
2463 &mdep_cfg_idx)) {
2464 p_dcb->in_use = true;
2465 p_dcb->mdl_handle = p_data->dch_open_ind.mdl_handle;
2466 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
2467 p_dcb->local_mdep_id = p_data->dch_open_ind.local_mdep_id;
2468 p_dcb->mdl_id = p_data->dch_open_ind.mdl_id;
2469 p_dcb->dch_mode = p_data->dch_open_ind.dch_mode;
2470 p_dcb->dch_mode = p_data->dch_open_ind.dch_mode;
2471 p_dcb->is_the_first_reliable = p_data->dch_open_ind.first_reliable;
2472 p_dcb->mtu = p_data->dch_open_ind.mtu;
2473
2474 if (btif_hl_find_channel_id_using_mdl_id(orig_app_idx, p_dcb->mdl_id,
2475 &p_dcb->channel_id)) {
2476 BTIF_TRACE_DEBUG(" app_idx=%d mcl_idx=%d mdl_idx=%d channel_id=%d",
2477 orig_app_idx, mcl_idx, mdl_idx, p_dcb->channel_id);
2478 if (!btif_hl_create_socket(orig_app_idx, mcl_idx, mdl_idx)) {
2479 BTIF_TRACE_ERROR("Unable to create socket");
2480 close_dch = true;
2481 }
2482 } else {
2483 BTIF_TRACE_ERROR("Unable find channel id for mdl_id=0x%x",
2484 p_dcb->mdl_id);
2485 close_dch = true;
2486 }
2487 } else {
2488 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d",
2489 p_data->dch_open_cfm.local_mdep_id);
2490 close_dch = true;
2491 }
2492
2493 if (close_dch) btif_hl_clean_mdl_cb(p_dcb);
2494 } else
2495 close_dch = true;
2496 } else
2497 close_dch = true;
2498
2499 if (close_dch) BTA_HlDchClose(p_data->dch_open_cfm.mdl_handle);
2500 }
2501
2502 /*******************************************************************************
2503 *
2504 * Function btif_hl_proc_dch_open_cfm
2505 *
2506 * Description Process the DCH close confirmation
2507 *
2508 * Returns Nothing
2509 *
2510 ******************************************************************************/
btif_hl_proc_dch_open_cfm(tBTA_HL * p_data)2511 static bool btif_hl_proc_dch_open_cfm(tBTA_HL* p_data)
2512
2513 {
2514 btif_hl_mdl_cb_t* p_dcb;
2515 btif_hl_pending_chan_cb_t* p_pcb;
2516 uint8_t app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2517 bool status = false;
2518 bool close_dch = false;
2519
2520 BTIF_TRACE_DEBUG("%s", __func__);
2521
2522 // Find the correct app_idx based on the mdep_id;
2523 btif_hl_find_app_idx_using_mdepId(p_data->dch_open_cfm.local_mdep_id,
2524 &app_idx);
2525
2526 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_open_cfm.mcl_handle,
2527 app_idx, &mcl_idx)) {
2528 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2529
2530 if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2531 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2532
2533 if (btif_hl_find_mdep_cfg_idx(app_idx, p_data->dch_open_cfm.local_mdep_id,
2534 &mdep_cfg_idx)) {
2535 p_dcb->in_use = true;
2536 p_dcb->mdl_handle = p_data->dch_open_cfm.mdl_handle;
2537 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
2538 p_dcb->local_mdep_id = p_data->dch_open_cfm.local_mdep_id;
2539 p_dcb->mdl_id = p_data->dch_open_cfm.mdl_id;
2540 p_dcb->dch_mode = p_data->dch_open_cfm.dch_mode;
2541 p_dcb->is_the_first_reliable = p_data->dch_open_cfm.first_reliable;
2542 p_dcb->mtu = p_data->dch_open_cfm.mtu;
2543 p_dcb->channel_id = p_pcb->channel_id;
2544
2545 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d mdl_idx=%d", app_idx, mcl_idx,
2546 mdl_idx);
2547 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
2548 if (btif_hl_create_socket(app_idx, mcl_idx, mdl_idx)) {
2549 status = true;
2550 BTIF_TRACE_DEBUG(
2551 "app_idx=%d mcl_idx=%d mdl_idx=%d p_dcb->channel_id=0x%08x",
2552 app_idx, mcl_idx, mdl_idx, p_dcb->channel_id);
2553 btif_hl_clean_pcb(p_pcb);
2554 } else {
2555 BTIF_TRACE_ERROR("Unable to create socket");
2556 close_dch = true;
2557 }
2558 } else {
2559 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d",
2560 p_data->dch_open_cfm.local_mdep_id);
2561 close_dch = true;
2562 }
2563
2564 if (close_dch) {
2565 btif_hl_clean_mdl_cb(p_dcb);
2566 BTA_HlDchClose(p_data->dch_open_cfm.mdl_handle);
2567 }
2568 }
2569 }
2570
2571 return status;
2572 }
2573 /*******************************************************************************
2574 *
2575 * Function btif_hl_proc_dch_reconnect_cfm
2576 *
2577 * Description Process the DCH reconnect indication
2578 *
2579 * Returns Nothing
2580 *
2581 ******************************************************************************/
btif_hl_proc_dch_reconnect_cfm(tBTA_HL * p_data)2582 static bool btif_hl_proc_dch_reconnect_cfm(tBTA_HL* p_data) {
2583 btif_hl_mdl_cb_t* p_dcb;
2584 btif_hl_pending_chan_cb_t* p_pcb;
2585 uint8_t app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2586 bool status = false;
2587 bool close_dch = false;
2588
2589 BTIF_TRACE_DEBUG("%s", __func__);
2590
2591 btif_hl_find_app_idx_using_mdepId(p_data->dch_reconnect_cfm.local_mdep_id,
2592 &app_idx);
2593
2594 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_cfm.mcl_handle,
2595 app_idx, &mcl_idx)) {
2596 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
2597
2598 if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2599 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2600
2601 if (btif_hl_find_mdep_cfg_idx(app_idx,
2602 p_data->dch_reconnect_cfm.local_mdep_id,
2603 &mdep_cfg_idx)) {
2604 p_dcb->in_use = true;
2605 p_dcb->mdl_handle = p_data->dch_reconnect_cfm.mdl_handle;
2606 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
2607 p_dcb->local_mdep_id = p_data->dch_reconnect_cfm.local_mdep_id;
2608 p_dcb->mdl_id = p_data->dch_reconnect_cfm.mdl_id;
2609 p_dcb->dch_mode = p_data->dch_reconnect_cfm.dch_mode;
2610 p_dcb->is_the_first_reliable = p_data->dch_reconnect_cfm.first_reliable;
2611 p_dcb->mtu = p_data->dch_reconnect_cfm.mtu;
2612 p_dcb->channel_id = p_pcb->channel_id;
2613
2614 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d mdl_idx=%d", app_idx, mcl_idx,
2615 mdl_idx);
2616 btif_hl_send_setup_connecting_cb(app_idx, mcl_idx);
2617 if (btif_hl_create_socket(app_idx, mcl_idx, mdl_idx)) {
2618 status = true;
2619 BTIF_TRACE_DEBUG(
2620 "app_idx=%d mcl_idx=%d mdl_idx=%d p_dcb->channel_id=0x%08x",
2621 app_idx, mcl_idx, mdl_idx, p_dcb->channel_id);
2622 btif_hl_clean_pcb(p_pcb);
2623 } else {
2624 BTIF_TRACE_ERROR("Unable to create socket");
2625 close_dch = true;
2626 }
2627 } else {
2628 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d",
2629 p_data->dch_open_cfm.local_mdep_id);
2630 close_dch = true;
2631 }
2632
2633 if (close_dch) {
2634 btif_hl_clean_mdl_cb(p_dcb);
2635 BTA_HlDchClose(p_data->dch_reconnect_cfm.mdl_handle);
2636 }
2637 }
2638 }
2639
2640 return status;
2641 }
2642 /*******************************************************************************
2643 *
2644 * Function btif_hl_proc_dch_reconnect_ind
2645 *
2646 * Description Process the DCH reconnect indication
2647 *
2648 * Returns Nothing
2649 *
2650 ******************************************************************************/
btif_hl_proc_dch_reconnect_ind(tBTA_HL * p_data)2651 static void btif_hl_proc_dch_reconnect_ind(tBTA_HL* p_data)
2652
2653 {
2654 btif_hl_app_cb_t* p_acb;
2655 btif_hl_mdl_cb_t* p_dcb;
2656 uint8_t app_idx, mcl_idx, mdl_idx, mdep_cfg_idx;
2657 bool close_dch = false;
2658
2659 BTIF_TRACE_DEBUG("%s", __func__);
2660
2661 // Find the correct app_idx based on the mdep_id;
2662 btif_hl_find_app_idx_using_mdepId(p_data->dch_reconnect_ind.local_mdep_id,
2663 &app_idx);
2664
2665 if (btif_hl_find_mcl_idx_using_app_idx(p_data->dch_reconnect_ind.mcl_handle,
2666 app_idx, &mcl_idx)) {
2667 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
2668 BTIF_TRACE_DEBUG(
2669 "btif_hl_proc_dch_reconnect_ind: app_idx = %d, mcl_idx = %d", app_idx,
2670 mcl_idx);
2671
2672 if (btif_hl_find_avail_mdl_idx(app_idx, mcl_idx, &mdl_idx)) {
2673 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2674
2675 if (btif_hl_find_mdep_cfg_idx(app_idx,
2676 p_data->dch_reconnect_ind.local_mdep_id,
2677 &mdep_cfg_idx)) {
2678 p_dcb->in_use = true;
2679 p_dcb->mdl_handle = p_data->dch_reconnect_ind.mdl_handle;
2680 p_dcb->local_mdep_cfg_idx = mdep_cfg_idx;
2681 p_dcb->local_mdep_id = p_data->dch_reconnect_ind.local_mdep_id;
2682 p_dcb->mdl_id = p_data->dch_reconnect_ind.mdl_id;
2683 p_dcb->dch_mode = p_data->dch_reconnect_ind.dch_mode;
2684 p_dcb->dch_mode = p_data->dch_reconnect_ind.dch_mode;
2685 p_dcb->is_the_first_reliable = p_data->dch_reconnect_ind.first_reliable;
2686 p_dcb->mtu = p_data->dch_reconnect_ind.mtu;
2687 p_dcb->channel_id = btif_hl_get_next_channel_id(p_acb->app_id);
2688
2689 BTIF_TRACE_DEBUG(" app_idx=%d mcl_idx=%d mdl_idx=%d channel_id=%d",
2690 app_idx, mcl_idx, mdl_idx, p_dcb->channel_id);
2691 if (!btif_hl_create_socket(app_idx, mcl_idx, mdl_idx)) {
2692 BTIF_TRACE_ERROR("Unable to create socket");
2693 close_dch = true;
2694 }
2695 } else {
2696 BTIF_TRACE_ERROR("INVALID_LOCAL_MDEP_ID mdep_id=%d",
2697 p_data->dch_open_cfm.local_mdep_id);
2698 close_dch = true;
2699 }
2700
2701 if (close_dch) btif_hl_clean_mdl_cb(p_dcb);
2702 } else
2703 close_dch = true;
2704 } else
2705 close_dch = true;
2706
2707 if (close_dch) BTA_HlDchClose(p_data->dch_reconnect_ind.mdl_handle);
2708 }
2709
2710 /*******************************************************************************
2711 *
2712 * Function btif_hl_proc_dch_close_ind
2713 *
2714 * Description Process the DCH close indication
2715 *
2716 * Returns Nothing
2717 *
2718 ******************************************************************************/
btif_hl_proc_dch_close_ind(tBTA_HL * p_data)2719 static void btif_hl_proc_dch_close_ind(tBTA_HL* p_data)
2720
2721 {
2722 btif_hl_mdl_cb_t* p_dcb;
2723 btif_hl_mcl_cb_t* p_mcb;
2724 uint8_t app_idx, mcl_idx, mdl_idx;
2725
2726 BTIF_TRACE_DEBUG("%s", __func__);
2727 if (btif_hl_find_mdl_idx_using_handle(p_data->dch_close_ind.mdl_handle,
2728 &app_idx, &mcl_idx, &mdl_idx)) {
2729 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2730 btif_hl_release_socket(app_idx, mcl_idx, mdl_idx);
2731 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
2732 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2733 btif_hl_clean_mdl_cb(p_dcb);
2734 if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle))
2735 btif_hl_start_cch_timer(app_idx, mcl_idx);
2736 BTIF_TRACE_DEBUG("remote DCH close success mdl_idx=%d", mdl_idx);
2737 }
2738 }
2739
2740 /*******************************************************************************
2741 *
2742 * Function btif_hl_proc_dch_close_cfm
2743 *
2744 * Description Process the DCH reconnect confirmation
2745 *
2746 * Returns Nothing
2747 *
2748 ******************************************************************************/
btif_hl_proc_dch_close_cfm(tBTA_HL * p_data)2749 static void btif_hl_proc_dch_close_cfm(tBTA_HL* p_data)
2750
2751 {
2752 btif_hl_mdl_cb_t* p_dcb;
2753 btif_hl_mcl_cb_t* p_mcb;
2754 uint8_t app_idx, mcl_idx, mdl_idx;
2755
2756 BTIF_TRACE_DEBUG("%s", __func__);
2757 if (btif_hl_find_mdl_idx_using_handle(p_data->dch_close_cfm.mdl_handle,
2758 &app_idx, &mcl_idx, &mdl_idx)) {
2759 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2760 btif_hl_release_socket(app_idx, mcl_idx, mdl_idx);
2761 btif_hl_clean_mdl_cb(p_dcb);
2762 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
2763 if (!btif_hl_num_dchs_in_use(p_mcb->mcl_handle))
2764 btif_hl_start_cch_timer(app_idx, mcl_idx);
2765 BTIF_TRACE_DEBUG(" local DCH close success mdl_idx=%d", mdl_idx);
2766 }
2767 }
2768
2769 /*******************************************************************************
2770 *
2771 * Function btif_hl_proc_abort_ind
2772 *
2773 * Description Process the abort indicaiton
2774 *
2775 * Returns Nothing
2776 *
2777 ******************************************************************************/
btif_hl_proc_abort_ind(tBTA_HL_MCL_HANDLE mcl_handle)2778 static void btif_hl_proc_abort_ind(tBTA_HL_MCL_HANDLE mcl_handle) {
2779 BTIF_TRACE_DEBUG("%s", __func__);
2780 btif_hl_app_cb_t* p_acb;
2781 uint8_t i, j;
2782
2783 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
2784 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
2785 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
2786 if (p_acb->mcb[j].in_use)
2787 BTIF_TRACE_DEBUG(
2788 "btif_hl_find_mcl_idx_using_handle: app_idx=%d,mcl_idx =%d "
2789 "mcl_handle=%d",
2790 i, j, p_acb->mcb[j].mcl_handle);
2791 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
2792 btif_hl_stop_cch_timer(i, j);
2793 btif_hl_send_setup_disconnected_cb(i, j);
2794 btif_hl_clean_mcl_cb(i, j);
2795 }
2796 }
2797 }
2798 }
2799
2800 /*******************************************************************************
2801 *
2802 * Function btif_hl_proc_abort_cfm
2803 *
2804 * Description Process the abort confirmation
2805 *
2806 * Returns Nothing
2807 *
2808 ******************************************************************************/
btif_hl_proc_abort_cfm(tBTA_HL_MCL_HANDLE mcl_handle)2809 static void btif_hl_proc_abort_cfm(tBTA_HL_MCL_HANDLE mcl_handle) {
2810 BTIF_TRACE_DEBUG("%s", __func__);
2811 btif_hl_app_cb_t* p_acb;
2812 uint8_t i, j;
2813
2814 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
2815 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
2816 for (j = 0; j < BTA_HL_NUM_MCLS; j++) {
2817 if (p_acb->mcb[j].in_use)
2818 BTIF_TRACE_DEBUG(
2819 "btif_hl_find_mcl_idx_using_handle: app_idx=%d,mcl_idx =%d "
2820 "mcl_handle=%d",
2821 i, j, p_acb->mcb[j].mcl_handle);
2822 if (p_acb->mcb[j].in_use && (p_acb->mcb[j].mcl_handle == mcl_handle)) {
2823 btif_hl_stop_cch_timer(i, j);
2824 btif_hl_send_setup_disconnected_cb(i, j);
2825 btif_hl_clean_mcl_cb(i, j);
2826 }
2827 }
2828 }
2829 }
2830
2831 /*******************************************************************************
2832 *
2833 * Function btif_hl_proc_send_data_cfm
2834 *
2835 * Description Process the send data confirmation
2836 *
2837 * Returns Nothing
2838 *
2839 ******************************************************************************/
btif_hl_proc_send_data_cfm(tBTA_HL_MDL_HANDLE mdl_handle,UNUSED_ATTR tBTA_HL_STATUS status)2840 static void btif_hl_proc_send_data_cfm(tBTA_HL_MDL_HANDLE mdl_handle,
2841 UNUSED_ATTR tBTA_HL_STATUS status) {
2842 uint8_t app_idx, mcl_idx, mdl_idx;
2843 btif_hl_mdl_cb_t* p_dcb;
2844
2845 BTIF_TRACE_DEBUG("%s", __func__);
2846 if (btif_hl_find_mdl_idx_using_handle(mdl_handle, &app_idx, &mcl_idx,
2847 &mdl_idx)) {
2848 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2849 osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
2850 BTIF_TRACE_DEBUG("send success free p_tx_pkt tx_size=%d", p_dcb->tx_size);
2851 p_dcb->tx_size = 0;
2852 }
2853 }
2854
2855 /*******************************************************************************
2856 *
2857 * Function btif_hl_proc_dch_cong_ind
2858 *
2859 * Description Process the DCH congestion change indication
2860 *
2861 * Returns Nothing
2862 *
2863 ******************************************************************************/
btif_hl_proc_dch_cong_ind(tBTA_HL * p_data)2864 static void btif_hl_proc_dch_cong_ind(tBTA_HL* p_data)
2865
2866 {
2867 btif_hl_mdl_cb_t* p_dcb;
2868 uint8_t app_idx, mcl_idx, mdl_idx;
2869
2870 BTIF_TRACE_DEBUG("btif_hl_proc_dch_cong_ind");
2871
2872 if (btif_hl_find_mdl_idx_using_handle(p_data->dch_cong_ind.mdl_handle,
2873 &app_idx, &mcl_idx, &mdl_idx)) {
2874 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
2875 p_dcb->cong = p_data->dch_cong_ind.cong;
2876 }
2877 }
2878
2879 /*******************************************************************************
2880 *
2881 * Function btif_hl_proc_reg_request
2882 *
2883 * Description Process registration request
2884 *
2885 * Returns void
2886 *
2887 ******************************************************************************/
btif_hl_proc_reg_request(uint8_t app_idx,uint8_t app_id,tBTA_HL_REG_PARAM * p_reg_param,UNUSED_ATTR tBTA_HL_CBACK * p_cback)2888 static void btif_hl_proc_reg_request(uint8_t app_idx, uint8_t app_id,
2889 tBTA_HL_REG_PARAM* p_reg_param,
2890 UNUSED_ATTR tBTA_HL_CBACK* p_cback) {
2891 BTIF_TRACE_DEBUG("%s app_idx=%d app_id=%d", __func__, app_idx, app_id);
2892
2893 if (reg_counter > 1) {
2894 BTIF_TRACE_DEBUG("btif_hl_proc_reg_request: calling uPDATE");
2895 BTA_HlUpdate(app_id, p_reg_param, true, btif_hl_cback);
2896 } else
2897 BTA_HlRegister(app_id, p_reg_param, btif_hl_cback);
2898 }
2899
2900 /*******************************************************************************
2901 *
2902 * Function btif_hl_proc_cb_evt
2903 *
2904 * Description Process HL callback events
2905 *
2906 * Returns void
2907 *
2908 ******************************************************************************/
btif_hl_proc_cb_evt(uint16_t event,char * p_param)2909 static void btif_hl_proc_cb_evt(uint16_t event, char* p_param) {
2910 btif_hl_evt_cb_t* p_data = (btif_hl_evt_cb_t*)p_param;
2911 bthl_channel_state_t state = BTHL_CONN_STATE_DISCONNECTED;
2912 bool send_chan_cb = true;
2913 tBTA_HL_REG_PARAM reg_param;
2914 btif_hl_app_cb_t* p_acb;
2915
2916 BTIF_TRACE_DEBUG("%s event %d", __func__, event);
2917 btif_hl_display_calling_process_name();
2918
2919 switch (event) {
2920 case BTIF_HL_SEND_CONNECTED_CB:
2921 case BTIF_HL_SEND_DISCONNECTED_CB:
2922 if (p_data->chan_cb.cb_state == BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING)
2923 state = BTHL_CONN_STATE_CONNECTED;
2924 else if (p_data->chan_cb.cb_state ==
2925 BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING)
2926 state = BTHL_CONN_STATE_DISCONNECTED;
2927 else
2928 send_chan_cb = false;
2929
2930 if (send_chan_cb) {
2931 RawAddress bd_addr = p_data->chan_cb.bd_addr;
2932 BTIF_TRACE_DEBUG(
2933 "state callbk: ch_id=0x%08x cb_state=%d state=%d fd=%d",
2934 p_data->chan_cb.channel_id, p_data->chan_cb.cb_state, state,
2935 p_data->chan_cb.fd);
2936 VLOG(1) << "BD " << bd_addr;
2937 BTIF_HL_CALL_CBACK(
2938 bt_hl_callbacks, channel_state_cb, p_data->chan_cb.app_id, &bd_addr,
2939 p_data->chan_cb.mdep_cfg_index, p_data->chan_cb.channel_id, state,
2940 p_data->chan_cb.fd);
2941 }
2942
2943 break;
2944
2945 case BTIF_HL_REG_APP:
2946 reg_counter++;
2947 p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->reg.app_idx);
2948 BTIF_TRACE_DEBUG("Rcv BTIF_HL_REG_APP app_idx=%d reg_pending=%d",
2949 p_data->reg.app_idx, p_acb->reg_pending);
2950 if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED && p_acb->reg_pending) {
2951 BTIF_TRACE_DEBUG("Rcv BTIF_HL_REG_APP reg_counter=%d", reg_counter);
2952 p_acb->reg_pending = false;
2953 reg_param.dev_type = p_acb->dev_type;
2954 reg_param.sec_mask = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT;
2955 reg_param.p_srv_name = p_acb->srv_name;
2956 reg_param.p_srv_desp = p_acb->srv_desp;
2957 reg_param.p_provider_name = p_acb->provider_name;
2958 btif_hl_proc_reg_request(p_data->reg.app_idx, p_acb->app_id, ®_param,
2959 btif_hl_cback);
2960 } else {
2961 BTIF_TRACE_DEBUG("reg request is processed state=%d reg_pending=%d",
2962 btif_hl_get_state(), p_acb->reg_pending);
2963 }
2964 break;
2965
2966 case BTIF_HL_UNREG_APP:
2967 reg_counter--;
2968 BTIF_TRACE_DEBUG("Rcv BTIF_HL_UNREG_APP app_idx=%d",
2969 p_data->unreg.app_idx);
2970 p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->unreg.app_idx);
2971 if (btif_hl_get_state() == BTIF_HL_STATE_ENABLED) {
2972 if (reg_counter >= 1)
2973 BTA_HlUpdate(p_acb->app_id, NULL, false, NULL);
2974 else
2975 BTA_HlDeregister(p_acb->app_id, p_acb->app_handle);
2976 }
2977 break;
2978
2979 case BTIF_HL_UPDATE_MDL:
2980 BTIF_TRACE_DEBUG("Rcv BTIF_HL_UPDATE_MDL app_idx=%d",
2981 p_data->update_mdl.app_idx);
2982 p_acb = BTIF_HL_GET_APP_CB_PTR(p_data->update_mdl.app_idx);
2983 break;
2984
2985 default:
2986 BTIF_TRACE_ERROR("Unknown event %d", event);
2987 break;
2988 }
2989 }
2990
2991 /*******************************************************************************
2992 *
2993 * Function btif_hl_upstreams_evt
2994 *
2995 * Description Process HL events
2996 *
2997 * Returns void
2998 *
2999 ******************************************************************************/
btif_hl_upstreams_evt(uint16_t event,char * p_param)3000 static void btif_hl_upstreams_evt(uint16_t event, char* p_param) {
3001 tBTA_HL* p_data = (tBTA_HL*)p_param;
3002 uint8_t app_idx, mcl_idx;
3003 btif_hl_app_cb_t* p_acb;
3004 btif_hl_mcl_cb_t* p_mcb = NULL;
3005 btif_hl_pend_dch_op_t pending_op;
3006 bool status;
3007
3008 BTIF_TRACE_DEBUG("%s event %d", __func__, event);
3009 btif_hl_display_calling_process_name();
3010 switch (event) {
3011 case BTA_HL_REGISTER_CFM_EVT:
3012 BTIF_TRACE_DEBUG("Rcv BTA_HL_REGISTER_CFM_EVT");
3013 BTIF_TRACE_DEBUG("app_id=%d app_handle=%d status=%d ",
3014 p_data->reg_cfm.app_id, p_data->reg_cfm.app_handle,
3015 p_data->reg_cfm.status);
3016
3017 btif_hl_proc_reg_cfm(p_data);
3018 break;
3019 case BTA_HL_SDP_INFO_IND_EVT:
3020 BTIF_TRACE_DEBUG("Rcv BTA_HL_SDP_INFO_IND_EVT");
3021 BTIF_TRACE_DEBUG(
3022 "app_handle=%d ctrl_psm=0x%04x data_psm=0x%04x x_spec=%d "
3023 "mcap_sup_procs=0x%02x",
3024 p_data->sdp_info_ind.app_handle, p_data->sdp_info_ind.ctrl_psm,
3025 p_data->sdp_info_ind.data_psm, p_data->sdp_info_ind.data_x_spec,
3026 p_data->sdp_info_ind.mcap_sup_procs);
3027 // btif_hl_proc_sdp_info_ind(p_data);
3028 break;
3029
3030 case BTA_HL_DEREGISTER_CFM_EVT:
3031 BTIF_TRACE_DEBUG("Rcv BTA_HL_DEREGISTER_CFM_EVT");
3032 BTIF_TRACE_DEBUG("app_handle=%d status=%d ", p_data->dereg_cfm.app_handle,
3033 p_data->dereg_cfm.status);
3034 btif_hl_proc_dereg_cfm(p_data);
3035 break;
3036
3037 case BTA_HL_SDP_QUERY_CFM_EVT:
3038 BTIF_TRACE_DEBUG("Rcv BTA_HL_SDP_QUERY_CFM_EVT");
3039 BTIF_TRACE_DEBUG("app_handle=%d app_id =%d,status =%d",
3040 p_data->sdp_query_cfm.app_handle,
3041 p_data->sdp_query_cfm.app_id,
3042 p_data->sdp_query_cfm.status);
3043 VLOG(0) << "DB " << p_data->sdp_query_cfm.bd_addr;
3044
3045 if (p_data->sdp_query_cfm.status == BTA_HL_STATUS_OK)
3046 status = btif_hl_proc_sdp_query_cfm(p_data);
3047 else
3048 status = false;
3049
3050 if (!status) {
3051 BTIF_TRACE_DEBUG("BTA_HL_SDP_QUERY_CFM_EVT Status = %d",
3052 p_data->sdp_query_cfm.status);
3053 if (btif_hl_find_app_idx_using_app_id(p_data->sdp_query_cfm.app_id,
3054 &app_idx)) {
3055 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3056 if (btif_hl_find_mcl_idx(app_idx, p_data->sdp_query_cfm.bd_addr,
3057 &mcl_idx)) {
3058 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3059 if ((p_mcb->cch_oper == BTIF_HL_CCH_OP_MDEP_FILTERING) ||
3060 (p_mcb->cch_oper == BTIF_HL_CCH_OP_DCH_OPEN)) {
3061 pending_op = p_mcb->pcb.op;
3062 switch (pending_op) {
3063 case BTIF_HL_PEND_DCH_OP_OPEN:
3064 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3065 break;
3066 case BTIF_HL_PEND_DCH_OP_RECONNECT:
3067 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3068 default:
3069 break;
3070 }
3071 if (!p_mcb->is_connected) btif_hl_clean_mcl_cb(app_idx, mcl_idx);
3072 }
3073 }
3074 }
3075 }
3076
3077 break;
3078
3079 case BTA_HL_CCH_OPEN_CFM_EVT:
3080 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_OPEN_CFM_EVT");
3081 BTIF_TRACE_DEBUG(
3082 "app_id=%d,app_handle=%d mcl_handle=%d status =%d",
3083 p_data->cch_open_cfm.app_id, p_data->cch_open_cfm.app_handle,
3084 p_data->cch_open_cfm.mcl_handle, p_data->cch_open_cfm.status);
3085 VLOG(1) << "BD " << p_data->cch_open_cfm.bd_addr;
3086
3087 if (p_data->cch_open_cfm.status == BTA_HL_STATUS_OK ||
3088 p_data->cch_open_cfm.status == BTA_HL_STATUS_DUPLICATE_CCH_OPEN) {
3089 status = btif_hl_proc_cch_open_cfm(p_data);
3090 } else {
3091 status = false;
3092 }
3093
3094 if (!status) {
3095 if (btif_hl_find_app_idx_using_app_id(p_data->cch_open_cfm.app_id,
3096 &app_idx)) {
3097 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3098 if (btif_hl_find_mcl_idx(app_idx, p_data->cch_open_cfm.bd_addr,
3099 &mcl_idx)) {
3100 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3101 pending_op = p_mcb->pcb.op;
3102 switch (pending_op) {
3103 case BTIF_HL_PEND_DCH_OP_OPEN:
3104 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3105 break;
3106 case BTIF_HL_PEND_DCH_OP_RECONNECT:
3107 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3108 default:
3109 break;
3110 }
3111 btif_hl_clean_mcl_cb(app_idx, mcl_idx);
3112 }
3113 }
3114 }
3115 break;
3116
3117 case BTA_HL_DCH_OPEN_CFM_EVT:
3118 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_OPEN_CFM_EVT");
3119 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=0x%x status=%d ",
3120 p_data->dch_open_cfm.mcl_handle,
3121 p_data->dch_open_cfm.mdl_handle,
3122 p_data->dch_open_cfm.status);
3123 BTIF_TRACE_DEBUG(
3124 "first_reliable =%d dch_mode=%d local_mdep_id=%d mdl_id=%d mtu=%d",
3125 p_data->dch_open_cfm.first_reliable, p_data->dch_open_cfm.dch_mode,
3126 p_data->dch_open_cfm.local_mdep_id, p_data->dch_open_cfm.mdl_id,
3127 p_data->dch_open_cfm.mtu);
3128 if (p_data->dch_open_cfm.status == BTA_HL_STATUS_OK) {
3129 status = btif_hl_proc_dch_open_cfm(p_data);
3130 } else {
3131 status = false;
3132 }
3133
3134 if (!status) {
3135 if (btif_hl_find_mcl_idx_using_handle(p_data->dch_open_cfm.mcl_handle,
3136 &app_idx, &mcl_idx)) {
3137 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3138 pending_op = p_mcb->pcb.op;
3139 switch (pending_op) {
3140 case BTIF_HL_PEND_DCH_OP_OPEN:
3141 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3142 break;
3143 case BTIF_HL_PEND_DCH_OP_RECONNECT:
3144 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3145 default:
3146 break;
3147 }
3148 }
3149 }
3150 break;
3151
3152 case BTA_HL_CCH_OPEN_IND_EVT:
3153 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_OPEN_IND_EVT");
3154 BTIF_TRACE_DEBUG("app_handle=%d mcl_handle=%d",
3155 p_data->cch_open_ind.app_handle,
3156 p_data->cch_open_ind.mcl_handle);
3157 VLOG(0) << "DB " << p_data->cch_open_ind.bd_addr;
3158
3159 btif_hl_proc_cch_open_ind(p_data);
3160 break;
3161
3162 case BTA_HL_DCH_CREATE_IND_EVT:
3163 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_CREATE_IND_EVT");
3164 BTIF_TRACE_DEBUG("mcl_handle=%d", p_data->dch_create_ind.mcl_handle);
3165 BTIF_TRACE_DEBUG("local_mdep_id =%d mdl_id=%d cfg=%d",
3166 p_data->dch_create_ind.local_mdep_id,
3167 p_data->dch_create_ind.mdl_id,
3168 p_data->dch_create_ind.cfg);
3169 btif_hl_proc_create_ind(p_data);
3170 break;
3171
3172 case BTA_HL_DCH_OPEN_IND_EVT:
3173 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_OPEN_IND_EVT");
3174 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=0x%x",
3175 p_data->dch_open_ind.mcl_handle,
3176 p_data->dch_open_ind.mdl_handle);
3177 BTIF_TRACE_DEBUG(
3178 "first_reliable =%d dch_mode=%d local_mdep_id=%d mdl_id=%d mtu=%d",
3179 p_data->dch_open_ind.first_reliable, p_data->dch_open_ind.dch_mode,
3180 p_data->dch_open_ind.local_mdep_id, p_data->dch_open_ind.mdl_id,
3181 p_data->dch_open_ind.mtu);
3182
3183 btif_hl_proc_dch_open_ind(p_data);
3184 break;
3185
3186 case BTA_HL_DELETE_MDL_IND_EVT:
3187 BTIF_TRACE_DEBUG("Rcv BTA_HL_DELETE_MDL_IND_EVT");
3188 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_id=0x%x",
3189 p_data->delete_mdl_ind.mcl_handle,
3190 p_data->delete_mdl_ind.mdl_id);
3191 break;
3192
3193 case BTA_HL_DELETE_MDL_CFM_EVT:
3194 BTIF_TRACE_DEBUG("Rcv BTA_HL_DELETE_MDL_CFM_EVT");
3195 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_id=0x%x status=%d",
3196 p_data->delete_mdl_cfm.mcl_handle,
3197 p_data->delete_mdl_cfm.mdl_id,
3198 p_data->delete_mdl_cfm.status);
3199
3200 if (btif_hl_find_app_idx_using_deleted_mdl_id(
3201 p_data->delete_mdl_cfm.mdl_id, &app_idx)) {
3202 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3203 btif_hl_send_destroyed_cb(p_acb);
3204 btif_hl_clean_delete_mdl(&p_acb->delete_mdl);
3205 }
3206 break;
3207
3208 case BTA_HL_DCH_RECONNECT_CFM_EVT:
3209 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RECONNECT_CFM_EVT");
3210 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=%d status=%d ",
3211 p_data->dch_reconnect_cfm.mcl_handle,
3212 p_data->dch_reconnect_cfm.mdl_handle,
3213 p_data->dch_reconnect_cfm.status);
3214 BTIF_TRACE_DEBUG("first_reliable =%d dch_mode=%d mdl_id=%d mtu=%d",
3215 p_data->dch_reconnect_cfm.first_reliable,
3216 p_data->dch_reconnect_cfm.dch_mode,
3217 p_data->dch_reconnect_cfm.mdl_id,
3218 p_data->dch_reconnect_cfm.mtu);
3219
3220 if (p_data->dch_reconnect_cfm.status == BTA_HL_STATUS_OK) {
3221 status = btif_hl_proc_dch_reconnect_cfm(p_data);
3222 } else {
3223 status = false;
3224 }
3225
3226 if (!status) {
3227 if (btif_hl_find_mcl_idx_using_handle(p_data->dch_open_cfm.mcl_handle,
3228 &app_idx, &mcl_idx)) {
3229 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3230 pending_op = p_mcb->pcb.op;
3231 switch (pending_op) {
3232 case BTIF_HL_PEND_DCH_OP_OPEN:
3233 btif_hl_send_setup_disconnected_cb(app_idx, mcl_idx);
3234 break;
3235 case BTIF_HL_PEND_DCH_OP_RECONNECT:
3236 case BTIF_HL_PEND_DCH_OP_DELETE_MDL:
3237 default:
3238 break;
3239 }
3240 }
3241 }
3242
3243 break;
3244
3245 case BTA_HL_CCH_CLOSE_CFM_EVT:
3246 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_CLOSE_CFM_EVT");
3247 BTIF_TRACE_DEBUG("mcl_handle=%d status =%d",
3248 p_data->cch_close_cfm.mcl_handle,
3249 p_data->cch_close_cfm.status);
3250 if (p_data->cch_close_cfm.status == BTA_HL_STATUS_OK) {
3251 btif_hl_proc_cch_close_cfm(p_data);
3252 }
3253 break;
3254
3255 case BTA_HL_CCH_CLOSE_IND_EVT:
3256 BTIF_TRACE_DEBUG("Rcv BTA_HL_CCH_CLOSE_IND_EVT");
3257 BTIF_TRACE_DEBUG("mcl_handle =%d intentional_close=%s",
3258 p_data->cch_close_ind.mcl_handle,
3259 (p_data->cch_close_ind.intentional ? "Yes" : "No"));
3260
3261 btif_hl_proc_cch_close_ind(p_data);
3262 break;
3263
3264 case BTA_HL_DCH_CLOSE_IND_EVT:
3265 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_CLOSE_IND_EVT");
3266 BTIF_TRACE_DEBUG("mdl_handle=%d intentional_close=%s",
3267 p_data->dch_close_ind.mdl_handle,
3268 (p_data->dch_close_ind.intentional ? "Yes" : "No"));
3269
3270 btif_hl_proc_dch_close_ind(p_data);
3271 break;
3272
3273 case BTA_HL_DCH_CLOSE_CFM_EVT:
3274 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_CLOSE_CFM_EVT");
3275 BTIF_TRACE_DEBUG("mdl_handle=%d status=%d ",
3276 p_data->dch_close_cfm.mdl_handle,
3277 p_data->dch_close_cfm.status);
3278
3279 if (p_data->dch_close_cfm.status == BTA_HL_STATUS_OK) {
3280 btif_hl_proc_dch_close_cfm(p_data);
3281 }
3282 break;
3283
3284 case BTA_HL_DCH_ECHO_TEST_CFM_EVT:
3285 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_ECHO_TEST_CFM_EVT");
3286 BTIF_TRACE_DEBUG("mcl_handle=%d status=%d",
3287 p_data->echo_test_cfm.mcl_handle,
3288 p_data->echo_test_cfm.status);
3289 /* not supported */
3290 break;
3291
3292 case BTA_HL_DCH_RECONNECT_IND_EVT:
3293 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RECONNECT_IND_EVT");
3294
3295 BTIF_TRACE_DEBUG("mcl_handle=%d mdl_handle=5d",
3296 p_data->dch_reconnect_ind.mcl_handle,
3297 p_data->dch_reconnect_ind.mdl_handle);
3298 BTIF_TRACE_DEBUG("first_reliable =%d dch_mode=%d mdl_id=%d mtu=%d",
3299 p_data->dch_reconnect_ind.first_reliable,
3300 p_data->dch_reconnect_ind.dch_mode,
3301 p_data->dch_reconnect_ind.mdl_id,
3302 p_data->dch_reconnect_ind.mtu);
3303
3304 btif_hl_proc_dch_reconnect_ind(p_data);
3305 break;
3306
3307 case BTA_HL_CONG_CHG_IND_EVT:
3308 BTIF_TRACE_DEBUG("Rcv BTA_HL_CONG_CHG_IND_EVT");
3309 BTIF_TRACE_DEBUG("mdl_handle=%d cong =%d",
3310 p_data->dch_cong_ind.mdl_handle,
3311 p_data->dch_cong_ind.cong);
3312 btif_hl_proc_dch_cong_ind(p_data);
3313 break;
3314
3315 case BTA_HL_DCH_ABORT_IND_EVT:
3316 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_ABORT_IND_EVT");
3317 BTIF_TRACE_DEBUG("mcl_handle=%d", p_data->dch_abort_ind.mcl_handle);
3318 btif_hl_proc_abort_ind(p_data->dch_abort_ind.mcl_handle);
3319 break;
3320 case BTA_HL_DCH_ABORT_CFM_EVT:
3321 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_ABORT_CFM_EVT");
3322 BTIF_TRACE_DEBUG("mcl_handle=%d status =%d",
3323 p_data->dch_abort_cfm.mcl_handle,
3324 p_data->dch_abort_cfm.status);
3325 if (p_data->dch_abort_cfm.status == BTA_HL_STATUS_OK) {
3326 btif_hl_proc_abort_cfm(p_data->dch_abort_ind.mcl_handle);
3327 }
3328 break;
3329
3330 case BTA_HL_DCH_SEND_DATA_CFM_EVT:
3331 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_SEND_DATA_CFM_EVT");
3332 BTIF_TRACE_DEBUG("mdl_handle=0x%x status =%d",
3333 p_data->dch_send_data_cfm.mdl_handle,
3334 p_data->dch_send_data_cfm.status);
3335 btif_hl_proc_send_data_cfm(p_data->dch_send_data_cfm.mdl_handle,
3336 p_data->dch_send_data_cfm.status);
3337 break;
3338
3339 case BTA_HL_DCH_RCV_DATA_IND_EVT:
3340 BTIF_TRACE_DEBUG("Rcv BTA_HL_DCH_RCV_DATA_IND_EVT");
3341 BTIF_TRACE_DEBUG("mdl_handle=0x%x ", p_data->dch_rcv_data_ind.mdl_handle);
3342 /* do nothing here */
3343 break;
3344
3345 default:
3346 BTIF_TRACE_DEBUG("Unknown Event (0x%02x)...", event);
3347 break;
3348 }
3349 }
3350
3351 /*******************************************************************************
3352 *
3353 * Function btif_hl_cback
3354 *
3355 * Description Callback function for HL events
3356 *
3357 * Returns void
3358 *
3359 ******************************************************************************/
btif_hl_cback(tBTA_HL_EVT event,tBTA_HL * p_data)3360 static void btif_hl_cback(tBTA_HL_EVT event, tBTA_HL* p_data) {
3361 bt_status_t status;
3362 int param_len = 0;
3363 BTIF_TRACE_DEBUG("%s event %d", __func__, event);
3364 btif_hl_display_calling_process_name();
3365 switch (event) {
3366 case BTA_HL_REGISTER_CFM_EVT:
3367 param_len = sizeof(tBTA_HL_REGISTER_CFM);
3368 break;
3369 case BTA_HL_SDP_INFO_IND_EVT:
3370 param_len = sizeof(tBTA_HL_SDP_INFO_IND);
3371 break;
3372 case BTA_HL_DEREGISTER_CFM_EVT:
3373 param_len = sizeof(tBTA_HL_DEREGISTER_CFM);
3374 break;
3375 case BTA_HL_SDP_QUERY_CFM_EVT:
3376 param_len = sizeof(tBTA_HL_SDP_QUERY_CFM);
3377 break;
3378 case BTA_HL_CCH_OPEN_CFM_EVT:
3379 param_len = sizeof(tBTA_HL_CCH_OPEN_CFM);
3380 break;
3381 case BTA_HL_DCH_OPEN_CFM_EVT:
3382 param_len = sizeof(tBTA_HL_DCH_OPEN_CFM);
3383 break;
3384 case BTA_HL_CCH_OPEN_IND_EVT:
3385 param_len = sizeof(tBTA_HL_CCH_OPEN_IND);
3386 break;
3387 case BTA_HL_DCH_CREATE_IND_EVT:
3388 param_len = sizeof(tBTA_HL_DCH_CREATE_IND);
3389 break;
3390 case BTA_HL_DCH_OPEN_IND_EVT:
3391 param_len = sizeof(tBTA_HL_DCH_OPEN_IND);
3392 break;
3393 case BTA_HL_DELETE_MDL_IND_EVT:
3394 param_len = sizeof(tBTA_HL_MDL_IND);
3395 break;
3396 case BTA_HL_DELETE_MDL_CFM_EVT:
3397 param_len = sizeof(tBTA_HL_MDL_CFM);
3398 break;
3399 case BTA_HL_DCH_RECONNECT_CFM_EVT:
3400 param_len = sizeof(tBTA_HL_DCH_OPEN_CFM);
3401 break;
3402 case BTA_HL_CCH_CLOSE_CFM_EVT:
3403 param_len = sizeof(tBTA_HL_MCL_CFM);
3404 break;
3405 case BTA_HL_CCH_CLOSE_IND_EVT:
3406 param_len = sizeof(tBTA_HL_CCH_CLOSE_IND);
3407 break;
3408 case BTA_HL_DCH_CLOSE_IND_EVT:
3409 param_len = sizeof(tBTA_HL_DCH_CLOSE_IND);
3410 break;
3411 case BTA_HL_DCH_CLOSE_CFM_EVT:
3412 param_len = sizeof(tBTA_HL_MDL_CFM);
3413 break;
3414 case BTA_HL_DCH_ECHO_TEST_CFM_EVT:
3415 param_len = sizeof(tBTA_HL_MCL_CFM);
3416 break;
3417 case BTA_HL_DCH_RECONNECT_IND_EVT:
3418 param_len = sizeof(tBTA_HL_DCH_OPEN_IND);
3419 break;
3420 case BTA_HL_CONG_CHG_IND_EVT:
3421 param_len = sizeof(tBTA_HL_DCH_CONG_IND);
3422 break;
3423 case BTA_HL_DCH_ABORT_IND_EVT:
3424 param_len = sizeof(tBTA_HL_MCL_IND);
3425 break;
3426 case BTA_HL_DCH_ABORT_CFM_EVT:
3427 param_len = sizeof(tBTA_HL_MCL_CFM);
3428 break;
3429 case BTA_HL_DCH_SEND_DATA_CFM_EVT:
3430 param_len = sizeof(tBTA_HL_MDL_CFM);
3431 break;
3432 case BTA_HL_DCH_RCV_DATA_IND_EVT:
3433 param_len = sizeof(tBTA_HL_MDL_IND);
3434 break;
3435 default:
3436 param_len = sizeof(tBTA_HL_MDL_IND);
3437 break;
3438 }
3439 status = btif_transfer_context(btif_hl_upstreams_evt, (uint16_t)event,
3440 (char*)p_data, param_len, NULL);
3441
3442 /* catch any failed context transfers */
3443 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
3444 }
3445
3446 /*******************************************************************************
3447 *
3448 * Function btif_hl_upstreams_ctrl_evt
3449 *
3450 * Description Callback function for HL control events in the BTIF task
3451 * context
3452 *
3453 * Returns void
3454 *
3455 ******************************************************************************/
btif_hl_upstreams_ctrl_evt(uint16_t event,char * p_param)3456 static void btif_hl_upstreams_ctrl_evt(uint16_t event, char* p_param) {
3457 tBTA_HL_CTRL* p_data = (tBTA_HL_CTRL*)p_param;
3458 uint8_t i;
3459 tBTA_HL_REG_PARAM reg_param;
3460 btif_hl_app_cb_t* p_acb;
3461
3462 BTIF_TRACE_DEBUG("%s event %d", __func__, event);
3463 btif_hl_display_calling_process_name();
3464
3465 switch (event) {
3466 case BTA_HL_CTRL_ENABLE_CFM_EVT:
3467 BTIF_TRACE_DEBUG("Rcv BTA_HL_CTRL_ENABLE_CFM_EVT");
3468 BTIF_TRACE_DEBUG("status=%d", p_data->enable_cfm.status);
3469
3470 if (p_data->enable_cfm.status == BTA_HL_STATUS_OK) {
3471 btif_hl_set_state(BTIF_HL_STATE_ENABLED);
3472
3473 for (i = 0; i < BTA_HL_NUM_APPS; i++) {
3474 p_acb = BTIF_HL_GET_APP_CB_PTR(i);
3475 if (p_acb->in_use && p_acb->reg_pending) {
3476 p_acb->reg_pending = false;
3477 reg_param.dev_type = p_acb->dev_type;
3478 reg_param.sec_mask = BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT;
3479 reg_param.p_srv_name = p_acb->srv_name;
3480 reg_param.p_srv_desp = p_acb->srv_desp;
3481 reg_param.p_provider_name = p_acb->provider_name;
3482
3483 BTIF_TRACE_DEBUG("Register pending app_id=%d", p_acb->app_id);
3484 btif_hl_proc_reg_request(i, p_acb->app_id, ®_param,
3485 btif_hl_cback);
3486 }
3487 }
3488 }
3489
3490 break;
3491 case BTA_HL_CTRL_DISABLE_CFM_EVT:
3492 BTIF_TRACE_DEBUG("Rcv BTA_HL_CTRL_DISABLE_CFM_EVT");
3493 BTIF_TRACE_DEBUG("status=%d", p_data->disable_cfm.status);
3494
3495 if (p_data->disable_cfm.status == BTA_HL_STATUS_OK) {
3496 for (size_t i = 0; i < BTA_HL_NUM_APPS; i++) {
3497 for (size_t j = 0; j < BTA_HL_NUM_MCLS; j++) {
3498 alarm_free(p_btif_hl_cb->acb[i].mcb[j].cch_timer);
3499 }
3500 }
3501 memset(p_btif_hl_cb, 0, sizeof(btif_hl_cb_t));
3502 btif_hl_set_state(BTIF_HL_STATE_DISABLED);
3503 }
3504
3505 break;
3506 default:
3507 break;
3508 }
3509 }
3510
3511 /*******************************************************************************
3512 *
3513 * Function btif_hl_ctrl_cback
3514 *
3515 * Description Callback function for HL control events
3516 *
3517 * Returns void
3518 *
3519 ******************************************************************************/
btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event,tBTA_HL_CTRL * p_data)3520 static void btif_hl_ctrl_cback(tBTA_HL_CTRL_EVT event, tBTA_HL_CTRL* p_data) {
3521 bt_status_t status;
3522 int param_len = 0;
3523
3524 BTIF_TRACE_DEBUG("%s event %d", __func__, event);
3525 btif_hl_display_calling_process_name();
3526
3527 switch (event) {
3528 case BTA_HL_CTRL_ENABLE_CFM_EVT:
3529 case BTA_HL_CTRL_DISABLE_CFM_EVT:
3530 param_len = sizeof(tBTA_HL_CTRL_ENABLE_DISABLE);
3531 break;
3532 default:
3533 break;
3534 }
3535
3536 status = btif_transfer_context(btif_hl_upstreams_ctrl_evt, (uint16_t)event,
3537 (char*)p_data, param_len, NULL);
3538 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
3539 }
3540 /*******************************************************************************
3541 *
3542 * Function connect_channel
3543 *
3544 * Description connect a data channel
3545 *
3546 * Returns bt_status_t
3547 *
3548 ******************************************************************************/
connect_channel(int app_id,RawAddress * bd_addr,int mdep_cfg_index,int * channel_id)3549 static bt_status_t connect_channel(int app_id, RawAddress* bd_addr,
3550 int mdep_cfg_index, int* channel_id) {
3551 uint8_t app_idx, mcl_idx;
3552 btif_hl_app_cb_t* p_acb = NULL;
3553 btif_hl_pending_chan_cb_t* p_pcb = NULL;
3554 btif_hl_mcl_cb_t* p_mcb = NULL;
3555 bt_status_t status = BT_STATUS_SUCCESS;
3556 tBTA_HL_DCH_OPEN_PARAM dch_open;
3557
3558 CHECK_BTHL_INIT();
3559 BTIF_TRACE_EVENT("%s", __func__);
3560 btif_hl_display_calling_process_name();
3561
3562 if (btif_hl_find_app_idx(((uint8_t)app_id), &app_idx)) {
3563 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3564 if (btif_hl_find_mcl_idx(app_idx, *bd_addr, &mcl_idx)) {
3565 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3566 if (p_mcb->is_connected) {
3567 dch_open.ctrl_psm = p_mcb->ctrl_psm;
3568 dch_open.local_mdep_id =
3569 p_acb->sup_feature.mdep[mdep_cfg_index].mdep_id;
3570 BTIF_TRACE_DEBUG(
3571 "connect_channel: app_idx =%d, mdep_cfg_indx =%d, mdep_id =%d "
3572 "app_id= %d",
3573 app_idx, mdep_cfg_index, dch_open.local_mdep_id, app_id);
3574 if (btif_hl_find_peer_mdep_id(
3575 p_acb->app_id, p_mcb->bd_addr,
3576 p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role,
3577 p_acb->sup_feature.mdep[mdep_cfg_index]
3578 .mdep_cfg.data_cfg[0]
3579 .data_type,
3580 &dch_open.peer_mdep_id)) {
3581 dch_open.local_cfg = p_acb->channel_type[mdep_cfg_index];
3582 if ((p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role ==
3583 BTA_HL_MDEP_ROLE_SOURCE) &&
3584 !btif_hl_is_the_first_reliable_existed(app_idx, mcl_idx)) {
3585 dch_open.local_cfg = BTA_HL_DCH_CFG_RELIABLE;
3586 }
3587 dch_open.sec_mask = (BTA_SEC_AUTHENTICATE | BTA_SEC_ENCRYPT);
3588
3589 if (!btif_hl_dch_open(p_acb->app_id, *bd_addr, &dch_open,
3590 mdep_cfg_index, BTIF_HL_PEND_DCH_OP_OPEN,
3591 channel_id)) {
3592 status = BT_STATUS_FAIL;
3593 BTIF_TRACE_EVENT("%s loc0 status = BT_STATUS_FAIL", __func__);
3594 }
3595 } else {
3596 p_mcb->cch_oper = BTIF_HL_CCH_OP_MDEP_FILTERING;
3597
3598 p_pcb = BTIF_HL_GET_PCB_PTR(app_idx, mcl_idx);
3599 p_pcb->in_use = true;
3600 p_pcb->mdep_cfg_idx = mdep_cfg_index;
3601 p_pcb->bd_addr = *bd_addr;
3602 p_pcb->op = BTIF_HL_PEND_DCH_OP_OPEN;
3603 BTA_HlSdpQuery(app_id, p_acb->app_handle, *bd_addr);
3604 }
3605 } else {
3606 status = BT_STATUS_FAIL;
3607 }
3608 } else {
3609 p_acb->filter.num_elems = 1;
3610 p_acb->filter.elem[0].data_type = p_acb->sup_feature.mdep[mdep_cfg_index]
3611 .mdep_cfg.data_cfg[mdep_cfg_index]
3612 .data_type;
3613 if (p_acb->sup_feature.mdep[mdep_cfg_index].mdep_cfg.mdep_role ==
3614 BTA_HL_MDEP_ROLE_SINK)
3615 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE;
3616 else
3617 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
3618
3619 if (!btif_hl_cch_open(p_acb->app_id, *bd_addr, 0, mdep_cfg_index,
3620 BTIF_HL_PEND_DCH_OP_OPEN, channel_id)) {
3621 status = BT_STATUS_FAIL;
3622 }
3623 }
3624 } else {
3625 status = BT_STATUS_FAIL;
3626 }
3627
3628 BTIF_TRACE_DEBUG("%s status=%d channel_id=0x%08x", __func__, status,
3629 *channel_id);
3630
3631 return status;
3632 }
3633 /*******************************************************************************
3634 *
3635 * Function destroy_channel
3636 *
3637 * Description destroy a data channel
3638 *
3639 * Returns bt_status_t
3640 *
3641 ******************************************************************************/
destroy_channel(int channel_id)3642 static bt_status_t destroy_channel(int channel_id) {
3643 uint8_t app_idx, mcl_idx, mdl_cfg_idx, mdep_cfg_idx = 0;
3644 bt_status_t status = BT_STATUS_SUCCESS;
3645 btif_hl_mdl_cfg_t* p_mdl;
3646 btif_hl_mcl_cb_t* p_mcb;
3647 btif_hl_app_cb_t* p_acb;
3648
3649 CHECK_BTHL_INIT();
3650 BTIF_TRACE_EVENT("%s channel_id=0x%08x", __func__, channel_id);
3651 btif_hl_display_calling_process_name();
3652
3653 if (btif_hl_if_channel_setup_pending(channel_id, &app_idx, &mcl_idx)) {
3654 btif_hl_dch_abort(app_idx, mcl_idx);
3655 } else {
3656 if (btif_hl_find_mdl_cfg_idx_using_channel_id(channel_id, &app_idx,
3657 &mdl_cfg_idx))
3658 // if(btif_hl_find_mdl_idx_using_channel_id(channel_id,
3659 // &app_idx,&mcl_idx, &mdl_idx))
3660 {
3661 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3662 if (!p_acb->delete_mdl.active) {
3663 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, mdl_cfg_idx);
3664 p_acb->delete_mdl.active = true;
3665 p_acb->delete_mdl.mdl_id = p_mdl->base.mdl_id;
3666 p_acb->delete_mdl.channel_id = channel_id;
3667 p_acb->delete_mdl.mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx;
3668 p_acb->delete_mdl.bd_addr = p_mdl->base.peer_bd_addr;
3669
3670 if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr, &mcl_idx)) {
3671 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3672 if (p_mcb->is_connected) {
3673 BTIF_TRACE_DEBUG("calling BTA_HlDeleteMdl mdl_id=%d",
3674 p_acb->delete_mdl.mdl_id);
3675 BTA_HlDeleteMdl(p_mcb->mcl_handle, p_acb->delete_mdl.mdl_id);
3676 } else {
3677 status = BT_STATUS_FAIL;
3678 }
3679 } else {
3680 BTIF_TRACE_DEBUG("btif_hl_delete_mdl calling btif_hl_cch_open");
3681 mdep_cfg_idx = p_mdl->extra.mdep_cfg_idx;
3682 p_acb->filter.num_elems = 1;
3683 p_acb->filter.elem[0].data_type =
3684 p_acb->sup_feature.mdep[mdep_cfg_idx]
3685 .mdep_cfg.data_cfg[mdep_cfg_idx]
3686 .data_type;
3687 if (p_acb->sup_feature.mdep[mdep_cfg_idx].mdep_cfg.mdep_role ==
3688 BTA_HL_MDEP_ROLE_SINK)
3689 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SOURCE;
3690 else
3691 p_acb->filter.elem[0].peer_mdep_role = BTA_HL_MDEP_ROLE_SINK;
3692 if (btif_hl_cch_open(p_acb->app_id, p_acb->delete_mdl.bd_addr, 0,
3693 mdep_cfg_idx, BTIF_HL_PEND_DCH_OP_DELETE_MDL,
3694 NULL)) {
3695 status = BT_STATUS_FAIL;
3696 }
3697 }
3698
3699 if (status == BT_STATUS_FAIL) {
3700 /* fail for now */
3701 btif_hl_clean_delete_mdl(&p_acb->delete_mdl);
3702 }
3703 } else {
3704 status = BT_STATUS_BUSY;
3705 }
3706 } else {
3707 status = BT_STATUS_FAIL;
3708 }
3709 }
3710 return status;
3711 }
3712 /*******************************************************************************
3713 *
3714 * Function unregister_application
3715 *
3716 * Description unregister an HDP application
3717 *
3718 * Returns bt_status_t
3719 *
3720 ******************************************************************************/
unregister_application(int app_id)3721 static bt_status_t unregister_application(int app_id) {
3722 uint8_t app_idx;
3723 int len;
3724 bt_status_t status = BT_STATUS_SUCCESS;
3725 btif_hl_evt_cb_t evt_param;
3726
3727 CHECK_BTHL_INIT();
3728 BTIF_TRACE_EVENT("%s app_id=%d", __func__, app_id);
3729 btif_hl_display_calling_process_name();
3730
3731 if (btif_hl_find_app_idx(((uint8_t)app_id), &app_idx)) {
3732 evt_param.unreg.app_idx = app_idx;
3733 reg_counter--;
3734 len = sizeof(btif_hl_unreg_t);
3735 status = btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_UNREG_APP,
3736 (char*)&evt_param, len, NULL);
3737 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
3738 } else {
3739 status = BT_STATUS_FAIL;
3740 }
3741
3742 BTIF_TRACE_DEBUG("de-reg return status=%d", status);
3743 return status;
3744 }
3745 /*******************************************************************************
3746 *
3747 * Function register_application
3748 *
3749 * Description register an HDP application
3750 *
3751 * Returns bt_status_t
3752 *
3753 ******************************************************************************/
register_application(bthl_reg_param_t * p_reg_param,int * app_id)3754 static bt_status_t register_application(bthl_reg_param_t* p_reg_param,
3755 int* app_id) {
3756 btif_hl_app_cb_t* p_acb;
3757 tBTA_HL_SUP_FEATURE* p_sup;
3758 tBTA_HL_MDEP_CFG* p_cfg;
3759 tBTA_HL_MDEP_DATA_TYPE_CFG* p_data;
3760 uint8_t app_idx = 0, i = 0;
3761 bthl_mdep_cfg_t* p_mdep_cfg;
3762 bt_status_t status = BT_STATUS_SUCCESS;
3763 btif_hl_evt_cb_t evt_param;
3764 int len;
3765
3766 CHECK_BTHL_INIT();
3767 BTIF_TRACE_EVENT("%s", __func__);
3768 btif_hl_display_calling_process_name();
3769
3770 if (btif_hl_get_state() == BTIF_HL_STATE_DISABLED) {
3771 btif_hl_init();
3772 btif_hl_set_state(BTIF_HL_STATE_ENABLING);
3773 BTA_HlEnable(btif_hl_ctrl_cback);
3774 }
3775
3776 if (!btif_hl_find_avail_app_idx(&app_idx)) {
3777 BTIF_TRACE_ERROR("Unable to allocate a new application control block");
3778 return BT_STATUS_FAIL;
3779 }
3780
3781 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3782 p_acb->in_use = true;
3783
3784 p_acb->app_id = btif_hl_get_next_app_id();
3785
3786 if (p_reg_param->application_name != NULL)
3787 strncpy(p_acb->application_name, p_reg_param->application_name,
3788 BTIF_HL_APPLICATION_NAME_LEN);
3789
3790 if (p_reg_param->provider_name != NULL)
3791 strncpy(p_acb->provider_name, p_reg_param->provider_name,
3792 BTA_PROVIDER_NAME_LEN);
3793
3794 if (p_reg_param->srv_name != NULL)
3795 strncpy(p_acb->srv_name, p_reg_param->srv_name, BTA_SERVICE_NAME_LEN);
3796
3797 if (p_reg_param->srv_desp != NULL)
3798 strncpy(p_acb->srv_desp, p_reg_param->srv_desp, BTA_SERVICE_DESP_LEN);
3799
3800 p_sup = &p_acb->sup_feature;
3801 p_sup->advertize_source_sdp = true;
3802 p_sup->echo_cfg.max_rx_apdu_size = BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE;
3803 p_sup->echo_cfg.max_tx_apdu_size = BTIF_HL_ECHO_MAX_TX_RX_APDU_SIZE;
3804 p_sup->num_of_mdeps = p_reg_param->number_of_mdeps;
3805
3806 for (i = 0, p_mdep_cfg = p_reg_param->mdep_cfg; i < p_sup->num_of_mdeps;
3807 i++, p_mdep_cfg++) {
3808 p_cfg = &p_sup->mdep[i].mdep_cfg;
3809 p_cfg->num_of_mdep_data_types = 1;
3810 p_data = &p_cfg->data_cfg[0];
3811
3812 if (!btif_hl_get_bta_mdep_role(p_mdep_cfg->mdep_role,
3813 &(p_cfg->mdep_role))) {
3814 BTIF_TRACE_ERROR("Invalid mdep_role=%d", p_mdep_cfg->mdep_role);
3815 status = BT_STATUS_FAIL;
3816 break;
3817 } else {
3818 if (p_cfg->mdep_role == BTA_HL_MDEP_ROLE_SINK)
3819 p_sup->app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SINK;
3820 else
3821 p_sup->app_role_mask |= BTA_HL_MDEP_ROLE_MASK_SOURCE;
3822
3823 if ((p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK) &&
3824 (p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SOURCE)) {
3825 p_acb->dev_type = BTA_HL_DEVICE_TYPE_DUAL;
3826 } else if (p_sup->app_role_mask & BTA_HL_MDEP_ROLE_MASK_SINK) {
3827 p_acb->dev_type = BTA_HL_DEVICE_TYPE_SINK;
3828 } else {
3829 p_acb->dev_type = BTA_HL_DEVICE_TYPE_SOURCE;
3830 }
3831
3832 p_data->data_type = (uint16_t)p_mdep_cfg->data_type;
3833 p_data->max_rx_apdu_size =
3834 btif_hl_get_max_rx_apdu_size(p_cfg->mdep_role, p_data->data_type);
3835 p_data->max_tx_apdu_size =
3836 btif_hl_get_max_tx_apdu_size(p_cfg->mdep_role, p_data->data_type);
3837
3838 if (p_mdep_cfg->mdep_description != NULL)
3839 strncpy(p_data->desp, p_mdep_cfg->mdep_description,
3840 BTA_SERVICE_DESP_LEN);
3841
3842 if (!btif_hl_get_bta_channel_type(p_mdep_cfg->channel_type,
3843 &(p_acb->channel_type[i]))) {
3844 BTIF_TRACE_ERROR("Invalid channel_type=%d", p_mdep_cfg->channel_type);
3845 status = BT_STATUS_FAIL;
3846 break;
3847 }
3848 }
3849 }
3850
3851 if (status == BT_STATUS_SUCCESS) {
3852 *app_id = (int)p_acb->app_id;
3853 evt_param.reg.app_idx = app_idx;
3854 len = sizeof(btif_hl_reg_t);
3855 p_acb->reg_pending = true;
3856 BTIF_TRACE_DEBUG("calling btif_transfer_context status=%d app_id=%d",
3857 status, *app_id);
3858 status = btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_REG_APP,
3859 (char*)&evt_param, len, NULL);
3860 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
3861
3862 } else {
3863 btif_hl_free_app_idx(app_idx);
3864 }
3865
3866 BTIF_TRACE_DEBUG("register_application status=%d app_id=%d", status, *app_id);
3867 return status;
3868 }
3869
3870 /*******************************************************************************
3871 *
3872 * Function btif_hl_save_mdl_cfg
3873 *
3874 * Description Save the MDL configuration
3875 *
3876 * Returns bool
3877 *
3878 ******************************************************************************/
btif_hl_save_mdl_cfg(uint8_t mdep_id,uint8_t item_idx,tBTA_HL_MDL_CFG * p_mdl_cfg)3879 bool btif_hl_save_mdl_cfg(uint8_t mdep_id, uint8_t item_idx,
3880 tBTA_HL_MDL_CFG* p_mdl_cfg) {
3881 btif_hl_mdl_cfg_t* p_mdl = NULL;
3882 bool success = false;
3883 btif_hl_app_cb_t* p_acb;
3884 btif_hl_mcl_cb_t* p_mcb;
3885 uint8_t app_idx, mcl_idx, len;
3886 bt_status_t bt_status;
3887 btif_hl_evt_cb_t evt_param;
3888 int* p_channel_id;
3889
3890 BTIF_TRACE_DEBUG(
3891 "%s mdep_id=%d item_idx=%d, local_mdep_id=%d mdl_id=0x%x dch_mode=%d",
3892 __func__, mdep_id, item_idx, p_mdl_cfg->local_mdep_id, p_mdl_cfg->mdl_id,
3893 p_mdl_cfg->dch_mode);
3894
3895 if (btif_hl_find_app_idx_using_mdepId(mdep_id, &app_idx)) {
3896 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
3897 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx);
3898 p_channel_id = BTIF_HL_GET_MDL_CFG_CHANNEL_ID_PTR(app_idx, item_idx);
3899 if (p_mdl) {
3900 memcpy(&p_mdl->base, p_mdl_cfg, sizeof(tBTA_HL_MDL_CFG));
3901 if (btif_hl_find_mcl_idx(app_idx, p_mdl->base.peer_bd_addr, &mcl_idx)) {
3902 p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
3903 if (p_mcb->pcb.in_use)
3904 *p_channel_id = p_mcb->pcb.channel_id;
3905 else
3906 *p_channel_id = btif_hl_get_next_channel_id(p_acb->app_id);
3907 p_mdl->extra.mdep_cfg_idx = p_mcb->pcb.mdep_cfg_idx;
3908 p_mdl->extra.data_type =
3909 p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx]
3910 .mdep_cfg.data_cfg[0]
3911 .data_type;
3912
3913 if (!btif_hl_find_peer_mdep_id(
3914 p_acb->app_id, p_mcb->bd_addr,
3915 p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx]
3916 .mdep_cfg.mdep_role,
3917 p_acb->sup_feature.mdep[p_mcb->pcb.mdep_cfg_idx]
3918 .mdep_cfg.data_cfg[0]
3919 .data_type,
3920 &p_mdl->extra.peer_mdep_id)) {
3921 p_mdl->extra.peer_mdep_id = BTA_HL_INVALID_MDEP_ID;
3922 }
3923 BTIF_TRACE_DEBUG("%s app_idx=%d item_idx=%d mld_id=0x%x", __func__,
3924 app_idx, item_idx, p_mdl->base.mdl_id);
3925 evt_param.update_mdl.app_idx = app_idx;
3926 len = sizeof(btif_hl_update_mdl_t);
3927 BTIF_TRACE_DEBUG("send BTIF_HL_UPDATE_MDL event app_idx=%d ", app_idx);
3928 bt_status =
3929 btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_UPDATE_MDL,
3930 (char*)&evt_param, len, NULL);
3931 if (bt_status == BT_STATUS_SUCCESS) {
3932 success = true;
3933 }
3934 ASSERTC(bt_status == BT_STATUS_SUCCESS, "context transfer failed",
3935 bt_status);
3936 }
3937 }
3938 }
3939 BTIF_TRACE_DEBUG("%s success=%d ", __func__, success);
3940
3941 return success;
3942 }
3943
3944 /*******************************************************************************
3945 *
3946 * Function btif_hl_delete_mdl_cfg
3947 *
3948 * Description Delete the MDL configuration
3949 *
3950 * Returns bool
3951 *
3952 ******************************************************************************/
btif_hl_delete_mdl_cfg(uint8_t mdep_id,uint8_t item_idx)3953 bool btif_hl_delete_mdl_cfg(uint8_t mdep_id, uint8_t item_idx) {
3954 btif_hl_mdl_cfg_t* p_mdl = NULL;
3955 bool success = false;
3956 uint8_t app_idx, len;
3957 bt_status_t bt_status;
3958 btif_hl_evt_cb_t evt_param;
3959
3960 if (btif_hl_find_app_idx_using_mdepId(mdep_id, &app_idx)) {
3961 p_mdl = BTIF_HL_GET_MDL_CFG_PTR(app_idx, item_idx);
3962 if (p_mdl) {
3963 memset(p_mdl, 0, sizeof(btif_hl_mdl_cfg_t));
3964 evt_param.update_mdl.app_idx = app_idx;
3965 len = sizeof(btif_hl_update_mdl_t);
3966 BTIF_TRACE_DEBUG("send BTIF_HL_UPDATE_MDL event app_idx=%d ", app_idx);
3967 bt_status = btif_transfer_context(btif_hl_proc_cb_evt, BTIF_HL_UPDATE_MDL,
3968 (char*)&evt_param, len, NULL);
3969 if (bt_status == BT_STATUS_SUCCESS) {
3970 success = true;
3971 }
3972 ASSERTC(bt_status == BT_STATUS_SUCCESS, "context transfer failed",
3973 bt_status);
3974 }
3975 }
3976
3977 BTIF_TRACE_DEBUG("%s success=%d ", __func__, success);
3978 return success;
3979 }
3980
3981 /*******************************************************************************
3982 *
3983 * Function init
3984 *
3985 * Description initializes the hl interface
3986 *
3987 * Returns bt_status_t
3988 *
3989 ******************************************************************************/
init(bthl_callbacks_t * callbacks)3990 static bt_status_t init(bthl_callbacks_t* callbacks) {
3991 bt_status_t status = BT_STATUS_SUCCESS;
3992
3993 BTIF_TRACE_EVENT("%s", __func__);
3994 btif_hl_display_calling_process_name();
3995 bt_hl_callbacks_cb = *callbacks;
3996 bt_hl_callbacks = &bt_hl_callbacks_cb;
3997 btif_hl_soc_thread_init();
3998 reg_counter = 0;
3999 return status;
4000 }
4001 /*******************************************************************************
4002 *
4003 * Function cleanup
4004 *
4005 * Description Closes the HL interface
4006 *
4007 * Returns void
4008 *
4009 ******************************************************************************/
cleanup(void)4010 static void cleanup(void) {
4011 BTIF_TRACE_EVENT("%s", __func__);
4012 btif_hl_display_calling_process_name();
4013 if (bt_hl_callbacks) {
4014 btif_disable_service(BTA_HDP_SERVICE_ID);
4015 bt_hl_callbacks = NULL;
4016 reg_counter = 0;
4017 }
4018
4019 btif_hl_disable();
4020 btif_hl_close_select_thread();
4021 }
4022
4023 static const bthl_interface_t bthlInterface = {
4024 sizeof(bthl_interface_t),
4025 init,
4026 register_application,
4027 unregister_application,
4028 connect_channel,
4029 destroy_channel,
4030 cleanup,
4031 };
4032
4033 /*******************************************************************************
4034 *
4035 * Function btif_hl_get_interface
4036 *
4037 * Description Get the hl callback interface
4038 *
4039 * Returns bthf_interface_t
4040 *
4041 ******************************************************************************/
btif_hl_get_interface()4042 const bthl_interface_t* btif_hl_get_interface() {
4043 BTIF_TRACE_EVENT("%s", __func__);
4044 return &bthlInterface;
4045 }
4046
4047 /*******************************************************************************
4048 *
4049 * Function btif_hl_update_maxfd
4050 *
4051 * Description Update the max fd if the input fd is greater than the current max
4052 * fd
4053 *
4054 * Returns int
4055 *
4056 ******************************************************************************/
btif_hl_update_maxfd(int max_org_s)4057 int btif_hl_update_maxfd(int max_org_s) {
4058 int maxfd = max_org_s;
4059
4060 BTIF_TRACE_DEBUG("btif_hl_update_maxfd max_org_s= %d", max_org_s);
4061 for (const list_node_t* node = list_begin(soc_queue);
4062 node != list_end(soc_queue); node = list_next(node)) {
4063 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node);
4064 if (maxfd < p_scb->max_s) {
4065 maxfd = p_scb->max_s;
4066 BTIF_TRACE_DEBUG("btif_hl_update_maxfd maxfd=%d", maxfd);
4067 }
4068 }
4069
4070 BTIF_TRACE_DEBUG("btif_hl_update_maxfd final *p_max_s=%d", maxfd);
4071 return maxfd;
4072 }
4073 /*******************************************************************************
4074 *
4075 * Function btif_hl_get_socket_state
4076 *
4077 * Description get socket state
4078 *
4079 * Returns btif_hl_soc_state_t
4080 *
4081 ******************************************************************************/
btif_hl_get_socket_state(btif_hl_soc_cb_t * p_scb)4082 btif_hl_soc_state_t btif_hl_get_socket_state(btif_hl_soc_cb_t* p_scb) {
4083 BTIF_TRACE_DEBUG("btif_hl_get_socket_state state=%d", p_scb->state);
4084 return p_scb->state;
4085 }
4086 /*******************************************************************************
4087 *
4088 * Function btif_hl_set_socket_state
4089 *
4090 * Description set socket state
4091 *
4092 * Returns void
4093 *
4094 ******************************************************************************/
btif_hl_set_socket_state(btif_hl_soc_cb_t * p_scb,btif_hl_soc_state_t new_state)4095 void btif_hl_set_socket_state(btif_hl_soc_cb_t* p_scb,
4096 btif_hl_soc_state_t new_state) {
4097 BTIF_TRACE_DEBUG("btif_hl_set_socket_state %d---->%d", p_scb->state,
4098 new_state);
4099 p_scb->state = new_state;
4100 }
4101 /*******************************************************************************
4102 *
4103 * Function btif_hl_release_mcl_sockets
4104 *
4105 * Description Release all sockets on the MCL
4106 *
4107 * Returns void
4108 *
4109 ******************************************************************************/
btif_hl_release_mcl_sockets(uint8_t app_idx,uint8_t mcl_idx)4110 void btif_hl_release_mcl_sockets(uint8_t app_idx, uint8_t mcl_idx) {
4111 uint8_t i;
4112 btif_hl_mdl_cb_t* p_dcb;
4113 bool found = false;
4114 BTIF_TRACE_DEBUG("%s", __func__);
4115 for (i = 0; i < BTA_HL_NUM_MDLS_PER_MCL; i++) {
4116 p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, i);
4117 if (p_dcb && p_dcb->in_use && p_dcb->p_scb) {
4118 BTIF_TRACE_DEBUG("found socket for app_idx=%d mcl_id=%d, mdl_idx=%d",
4119 app_idx, mcl_idx, i);
4120 btif_hl_set_socket_state(p_dcb->p_scb, BTIF_HL_SOC_STATE_W4_REL);
4121 p_dcb->p_scb = NULL;
4122 found = true;
4123 }
4124 }
4125 if (found) btif_hl_select_close_connected();
4126 }
4127 /*******************************************************************************
4128 *
4129 * Function btif_hl_release_socket
4130 *
4131 * Description release a specified socket
4132 *
4133 * Returns void
4134 *
4135 ******************************************************************************/
btif_hl_release_socket(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)4136 void btif_hl_release_socket(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
4137 btif_hl_soc_cb_t* p_scb = NULL;
4138 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
4139
4140 BTIF_TRACE_DEBUG("%s", __func__);
4141 BTIF_TRACE_DEBUG("app_idx=%d mcl_idx=%d mdl_idx=%d", app_idx, mcl_idx,
4142 mdl_idx);
4143
4144 if (p_dcb && p_dcb->p_scb) {
4145 p_scb = p_dcb->p_scb;
4146 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_REL);
4147 p_dcb->p_scb = NULL;
4148 btif_hl_select_close_connected();
4149 }
4150 }
4151 /*******************************************************************************
4152 *
4153 * Function btif_hl_create_socket
4154 *
4155 * Description create a socket
4156 *
4157 * Returns bool
4158 *
4159 ******************************************************************************/
btif_hl_create_socket(uint8_t app_idx,uint8_t mcl_idx,uint8_t mdl_idx)4160 bool btif_hl_create_socket(uint8_t app_idx, uint8_t mcl_idx, uint8_t mdl_idx) {
4161 btif_hl_mcl_cb_t* p_mcb = BTIF_HL_GET_MCL_CB_PTR(app_idx, mcl_idx);
4162 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(app_idx, mcl_idx, mdl_idx);
4163 bool status = false;
4164
4165 BTIF_TRACE_DEBUG("%s", __func__);
4166
4167 if (p_dcb) {
4168 btif_hl_soc_cb_t* p_scb =
4169 (btif_hl_soc_cb_t*)osi_malloc(sizeof(btif_hl_soc_cb_t));
4170 if (socketpair(AF_UNIX, SOCK_STREAM, 0, p_scb->socket_id) >= 0) {
4171 BTIF_TRACE_DEBUG("socket id[0]=%d id[1]=%d", p_scb->socket_id[0],
4172 p_scb->socket_id[1]);
4173 p_dcb->p_scb = p_scb;
4174 p_scb->app_idx = app_idx;
4175 p_scb->mcl_idx = mcl_idx;
4176 p_scb->mdl_idx = mdl_idx;
4177 p_scb->channel_id = p_dcb->channel_id;
4178 p_scb->mdep_cfg_idx = p_dcb->local_mdep_cfg_idx;
4179 p_scb->bd_addr = p_mcb->bd_addr;
4180 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_ADD);
4181 p_scb->max_s = p_scb->socket_id[1];
4182 list_append(soc_queue, (void*)p_scb);
4183 btif_hl_select_wakeup();
4184 status = true;
4185 } else {
4186 osi_free_and_reset((void**)&p_scb);
4187 }
4188 }
4189
4190 BTIF_TRACE_DEBUG("%s status=%d", __func__, status);
4191 return status;
4192 }
4193 /*******************************************************************************
4194 *
4195 * Function btif_hl_add_socket_to_set
4196 *
4197 * Description Add a socket
4198 *
4199 * Returns void
4200 *
4201 ******************************************************************************/
btif_hl_add_socket_to_set(fd_set * p_org_set)4202 void btif_hl_add_socket_to_set(fd_set* p_org_set) {
4203 btif_hl_mdl_cb_t* p_dcb = NULL;
4204 btif_hl_mcl_cb_t* p_mcb = NULL;
4205 btif_hl_app_cb_t* p_acb = NULL;
4206 btif_hl_evt_cb_t evt_param;
4207 bt_status_t status;
4208 int len;
4209
4210 BTIF_TRACE_DEBUG("entering %s", __func__);
4211
4212 for (const list_node_t* node = list_begin(soc_queue);
4213 node != list_end(soc_queue); node = list_next(node)) {
4214 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node);
4215
4216 BTIF_TRACE_DEBUG("btif_hl_add_socket_to_set first p_scb=0x%x", p_scb);
4217 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_ADD) {
4218 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_W4_READ);
4219 FD_SET(p_scb->socket_id[1], p_org_set);
4220 BTIF_TRACE_DEBUG("found and set socket_id=%d is_set=%d",
4221 p_scb->socket_id[1],
4222 FD_ISSET(p_scb->socket_id[1], p_org_set));
4223 p_mcb = BTIF_HL_GET_MCL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx);
4224 p_dcb = BTIF_HL_GET_MDL_CB_PTR(p_scb->app_idx, p_scb->mcl_idx,
4225 p_scb->mdl_idx);
4226 p_acb = BTIF_HL_GET_APP_CB_PTR(p_scb->app_idx);
4227 if (p_mcb && p_dcb) {
4228 btif_hl_stop_timer_using_handle(p_mcb->mcl_handle);
4229 evt_param.chan_cb.app_id = p_acb->app_id;
4230 evt_param.chan_cb.bd_addr = p_mcb->bd_addr;
4231 evt_param.chan_cb.channel_id = p_dcb->channel_id;
4232 evt_param.chan_cb.fd = p_scb->socket_id[0];
4233 evt_param.chan_cb.mdep_cfg_index = (int)p_dcb->local_mdep_cfg_idx;
4234 evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_CONNECTED_PENDING;
4235 len = sizeof(btif_hl_send_chan_state_cb_t);
4236 status = btif_transfer_context(btif_hl_proc_cb_evt,
4237 BTIF_HL_SEND_CONNECTED_CB,
4238 (char*)&evt_param, len, NULL);
4239 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4240 }
4241 }
4242 }
4243 BTIF_TRACE_DEBUG("leaving %s", __func__);
4244 }
4245
4246 /*******************************************************************************
4247 *
4248 * Function btif_hl_close_socket
4249 *
4250 * Description close a socket
4251 *
4252 * Returns void
4253 *
4254 ******************************************************************************/
btif_hl_close_socket(fd_set * p_org_set)4255 void btif_hl_close_socket(fd_set* p_org_set) {
4256 BTIF_TRACE_DEBUG("entering %s", __func__);
4257 for (const list_node_t* node = list_begin(soc_queue);
4258 node != list_end(soc_queue); node = list_next(node)) {
4259 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node);
4260 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_REL) {
4261 BTIF_TRACE_DEBUG("app_idx=%d mcl_id=%d, mdl_idx=%d", p_scb->app_idx,
4262 p_scb->mcl_idx, p_scb->mdl_idx);
4263 btif_hl_set_socket_state(p_scb, BTIF_HL_SOC_STATE_IDLE);
4264 if (p_scb->socket_id[1] != -1) {
4265 FD_CLR(p_scb->socket_id[1], p_org_set);
4266 shutdown(p_scb->socket_id[1], SHUT_RDWR);
4267 close(p_scb->socket_id[1]);
4268
4269 btif_hl_evt_cb_t evt_param;
4270 evt_param.chan_cb.app_id = (int)btif_hl_get_app_id(p_scb->channel_id);
4271 evt_param.chan_cb.bd_addr = p_scb->bd_addr;
4272 evt_param.chan_cb.channel_id = p_scb->channel_id;
4273 evt_param.chan_cb.fd = p_scb->socket_id[0];
4274 evt_param.chan_cb.mdep_cfg_index = (int)p_scb->mdep_cfg_idx;
4275 evt_param.chan_cb.cb_state = BTIF_HL_CHAN_CB_STATE_DISCONNECTED_PENDING;
4276 int len = sizeof(btif_hl_send_chan_state_cb_t);
4277 bt_status_t status = btif_transfer_context(
4278 btif_hl_proc_cb_evt, BTIF_HL_SEND_DISCONNECTED_CB,
4279 (char*)&evt_param, len, NULL);
4280 ASSERTC(status == BT_STATUS_SUCCESS, "context transfer failed", status);
4281 }
4282 }
4283 }
4284
4285 for (const list_node_t* node = list_begin(soc_queue);
4286 node != list_end(soc_queue);) {
4287 // We may mutate this list so we need keep track of
4288 // the current node and only remove items behind.
4289 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node);
4290 BTIF_TRACE_DEBUG("p_scb=0x%x", p_scb);
4291 node = list_next(node);
4292 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_IDLE) {
4293 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(
4294 p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
4295 BTIF_TRACE_DEBUG(
4296 "idle socket app_idx=%d mcl_id=%d, mdl_idx=%d p_dcb->in_use=%d",
4297 p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx, p_dcb->in_use);
4298 list_remove(soc_queue, p_scb);
4299 osi_free(p_scb);
4300 p_dcb->p_scb = NULL;
4301 }
4302 }
4303 BTIF_TRACE_DEBUG("leaving %s", __func__);
4304 }
4305
4306 /*******************************************************************************
4307 *
4308 * Function btif_hl_select_wakeup_callback
4309 *
4310 * Description Select wakup callback to add or close a socket
4311 *
4312 * Returns void
4313 *
4314 ******************************************************************************/
4315
btif_hl_select_wakeup_callback(fd_set * p_org_set,int wakeup_signal)4316 void btif_hl_select_wakeup_callback(fd_set* p_org_set, int wakeup_signal) {
4317 BTIF_TRACE_DEBUG("entering %s wakeup_signal=0x%04x", __func__, wakeup_signal);
4318
4319 if (wakeup_signal == btif_hl_signal_select_wakeup) {
4320 btif_hl_add_socket_to_set(p_org_set);
4321 } else if (wakeup_signal == btif_hl_signal_select_close_connected) {
4322 btif_hl_close_socket(p_org_set);
4323 }
4324 BTIF_TRACE_DEBUG("leaving %s", __func__);
4325 }
4326
4327 /*******************************************************************************
4328 *
4329 * Function btif_hl_select_monitor_callback
4330 *
4331 * Description Select monitor callback to check pending socket actions
4332 *
4333 * Returns void
4334 *
4335 ******************************************************************************/
btif_hl_select_monitor_callback(fd_set * p_cur_set,UNUSED_ATTR fd_set * p_org_set)4336 void btif_hl_select_monitor_callback(fd_set* p_cur_set,
4337 UNUSED_ATTR fd_set* p_org_set) {
4338 BTIF_TRACE_DEBUG("entering %s", __func__);
4339
4340 for (const list_node_t* node = list_begin(soc_queue);
4341 node != list_end(soc_queue); node = list_next(node)) {
4342 btif_hl_soc_cb_t* p_scb = (btif_hl_soc_cb_t*)list_node(node);
4343 if (btif_hl_get_socket_state(p_scb) == BTIF_HL_SOC_STATE_W4_READ) {
4344 if (FD_ISSET(p_scb->socket_id[1], p_cur_set)) {
4345 BTIF_TRACE_DEBUG("read data state= BTIF_HL_SOC_STATE_W4_READ");
4346 btif_hl_mdl_cb_t* p_dcb = BTIF_HL_GET_MDL_CB_PTR(
4347 p_scb->app_idx, p_scb->mcl_idx, p_scb->mdl_idx);
4348 CHECK(p_dcb != NULL);
4349 if (p_dcb->p_tx_pkt) {
4350 BTIF_TRACE_ERROR(
4351 "Rcv new pkt but the last pkt is still not been"
4352 " sent tx_size=%d",
4353 p_dcb->tx_size);
4354 osi_free_and_reset((void**)&p_dcb->p_tx_pkt);
4355 }
4356 p_dcb->p_tx_pkt = (uint8_t*)osi_malloc(p_dcb->mtu);
4357 ssize_t r;
4358 OSI_NO_INTR(r = recv(p_scb->socket_id[1], p_dcb->p_tx_pkt, p_dcb->mtu,
4359 MSG_DONTWAIT));
4360 if (r > 0) {
4361 BTIF_TRACE_DEBUG("btif_hl_select_monitor_callback send data r =%d",
4362 r);
4363 p_dcb->tx_size = r;
4364 BTIF_TRACE_DEBUG(
4365 "btif_hl_select_monitor_callback send data tx_size=%d",
4366 p_dcb->tx_size);
4367 BTA_HlSendData(p_dcb->mdl_handle, p_dcb->tx_size);
4368 } else {
4369 BTIF_TRACE_DEBUG(
4370 "btif_hl_select_monitor_callback receive failed r=%d", r);
4371 BTA_HlDchClose(p_dcb->mdl_handle);
4372 }
4373 }
4374 }
4375 }
4376
4377 if (list_is_empty(soc_queue))
4378 BTIF_TRACE_DEBUG("btif_hl_select_monitor_queue is empty");
4379
4380 BTIF_TRACE_DEBUG("leaving %s", __func__);
4381 }
4382
4383 /*******************************************************************************
4384 *
4385 * Function btif_hl_select_wakeup_init
4386 *
4387 * Description select loop wakup init
4388 *
4389 * Returns int
4390 *
4391 ******************************************************************************/
btif_hl_select_wakeup_init(fd_set * set)4392 static inline int btif_hl_select_wakeup_init(fd_set* set) {
4393 BTIF_TRACE_DEBUG("%s", __func__);
4394 if (signal_fds[0] == -1 &&
4395 socketpair(AF_UNIX, SOCK_STREAM, 0, signal_fds) < 0) {
4396 BTIF_TRACE_ERROR("socketpair failed: %s", strerror(errno));
4397 return -1;
4398 }
4399
4400 BTIF_TRACE_DEBUG(
4401 "btif_hl_select_wakeup_init signal_fds[0]=%d signal_fds[1]=%d",
4402 signal_fds[0], signal_fds[1]);
4403 FD_SET(signal_fds[0], set);
4404
4405 return signal_fds[0];
4406 }
4407
4408 /*******************************************************************************
4409 *
4410 * Function btif_hl_select_wakeup
4411 *
4412 * Description send a signal to wakupo the select loop
4413 *
4414 * Returns int
4415 *
4416 ******************************************************************************/
btif_hl_select_wakeup(void)4417 static inline int btif_hl_select_wakeup(void) {
4418 char sig_on = btif_hl_signal_select_wakeup;
4419
4420 BTIF_TRACE_DEBUG("%s", __func__);
4421
4422 ssize_t ret;
4423 OSI_NO_INTR(ret = send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
4424
4425 return (int)ret;
4426 }
4427
4428 /*******************************************************************************
4429 *
4430 * Function btif_hl_select_close_connected
4431 *
4432 * Description send a signal to close a socket
4433 *
4434 * Returns int
4435 *
4436 ******************************************************************************/
btif_hl_select_close_connected(void)4437 static inline int btif_hl_select_close_connected(void) {
4438 char sig_on = btif_hl_signal_select_close_connected;
4439
4440 BTIF_TRACE_DEBUG("%s", __func__);
4441
4442 ssize_t ret;
4443 OSI_NO_INTR(ret = send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
4444
4445 return (int)ret;
4446 }
4447
4448 /*******************************************************************************
4449 *
4450 * Function btif_hl_close_select_thread
4451 *
4452 * Description send signal to close the thread and then close all signal FDs
4453 *
4454 * Returns int
4455 *
4456 ******************************************************************************/
btif_hl_close_select_thread(void)4457 static inline int btif_hl_close_select_thread(void) {
4458 ssize_t result = 0;
4459 char sig_on = btif_hl_signal_select_exit;
4460
4461 BTIF_TRACE_DEBUG("%", __func__);
4462
4463 OSI_NO_INTR(result = send(signal_fds[1], &sig_on, sizeof(sig_on), 0));
4464
4465 if (btif_is_enabled()) {
4466 /* Wait for the select_thread_id to exit if BT is still enabled
4467 and only this profile getting cleaned up*/
4468 if (select_thread_id != -1) {
4469 pthread_join(select_thread_id, NULL);
4470 select_thread_id = -1;
4471 }
4472 }
4473 list_free(soc_queue);
4474 soc_queue = NULL;
4475
4476 return (int)result;
4477 }
4478
4479 /*******************************************************************************
4480 *
4481 * Function btif_hl_select_wake_reset
4482 *
4483 * Description clear the received signal for the select loop
4484 *
4485 * Returns int
4486 *
4487 ******************************************************************************/
btif_hl_select_wake_reset(void)4488 static inline int btif_hl_select_wake_reset(void) {
4489 char sig_recv = 0;
4490
4491 BTIF_TRACE_DEBUG("%s", __func__);
4492
4493 ssize_t r;
4494 OSI_NO_INTR(
4495 r = recv(signal_fds[0], &sig_recv, sizeof(sig_recv), MSG_WAITALL));
4496
4497 return (int)sig_recv;
4498 }
4499 /*******************************************************************************
4500 *
4501 * Function btif_hl_select_wake_signaled
4502 *
4503 * Description check whether a fd is set or not
4504 *
4505 * Returns int
4506 *
4507 ******************************************************************************/
btif_hl_select_wake_signaled(fd_set * set)4508 static inline int btif_hl_select_wake_signaled(fd_set* set) {
4509 BTIF_TRACE_DEBUG("btif_hl_select_wake_signaled");
4510 return FD_ISSET(signal_fds[0], set);
4511 }
4512 /*******************************************************************************
4513 *
4514 * Function btif_hl_thread_cleanup
4515 *
4516 * Description shut down and clean up the select loop
4517 *
4518 * Returns void
4519 *
4520 ******************************************************************************/
btif_hl_thread_cleanup()4521 static void btif_hl_thread_cleanup() {
4522 if (listen_s != -1) close(listen_s);
4523 if (connected_s != -1) {
4524 shutdown(connected_s, SHUT_RDWR);
4525 close(connected_s);
4526 }
4527 listen_s = connected_s = -1;
4528 BTIF_TRACE_DEBUG("hl thread cleanup");
4529 }
4530 /*******************************************************************************
4531 *
4532 * Function btif_hl_select_thread
4533 *
4534 * Description the select loop
4535 *
4536 * Returns void
4537 *
4538 ******************************************************************************/
btif_hl_select_thread(UNUSED_ATTR void * arg)4539 static void* btif_hl_select_thread(UNUSED_ATTR void* arg) {
4540 fd_set org_set, curr_set;
4541 int r, max_curr_s, max_org_s;
4542
4543 BTIF_TRACE_DEBUG("entered btif_hl_select_thread");
4544 FD_ZERO(&org_set);
4545 max_org_s = btif_hl_select_wakeup_init(&org_set);
4546 BTIF_TRACE_DEBUG("max_s=%d ", max_org_s);
4547
4548 for (;;) {
4549 r = 0;
4550 BTIF_TRACE_DEBUG("set curr_set = org_set ");
4551 curr_set = org_set;
4552 max_curr_s = max_org_s;
4553 int ret = select((max_curr_s + 1), &curr_set, NULL, NULL, NULL);
4554 BTIF_TRACE_DEBUG("select unblocked ret=%d", ret);
4555 if (ret == -1) {
4556 if (errno == EINTR) continue;
4557 BTIF_TRACE_DEBUG("select() ret -1, exit the thread");
4558 btif_hl_thread_cleanup();
4559 select_thread_id = -1;
4560 return 0;
4561 } else if (ret) {
4562 BTIF_TRACE_DEBUG("btif_hl_select_wake_signaled, signal ret=%d", ret);
4563 if (btif_hl_select_wake_signaled(&curr_set)) {
4564 r = btif_hl_select_wake_reset();
4565 BTIF_TRACE_DEBUG("btif_hl_select_wake_signaled, signal:%d", r);
4566 if (r == btif_hl_signal_select_wakeup ||
4567 r == btif_hl_signal_select_close_connected) {
4568 btif_hl_select_wakeup_callback(&org_set, r);
4569 } else if (r == btif_hl_signal_select_exit) {
4570 btif_hl_thread_cleanup();
4571 BTIF_TRACE_DEBUG(
4572 "Exit hl_select_thread for btif_hl_signal_select_exit");
4573 return 0;
4574 }
4575 }
4576
4577 btif_hl_select_monitor_callback(&curr_set, &org_set);
4578 max_org_s = btif_hl_update_maxfd(max_org_s);
4579 } else
4580 BTIF_TRACE_DEBUG("no data, select ret: %d\n", ret);
4581 }
4582 BTIF_TRACE_DEBUG("leaving hl_select_thread");
4583 return 0;
4584 }
4585
4586 /*******************************************************************************
4587 *
4588 * Function create_thread
4589 *
4590 * Description creat a select loop
4591 *
4592 * Returns pthread_t
4593 *
4594 ******************************************************************************/
create_thread(void * (* start_routine)(void *),void * arg)4595 static inline pthread_t create_thread(void* (*start_routine)(void*),
4596 void* arg) {
4597 BTIF_TRACE_DEBUG("create_thread: entered");
4598 pthread_attr_t thread_attr;
4599
4600 pthread_attr_init(&thread_attr);
4601 pthread_attr_setdetachstate(&thread_attr, PTHREAD_CREATE_JOINABLE);
4602 pthread_t thread_id = -1;
4603 if (pthread_create(&thread_id, &thread_attr, start_routine, arg) != 0) {
4604 BTIF_TRACE_ERROR("pthread_create : %s", strerror(errno));
4605 return -1;
4606 }
4607 BTIF_TRACE_DEBUG("create_thread: thread created successfully");
4608 return thread_id;
4609 }
4610
4611 /*******************************************************************************
4612 *
4613 * Function btif_hl_soc_thread_init
4614 *
4615 * Description HL select loop init function.
4616 *
4617 * Returns void
4618 *
4619 ******************************************************************************/
btif_hl_soc_thread_init(void)4620 void btif_hl_soc_thread_init(void) {
4621 BTIF_TRACE_DEBUG("%s", __func__);
4622 soc_queue = list_new(NULL);
4623 if (soc_queue == NULL)
4624 LOG_ERROR(LOG_TAG, "%s unable to allocate resources for thread", __func__);
4625 select_thread_id = create_thread(btif_hl_select_thread, NULL);
4626 }
4627 /*******************************************************************************
4628 *
4629 * Function btif_hl_load_mdl_config
4630 *
4631 * Description load the MDL configuation from the application control block
4632 *
4633 * Returns bool
4634 *
4635 ******************************************************************************/
btif_hl_load_mdl_config(uint8_t app_id,uint8_t buffer_size,tBTA_HL_MDL_CFG * p_mdl_buf)4636 bool btif_hl_load_mdl_config(uint8_t app_id, uint8_t buffer_size,
4637 tBTA_HL_MDL_CFG* p_mdl_buf) {
4638 uint8_t app_idx;
4639 bool result = false;
4640 btif_hl_app_cb_t* p_acb;
4641 tBTA_HL_MDL_CFG* p;
4642 int i;
4643 BTIF_TRACE_DEBUG("%s", __func__);
4644
4645 if (btif_hl_find_app_idx(app_id, &app_idx)) {
4646 p_acb = BTIF_HL_GET_APP_CB_PTR(app_idx);
4647 for (i = 0, p = p_mdl_buf; i < buffer_size; i++, p++) {
4648 memcpy(p, &p_acb->mdl_cfg[i].base, sizeof(tBTA_HL_MDL_CFG));
4649 }
4650 result = true;
4651 }
4652
4653 BTIF_TRACE_DEBUG("result=%d", result);
4654 return result;
4655 }
4656