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