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