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