• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright (C) 2000-2012 Broadcom Corporation
4  *
5  *  Licensed under the Apache License, Version 2.0 (the "License");
6  *  you may not use this file except in compliance with the License.
7  *  You may obtain a copy of the License at:
8  *
9  *  http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under the License is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the License for the specific language governing permissions and
15  *  limitations under the License.
16  *
17  ******************************************************************************/
18 
19 /******************************************************************************
20  *
21  *  This file contains functions that handle SCO connections. This includes
22  *  operations such as connect, disconnect, change supported packet types.
23  *
24  ******************************************************************************/
25 
26 #include <string.h>
27 #include "bt_common.h"
28 #include "bt_target.h"
29 #include "bt_types.h"
30 #include "bt_utils.h"
31 #include "btm_api.h"
32 #include "btm_int.h"
33 #include "btu.h"
34 #include "device/include/controller.h"
35 #include "device/include/esco_parameters.h"
36 #include "hcidefs.h"
37 #include "hcimsgs.h"
38 #include "osi/include/osi.h"
39 
40 #if (BTM_SCO_INCLUDED == TRUE)
41 
42 /******************************************************************************/
43 /*               L O C A L    D A T A    D E F I N I T I O N S                */
44 /******************************************************************************/
45 
46 #define SCO_ST_UNUSED 0
47 #define SCO_ST_LISTENING 1
48 #define SCO_ST_W4_CONN_RSP 2
49 #define SCO_ST_CONNECTING 3
50 #define SCO_ST_CONNECTED 4
51 #define SCO_ST_DISCONNECTING 5
52 #define SCO_ST_PEND_UNPARK 6
53 #define SCO_ST_PEND_ROLECHANGE 7
54 #define SCO_ST_PEND_MODECHANGE 8
55 
56 /******************************************************************************/
57 /*            L O C A L    F U N C T I O N     P R O T O T Y P E S            */
58 /******************************************************************************/
59 
60 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_parms);
61 
62 /*******************************************************************************
63  *
64  * Function         btm_sco_flush_sco_data
65  *
66  * Description      This function is called to flush the SCO data for this
67  *                  channel.
68  *
69  * Returns          void
70  *
71  ******************************************************************************/
72 #if (BTM_SCO_HCI_INCLUDED == TRUE && BTM_MAX_SCO_LINKS > 0)
btm_sco_flush_sco_data(uint16_t sco_inx)73 void btm_sco_flush_sco_data(uint16_t sco_inx) {
74   tSCO_CONN* p;
75   BT_HDR* p_buf;
76 
77   if (sco_inx < BTM_MAX_SCO_LINKS) {
78     p = &btm_cb.sco_cb.sco_db[sco_inx];
79     while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p->xmit_data_q)) != NULL)
80       osi_free(p_buf);
81   }
82 }
83 }
84 #else
85 void btm_sco_flush_sco_data(UNUSED_ATTR uint16_t sco_inx) {}
86 #endif
87 /*******************************************************************************
88  *
89  * Function         btm_sco_init
90  *
91  * Description      This function is called at BTM startup to initialize
92  *
93  * Returns          void
94  *
95  ******************************************************************************/
96 void btm_sco_init(void) {
97 #if (BTM_SCO_HCI_INCLUDED == TRUE)
98   for (int i = 0; i < BTM_MAX_SCO_LINKS; i++)
99     btm_cb.sco_cb.sco_db[i].xmit_data_q = fixed_queue_new(SIZE_MAX);
100 #endif
101   /* Initialize nonzero defaults */
102   btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
103   btm_cb.sco_cb.def_esco_parms = esco_parameters_for_codec(ESCO_CODEC_CVSD);
104   btm_cb.sco_cb.def_esco_parms.max_latency_ms = 12;
105   btm_cb.sco_cb.sco_route = ESCO_DATA_PATH_PCM;
106 }
107 
108 /*******************************************************************************
109  *
110  * Function         btm_esco_conn_rsp
111  *
112  * Description      This function is called upon receipt of an (e)SCO connection
113  *                  request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
114  *                  the request. Parameters used to negotiate eSCO links.
115  *                  If p_parms is NULL, then default values are used.
116  *                  If the link type of the incoming request is SCO, then only
117  *                  the tx_bw, max_latency, content format, and packet_types are
118  *                  valid.  The hci_status parameter should be
119  *                  ([0x0] to accept, [0x0d..0x0f] to reject)
120  *
121  * Returns          void
122  *
123  ******************************************************************************/
124 static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status, BD_ADDR bda,
125                               enh_esco_params_t* p_parms) {
126 #if (BTM_MAX_SCO_LINKS > 0)
127   tSCO_CONN* p_sco = NULL;
128 
129   if (sco_inx < BTM_MAX_SCO_LINKS) p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
130 
131   /* Reject the connect request if refused by caller or wrong state */
132   if (hci_status != HCI_SUCCESS || p_sco == NULL) {
133     if (p_sco) {
134       p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
135                                                           : SCO_ST_UNUSED;
136     }
137     if (!btm_cb.sco_cb.esco_supported) {
138       btsnd_hcic_reject_conn(bda, hci_status);
139     } else {
140       btsnd_hcic_reject_esco_conn(bda, hci_status);
141     }
142   } else {
143     /* Connection is being accepted */
144     p_sco->state = SCO_ST_CONNECTING;
145     enh_esco_params_t* p_setup = &p_sco->esco.setup;
146     /* If parameters not specified use the default */
147     if (p_parms) {
148       *p_setup = *p_parms;
149     } else {
150       /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
151       *p_setup = btm_cb.sco_cb.def_esco_parms;
152     }
153 
154     uint16_t temp_packet_types =
155         (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
156          btm_cb.btm_sco_pkt_types_supported);
157 
158     /* Make sure at least one eSCO packet type is sent, else might confuse peer
159      */
160     /* Taking this out to confirm with BQB tests
161     ** Real application would like to include this though, as many devices
162     ** do not retry with SCO only if an eSCO connection fails.
163     if (!(temp_packet_types & BTM_ESCO_LINK_ONLY_MASK))
164     {
165         temp_packet_types |= BTM_SCO_PKT_TYPES_MASK_EV3;
166     }
167     */
168     /* If SCO request, remove eSCO packet types (conformance) */
169     if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO) {
170       temp_packet_types &= BTM_SCO_LINK_ONLY_MASK;
171       temp_packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
172     } else {
173       /* OR in any exception packet types */
174       temp_packet_types |=
175           ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
176            (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
177     }
178 
179     /* Use Enhanced Synchronous commands if supported */
180     if (controller_get_interface()
181             ->supports_enhanced_setup_synchronous_connection()) {
182       /* Use the saved SCO routing */
183       p_setup->input_data_path = p_setup->output_data_path =
184           btm_cb.sco_cb.sco_route;
185 
186       BTM_TRACE_DEBUG(
187           "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, "
188           "pkt 0x%04x, path %u",
189           __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
190           p_setup->max_latency_ms, p_setup->retransmission_effort,
191           p_setup->packet_types, p_setup->input_data_path);
192 
193       btsnd_hcic_enhanced_accept_synchronous_connection(bda, p_setup);
194 
195     } else {
196       /* Use legacy command if enhanced SCO setup is not supported */
197       uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
198       btsnd_hcic_accept_esco_conn(
199           bda, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
200           p_setup->max_latency_ms, voice_content_format,
201           p_setup->retransmission_effort, p_setup->packet_types);
202     }
203   }
204 #endif
205 }
206 
207 #if (BTM_SCO_HCI_INCLUDED == TRUE)
208 /*******************************************************************************
209  *
210  * Function         btm_sco_check_send_pkts
211  *
212  * Description      This function is called to check if it can send packets
213  *                  to the Host Controller.
214  *
215  * Returns          void
216  *
217  ******************************************************************************/
218 void btm_sco_check_send_pkts(uint16_t sco_inx) {
219   tSCO_CB* p_cb = &btm_cb.sco_cb;
220   tSCO_CONN* p_ccb = &p_cb->sco_db[sco_inx];
221 
222   /* If there is data to send, send it now */
223   BT_HDR* p_buf;
224   while ((p_buf = (BT_HDR*)fixed_queue_try_dequeue(p_ccb->xmit_data_q)) !=
225          NULL) {
226 #if (BTM_SCO_HCI_DEBUG == TRUE)
227     BTM_TRACE_DEBUG("btm: [%d] buf in xmit_data_q",
228                     fixed_queue_length(p_ccb->xmit_data_q) + 1);
229 #endif
230 
231     HCI_SCO_DATA_TO_LOWER(p_buf);
232   }
233 }
234 #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
235 
236 /*******************************************************************************
237  *
238  * Function         btm_route_sco_data
239  *
240  * Description      Route received SCO data.
241  *
242  * Returns          void
243  *
244  ******************************************************************************/
245 void btm_route_sco_data(BT_HDR* p_msg) {
246 #if (BTM_SCO_HCI_INCLUDED == TRUE)
247   uint16_t sco_inx, handle;
248   uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;
249   uint8_t pkt_size = 0;
250   uint8_t pkt_status = 0;
251 
252   /* Extract Packet_Status_Flag and handle */
253   STREAM_TO_UINT16(handle, p);
254   pkt_status = HCID_GET_EVENT(handle);
255   handle = HCID_GET_HANDLE(handle);
256 
257   STREAM_TO_UINT8(pkt_size, p);
258 
259   sco_inx = btm_find_scb_by_handle(handle);
260   if (sco_inx != BTM_MAX_SCO_LINKS) {
261     /* send data callback */
262     if (!btm_cb.sco_cb.p_data_cb)
263       /* if no data callback registered,  just free the buffer  */
264       osi_free(p_msg);
265     else {
266       (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg,
267                                  (tBTM_SCO_DATA_FLAG)pkt_status);
268     }
269   } else /* no mapping handle SCO connection is active, free the buffer */
270   {
271     osi_free(p_msg);
272   }
273 #else
274   osi_free(p_msg);
275 #endif
276 }
277 
278 /*******************************************************************************
279  *
280  * Function         BTM_WriteScoData
281  *
282  * Description      This function write SCO data to a specified instance. The
283  *                  data to be written p_buf needs to carry an offset of
284  *                  HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
285  *                  exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is
286  *                  set to 60 and is configurable. Data longer than the maximum
287  *                  bytes will be truncated.
288  *
289  * Returns          BTM_SUCCESS: data write is successful
290  *                  BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
291  *                  BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO
292  *                                      packet size.
293  *                  BTM_NO_RESOURCES: no resources.
294  *                  BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is
295  *                                    not routed via HCI.
296  *
297  *
298  ******************************************************************************/
299 #if (BTM_SCO_HCI_INCLUDED == TRUE && BTM_MAX_SCO_LINKS > 0)
300 tBTM_STATUS BTM_WriteScoData(uint16_t sco_inx, BT_HDR* p_buf) {
301   tSCO_CONN* p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
302   uint8_t* p;
303   tBTM_STATUS status = BTM_SUCCESS;
304 
305   if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
306       p_ccb->state == SCO_ST_CONNECTED) {
307     /* Ensure we have enough space in the buffer for the SCO and HCI headers */
308     if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE) {
309       BTM_TRACE_ERROR("BTM SCO - cannot send buffer, offset: %d",
310                       p_buf->offset);
311       osi_free(p_buf);
312       status = BTM_ILLEGAL_VALUE;
313     } else /* write HCI header */
314     {
315       /* Step back 3 bytes to add the headers */
316       p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
317       /* Set the pointer to the beginning of the data */
318       p = (uint8_t*)(p_buf + 1) + p_buf->offset;
319       /* add HCI handle */
320       UINT16_TO_STREAM(p, p_ccb->hci_handle);
321       /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
322          and set warning status */
323       if (p_buf->len > BTM_SCO_DATA_SIZE_MAX) {
324         p_buf->len = BTM_SCO_DATA_SIZE_MAX;
325         status = BTM_SCO_BAD_LENGTH;
326       }
327 
328       UINT8_TO_STREAM(p, (uint8_t)p_buf->len);
329       p_buf->len += HCI_SCO_PREAMBLE_SIZE;
330 
331       fixed_queue_enqueue(p_ccb->xmit_data_q, p_buf);
332 
333       btm_sco_check_send_pkts(sco_inx);
334     }
335   } else {
336     osi_free(p_buf);
337 
338     BTM_TRACE_ERROR("%s:invalid sco index: %d at state [%d]", __func__, sco_inx,
339                     btm_cb.sco_cb.sco_db[sco_inx].state);
340     status = BTM_UNKNOWN_ADDR;
341   }
342 
343   return status;
344 }
345 #else
346 tBTM_STATUS BTM_WriteScoData(UNUSED_ATTR uint16_t sco_inx,
347                              UNUSED_ATTR BT_HDR* p_buf) {
348   return (BTM_NO_RESOURCES);
349 }
350 #endif
351 
352 #if (BTM_MAX_SCO_LINKS > 0)
353 /*******************************************************************************
354  *
355  * Function         btm_send_connect_request
356  *
357  * Description      This function is called to respond to SCO connect
358  *                  indications
359  *
360  * Returns          void
361  *
362  ******************************************************************************/
363 static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle,
364                                             enh_esco_params_t* p_setup) {
365   tACL_CONN* p_acl;
366 
367   /* Send connect request depending on version of spec */
368   if (!btm_cb.sco_cb.esco_supported) {
369     btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types));
370   } else {
371     uint16_t temp_packet_types =
372         (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
373          btm_cb.btm_sco_pkt_types_supported);
374 
375     /* OR in any exception packet types */
376     temp_packet_types |=
377         ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
378          (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
379 
380     /* Finally, remove EDR eSCO if the remote device doesn't support it */
381     /* UPF25:  Only SCO was brought up in this case */
382     btm_handle_to_acl_index(acl_handle);
383     uint8_t acl_index = btm_handle_to_acl_index(acl_handle);
384     if (acl_index < MAX_L2CAP_LINKS) {
385       p_acl = &btm_cb.acl_db[acl_index];
386       if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_feature_pages[0])) {
387         BTM_TRACE_WARNING("BTM Remote does not support 2-EDR eSCO");
388         temp_packet_types |=
389             (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5);
390       }
391       if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->peer_lmp_feature_pages[0])) {
392         BTM_TRACE_WARNING("BTM Remote does not support 3-EDR eSCO");
393         temp_packet_types |=
394             (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV5);
395       }
396 
397       /* Check to see if BR/EDR Secure Connections is being used
398       ** If so, we cannot use SCO-only packet types (HFP 1.7)
399       */
400       if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr)) {
401         temp_packet_types &= ~(BTM_SCO_PKT_TYPE_MASK);
402         BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)",
403                         __func__, temp_packet_types);
404 
405         /* Return error if no packet types left */
406         if (temp_packet_types == 0) {
407           BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",
408                           __func__);
409           return (BTM_WRONG_MODE);
410         }
411       } else {
412         BTM_TRACE_DEBUG(
413             "%s: SCO Conn(BR/EDR SC):local or peer does not support BR/EDR SC",
414             __func__);
415       }
416     }
417 
418     /* Save the previous types in case command fails */
419     uint16_t saved_packet_types = p_setup->packet_types;
420     p_setup->packet_types = temp_packet_types;
421 
422     /* Use Enhanced Synchronous commands if supported */
423     if (controller_get_interface()
424             ->supports_enhanced_setup_synchronous_connection()) {
425       /* Use the saved SCO routing */
426       p_setup->input_data_path = p_setup->output_data_path =
427           btm_cb.sco_cb.sco_route;
428 
429       BTM_TRACE_DEBUG(
430           "%s: txbw 0x%x, rxbw 0x%x, "
431           "lat 0x%x, retrans 0x%02x, pkt 0x%04x, path %u",
432           __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
433           p_setup->max_latency_ms, p_setup->retransmission_effort,
434           p_setup->packet_types, p_setup->input_data_path);
435 
436       btsnd_hcic_enhanced_set_up_synchronous_connection(acl_handle, p_setup);
437       p_setup->packet_types = saved_packet_types;
438     } else { /* Use older command */
439       uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
440 
441       BTM_TRACE_API(
442           "%s: txbw 0x%x, rxbw 0x%x, "
443           "lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
444           __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
445           p_setup->max_latency_ms, voice_content_format,
446           p_setup->retransmission_effort, p_setup->packet_types);
447 
448       btsnd_hcic_setup_esco_conn(
449           acl_handle, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
450           p_setup->max_latency_ms, voice_content_format,
451           p_setup->retransmission_effort, p_setup->packet_types);
452     }
453   }
454 
455   return (BTM_CMD_STARTED);
456 }
457 #endif
458 
459 /*******************************************************************************
460  *
461  * Function         btm_set_sco_ind_cback
462  *
463  * Description      This function is called to register for TCS SCO connect
464  *                  indications.
465  *
466  * Returns          void
467  *
468  ******************************************************************************/
469 void btm_set_sco_ind_cback(tBTM_SCO_IND_CBACK* sco_ind_cb) {
470   btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
471 }
472 
473 /*******************************************************************************
474  *
475  * Function         btm_accept_sco_link
476  *
477  * Description      This function is called to respond to TCS SCO connect
478  *                  indications
479  *
480  * Returns          void
481  *
482  ******************************************************************************/
483 void btm_accept_sco_link(uint16_t sco_inx, enh_esco_params_t* p_setup,
484                          tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {
485 #if (BTM_MAX_SCO_LINKS > 0)
486   tSCO_CONN* p_sco;
487 
488   if (sco_inx >= BTM_MAX_SCO_LINKS) {
489     BTM_TRACE_ERROR("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
490     return;
491   }
492 
493   /* Link role is ignored in for this message */
494   p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
495   p_sco->p_conn_cb = p_conn_cb;
496   p_sco->p_disc_cb = p_disc_cb;
497   p_sco->esco.data.link_type =
498       BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
499 
500   BTM_TRACE_DEBUG("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
501 
502   btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
503 #else
504   btm_reject_sco_link(sco_inx);
505 #endif
506 }
507 
508 /*******************************************************************************
509  *
510  * Function         btm_reject_sco_link
511  *
512  * Description      This function is called to respond to SCO connect
513  *                  indications
514  *
515  * Returns          void
516  *
517  ******************************************************************************/
518 void btm_reject_sco_link(uint16_t sco_inx) {
519   btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
520                     btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
521 }
522 
523 /*******************************************************************************
524  *
525  * Function         BTM_CreateSco
526  *
527  * Description      This function is called to create an SCO connection. If the
528  *                  "is_orig" flag is true, the connection will be originated,
529  *                  otherwise BTM will wait for the other side to connect.
530  *
531  *                  NOTE:  If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
532  *                      parameter the default packet types is used.
533  *
534  * Returns          BTM_UNKNOWN_ADDR if the ACL connection is not up
535  *                  BTM_BUSY         if another SCO being set up to
536  *                                   the same BD address
537  *                  BTM_NO_RESOURCES if the max SCO limit has been reached
538  *                  BTM_CMD_STARTED  if the connection establishment is started.
539  *                                   In this case, "*p_sco_inx" is filled in
540  *                                   with the sco index used for the connection.
541  *
542  ******************************************************************************/
543 tBTM_STATUS BTM_CreateSco(BD_ADDR remote_bda, bool is_orig, uint16_t pkt_types,
544                           uint16_t* p_sco_inx, tBTM_SCO_CB* p_conn_cb,
545                           tBTM_SCO_CB* p_disc_cb) {
546 #if (BTM_MAX_SCO_LINKS > 0)
547   enh_esco_params_t* p_setup;
548   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
549   uint16_t xx;
550   uint16_t acl_handle = 0;
551   tACL_CONN* p_acl;
552 
553 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
554   tBTM_PM_PWR_MD pm;
555   tBTM_PM_STATE state;
556 #else
557   uint8_t mode;
558 #endif  // BTM_SCO_WAKE_PARKED_LINK
559 
560   *p_sco_inx = BTM_INVALID_SCO_INDEX;
561 
562   /* If originating, ensure that there is an ACL connection to the BD Address */
563 
564   if (is_orig) {
565     if (!remote_bda) {
566       BTM_TRACE_ERROR("%s: remote_bda is null", __func__);
567       return BTM_ILLEGAL_VALUE;
568     }
569     acl_handle = BTM_GetHCIConnHandle(remote_bda, BT_TRANSPORT_BR_EDR);
570     if (acl_handle == 0xFFFF) {
571       BTM_TRACE_ERROR(
572           "%s: cannot find ACL handle for remote device "
573           "%02x:%02x:%02x:%02x:%02x:%02x",
574           __func__, remote_bda[0], remote_bda[1], remote_bda[2], remote_bda[3],
575           remote_bda[4], remote_bda[5]);
576       return BTM_UNKNOWN_ADDR;
577     }
578   }
579 
580   if (remote_bda) {
581     /* If any SCO is being established to the remote BD address, refuse this */
582     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
583       if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
584            (p->state == SCO_ST_PEND_UNPARK)) &&
585           (!memcmp(p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN))) {
586         return BTM_BUSY;
587       }
588     }
589   } else {
590     /* Support only 1 wildcard BD address at a time */
591     for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
592       if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) return BTM_BUSY;
593     }
594   }
595 
596   /* Try to find an unused control block, and kick off the SCO establishment */
597   for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS;
598        xx++, p++) {
599     if (p->state == SCO_ST_UNUSED) {
600       if (remote_bda) {
601         if (is_orig) {
602 /* can not create SCO link if in park mode */
603 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
604           if ((btm_read_power_mode_state(p->esco.data.bd_addr, &state) ==
605                BTM_SUCCESS)) {
606             if (state == BTM_PM_ST_SNIFF || state == BTM_PM_ST_PARK ||
607                 state == BTM_PM_ST_PENDING) {
608               BTM_TRACE_DEBUG("%s In sniff, park or pend mode: %d", __func__,
609                               state);
610               memset((void*)&pm, 0, sizeof(pm));
611               pm.mode = BTM_PM_MD_ACTIVE;
612               BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
613               p->state = SCO_ST_PEND_UNPARK;
614             }
615           }
616 #else   // BTM_SCO_WAKE_PARKED_LINK
617           if ((BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) &&
618               (mode == BTM_PM_MD_PARK))
619             return (BTM_WRONG_MODE);
620 #endif  // BTM_SCO_WAKE_PARKED_LINK
621         }
622         memcpy(p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
623         p->rem_bd_known = true;
624       } else
625         p->rem_bd_known = false;
626 
627       p_setup = &p->esco.setup;
628       *p_setup = btm_cb.sco_cb.def_esco_parms;
629 
630       /* Determine the packet types */
631       p_setup->packet_types = pkt_types & BTM_SCO_SUPPORTED_PKTS_MASK &
632                               btm_cb.btm_sco_pkt_types_supported;
633       /* OR in any exception packet types */
634       if (controller_get_interface()->get_bt_version()->hci_version >=
635           HCI_PROTO_VERSION_2_0) {
636         p_setup->packet_types |=
637             (pkt_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
638             (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK);
639       }
640 
641       p->p_conn_cb = p_conn_cb;
642       p->p_disc_cb = p_disc_cb;
643       p->hci_handle = BTM_INVALID_HCI_HANDLE;
644       p->is_orig = is_orig;
645 
646       if (p->state != SCO_ST_PEND_UNPARK) {
647         if (is_orig) {
648           /* If role change is in progress, do not proceed with SCO setup
649            * Wait till role change is complete */
650           p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
651           if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE) {
652             BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x",
653                           acl_handle);
654             p->state = SCO_ST_PEND_ROLECHANGE;
655           }
656         }
657       }
658 
659       if (p->state != SCO_ST_PEND_UNPARK &&
660           p->state != SCO_ST_PEND_ROLECHANGE) {
661         if (is_orig) {
662           BTM_TRACE_API("%s:(e)SCO Link for ACL handle 0x%04x", __func__,
663                         acl_handle);
664 
665           if ((btm_send_connect_request(acl_handle, p_setup)) !=
666               BTM_CMD_STARTED)
667             return (BTM_NO_RESOURCES);
668 
669           p->state = SCO_ST_CONNECTING;
670         } else
671           p->state = SCO_ST_LISTENING;
672       }
673 
674       *p_sco_inx = xx;
675 
676       return BTM_CMD_STARTED;
677     }
678   }
679 
680 #endif
681   /* If here, all SCO blocks in use */
682   return BTM_NO_RESOURCES;
683 }
684 
685 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
686 /*******************************************************************************
687  *
688  * Function         btm_sco_chk_pend_unpark
689  *
690  * Description      This function is called by BTIF when there is a mode change
691  *                  event to see if there are SCO commands waiting for the
692  *                  unpark.
693  *
694  * Returns          void
695  *
696  ******************************************************************************/
697 void btm_sco_chk_pend_unpark(uint8_t hci_status, uint16_t hci_handle) {
698 #if (BTM_MAX_SCO_LINKS > 0)
699   uint16_t xx;
700   uint16_t acl_handle;
701   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
702 
703   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
704     if ((p->state == SCO_ST_PEND_UNPARK) &&
705         ((acl_handle = BTM_GetHCIConnHandle(
706               p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
707 
708     {
709       BTM_TRACE_API(
710           "%s:(e)SCO Link for ACL "
711           "handle 0x%04x, hci_status 0x%02x",
712           __func__, acl_handle, hci_status);
713 
714       if ((btm_send_connect_request(acl_handle, &p->esco.setup)) ==
715           BTM_CMD_STARTED)
716         p->state = SCO_ST_CONNECTING;
717     }
718   }
719 #endif  // BTM_MAX_SCO_LINKS
720 }
721 #endif  // BTM_SCO_WAKE_PARKED_LINK
722 
723 /*******************************************************************************
724  *
725  * Function         btm_sco_chk_pend_rolechange
726  *
727  * Description      This function is called by BTIF when there is a role change
728  *                  event to see if there are SCO commands waiting for the role
729  *                  change.
730  *
731  * Returns          void
732  *
733  ******************************************************************************/
734 void btm_sco_chk_pend_rolechange(uint16_t hci_handle) {
735 #if (BTM_MAX_SCO_LINKS > 0)
736   uint16_t xx;
737   uint16_t acl_handle;
738   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
739 
740   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
741     if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
742         ((acl_handle = BTM_GetHCIConnHandle(
743               p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
744 
745     {
746       BTM_TRACE_API(
747           "btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x",
748           acl_handle);
749 
750       if ((btm_send_connect_request(acl_handle, &p->esco.setup)) ==
751           BTM_CMD_STARTED)
752         p->state = SCO_ST_CONNECTING;
753     }
754   }
755 #endif
756 }
757 
758 /*******************************************************************************
759  *
760  * Function        btm_sco_disc_chk_pend_for_modechange
761  *
762  * Description     This function is called by btm when there is a mode change
763  *                 event to see if there are SCO  disconnect commands waiting
764  *                 for the mode change.
765  *
766  * Returns         void
767  *
768  ******************************************************************************/
769 void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle) {
770 #if (BTM_MAX_SCO_LINKS > 0)
771   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
772 
773   BTM_TRACE_DEBUG("%s: hci_handle 0x%04x, p->state 0x%02x", __func__,
774                   hci_handle, p->state);
775 
776   for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
777     if ((p->state == SCO_ST_PEND_MODECHANGE) &&
778         (BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) ==
779             hci_handle)
780 
781     {
782       BTM_TRACE_DEBUG("%s: SCO Link handle 0x%04x", __func__, p->hci_handle);
783       BTM_RemoveSco(xx);
784     }
785   }
786 #endif
787 }
788 
789 /*******************************************************************************
790  *
791  * Function         btm_sco_conn_req
792  *
793  * Description      This function is called by BTIF when an SCO connection
794  *                  request is received from a remote.
795  *
796  * Returns          void
797  *
798  ******************************************************************************/
799 void btm_sco_conn_req(BD_ADDR bda, DEV_CLASS dev_class, uint8_t link_type) {
800 #if (BTM_MAX_SCO_LINKS > 0)
801   tSCO_CB* p_sco = &btm_cb.sco_cb;
802   tSCO_CONN* p = &p_sco->sco_db[0];
803   uint16_t xx;
804   tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
805 
806   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
807     /*
808      * If the sco state is in the SCO_ST_CONNECTING state, we still need
809      * to return accept sco to avoid race conditon for sco creation
810      */
811     int rem_bd_matches =
812         p->rem_bd_known && !memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN);
813     if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
814         ((p->state == SCO_ST_LISTENING) &&
815          (rem_bd_matches || !p->rem_bd_known))) {
816       /* If this guy was a wildcard, he is not one any more */
817       p->rem_bd_known = true;
818       p->esco.data.link_type = link_type;
819       p->state = SCO_ST_W4_CONN_RSP;
820       memcpy(p->esco.data.bd_addr, bda, BD_ADDR_LEN);
821 
822       /* If no callback, auto-accept the connection if packet types match */
823       if (!p->esco.p_esco_cback) {
824         /* If requesting eSCO reject if default parameters are SCO only */
825         if ((link_type == BTM_LINK_TYPE_ESCO &&
826              !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK) &&
827              ((p_sco->def_esco_parms.packet_types &
828                BTM_SCO_EXCEPTION_PKTS_MASK) == BTM_SCO_EXCEPTION_PKTS_MASK))
829 
830             /* Reject request if SCO is desired but no SCO packets delected */
831             ||
832             (link_type == BTM_LINK_TYPE_SCO &&
833              !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) {
834           btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
835         } else /* Accept the request */
836         {
837           btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
838         }
839       } else /* Notify upper layer of connect indication */
840       {
841         memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
842         memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
843         evt_data.link_type = link_type;
844         evt_data.sco_inx = xx;
845         p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT,
846                              (tBTM_ESCO_EVT_DATA*)&evt_data);
847       }
848 
849       return;
850     }
851   }
852 
853   /* TCS usage */
854   if (btm_cb.sco_cb.app_sco_ind_cb) {
855     /* Now, try to find an unused control block */
856     for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS;
857          xx++, p++) {
858       if (p->state == SCO_ST_UNUSED) {
859         p->is_orig = false;
860         p->state = SCO_ST_LISTENING;
861 
862         p->esco.data.link_type = link_type;
863         memcpy(p->esco.data.bd_addr, bda, BD_ADDR_LEN);
864         p->rem_bd_known = true;
865         break;
866       }
867     }
868     if (xx < BTM_MAX_SCO_LINKS) {
869       btm_cb.sco_cb.app_sco_ind_cb(xx);
870       return;
871     }
872   }
873 
874 #endif
875   /* If here, no one wants the SCO connection. Reject it */
876   BTM_TRACE_WARNING(
877       "btm_sco_conn_req: No one wants this SCO connection; rejecting it");
878   btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda,
879                     NULL);
880 }
881 
882 /*******************************************************************************
883  *
884  * Function         btm_sco_connected
885  *
886  * Description      This function is called by BTIF when an (e)SCO connection
887  *                  is connected.
888  *
889  * Returns          void
890  *
891  ******************************************************************************/
892 void btm_sco_connected(uint8_t hci_status, BD_ADDR bda, uint16_t hci_handle,
893                        tBTM_ESCO_DATA* p_esco_data) {
894 #if (BTM_MAX_SCO_LINKS > 0)
895   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
896   uint16_t xx;
897   bool spt = false;
898   tBTM_CHG_ESCO_PARAMS parms;
899 #endif
900 
901   btm_cb.sco_cb.sco_disc_reason = hci_status;
902 
903 #if (BTM_MAX_SCO_LINKS > 0)
904   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
905     if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
906          (p->state == SCO_ST_W4_CONN_RSP)) &&
907         (p->rem_bd_known) &&
908         (!bda || !memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
909       if (hci_status != HCI_SUCCESS) {
910         /* Report the error if originator, otherwise remain in Listen mode */
911         if (p->is_orig) {
912           /* If role switch is pending, we need try again after role switch is
913            * complete */
914           if (hci_status == HCI_ERR_ROLE_SWITCH_PENDING) {
915             BTM_TRACE_API("Role Change pending for HCI handle 0x%04x",
916                           hci_handle);
917             p->state = SCO_ST_PEND_ROLECHANGE;
918           }
919           /* avoid calling disconnect callback because of sco creation race */
920           else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION) {
921             p->state = SCO_ST_UNUSED;
922             (*p->p_disc_cb)(xx);
923           }
924         } else {
925           /* Notify the upper layer that incoming sco connection has failed. */
926           if (p->state == SCO_ST_CONNECTING) {
927             p->state = SCO_ST_UNUSED;
928             (*p->p_disc_cb)(xx);
929           } else
930             p->state = SCO_ST_LISTENING;
931         }
932 
933         return;
934       }
935 
936       if (p->state == SCO_ST_LISTENING) spt = true;
937 
938       p->state = SCO_ST_CONNECTED;
939       p->hci_handle = hci_handle;
940 
941       if (!btm_cb.sco_cb.esco_supported) {
942         p->esco.data.link_type = BTM_LINK_TYPE_SCO;
943         if (spt) {
944           parms.packet_types = p->esco.setup.packet_types;
945           /* Keep the other parameters the same for SCO */
946           parms.max_latency_ms = p->esco.setup.max_latency_ms;
947           parms.retransmission_effort = p->esco.setup.retransmission_effort;
948 
949           BTM_ChangeEScoLinkParms(xx, &parms);
950         }
951       } else {
952         if (p_esco_data) p->esco.data = *p_esco_data;
953       }
954 
955       (*p->p_conn_cb)(xx);
956 
957       return;
958     }
959   }
960 #endif
961 }
962 
963 /*******************************************************************************
964  *
965  * Function         btm_find_scb_by_handle
966  *
967  * Description      Look through all active SCO connection for a match based on
968  *                  the HCI handle.
969  *
970  * Returns          index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
971  *                  no match.
972  *
973  ******************************************************************************/
974 uint16_t btm_find_scb_by_handle(uint16_t handle) {
975   int xx;
976   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
977 
978   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
979     if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle)) {
980       return (xx);
981     }
982   }
983 
984   /* If here, no match found */
985   return (xx);
986 }
987 
988 /*******************************************************************************
989  *
990  * Function         BTM_RemoveSco
991  *
992  * Description      This function is called to remove a specific SCO connection.
993  *
994  * Returns          status of the operation
995  *
996  ******************************************************************************/
997 tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) {
998 #if (BTM_MAX_SCO_LINKS > 0)
999   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1000   uint16_t tempstate;
1001   tBTM_PM_STATE state = BTM_PM_ST_INVALID;
1002 
1003   BTM_TRACE_DEBUG("%s", __func__);
1004 
1005   /* Validity check */
1006   if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
1007     return (BTM_UNKNOWN_ADDR);
1008 
1009   /* If no HCI handle, simply drop the connection and return */
1010   if (p->hci_handle == BTM_INVALID_HCI_HANDLE ||
1011       p->state == SCO_ST_PEND_UNPARK) {
1012     p->hci_handle = BTM_INVALID_HCI_HANDLE;
1013     p->state = SCO_ST_UNUSED;
1014     p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
1015     return (BTM_SUCCESS);
1016   }
1017 
1018   if ((btm_read_power_mode_state(p->esco.data.bd_addr, &state) ==
1019        BTM_SUCCESS) &&
1020       state == BTM_PM_ST_PENDING) {
1021     BTM_TRACE_DEBUG("%s: BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x%04x",
1022                     __func__, p->hci_handle);
1023     p->state = SCO_ST_PEND_MODECHANGE;
1024     return (BTM_CMD_STARTED);
1025   }
1026 
1027   tempstate = p->state;
1028   p->state = SCO_ST_DISCONNECTING;
1029 
1030   btsnd_hcic_disconnect(p->hci_handle, HCI_ERR_PEER_USER);
1031 
1032   return (BTM_CMD_STARTED);
1033 #else
1034   return (BTM_NO_RESOURCES);
1035 #endif
1036 }
1037 
1038 /*******************************************************************************
1039  *
1040  * Function         btm_remove_sco_links
1041  *
1042  * Description      This function is called to remove all sco links for an ACL
1043  *                  link.
1044  *
1045  * Returns          void
1046  *
1047  ******************************************************************************/
1048 void btm_remove_sco_links(BD_ADDR bda) {
1049 #if (BTM_MAX_SCO_LINKS > 0)
1050   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1051   uint16_t xx;
1052 
1053   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1054     if (p->rem_bd_known && (!memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN))) {
1055       BTM_RemoveSco(xx);
1056     }
1057   }
1058 #endif
1059 }
1060 
1061 /*******************************************************************************
1062  *
1063  * Function         btm_sco_removed
1064  *
1065  * Description      This function is called by BTIF when an SCO connection
1066  *                  is removed.
1067  *
1068  * Returns          void
1069  *
1070  ******************************************************************************/
1071 void btm_sco_removed(uint16_t hci_handle, uint8_t reason) {
1072 #if (BTM_MAX_SCO_LINKS > 0)
1073   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1074   uint16_t xx;
1075 #endif
1076 
1077   btm_cb.sco_cb.sco_disc_reason = reason;
1078 
1079 #if (BTM_MAX_SCO_LINKS > 0)
1080   p = &btm_cb.sco_cb.sco_db[0];
1081   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1082     if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) &&
1083         (p->hci_handle == hci_handle)) {
1084       btm_sco_flush_sco_data(xx);
1085 
1086       p->state = SCO_ST_UNUSED;
1087       p->hci_handle = BTM_INVALID_HCI_HANDLE;
1088       p->rem_bd_known = false;
1089       p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1090       (*p->p_disc_cb)(xx);
1091 
1092       return;
1093     }
1094   }
1095 #endif
1096 }
1097 
1098 /*******************************************************************************
1099  *
1100  * Function         btm_sco_acl_removed
1101  *
1102  * Description      This function is called when an ACL connection is
1103  *                  removed. If the BD address is NULL, it is assumed that
1104  *                  the local device is down, and all SCO links are removed.
1105  *                  If a specific BD address is passed, only SCO connections
1106  *                  to that BD address are removed.
1107  *
1108  * Returns          void
1109  *
1110  ******************************************************************************/
1111 void btm_sco_acl_removed(BD_ADDR bda) {
1112 #if (BTM_MAX_SCO_LINKS > 0)
1113   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1114   uint16_t xx;
1115 
1116   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1117     if (p->state != SCO_ST_UNUSED) {
1118       if ((!bda) || (!memcmp(p->esco.data.bd_addr, bda, BD_ADDR_LEN) &&
1119                      p->rem_bd_known)) {
1120         btm_sco_flush_sco_data(xx);
1121 
1122         p->state = SCO_ST_UNUSED;
1123         p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1124         (*p->p_disc_cb)(xx);
1125       }
1126     }
1127   }
1128 #endif
1129 }
1130 
1131 /*******************************************************************************
1132  *
1133  * Function         BTM_SetScoPacketTypes
1134  *
1135  * Description      This function is called to set the packet types used for
1136  *                  a specific SCO connection,
1137  *
1138  * Parameters       pkt_types - One or more of the following
1139  *                  BTM_SCO_PKT_TYPES_MASK_HV1
1140  *                  BTM_SCO_PKT_TYPES_MASK_HV2
1141  *                  BTM_SCO_PKT_TYPES_MASK_HV3
1142  *                  BTM_SCO_PKT_TYPES_MASK_EV3
1143  *                  BTM_SCO_PKT_TYPES_MASK_EV4
1144  *                  BTM_SCO_PKT_TYPES_MASK_EV5
1145  *                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1146  *                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1147  *                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1148  *                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1149  *
1150  *                  BTM_SCO_LINK_ALL_MASK   - enables all supported types
1151  *
1152  * Returns          status of the operation
1153  *
1154  ******************************************************************************/
1155 tBTM_STATUS BTM_SetScoPacketTypes(uint16_t sco_inx, uint16_t pkt_types) {
1156 #if (BTM_MAX_SCO_LINKS > 0)
1157   tBTM_CHG_ESCO_PARAMS parms;
1158   tSCO_CONN* p;
1159 
1160   /* Validity check */
1161   if (sco_inx >= BTM_MAX_SCO_LINKS) return (BTM_UNKNOWN_ADDR);
1162 
1163   p = &btm_cb.sco_cb.sco_db[sco_inx];
1164   parms.packet_types = pkt_types;
1165 
1166   /* Keep the other parameters the same for SCO */
1167   parms.max_latency_ms = p->esco.setup.max_latency_ms;
1168   parms.retransmission_effort = p->esco.setup.retransmission_effort;
1169 
1170   return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
1171 #else
1172   return (BTM_UNKNOWN_ADDR);
1173 #endif
1174 }
1175 
1176 /*******************************************************************************
1177  *
1178  * Function         BTM_ReadScoPacketTypes
1179  *
1180  * Description      This function is read the packet types used for a specific
1181  *                  SCO connection.
1182  *
1183  * Returns          Packet types supported for the connection
1184  *                  One or more of the following (bitmask):
1185  *                  BTM_SCO_PKT_TYPES_MASK_HV1
1186  *                  BTM_SCO_PKT_TYPES_MASK_HV2
1187  *                  BTM_SCO_PKT_TYPES_MASK_HV3
1188  *                  BTM_SCO_PKT_TYPES_MASK_EV3
1189  *                  BTM_SCO_PKT_TYPES_MASK_EV4
1190  *                  BTM_SCO_PKT_TYPES_MASK_EV5
1191  *                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1192  *                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1193  *                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1194  *                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1195  *
1196  ******************************************************************************/
1197 uint16_t BTM_ReadScoPacketTypes(uint16_t sco_inx) {
1198 #if (BTM_MAX_SCO_LINKS > 0)
1199   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1200 
1201   /* Validity check */
1202   if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1203     return (p->esco.setup.packet_types);
1204   else
1205     return (0);
1206 #else
1207   return (0);
1208 #endif
1209 }
1210 
1211 /*******************************************************************************
1212  *
1213  * Function         BTM_ReadScoDiscReason
1214  *
1215  * Description      This function is returns the reason why an (e)SCO connection
1216  *                  has been removed. It contains the value until read, or until
1217  *                  another (e)SCO connection has disconnected.
1218  *
1219  * Returns          HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
1220  *
1221  ******************************************************************************/
1222 uint16_t BTM_ReadScoDiscReason(void) {
1223   uint16_t res = btm_cb.sco_cb.sco_disc_reason;
1224   btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
1225   return (res);
1226 }
1227 
1228 /*******************************************************************************
1229  *
1230  * Function         BTM_ReadDeviceScoPacketTypes
1231  *
1232  * Description      This function is read the SCO packet types that
1233  *                  the device supports.
1234  *
1235  * Returns          Packet types supported by the device.
1236  *                  One or more of the following (bitmask):
1237  *                  BTM_SCO_PKT_TYPES_MASK_HV1
1238  *                  BTM_SCO_PKT_TYPES_MASK_HV2
1239  *                  BTM_SCO_PKT_TYPES_MASK_HV3
1240  *                  BTM_SCO_PKT_TYPES_MASK_EV3
1241  *                  BTM_SCO_PKT_TYPES_MASK_EV4
1242  *                  BTM_SCO_PKT_TYPES_MASK_EV5
1243  *                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1244  *                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1245  *                  BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1246  *                  BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1247  *
1248  ******************************************************************************/
1249 uint16_t BTM_ReadDeviceScoPacketTypes(void) {
1250   return (btm_cb.btm_sco_pkt_types_supported);
1251 }
1252 
1253 /*******************************************************************************
1254  *
1255  * Function         BTM_ReadScoHandle
1256  *
1257  * Description      This function is used to read the HCI handle used for a
1258  *                  specific SCO connection,
1259  *
1260  * Returns          handle for the connection, or 0xFFFF if invalid SCO index.
1261  *
1262  ******************************************************************************/
1263 uint16_t BTM_ReadScoHandle(uint16_t sco_inx) {
1264 #if (BTM_MAX_SCO_LINKS > 0)
1265   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1266 
1267   /* Validity check */
1268   if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1269     return (p->hci_handle);
1270   else
1271     return (BTM_INVALID_HCI_HANDLE);
1272 #else
1273   return (BTM_INVALID_HCI_HANDLE);
1274 #endif
1275 }
1276 
1277 /*******************************************************************************
1278  *
1279  * Function         BTM_ReadScoBdAddr
1280  *
1281  * Description      This function is read the remote BD Address for a specific
1282  *                  SCO connection,
1283  *
1284  * Returns          pointer to BD address or NULL if not known
1285  *
1286  ******************************************************************************/
1287 uint8_t* BTM_ReadScoBdAddr(uint16_t sco_inx) {
1288 #if (BTM_MAX_SCO_LINKS > 0)
1289   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1290 
1291   /* Validity check */
1292   if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1293     return (p->esco.data.bd_addr);
1294   else
1295     return (NULL);
1296 #else
1297   return (NULL);
1298 #endif
1299 }
1300 
1301 /*******************************************************************************
1302  *
1303  * Function         BTM_SetEScoMode
1304  *
1305  * Description      This function sets up the negotiated parameters for SCO or
1306  *                  eSCO, and sets as the default mode used for outgoing calls
1307  *                  to BTM_CreateSco.  It does not change any currently active
1308  *                  (e)SCO links.
1309  *                  Note:  Incoming (e)SCO connections will always use packet
1310  *                      types supported by the controller.  If eSCO is not
1311  *                      desired the feature should be disabled in the
1312  *                      controller's feature mask.
1313  *
1314  * Returns          BTM_SUCCESS if the successful.
1315  *                  BTM_BUSY if there are one or more active (e)SCO links.
1316  *
1317  ******************************************************************************/
1318 tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) {
1319   enh_esco_params_t* p_def = &btm_cb.sco_cb.def_esco_parms;
1320 
1321   if (btm_cb.sco_cb.esco_supported) {
1322     *p_def = *p_parms;
1323   } else {
1324     /* Load defaults for SCO only */
1325     *p_def = esco_parameters_for_codec(ESCO_CODEC_CVSD);
1326     p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
1327     p_def->retransmission_effort = ESCO_RETRANSMISSION_OFF;
1328     p_def->max_latency_ms = 12;
1329     BTM_TRACE_WARNING("%s: eSCO not supported", __func__);
1330   }
1331 
1332   BTM_TRACE_API(
1333       "%s: txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, "
1334       "pkt 0x%04x, rtx effort 0x%02x",
1335       __func__, p_def->transmit_bandwidth, p_def->receive_bandwidth,
1336       p_def->max_latency_ms, p_def->packet_types, p_def->retransmission_effort);
1337 
1338   return BTM_SUCCESS;
1339 }
1340 
1341 /*******************************************************************************
1342  *
1343  * Function         BTM_RegForEScoEvts
1344  *
1345  * Description      This function registers a SCO event callback with the
1346  *                  specified instance.  It should be used to received
1347  *                  connection indication events and change of link parameter
1348  *                  events.
1349  *
1350  * Returns          BTM_SUCCESS if the successful.
1351  *                  BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1352  *                  BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1353  *                          later or does not support eSCO.
1354  *
1355  ******************************************************************************/
1356 tBTM_STATUS BTM_RegForEScoEvts(uint16_t sco_inx,
1357                                tBTM_ESCO_CBACK* p_esco_cback) {
1358 #if (BTM_MAX_SCO_LINKS > 0)
1359   if (!btm_cb.sco_cb.esco_supported) {
1360     btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1361     return (BTM_MODE_UNSUPPORTED);
1362   }
1363 
1364   if (sco_inx < BTM_MAX_SCO_LINKS &&
1365       btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) {
1366     btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1367     return (BTM_SUCCESS);
1368   }
1369   return (BTM_ILLEGAL_VALUE);
1370 #else
1371   return (BTM_MODE_UNSUPPORTED);
1372 #endif
1373 }
1374 
1375 /*******************************************************************************
1376  *
1377  * Function         BTM_ReadEScoLinkParms
1378  *
1379  * Description      This function returns the current eSCO link parameters for
1380  *                  the specified handle.  This can be called anytime a
1381  *                  connection is active, but is typically called after
1382  *                  receiving the SCO opened callback.
1383  *
1384  *                  Note: If called over a 1.1 controller, only the packet types
1385  *                        field has meaning.
1386  *
1387  * Returns          BTM_SUCCESS if returned data is valid connection.
1388  *                  BTM_WRONG_MODE if no connection with a peer device or bad
1389  *                                 sco_inx.
1390  *
1391  ******************************************************************************/
1392 tBTM_STATUS BTM_ReadEScoLinkParms(uint16_t sco_inx, tBTM_ESCO_DATA* p_parms) {
1393 #if (BTM_MAX_SCO_LINKS > 0)
1394   uint8_t index;
1395 
1396   BTM_TRACE_API("%s: -> sco_inx 0x%04x", __func__, sco_inx);
1397 
1398   if (sco_inx < BTM_MAX_SCO_LINKS &&
1399       btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED) {
1400     *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
1401     return (BTM_SUCCESS);
1402   }
1403 
1404   if (sco_inx == BTM_FIRST_ACTIVE_SCO_INDEX) {
1405     for (index = 0; index < BTM_MAX_SCO_LINKS; index++) {
1406       if (btm_cb.sco_cb.sco_db[index].state >= SCO_ST_CONNECTED) {
1407         BTM_TRACE_API("%s: the first active SCO index is %d", __func__, index);
1408         *p_parms = btm_cb.sco_cb.sco_db[index].esco.data;
1409         return (BTM_SUCCESS);
1410       }
1411     }
1412   }
1413 
1414 #endif
1415 
1416   BTM_TRACE_API("BTM_ReadEScoLinkParms cannot find the SCO index!");
1417   memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
1418   return (BTM_WRONG_MODE);
1419 }
1420 
1421 /*******************************************************************************
1422  *
1423  * Function         BTM_ChangeEScoLinkParms
1424  *
1425  * Description      This function requests renegotiation of the parameters on
1426  *                  the current eSCO Link.  If any of the changes are accepted
1427  *                  by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1428  *                  the tBTM_ESCO_CBACK function with the current settings of
1429  *                  the link. The callback is registered through the call to
1430  *                  BTM_SetEScoMode.
1431  *
1432  *                  Note: If called over a SCO link (including 1.1 controller),
1433  *                        a change packet type request is sent out instead.
1434  *
1435  * Returns          BTM_CMD_STARTED if command is successfully initiated.
1436  *                  BTM_NO_RESOURCES - not enough resources to initiate command.
1437  *                  BTM_WRONG_MODE if no connection with a peer device or bad
1438  *                                 sco_inx.
1439  *
1440  ******************************************************************************/
1441 tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
1442                                     tBTM_CHG_ESCO_PARAMS* p_parms) {
1443 #if (BTM_MAX_SCO_LINKS > 0)
1444 
1445   /* Make sure sco handle is valid and on an active link */
1446   if (sco_inx >= BTM_MAX_SCO_LINKS ||
1447       btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1448     return (BTM_WRONG_MODE);
1449 
1450   tSCO_CONN* p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1451   enh_esco_params_t* p_setup = &p_sco->esco.setup;
1452 
1453   /* Save the previous types in case command fails */
1454   uint16_t saved_packet_types = p_setup->packet_types;
1455 
1456   /* If SCO connection OR eSCO not supported just send change packet types */
1457   if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1458       !btm_cb.sco_cb.esco_supported) {
1459     p_setup->packet_types =
1460         p_parms->packet_types &
1461         (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1462 
1463     BTM_TRACE_API("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__,
1464                   p_sco->hci_handle, p_setup->packet_types);
1465 
1466     BTM_TRACE_API("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__,
1467                   p_sco->hci_handle, p_setup->packet_types);
1468 
1469     btsnd_hcic_change_conn_type(p_sco->hci_handle,
1470                                 BTM_ESCO_2_SCO(p_setup->packet_types));
1471   } else /* eSCO is supported and the link type is eSCO */
1472   {
1473     uint16_t temp_packet_types =
1474         (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1475          btm_cb.btm_sco_pkt_types_supported);
1476 
1477     /* OR in any exception packet types */
1478     temp_packet_types |=
1479         ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
1480          (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
1481     p_setup->packet_types = temp_packet_types;
1482 
1483     BTM_TRACE_API("%s -> eSCO Link for handle 0x%04x", __func__,
1484                   p_sco->hci_handle);
1485     BTM_TRACE_API(
1486         "   txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x",
1487         p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1488         p_parms->max_latency_ms, p_parms->retransmission_effort,
1489         temp_packet_types);
1490 
1491     /* Use Enhanced Synchronous commands if supported */
1492     if (controller_get_interface()
1493             ->supports_enhanced_setup_synchronous_connection()) {
1494       /* Use the saved SCO routing */
1495       p_setup->input_data_path = p_setup->output_data_path =
1496           btm_cb.sco_cb.sco_route;
1497 
1498       btsnd_hcic_enhanced_set_up_synchronous_connection(p_sco->hci_handle,
1499                                                         p_setup);
1500       p_setup->packet_types = saved_packet_types;
1501     } else { /* Use older command */
1502       uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
1503       /* When changing an existing link, only change latency, retrans, and
1504        * pkts */
1505       btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->transmit_bandwidth,
1506                                  p_setup->receive_bandwidth,
1507                                  p_parms->max_latency_ms, voice_content_format,
1508                                  p_parms->retransmission_effort,
1509                                  p_setup->packet_types);
1510     }
1511 
1512     BTM_TRACE_API(
1513         "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x",
1514         __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1515         p_parms->max_latency_ms, p_parms->retransmission_effort,
1516         temp_packet_types);
1517   }
1518 
1519   return (BTM_CMD_STARTED);
1520 #else
1521   return (BTM_WRONG_MODE);
1522 #endif
1523 }
1524 
1525 /*******************************************************************************
1526  *
1527  * Function         BTM_EScoConnRsp
1528  *
1529  * Description      This function is called upon receipt of an (e)SCO connection
1530  *                  request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1531  *                  the request. Parameters used to negotiate eSCO links.
1532  *                  If p_parms is NULL, then values set through BTM_SetEScoMode
1533  *                  are used.
1534  *                  If the link type of the incoming request is SCO, then only
1535  *                  the tx_bw, max_latency, content format, and packet_types are
1536  *                  valid.  The hci_status parameter should be
1537  *                  ([0x0] to accept, [0x0d..0x0f] to reject)
1538  *
1539  *
1540  * Returns          void
1541  *
1542  ******************************************************************************/
1543 void BTM_EScoConnRsp(uint16_t sco_inx, uint8_t hci_status,
1544                      enh_esco_params_t* p_parms) {
1545 #if (BTM_MAX_SCO_LINKS > 0)
1546   if (sco_inx < BTM_MAX_SCO_LINKS &&
1547       btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) {
1548     btm_esco_conn_rsp(sco_inx, hci_status,
1549                       btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, p_parms);
1550   }
1551 #endif
1552 }
1553 
1554 /*******************************************************************************
1555  *
1556  * Function         btm_read_def_esco_mode
1557  *
1558  * Description      This function copies the current default esco settings into
1559  *                  the return buffer.
1560  *
1561  * Returns          tBTM_SCO_TYPE
1562  *
1563  ******************************************************************************/
1564 void btm_read_def_esco_mode(enh_esco_params_t* p_parms) {
1565 #if (BTM_MAX_SCO_LINKS > 0)
1566   *p_parms = btm_cb.sco_cb.def_esco_parms;
1567 #endif
1568 }
1569 
1570 /*******************************************************************************
1571  *
1572  * Function         btm_esco_proc_conn_chg
1573  *
1574  * Description      This function is called by BTIF when an SCO connection
1575  *                  is changed.
1576  *
1577  * Returns          void
1578  *
1579  ******************************************************************************/
1580 void btm_esco_proc_conn_chg(uint8_t status, uint16_t handle,
1581                             uint8_t tx_interval, uint8_t retrans_window,
1582                             uint16_t rx_pkt_len, uint16_t tx_pkt_len) {
1583 #if (BTM_MAX_SCO_LINKS > 0)
1584   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1585   tBTM_CHG_ESCO_EVT_DATA data;
1586   uint16_t xx;
1587 
1588   BTM_TRACE_EVENT("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
1589                   handle, status);
1590 
1591   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1592     if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle) {
1593       /* If upper layer wants notification */
1594       if (p->esco.p_esco_cback) {
1595         memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
1596         data.hci_status = status;
1597         data.sco_inx = xx;
1598         data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
1599         data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
1600         data.tx_interval = p->esco.data.tx_interval = tx_interval;
1601         data.retrans_window = p->esco.data.retrans_window = retrans_window;
1602 
1603         (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT, (tBTM_ESCO_EVT_DATA*)&data);
1604       }
1605       return;
1606     }
1607   }
1608 #endif
1609 }
1610 
1611 /*******************************************************************************
1612  *
1613  * Function         btm_is_sco_active
1614  *
1615  * Description      This function is called to see if a SCO handle is already in
1616  *                  use.
1617  *
1618  * Returns          bool
1619  *
1620  ******************************************************************************/
1621 bool btm_is_sco_active(uint16_t handle) {
1622 #if (BTM_MAX_SCO_LINKS > 0)
1623   uint16_t xx;
1624   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1625 
1626   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1627     if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED) return (true);
1628   }
1629 #endif
1630   return (false);
1631 }
1632 
1633 /*******************************************************************************
1634  *
1635  * Function         BTM_GetNumScoLinks
1636  *
1637  * Description      This function returns the number of active sco links.
1638  *
1639  * Returns          uint8_t
1640  *
1641  ******************************************************************************/
1642 uint8_t BTM_GetNumScoLinks(void) {
1643 #if (BTM_MAX_SCO_LINKS > 0)
1644   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1645   uint16_t xx;
1646   uint8_t num_scos = 0;
1647 
1648   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1649     switch (p->state) {
1650       case SCO_ST_W4_CONN_RSP:
1651       case SCO_ST_CONNECTING:
1652       case SCO_ST_CONNECTED:
1653       case SCO_ST_DISCONNECTING:
1654       case SCO_ST_PEND_UNPARK:
1655         num_scos++;
1656     }
1657   }
1658   return (num_scos);
1659 #else
1660   return (0);
1661 #endif
1662 }
1663 
1664 /*******************************************************************************
1665  *
1666  * Function         btm_is_sco_active_by_bdaddr
1667  *
1668  * Description      This function is called to see if a SCO connection is active
1669  *                  for a bd address.
1670  *
1671  * Returns          bool
1672  *
1673  ******************************************************************************/
1674 bool btm_is_sco_active_by_bdaddr(BD_ADDR remote_bda) {
1675 #if (BTM_MAX_SCO_LINKS > 0)
1676   uint8_t xx;
1677   tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1678 
1679   /* If any SCO is being established to the remote BD address, refuse this */
1680   for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1681     if ((!memcmp(p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) &&
1682         (p->state == SCO_ST_CONNECTED)) {
1683       return (true);
1684     }
1685   }
1686 #endif
1687   return (false);
1688 }
1689 
1690 /*******************************************************************************
1691  *
1692  * Function         btm_sco_voice_settings_2_legacy
1693  *
1694  * Description      This function is called to convert the Enhanced eSCO
1695  *                  parameters into voice setting parameter mask used
1696  *                  for legacy setup synchronous connection HCI commands
1697  *
1698  * Returns          UINT16 - 16-bit mask for voice settings
1699  *
1700  *          HCI_INP_CODING_LINEAR           0x0000 (0000000000)
1701  *          HCI_INP_CODING_U_LAW            0x0100 (0100000000)
1702  *          HCI_INP_CODING_A_LAW            0x0200 (1000000000)
1703  *          HCI_INP_CODING_MASK             0x0300 (1100000000)
1704  *
1705  *          HCI_INP_DATA_FMT_1S_COMPLEMENT  0x0000 (0000000000)
1706  *          HCI_INP_DATA_FMT_2S_COMPLEMENT  0x0040 (0001000000)
1707  *          HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 (0010000000)
1708  *          HCI_INP_DATA_FMT_UNSIGNED       0x00c0 (0011000000)
1709  *          HCI_INP_DATA_FMT_MASK           0x00c0 (0011000000)
1710  *
1711  *          HCI_INP_SAMPLE_SIZE_8BIT        0x0000 (0000000000)
1712  *          HCI_INP_SAMPLE_SIZE_16BIT       0x0020 (0000100000)
1713  *          HCI_INP_SAMPLE_SIZE_MASK        0x0020 (0000100000)
1714  *
1715  *          HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c (0000011100)
1716  *          HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
1717  *
1718  *          HCI_AIR_CODING_FORMAT_CVSD      0x0000 (0000000000)
1719  *          HCI_AIR_CODING_FORMAT_U_LAW     0x0001 (0000000001)
1720  *          HCI_AIR_CODING_FORMAT_A_LAW     0x0002 (0000000010)
1721  *          HCI_AIR_CODING_FORMAT_TRANSPNT  0x0003 (0000000011)
1722  *          HCI_AIR_CODING_FORMAT_MASK      0x0003 (0000000011)
1723  *
1724  *          default (0001100000)
1725  *          HCI_DEFAULT_VOICE_SETTINGS    (HCI_INP_CODING_LINEAR \
1726  *                                   | HCI_INP_DATA_FMT_2S_COMPLEMENT \
1727  *                                   | HCI_INP_SAMPLE_SIZE_16BIT \
1728  *                                   | HCI_AIR_CODING_FORMAT_CVSD)
1729  *
1730  ******************************************************************************/
1731 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_params) {
1732   uint16_t voice_settings = 0;
1733 
1734   /* Convert Input Coding Format: If no uLaw or aLAW then Linear will be used
1735    * (0) */
1736   if (p_params->input_coding_format.coding_format == ESCO_CODING_FORMAT_ULAW)
1737     voice_settings |= HCI_INP_CODING_U_LAW;
1738   else if (p_params->input_coding_format.coding_format ==
1739            ESCO_CODING_FORMAT_ALAW)
1740     voice_settings |= HCI_INP_CODING_A_LAW;
1741   /* else default value of '0 is good 'Linear' */
1742 
1743   /* Convert Input Data Format. Use 2's Compliment as the default */
1744   switch (p_params->input_pcm_data_format) {
1745     case ESCO_PCM_DATA_FORMAT_1_COMP:
1746       /* voice_settings |= HCI_INP_DATA_FMT_1S_COMPLEMENT;     value is '0'
1747        * already */
1748       break;
1749 
1750     case ESCO_PCM_DATA_FORMAT_SIGN:
1751       voice_settings |= HCI_INP_DATA_FMT_SIGN_MAGNITUDE;
1752       break;
1753 
1754     case ESCO_PCM_DATA_FORMAT_UNSIGN:
1755       voice_settings |= HCI_INP_DATA_FMT_UNSIGNED;
1756       break;
1757 
1758     default: /* 2's Compliment */
1759       voice_settings |= HCI_INP_DATA_FMT_2S_COMPLEMENT;
1760       break;
1761   }
1762 
1763   /* Convert Over the Air Coding. Use CVSD as the default */
1764   switch (p_params->transmit_coding_format.coding_format) {
1765     case ESCO_CODING_FORMAT_ULAW:
1766       voice_settings |= HCI_AIR_CODING_FORMAT_U_LAW;
1767       break;
1768 
1769     case ESCO_CODING_FORMAT_ALAW:
1770       voice_settings |= HCI_AIR_CODING_FORMAT_A_LAW;
1771       break;
1772 
1773     case ESCO_CODING_FORMAT_MSBC:
1774       voice_settings |= HCI_AIR_CODING_FORMAT_TRANSPNT;
1775       break;
1776 
1777     default: /* CVSD (0) */
1778       break;
1779   }
1780 
1781   /* Convert PCM payload MSB position (0000011100) */
1782   voice_settings |= (uint16_t)(((p_params->input_pcm_payload_msb_position & 0x7)
1783                                 << HCI_INP_LINEAR_PCM_BIT_POS_OFFS));
1784 
1785   /* Convert Input Sample Size (0000011100) */
1786   if (p_params->input_coded_data_size == 16)
1787     voice_settings |= HCI_INP_SAMPLE_SIZE_16BIT;
1788   else /* Use 8 bit for all others */
1789     voice_settings |= HCI_INP_SAMPLE_SIZE_8BIT;
1790 
1791   BTM_TRACE_DEBUG("%s: voice setting for legacy 0x%03x", __func__,
1792                   voice_settings);
1793 
1794   return (voice_settings);
1795 }
1796 
1797 #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
1798 
1799 tBTM_STATUS BTM_CreateSco(BD_ADDR remote_bda, bool is_orig, uint16_t pkt_types,
1800                           uint16_t* p_sco_inx, tBTM_SCO_CB* p_conn_cb,
1801                           tBTM_SCO_CB* p_disc_cb) {
1802   return (BTM_NO_RESOURCES);
1803 }
1804 tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) { return (BTM_NO_RESOURCES); }
1805 tBTM_STATUS BTM_SetScoPacketTypes(uint16_t sco_inx, uint16_t pkt_types) {
1806   return (BTM_NO_RESOURCES);
1807 }
1808 uint16_t BTM_ReadScoPacketTypes(uint16_t sco_inx) { return (0); }
1809 uint16_t BTM_ReadDeviceScoPacketTypes(void) { return (0); }
1810 uint16_t BTM_ReadScoHandle(uint16_t sco_inx) {
1811   return (BTM_INVALID_HCI_HANDLE);
1812 }
1813 uint8_t* BTM_ReadScoBdAddr(uint16_t sco_inx) { return ((uint8_t*)NULL); }
1814 uint16_t BTM_ReadScoDiscReason(void) { return (BTM_INVALID_SCO_DISC_REASON); }
1815 tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) {
1816   return (BTM_MODE_UNSUPPORTED);
1817 }
1818 tBTM_STATUS BTM_RegForEScoEvts(uint16_t sco_inx,
1819                                tBTM_ESCO_CBACK* p_esco_cback) {
1820   return (BTM_ILLEGAL_VALUE);
1821 }
1822 tBTM_STATUS BTM_ReadEScoLinkParms(uint16_t sco_inx, tBTM_ESCO_DATA* p_parms) {
1823   return (BTM_MODE_UNSUPPORTED);
1824 }
1825 tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
1826                                     tBTM_CHG_ESCO_PARAMS* p_parms) {
1827   return (BTM_MODE_UNSUPPORTED);
1828 }
1829 void BTM_EScoConnRsp(uint16_t sco_inx, uint8_t hci_status,
1830                      enh_esco_params_t* p_parms) {}
1831 uint8_t BTM_GetNumScoLinks(void) { return (0); }
1832 
1833 #endif /* If SCO is being used */
1834