OSDN Git Service

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