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