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