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