1 /******************************************************************************
2 *
3 * Copyright (c) 2014 The Android Open Source Project
4 * Copyright (C) 2004-2012 Broadcom Corporation
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at:
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 *
18 ******************************************************************************/
19
20 #include "bta_hf_client_int.h"
21 #include <bt_trace.h>
22 #include <string.h>
23 #include "bt_utils.h"
24
25 #define BTA_HF_CLIENT_NO_EDR_ESCO (BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 | \
26 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 | \
27 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 | \
28 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5)
29
30 static const tBTM_ESCO_PARAMS bta_hf_client_esco_params[] = {
31 /* SCO CVSD */
32 {
33 .rx_bw = BTM_64KBITS_RATE,
34 .tx_bw = BTM_64KBITS_RATE,
35 .max_latency = 10,
36 .voice_contfmt = BTM_VOICE_SETTING_CVSD,
37 .packet_types = (BTM_SCO_LINK_ONLY_MASK |
38 BTM_SCO_PKT_TYPES_MASK_NO_2_EV3 |
39 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
40 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
41 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
42 .retrans_effort = BTM_ESCO_RETRANS_POWER,
43 },
44 /* ESCO CVSD */
45 {
46 .rx_bw = BTM_64KBITS_RATE,
47 .tx_bw = BTM_64KBITS_RATE,
48 .max_latency = 10,
49 .voice_contfmt = BTM_VOICE_SETTING_CVSD,
50 /* Allow controller to use all types available except 5-slot EDR */
51 .packet_types = (BTM_SCO_LINK_ALL_PKT_MASK |
52 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
53 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
54 .retrans_effort = BTM_ESCO_RETRANS_POWER,
55 },
56 /* ESCO mSBC */
57 {
58 .rx_bw = BTM_64KBITS_RATE,
59 .tx_bw = BTM_64KBITS_RATE,
60 .max_latency = 13,
61 .voice_contfmt = BTM_VOICE_SETTING_TRANS,
62 /* Packet Types : EV3 + 2-EV3 */
63 .packet_types = (BTM_SCO_PKT_TYPES_MASK_EV3 |
64 BTM_SCO_PKT_TYPES_MASK_NO_3_EV3 |
65 BTM_SCO_PKT_TYPES_MASK_NO_2_EV5 |
66 BTM_SCO_PKT_TYPES_MASK_NO_3_EV5),
67 .retrans_effort = BTM_ESCO_RETRANS_QUALITY,
68 }
69 };
70
71 enum
72 {
73 BTA_HF_CLIENT_SCO_LISTEN_E,
74 BTA_HF_CLIENT_SCO_OPEN_E, /* open request */
75 BTA_HF_CLIENT_SCO_CLOSE_E, /* close request */
76 BTA_HF_CLIENT_SCO_SHUTDOWN_E, /* shutdown request */
77 BTA_HF_CLIENT_SCO_CONN_OPEN_E, /* sco opened */
78 BTA_HF_CLIENT_SCO_CONN_CLOSE_E, /* sco closed */
79 };
80
81 /*******************************************************************************
82 **
83 ** Function bta_hf_client_remove_sco
84 **
85 ** Description Removes the specified SCO from the system.
86 ** If only_active is TRUE, then SCO is only removed if connected
87 **
88 ** Returns BOOLEAN - TRUE if Sco removal was started
89 **
90 *******************************************************************************/
bta_hf_client_sco_remove(BOOLEAN only_active)91 static BOOLEAN bta_hf_client_sco_remove(BOOLEAN only_active)
92 {
93 BOOLEAN removed_started = FALSE;
94 tBTM_STATUS status;
95
96 APPL_TRACE_DEBUG("%s %d", __FUNCTION__, only_active);
97
98 if (bta_hf_client_cb.scb.sco_idx != BTM_INVALID_SCO_INDEX)
99 {
100 status = BTM_RemoveSco(bta_hf_client_cb.scb.sco_idx);
101
102 APPL_TRACE_DEBUG("%s idx 0x%04x, status:0x%x", __FUNCTION__, bta_hf_client_cb.scb.sco_idx, status);
103
104 if (status == BTM_CMD_STARTED)
105 {
106 removed_started = TRUE;
107 }
108 /* If no connection reset the sco handle */
109 else if ( (status == BTM_SUCCESS) || (status == BTM_UNKNOWN_ADDR) )
110 {
111 bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX;
112 }
113 }
114 return removed_started;
115 }
116
117 /*******************************************************************************
118 **
119 ** Function bta_hf_client_cback_sco
120 **
121 ** Description Call application callback function with SCO event.
122 **
123 **
124 ** Returns void
125 **
126 *******************************************************************************/
bta_hf_client_cback_sco(UINT8 event)127 void bta_hf_client_cback_sco(UINT8 event)
128 {
129 tBTA_HF_CLIENT evt;
130
131 memset(&evt, 0, sizeof(evt));
132
133 /* call app cback */
134 (*bta_hf_client_cb.p_cback)(event, (tBTA_HF_CLIENT *) &evt);
135 }
136
137 /*******************************************************************************
138 **
139 ** Function bta_hf_client_sco_conn_rsp
140 **
141 ** Description Process the SCO connection request
142 **
143 **
144 ** Returns void
145 **
146 *******************************************************************************/
bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA * p_data)147 static void bta_hf_client_sco_conn_rsp(tBTM_ESCO_CONN_REQ_EVT_DATA *p_data)
148 {
149 tBTM_ESCO_PARAMS resp;
150 UINT8 hci_status = HCI_SUCCESS;
151
152 APPL_TRACE_DEBUG("%s", __FUNCTION__);
153
154 if (bta_hf_client_cb.scb.sco_state == BTA_HF_CLIENT_SCO_LISTEN_ST)
155 {
156 if (p_data->link_type == BTM_LINK_TYPE_SCO)
157 {
158 resp = bta_hf_client_esco_params[0];
159 }
160 else
161 {
162 resp = bta_hf_client_esco_params[bta_hf_client_cb.scb.negotiated_codec];
163 }
164
165 /* tell sys to stop av if any */
166 bta_sys_sco_use(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
167 }
168 else
169 {
170 hci_status = HCI_ERR_HOST_REJECT_DEVICE;
171 }
172
173 BTM_EScoConnRsp(p_data->sco_inx, hci_status, &resp);
174 }
175
176 /*******************************************************************************
177 **
178 ** Function bta_hf_client_sco_connreq_cback
179 **
180 ** Description BTM eSCO connection requests and eSCO change requests
181 ** Only the connection requests are processed by BTA.
182 **
183 ** Returns void
184 **
185 *******************************************************************************/
bta_hf_client_esco_connreq_cback(tBTM_ESCO_EVT event,tBTM_ESCO_EVT_DATA * p_data)186 static void bta_hf_client_esco_connreq_cback(tBTM_ESCO_EVT event, tBTM_ESCO_EVT_DATA *p_data)
187 {
188 APPL_TRACE_DEBUG("%s %d", __FUNCTION__, event);
189
190 if (event != BTM_ESCO_CONN_REQ_EVT)
191 {
192 return;
193 }
194
195 /* TODO check remote bdaddr, should allow connect only from device with
196 * active SLC */
197
198 bta_hf_client_cb.scb.sco_idx = p_data->conn_evt.sco_inx;
199
200 bta_hf_client_sco_conn_rsp(&p_data->conn_evt);
201
202 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
203 }
204
205 /*******************************************************************************
206 **
207 ** Function bta_hf_client_sco_conn_cback
208 **
209 ** Description BTM SCO connection callback.
210 **
211 **
212 ** Returns void
213 **
214 *******************************************************************************/
bta_hf_client_sco_conn_cback(UINT16 sco_idx)215 static void bta_hf_client_sco_conn_cback(UINT16 sco_idx)
216 {
217 UINT8 *rem_bd;
218
219 APPL_TRACE_DEBUG("%s %d", __FUNCTION__, sco_idx);
220
221 rem_bd = BTM_ReadScoBdAddr(sco_idx);
222
223 if (rem_bd && bdcmp(bta_hf_client_cb.scb.peer_addr, rem_bd) == 0 &&
224 bta_hf_client_cb.scb.svc_conn && bta_hf_client_cb.scb.sco_idx == sco_idx)
225 {
226 BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
227 p_buf->event = BTA_HF_CLIENT_SCO_OPEN_EVT;
228 p_buf->layer_specific = bta_hf_client_cb.scb.conn_handle;
229 bta_sys_sendmsg(p_buf);
230 }
231 /* no match found; disconnect sco, init sco variables */
232 else
233 {
234 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
235 BTM_RemoveSco(sco_idx);
236 }
237 }
238
239 /*******************************************************************************
240 **
241 ** Function bta_hf_client_sco_disc_cback
242 **
243 ** Description BTM SCO disconnection callback.
244 **
245 **
246 ** Returns void
247 **
248 *******************************************************************************/
bta_hf_client_sco_disc_cback(UINT16 sco_idx)249 static void bta_hf_client_sco_disc_cback(UINT16 sco_idx)
250 {
251 APPL_TRACE_DEBUG("%s %d", __func__, sco_idx);
252
253 if (bta_hf_client_cb.scb.sco_idx == sco_idx) {
254 BT_HDR *p_buf = (BT_HDR *)osi_malloc(sizeof(BT_HDR));
255 p_buf->event = BTA_HF_CLIENT_SCO_CLOSE_EVT;
256 p_buf->layer_specific = bta_hf_client_cb.scb.conn_handle;;
257 bta_sys_sendmsg(p_buf);
258 }
259 }
260
261 /*******************************************************************************
262 **
263 ** Function bta_hf_client_create_sco
264 **
265 ** Description
266 **
267 **
268 ** Returns void
269 **
270 *******************************************************************************/
bta_hf_client_sco_create(BOOLEAN is_orig)271 static void bta_hf_client_sco_create(BOOLEAN is_orig)
272 {
273 tBTM_STATUS status;
274 UINT8 *p_bd_addr = NULL;
275 tBTM_ESCO_PARAMS params;
276
277 APPL_TRACE_DEBUG("%s %d", __FUNCTION__, is_orig);
278
279 /* Make sure this sco handle is not already in use */
280 if (bta_hf_client_cb.scb.sco_idx != BTM_INVALID_SCO_INDEX)
281 {
282 APPL_TRACE_WARNING("%s: Index 0x%04x already in use", __FUNCTION__,
283 bta_hf_client_cb.scb.sco_idx);
284 return;
285 }
286
287 params = bta_hf_client_esco_params[1];
288
289 /* if initiating set current scb and peer bd addr */
290 if (is_orig)
291 {
292 /* Attempt to use eSCO if remote host supports HFP >= 1.5 */
293 if (bta_hf_client_cb.scb.peer_version >= HFP_VERSION_1_5 && !bta_hf_client_cb.scb.retry_with_sco_only)
294 {
295 BTM_SetEScoMode(BTM_LINK_TYPE_ESCO, ¶ms);
296 /* If ESCO or EDR ESCO, retry with SCO only in case of failure */
297 if((params.packet_types & BTM_ESCO_LINK_ONLY_MASK)
298 ||!((params.packet_types & ~(BTM_ESCO_LINK_ONLY_MASK | BTM_SCO_LINK_ONLY_MASK)) ^ BTA_HF_CLIENT_NO_EDR_ESCO))
299 {
300 bta_hf_client_cb.scb.retry_with_sco_only = TRUE;
301 APPL_TRACE_API("Setting retry_with_sco_only to TRUE");
302 }
303 }
304 else
305 {
306 if(bta_hf_client_cb.scb.retry_with_sco_only)
307 APPL_TRACE_API("retrying with SCO only");
308 bta_hf_client_cb.scb.retry_with_sco_only = FALSE;
309
310 BTM_SetEScoMode(BTM_LINK_TYPE_SCO, ¶ms);
311 }
312
313 /* tell sys to stop av if any */
314 bta_sys_sco_use(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
315 }
316 else
317 {
318 bta_hf_client_cb.scb.retry_with_sco_only = FALSE;
319 }
320
321 p_bd_addr = bta_hf_client_cb.scb.peer_addr;
322
323 status = BTM_CreateSco(p_bd_addr, is_orig, params.packet_types,
324 &bta_hf_client_cb.scb.sco_idx, bta_hf_client_sco_conn_cback,
325 bta_hf_client_sco_disc_cback);
326 if (status == BTM_CMD_STARTED && !is_orig)
327 {
328 if(!BTM_RegForEScoEvts(bta_hf_client_cb.scb.sco_idx, bta_hf_client_esco_connreq_cback))
329 APPL_TRACE_DEBUG("%s SCO registration success", __FUNCTION__);
330 }
331
332 APPL_TRACE_API("%s: orig %d, inx 0x%04x, status 0x%x, pkt types 0x%04x",
333 __FUNCTION__, is_orig, bta_hf_client_cb.scb.sco_idx,
334 status, params.packet_types);
335 }
336
337
338 /*******************************************************************************
339 **
340 ** Function bta_hf_client_sco_event
341 **
342 ** Description Handle SCO events
343 **
344 **
345 ** Returns void
346 **
347 *******************************************************************************/
bta_hf_client_sco_event(UINT8 event)348 static void bta_hf_client_sco_event(UINT8 event)
349 {
350 APPL_TRACE_DEBUG("%s state: %d event: %d", __FUNCTION__,
351 bta_hf_client_cb.scb.sco_state, event);
352
353 switch (bta_hf_client_cb.scb.sco_state)
354 {
355 case BTA_HF_CLIENT_SCO_SHUTDOWN_ST:
356 switch (event)
357 {
358 case BTA_HF_CLIENT_SCO_LISTEN_E:
359 /* create sco listen connection */
360 bta_hf_client_sco_create(FALSE);
361 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
362 break;
363
364 default:
365 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_SHUTDOWN_ST: Ignoring event %d", event);
366 break;
367 }
368 break;
369
370 case BTA_HF_CLIENT_SCO_LISTEN_ST:
371 switch (event)
372 {
373 case BTA_HF_CLIENT_SCO_LISTEN_E:
374 /* create sco listen connection (Additional channel) */
375 bta_hf_client_sco_create(FALSE);
376 break;
377
378 case BTA_HF_CLIENT_SCO_OPEN_E:
379 /* remove listening connection */
380 bta_hf_client_sco_remove(FALSE);
381
382 /* create sco connection to peer */
383 bta_hf_client_sco_create(TRUE);
384 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
385 break;
386
387 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
388 /* remove listening connection */
389 bta_hf_client_sco_remove(FALSE);
390
391 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
392 break;
393
394 case BTA_HF_CLIENT_SCO_CLOSE_E:
395 /* remove listening connection */
396 /* Ignore the event. We need to keep listening SCO for the active SLC */
397 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_LISTEN_ST: Ignoring event %d", event);
398 break;
399
400 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
401 /* sco failed; create sco listen connection */
402 bta_hf_client_sco_create(FALSE);
403 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
404 break;
405
406 default:
407 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_LISTEN_ST: Ignoring event %d", event);
408 break;
409 }
410 break;
411
412 case BTA_HF_CLIENT_SCO_OPENING_ST:
413 switch (event)
414 {
415 case BTA_HF_CLIENT_SCO_CLOSE_E:
416 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_OPEN_CL_ST;
417 break;
418
419 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
420 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
421 break;
422
423 case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
424 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_OPEN_ST;
425 break;
426
427 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
428 /* sco failed; create sco listen connection */
429 bta_hf_client_sco_create(FALSE);
430 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
431 break;
432
433 default:
434 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_OPENING_ST: Ignoring event %d", event);
435 break;
436 }
437 break;
438
439 case BTA_HF_CLIENT_SCO_OPEN_CL_ST:
440 switch (event)
441 {
442 case BTA_HF_CLIENT_SCO_OPEN_E:
443 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
444 break;
445
446 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
447 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
448 break;
449
450 case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
451 /* close sco connection */
452 bta_hf_client_sco_remove(TRUE);
453
454 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
455 break;
456
457 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
458 /* sco failed; create sco listen connection */
459
460 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
461 break;
462
463 default:
464 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_OPEN_CL_ST: Ignoring event %d", event);
465 break;
466 }
467 break;
468
469 case BTA_HF_CLIENT_SCO_OPEN_ST:
470 switch (event)
471 {
472 case BTA_HF_CLIENT_SCO_CLOSE_E:
473 /* close sco connection if active */
474 if (bta_hf_client_sco_remove(TRUE))
475 {
476 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
477 }
478 break;
479
480 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
481 /* remove all listening connections */
482 bta_hf_client_sco_remove(FALSE);
483
484 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
485 break;
486
487 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
488 /* peer closed sco; create sco listen connection */
489 bta_hf_client_sco_create(FALSE);
490 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
491 break;
492
493 default:
494 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_OPEN_ST: Ignoring event %d", event);
495 break;
496 }
497 break;
498
499 case BTA_HF_CLIENT_SCO_CLOSING_ST:
500 switch (event)
501 {
502 case BTA_HF_CLIENT_SCO_OPEN_E:
503 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_CLOSE_OP_ST;
504 break;
505
506 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
507 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
508 break;
509
510 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
511 /* peer closed sco; create sco listen connection */
512 bta_hf_client_sco_create(FALSE);
513
514 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_LISTEN_ST;
515 break;
516
517 default:
518 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_CLOSING_ST: Ignoring event %d", event);
519 break;
520 }
521 break;
522
523 case BTA_HF_CLIENT_SCO_CLOSE_OP_ST:
524 switch (event)
525 {
526 case BTA_HF_CLIENT_SCO_CLOSE_E:
527 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_CLOSING_ST;
528 break;
529
530 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
531 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTTING_ST;
532 break;
533
534 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
535 /* open sco connection */
536 bta_hf_client_sco_create(TRUE);
537 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_OPENING_ST;
538 break;
539
540 default:
541 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_CLOSE_OP_ST: Ignoring event %d", event);
542 break;
543 }
544 break;
545
546 case BTA_HF_CLIENT_SCO_SHUTTING_ST:
547 switch (event)
548 {
549 case BTA_HF_CLIENT_SCO_CONN_OPEN_E:
550 /* close sco connection; wait for conn close event */
551 bta_hf_client_sco_remove(TRUE);
552 break;
553
554 case BTA_HF_CLIENT_SCO_CONN_CLOSE_E:
555 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
556 break;
557
558 case BTA_HF_CLIENT_SCO_SHUTDOWN_E:
559 bta_hf_client_cb.scb.sco_state = BTA_HF_CLIENT_SCO_SHUTDOWN_ST;
560 break;
561
562 default:
563 APPL_TRACE_WARNING("BTA_HF_CLIENT_SCO_SHUTTING_ST: Ignoring event %d", event);
564 break;
565 }
566 break;
567
568 default:
569 break;
570 }
571 }
572
573 /*******************************************************************************
574 **
575 ** Function bta_hf_client_sco_listen
576 **
577 ** Description Initialize SCO listener
578 **
579 **
580 ** Returns void
581 **
582 *******************************************************************************/
bta_hf_client_sco_listen(tBTA_HF_CLIENT_DATA * p_data)583 void bta_hf_client_sco_listen(tBTA_HF_CLIENT_DATA *p_data)
584 {
585 UNUSED(p_data);
586
587 APPL_TRACE_DEBUG("%s", __FUNCTION__);
588
589 bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_LISTEN_E);
590 }
591
592 /*******************************************************************************
593 **
594 ** Function bta_hf_client_sco_shutdown
595 **
596 ** Description
597 **
598 **
599 ** Returns void
600 **
601 *******************************************************************************/
bta_hf_client_sco_shutdown(tBTA_HF_CLIENT_DATA * p_data)602 void bta_hf_client_sco_shutdown(tBTA_HF_CLIENT_DATA *p_data)
603 {
604 UNUSED(p_data);
605
606 APPL_TRACE_DEBUG("%s", __FUNCTION__);
607
608 bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_SHUTDOWN_E);
609 }
610
611 /*******************************************************************************
612 **
613 ** Function bta_hf_client_sco_conn_open
614 **
615 ** Description
616 **
617 **
618 ** Returns void
619 **
620 *******************************************************************************/
bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA * p_data)621 void bta_hf_client_sco_conn_open(tBTA_HF_CLIENT_DATA *p_data)
622 {
623 UNUSED(p_data);
624
625 APPL_TRACE_DEBUG("%s", __FUNCTION__);
626
627 bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_CONN_OPEN_E);
628
629 bta_sys_sco_open(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
630
631 if (bta_hf_client_cb.scb.negotiated_codec == BTM_SCO_CODEC_MSBC)
632 {
633 bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_MSBC_OPEN_EVT);
634 }
635 else
636 {
637 bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_OPEN_EVT);
638 }
639
640 bta_hf_client_cb.scb.retry_with_sco_only = FALSE;
641 }
642
643 /*******************************************************************************
644 **
645 ** Function bta_hf_client_sco_conn_close
646 **
647 ** Description
648 **
649 **
650 ** Returns void
651 **
652 *******************************************************************************/
bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA * p_data)653 void bta_hf_client_sco_conn_close(tBTA_HF_CLIENT_DATA *p_data)
654 {
655 APPL_TRACE_DEBUG("%s", __FUNCTION__);
656
657 /* clear current scb */
658 bta_hf_client_cb.scb.sco_idx = BTM_INVALID_SCO_INDEX;
659
660 /* retry_with_sco_only, will be set only when initiator
661 ** and HFClient is first trying to establish an eSCO connection */
662 if (bta_hf_client_cb.scb.retry_with_sco_only && bta_hf_client_cb.scb.svc_conn)
663 {
664 bta_hf_client_sco_create(TRUE);
665 }
666 else
667 {
668 bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_CONN_CLOSE_E);
669
670 bta_sys_sco_close(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
671
672 bta_sys_sco_unuse(BTA_ID_HS, 1, bta_hf_client_cb.scb.peer_addr);
673
674 /* call app callback */
675 bta_hf_client_cback_sco(BTA_HF_CLIENT_AUDIO_CLOSE_EVT);
676
677 if (bta_hf_client_cb.scb.sco_close_rfc == TRUE)
678 {
679 bta_hf_client_cb.scb.sco_close_rfc = FALSE;
680 bta_hf_client_rfc_do_close(p_data);
681 }
682 }
683 bta_hf_client_cb.scb.retry_with_sco_only = FALSE;
684 }
685
686 /*******************************************************************************
687 **
688 ** Function bta_hf_client_sco_open
689 **
690 ** Description
691 **
692 **
693 ** Returns void
694 **
695 *******************************************************************************/
bta_hf_client_sco_open(tBTA_HF_CLIENT_DATA * p_data)696 void bta_hf_client_sco_open(tBTA_HF_CLIENT_DATA *p_data)
697 {
698 UNUSED(p_data);
699
700 APPL_TRACE_DEBUG("%s", __FUNCTION__);
701
702 bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_OPEN_E);
703 }
704
705 /*******************************************************************************
706 **
707 ** Function bta_hf_client_sco_close
708 **
709 ** Description
710 **
711 **
712 ** Returns void
713 **
714 *******************************************************************************/
bta_hf_client_sco_close(tBTA_HF_CLIENT_DATA * p_data)715 void bta_hf_client_sco_close(tBTA_HF_CLIENT_DATA *p_data)
716 {
717 UNUSED(p_data);
718
719 APPL_TRACE_DEBUG("%s 0x%x", __FUNCTION__, bta_hf_client_cb.scb.sco_idx);
720
721 if (bta_hf_client_cb.scb.sco_idx != BTM_INVALID_SCO_INDEX)
722 {
723 bta_hf_client_sco_event(BTA_HF_CLIENT_SCO_CLOSE_E);
724 }
725 }
726