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