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