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