1 /******************************************************************************
3 * Copyright (C) 2000-2012 Broadcom Corporation
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:
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 ******************************************************************************/
19 /******************************************************************************
21 * This file contains functions that handle SCO connections. This includes
22 * operations such as connect, disconnect, change supported packet types.
24 ******************************************************************************/
28 #include "bt_target.h"
38 #if BTM_SCO_INCLUDED == TRUE
40 /********************************************************************************/
41 /* L O C A L D A T A D E F I N I T I O N S */
42 /********************************************************************************/
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
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 /********************************************************************************/
57 static const tBTM_ESCO_PARAMS btm_esco_defaults =
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) */
72 /*******************************************************************************
74 ** Function btm_sco_flush_sco_data
76 ** Description This function is called to flush the SCO data for this channel.
80 *******************************************************************************/
81 void btm_sco_flush_sco_data(UINT16 sco_inx)
83 #if BTM_SCO_HCI_INCLUDED == TRUE
84 #if (BTM_MAX_SCO_LINKS>0)
88 if (sco_inx < BTM_MAX_SCO_LINKS)
90 p = &btm_cb.sco_cb.sco_db[sco_inx];
91 while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p->xmit_data_q)) != NULL)
102 /*******************************************************************************
104 ** Function btm_sco_init
106 ** Description This function is called at BTM startup to initialize
110 *******************************************************************************/
111 void btm_sco_init (void)
113 #if 0 /* cleared in btm_init; put back in if called from anywhere else! */
114 memset (&btm_cb.sco_cb, 0, sizeof(tSCO_CB));
117 #if BTM_SCO_HCI_INCLUDED == TRUE
118 for (int i = 0; i < BTM_MAX_SCO_LINKS; i++)
119 btm_cb.sco_cb.sco_db[i].xmit_data_q = fixed_queue_new(SIZE_MAX);
122 /* Initialize nonzero defaults */
123 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
125 btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */
126 btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE;
129 /*******************************************************************************
131 ** Function btm_esco_conn_rsp
133 ** Description This function is called upon receipt of an (e)SCO connection
134 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
135 ** the request. Parameters used to negotiate eSCO links.
136 ** If p_parms is NULL, then default values are used.
137 ** If the link type of the incoming request is SCO, then only
138 ** the tx_bw, max_latency, content format, and packet_types are
139 ** valid. The hci_status parameter should be
140 ** ([0x0] to accept, [0x0d..0x0f] to reject)
144 *******************************************************************************/
145 static void btm_esco_conn_rsp (UINT16 sco_inx, UINT8 hci_status, BD_ADDR bda,
146 tBTM_ESCO_PARAMS *p_parms)
148 #if (BTM_MAX_SCO_LINKS>0)
149 tSCO_CONN *p_sco = NULL;
150 tBTM_ESCO_PARAMS *p_setup;
151 UINT16 temp_pkt_types;
153 if (sco_inx < BTM_MAX_SCO_LINKS)
154 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
156 /* Reject the connect request if refused by caller or wrong state */
157 if (hci_status != HCI_SUCCESS || p_sco == NULL)
161 p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
165 if (!btm_cb.sco_cb.esco_supported)
167 if (!btsnd_hcic_reject_conn (bda, hci_status))
169 BTM_TRACE_ERROR("Could not reject (e)SCO conn: No Buffer!!!");
174 if (!btsnd_hcic_reject_esco_conn (bda, hci_status))
176 BTM_TRACE_ERROR("Could not reject (e)SCO conn: No Buffer!!!");
180 else /* Connection is being accepted */
182 p_sco->state = SCO_ST_CONNECTING;
183 p_setup = &p_sco->esco.setup;
184 /* If parameters not specified use the default */
187 else /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
189 *p_setup = btm_cb.sco_cb.def_esco_parms;
192 temp_pkt_types = (p_setup->packet_types &
193 BTM_SCO_SUPPORTED_PKTS_MASK &
194 btm_cb.btm_sco_pkt_types_supported);
196 /* Make sure at least one eSCO packet type is sent, else might confuse peer */
197 /* Taking this out to confirm with BQB tests
198 ** Real application would like to include this though, as many devices
199 ** do not retry with SCO only if an eSCO connection fails.
200 if (!(temp_pkt_types & BTM_ESCO_LINK_ONLY_MASK))
202 temp_pkt_types |= BTM_SCO_PKT_TYPES_MASK_EV3;
205 /* If SCO request, remove eSCO packet types (conformance) */
206 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO)
208 temp_pkt_types &= BTM_SCO_LINK_ONLY_MASK;
209 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
213 /* OR in any exception packet types */
214 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
215 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
218 if (btsnd_hcic_accept_esco_conn (bda, p_setup->tx_bw, p_setup->rx_bw,
219 p_setup->max_latency, p_setup->voice_contfmt,
220 p_setup->retrans_effort, temp_pkt_types))
222 p_setup->packet_types = temp_pkt_types;
226 BTM_TRACE_ERROR("Could not accept SCO conn: No Buffer!!!");
233 #if BTM_SCO_HCI_INCLUDED == TRUE
234 /*******************************************************************************
236 ** Function btm_sco_check_send_pkts
238 ** Description This function is called to check if it can send packets
239 ** to the Host Controller.
243 *******************************************************************************/
244 void btm_sco_check_send_pkts (UINT16 sco_inx)
246 tSCO_CB *p_cb = &btm_cb.sco_cb;
247 tSCO_CONN *p_ccb = &p_cb->sco_db[sco_inx];
249 /* If there is data to send, send it now */
251 while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->xmit_data_q)) != NULL)
253 #if BTM_SCO_HCI_DEBUG
254 BTM_TRACE_DEBUG("btm: [%d] buf in xmit_data_q",
255 fixed_queue_length(p_ccb->xmit_data_q) + 1);
258 HCI_SCO_DATA_TO_LOWER(p_buf);
261 #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
263 /*******************************************************************************
265 ** Function btm_route_sco_data
267 ** Description Route received SCO data.
271 *******************************************************************************/
272 void btm_route_sco_data(BT_HDR *p_msg)
274 #if BTM_SCO_HCI_INCLUDED == TRUE
275 UINT16 sco_inx, handle;
276 UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
278 UINT8 pkt_status = 0;
280 /* Extract Packet_Status_Flag and handle */
281 STREAM_TO_UINT16 (handle, p);
282 pkt_status = HCID_GET_EVENT(handle);
283 handle = HCID_GET_HANDLE (handle);
285 STREAM_TO_UINT8 (pkt_size, p);
287 if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS )
289 /* send data callback */
290 if (!btm_cb.sco_cb.p_data_cb )
291 /* if no data callback registered, just free the buffer */
295 (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status);
298 else /* no mapping handle SCO connection is active, free the buffer */
307 /*******************************************************************************
309 ** Function BTM_WriteScoData
311 ** Description This function write SCO data to a specified instance. The data
312 ** to be written p_buf needs to carry an offset of
313 ** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
314 ** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set
315 ** to 60 and is configurable. Data longer than the maximum bytes
316 ** will be truncated.
318 ** Returns BTM_SUCCESS: data write is successful
319 ** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
320 ** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet
322 ** BTM_NO_RESOURCES: no resources.
323 ** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not
327 *******************************************************************************/
328 tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
330 #if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_MAX_SCO_LINKS>0)
331 tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
333 tBTM_STATUS status = BTM_SUCCESS;
335 if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
336 p_ccb->state == SCO_ST_CONNECTED)
338 /* Ensure we have enough space in the buffer for the SCO and HCI headers */
339 if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE)
341 BTM_TRACE_ERROR ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset);
343 status = BTM_ILLEGAL_VALUE;
345 else /* write HCI header */
347 /* Step back 3 bytes to add the headers */
348 p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
349 /* Set the pointer to the beginning of the data */
350 p = (UINT8 *)(p_buf + 1) + p_buf->offset;
352 UINT16_TO_STREAM (p, p_ccb->hci_handle);
353 /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
354 and set warning status */
355 if (p_buf->len > BTM_SCO_DATA_SIZE_MAX)
357 p_buf->len = BTM_SCO_DATA_SIZE_MAX;
358 status = BTM_SCO_BAD_LENGTH;
361 UINT8_TO_STREAM (p, (UINT8)p_buf->len);
362 p_buf->len += HCI_SCO_PREAMBLE_SIZE;
364 fixed_queue_enqueue(p_ccb->xmit_data_q, p_buf);
366 btm_sco_check_send_pkts (sco_inx);
373 BTM_TRACE_WARNING ("BTM_WriteScoData, invalid sco index: %d at state [%d]",
374 sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state);
375 status = BTM_UNKNOWN_ADDR;
383 return (BTM_NO_RESOURCES);
387 #if (BTM_MAX_SCO_LINKS>0)
388 /*******************************************************************************
390 ** Function btm_send_connect_request
392 ** Description This function is called to respond to SCO connect indications
396 *******************************************************************************/
397 static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
398 tBTM_ESCO_PARAMS *p_setup)
400 UINT16 temp_pkt_types;
404 /* Send connect request depending on version of spec */
405 if (!btm_cb.sco_cb.esco_supported)
407 if (!btsnd_hcic_add_SCO_conn (acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types)))
408 return (BTM_NO_RESOURCES);
412 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
413 btm_cb.btm_sco_pkt_types_supported);
415 /* OR in any exception packet types */
416 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
417 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
419 /* Finally, remove EDR eSCO if the remote device doesn't support it */
420 /* UPF25: Only SCO was brought up in this case */
421 btm_handle_to_acl_index(acl_handle);
422 if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS)
424 p_acl = &btm_cb.acl_db[xx];
425 if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
428 BTM_TRACE_WARNING("BTM Remote does not support 2-EDR eSCO");
429 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 |
430 HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5);
432 if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
435 BTM_TRACE_WARNING("BTM Remote does not support 3-EDR eSCO");
436 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
437 HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
440 /* Check to see if BR/EDR Secure Connections is being used
441 ** If so, we cannot use SCO-only packet types (HFP 1.7)
443 if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr))
445 temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK);
446 BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __FUNCTION__,
449 /* Return error if no packet types left */
450 if (temp_pkt_types == 0)
452 BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",
454 return (BTM_WRONG_MODE);
459 BTM_TRACE_DEBUG("%s: SCO Conn(BR/EDR SC):local or peer does not support BR/EDR SC",
465 BTM_TRACE_API(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
466 p_setup->tx_bw, p_setup->rx_bw,
467 p_setup->max_latency, p_setup->voice_contfmt,
468 p_setup->retrans_effort, temp_pkt_types);
470 if (!btsnd_hcic_setup_esco_conn(acl_handle,
473 p_setup->max_latency,
474 p_setup->voice_contfmt,
475 p_setup->retrans_effort,
477 return (BTM_NO_RESOURCES);
479 p_setup->packet_types = temp_pkt_types;
482 return (BTM_CMD_STARTED);
486 /*******************************************************************************
488 ** Function btm_set_sco_ind_cback
490 ** Description This function is called to register for TCS SCO connect
495 *******************************************************************************/
496 void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb )
498 btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
501 /*******************************************************************************
503 ** Function btm_accept_sco_link
505 ** Description This function is called to respond to TCS SCO connect
510 *******************************************************************************/
511 void btm_accept_sco_link(UINT16 sco_inx, tBTM_ESCO_PARAMS *p_setup,
512 tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb)
514 #if (BTM_MAX_SCO_LINKS>0)
517 if (sco_inx >= BTM_MAX_SCO_LINKS)
519 BTM_TRACE_ERROR("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
523 /* Link role is ignored in for this message */
524 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
525 p_sco->p_conn_cb = p_conn_cb;
526 p_sco->p_disc_cb = p_disc_cb;
527 p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
529 BTM_TRACE_DEBUG("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
531 btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
533 btm_reject_sco_link(sco_inx);
537 /*******************************************************************************
539 ** Function btm_reject_sco_link
541 ** Description This function is called to respond to SCO connect indications
545 *******************************************************************************/
546 void btm_reject_sco_link( UINT16 sco_inx )
548 btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
549 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
552 /*******************************************************************************
554 ** Function BTM_CreateSco
556 ** Description This function is called to create an SCO connection. If the
557 ** "is_orig" flag is TRUE, the connection will be originated,
558 ** otherwise BTM will wait for the other side to connect.
560 ** NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
561 ** parameter the default packet types is used.
563 ** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
564 ** BTM_BUSY if another SCO being set up to
565 ** the same BD address
566 ** BTM_NO_RESOURCES if the max SCO limit has been reached
567 ** BTM_CMD_STARTED if the connection establishment is started.
568 ** In this case, "*p_sco_inx" is filled in
569 ** with the sco index used for the connection.
571 *******************************************************************************/
572 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types,
573 UINT16 *p_sco_inx, tBTM_SCO_CB *p_conn_cb,
574 tBTM_SCO_CB *p_disc_cb)
576 #if (BTM_MAX_SCO_LINKS > 0)
577 tBTM_ESCO_PARAMS *p_setup;
578 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
580 UINT16 acl_handle = 0;
581 UINT16 temp_pkt_types;
584 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
587 #else // BTM_SCO_WAKE_PARKED_LINK
589 #endif // BTM_SCO_WAKE_PARKED_LINK
591 *p_sco_inx = BTM_INVALID_SCO_INDEX;
593 /* If originating, ensure that there is an ACL connection to the BD Address */
596 if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF))
597 return (BTM_UNKNOWN_ADDR);
602 /* If any SCO is being established to the remote BD address, refuse this */
603 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
605 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING)
606 || (p->state == SCO_ST_PEND_UNPARK))
607 && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)))
615 /* Support only 1 wildcard BD address at a time */
616 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
618 if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known))
623 /* Now, try to find an unused control block, and kick off the SCO establishment */
624 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
626 if (p->state == SCO_ST_UNUSED)
632 /* can not create SCO link if in park mode */
633 #if BTM_SCO_WAKE_PARKED_LINK == TRUE
634 if(BTM_ReadPowerMode(remote_bda, &md) == BTM_SUCCESS)
636 if (md == BTM_PM_MD_PARK || md == BTM_PM_MD_SNIFF)
638 memset( (void*)&pm, 0, sizeof(pm));
639 pm.mode = BTM_PM_MD_ACTIVE;
640 BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
641 p->state = SCO_ST_PEND_UNPARK;
644 #else // BTM_SCO_WAKE_PARKED_LINK
645 if( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) )
646 return (BTM_WRONG_MODE);
647 #endif // BTM_SCO_WAKE_PARKED_LINK
649 memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
650 p->rem_bd_known = TRUE;
653 p->rem_bd_known = FALSE;
655 /* Link role is ignored in for this message */
656 if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE)
657 pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types;
659 p_setup = &p->esco.setup;
660 *p_setup = btm_cb.sco_cb.def_esco_parms;
661 p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO)
662 ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types;
664 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
665 btm_cb.btm_sco_pkt_types_supported);
667 /* OR in any exception packet types */
668 if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO)
670 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
671 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
673 else /* Only using SCO packet types; turn off EDR also */
675 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
678 p_setup->packet_types = temp_pkt_types;
679 p->p_conn_cb = p_conn_cb;
680 p->p_disc_cb = p_disc_cb;
681 p->hci_handle = BTM_INVALID_HCI_HANDLE;
682 p->is_orig = is_orig;
684 if( p->state != SCO_ST_PEND_UNPARK )
688 /* If role change is in progress, do not proceed with SCO setup
689 * Wait till role change is complete */
690 p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
691 if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
693 BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x",acl_handle);
694 p->state = SCO_ST_PEND_ROLECHANGE;
700 if( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE )
704 BTM_TRACE_API("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d",
705 acl_handle, btm_cb.sco_cb.desired_sco_mode);
707 if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED)
708 return (BTM_NO_RESOURCES);
710 p->state = SCO_ST_CONNECTING;
713 p->state = SCO_ST_LISTENING;
718 return (BTM_CMD_STARTED);
723 /* If here, all SCO blocks in use */
724 return (BTM_NO_RESOURCES);
727 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
728 /*******************************************************************************
730 ** Function btm_sco_chk_pend_unpark
732 ** Description This function is called by BTIF when there is a mode change
733 ** event to see if there are SCO commands waiting for the unpark.
737 *******************************************************************************/
738 void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle)
740 #if (BTM_MAX_SCO_LINKS>0)
743 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
745 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
747 if ((p->state == SCO_ST_PEND_UNPARK) &&
748 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
751 BTM_TRACE_API("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
752 acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status);
754 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
755 p->state = SCO_ST_CONNECTING;
758 #endif // BTM_MAX_SCO_LINKS
760 #endif // BTM_SCO_WAKE_PARKED_LINK
762 /*******************************************************************************
764 ** Function btm_sco_chk_pend_rolechange
766 ** Description This function is called by BTIF when there is a role change
767 ** event to see if there are SCO commands waiting for the role change.
771 *******************************************************************************/
772 void btm_sco_chk_pend_rolechange (UINT16 hci_handle)
774 #if (BTM_MAX_SCO_LINKS>0)
777 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
779 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
781 if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
782 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
785 BTM_TRACE_API("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
787 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
788 p->state = SCO_ST_CONNECTING;
794 /*******************************************************************************
796 ** Function btm_sco_conn_req
798 ** Description This function is called by BTIF when an SCO connection
799 ** request is received from a remote.
803 *******************************************************************************/
804 void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type)
806 #if (BTM_MAX_SCO_LINKS>0)
807 tSCO_CB *p_sco = &btm_cb.sco_cb;
808 tSCO_CONN *p = &p_sco->sco_db[0];
810 tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
812 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
815 * If the sco state is in the SCO_ST_CONNECTING state, we still need
816 * to return accept sco to avoid race conditon for sco creation
818 int rem_bd_matches = p->rem_bd_known &&
819 !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
820 if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
821 ((p->state == SCO_ST_LISTENING) && (rem_bd_matches || !p->rem_bd_known)))
823 /* If this guy was a wildcard, he is not one any more */
824 p->rem_bd_known = TRUE;
825 p->esco.data.link_type = link_type;
826 p->state = SCO_ST_W4_CONN_RSP;
827 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
829 /* If no callback, auto-accept the connection if packet types match */
830 if (!p->esco.p_esco_cback)
832 /* If requesting eSCO reject if default parameters are SCO only */
833 if ((link_type == BTM_LINK_TYPE_ESCO
834 && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK)
835 && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK)
836 == BTM_SCO_EXCEPTION_PKTS_MASK))
838 /* Reject request if SCO is desired but no SCO packets delected */
839 || (link_type == BTM_LINK_TYPE_SCO
840 && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK)))
842 btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
844 else /* Accept the request */
846 btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
849 else /* Notify upper layer of connect indication */
851 memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
852 memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
853 evt_data.link_type = link_type;
854 evt_data.sco_inx = xx;
855 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data);
863 if (btm_cb.sco_cb.app_sco_ind_cb)
865 /* Now, try to find an unused control block */
866 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
868 if (p->state == SCO_ST_UNUSED)
871 p->state = SCO_ST_LISTENING;
873 p->esco.data.link_type = link_type;
874 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
875 p->rem_bd_known = TRUE;
879 if( xx < BTM_MAX_SCO_LINKS)
881 btm_cb.sco_cb.app_sco_ind_cb(xx);
887 /* If here, no one wants the SCO connection. Reject it */
888 BTM_TRACE_WARNING("btm_sco_conn_req: No one wants this SCO connection; rejecting it");
889 btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
892 /*******************************************************************************
894 ** Function btm_sco_connected
896 ** Description This function is called by BTIF when an (e)SCO connection
901 *******************************************************************************/
902 void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
903 tBTM_ESCO_DATA *p_esco_data)
905 #if (BTM_MAX_SCO_LINKS>0)
906 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
909 tBTM_CHG_ESCO_PARAMS parms;
912 btm_cb.sco_cb.sco_disc_reason = hci_status;
914 #if (BTM_MAX_SCO_LINKS>0)
915 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
917 if (((p->state == SCO_ST_CONNECTING) ||
918 (p->state == SCO_ST_LISTENING) ||
919 (p->state == SCO_ST_W4_CONN_RSP))
921 && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
923 if (hci_status != HCI_SUCCESS)
925 /* Report the error if originator, otherwise remain in Listen mode */
928 /* If role switch is pending, we need try again after role switch is complete */
929 if(hci_status == HCI_ERR_ROLE_SWITCH_PENDING)
931 BTM_TRACE_API("Role Change pending for HCI handle 0x%04x",hci_handle);
932 p->state = SCO_ST_PEND_ROLECHANGE;
934 /* avoid calling disconnect callback because of sco creation race */
935 else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION)
937 p->state = SCO_ST_UNUSED;
943 /* Notify the upper layer that incoming sco connection has failed. */
944 if (p->state == SCO_ST_CONNECTING)
946 p->state = SCO_ST_UNUSED;
950 p->state = SCO_ST_LISTENING;
956 if (p->state == SCO_ST_LISTENING)
959 p->state = SCO_ST_CONNECTED;
960 p->hci_handle = hci_handle;
962 if (!btm_cb.sco_cb.esco_supported)
964 p->esco.data.link_type = BTM_LINK_TYPE_SCO;
967 parms.packet_types = p->esco.setup.packet_types;
968 /* Keep the other parameters the same for SCO */
969 parms.max_latency = p->esco.setup.max_latency;
970 parms.retrans_effort = p->esco.setup.retrans_effort;
972 BTM_ChangeEScoLinkParms(xx, &parms);
978 p->esco.data = *p_esco_data;
990 /*******************************************************************************
992 ** Function btm_find_scb_by_handle
994 ** Description Look through all active SCO connection for a match based on the
997 ** Returns index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
1000 *******************************************************************************/
1001 UINT16 btm_find_scb_by_handle (UINT16 handle)
1004 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1006 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1008 if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle))
1014 /* If here, no match found */
1018 /*******************************************************************************
1020 ** Function BTM_RemoveSco
1022 ** Description This function is called to remove a specific SCO connection.
1024 ** Returns status of the operation
1026 *******************************************************************************/
1027 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
1029 #if (BTM_MAX_SCO_LINKS>0)
1030 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1033 /* Validity check */
1034 if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
1035 return (BTM_UNKNOWN_ADDR);
1037 /* If no HCI handle, simply drop the connection and return */
1038 if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK)
1040 p->hci_handle = BTM_INVALID_HCI_HANDLE;
1041 p->state = SCO_ST_UNUSED;
1042 p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
1043 return (BTM_SUCCESS);
1046 tempstate = p->state;
1047 p->state = SCO_ST_DISCONNECTING;
1049 if (!btsnd_hcic_disconnect (p->hci_handle, HCI_ERR_PEER_USER))
1051 p->state = tempstate;
1052 return (BTM_NO_RESOURCES);
1055 return (BTM_CMD_STARTED);
1057 return (BTM_NO_RESOURCES);
1061 /*******************************************************************************
1063 ** Function btm_remove_sco_links
1065 ** Description This function is called to remove all sco links for an ACL link.
1069 *******************************************************************************/
1070 void btm_remove_sco_links (BD_ADDR bda)
1072 #if (BTM_MAX_SCO_LINKS>0)
1073 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1076 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1078 if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
1086 /*******************************************************************************
1088 ** Function btm_sco_removed
1090 ** Description This function is called by BTIF when an SCO connection
1095 *******************************************************************************/
1096 void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
1098 #if (BTM_MAX_SCO_LINKS>0)
1099 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1103 btm_cb.sco_cb.sco_disc_reason = reason;
1105 #if (BTM_MAX_SCO_LINKS>0)
1106 p = &btm_cb.sco_cb.sco_db[0];
1107 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1109 if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle))
1111 btm_sco_flush_sco_data(xx);
1113 p->state = SCO_ST_UNUSED;
1114 p->hci_handle = BTM_INVALID_HCI_HANDLE;
1115 p->rem_bd_known = FALSE;
1116 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1117 (*p->p_disc_cb)(xx);
1126 /*******************************************************************************
1128 ** Function btm_sco_acl_removed
1130 ** Description This function is called when an ACL connection is
1131 ** removed. If the BD address is NULL, it is assumed that
1132 ** the local device is down, and all SCO links are removed.
1133 ** If a specific BD address is passed, only SCO connections
1134 ** to that BD address are removed.
1138 *******************************************************************************/
1139 void btm_sco_acl_removed (BD_ADDR bda)
1141 #if (BTM_MAX_SCO_LINKS>0)
1142 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1145 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1147 if (p->state != SCO_ST_UNUSED)
1149 if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known))
1151 btm_sco_flush_sco_data(xx);
1153 p->state = SCO_ST_UNUSED;
1154 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1155 (*p->p_disc_cb)(xx);
1163 /*******************************************************************************
1165 ** Function BTM_SetScoPacketTypes
1167 ** Description This function is called to set the packet types used for
1168 ** a specific SCO connection,
1170 ** Parameters pkt_types - One or more of the following
1171 ** BTM_SCO_PKT_TYPES_MASK_HV1
1172 ** BTM_SCO_PKT_TYPES_MASK_HV2
1173 ** BTM_SCO_PKT_TYPES_MASK_HV3
1174 ** BTM_SCO_PKT_TYPES_MASK_EV3
1175 ** BTM_SCO_PKT_TYPES_MASK_EV4
1176 ** BTM_SCO_PKT_TYPES_MASK_EV5
1177 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1178 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1179 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1180 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1182 ** BTM_SCO_LINK_ALL_MASK - enables all supported types
1184 ** Returns status of the operation
1186 *******************************************************************************/
1187 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
1189 #if (BTM_MAX_SCO_LINKS>0)
1190 tBTM_CHG_ESCO_PARAMS parms;
1193 /* Validity check */
1194 if (sco_inx >= BTM_MAX_SCO_LINKS)
1195 return (BTM_UNKNOWN_ADDR);
1197 p = &btm_cb.sco_cb.sco_db[sco_inx];
1198 parms.packet_types = pkt_types;
1200 /* Keep the other parameters the same for SCO */
1201 parms.max_latency = p->esco.setup.max_latency;
1202 parms.retrans_effort = p->esco.setup.retrans_effort;
1204 return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
1206 return (BTM_UNKNOWN_ADDR);
1211 /*******************************************************************************
1213 ** Function BTM_ReadScoPacketTypes
1215 ** Description This function is read the packet types used for a specific
1218 ** Returns Packet types supported for the connection
1219 ** One or more of the following (bitmask):
1220 ** BTM_SCO_PKT_TYPES_MASK_HV1
1221 ** BTM_SCO_PKT_TYPES_MASK_HV2
1222 ** BTM_SCO_PKT_TYPES_MASK_HV3
1223 ** BTM_SCO_PKT_TYPES_MASK_EV3
1224 ** BTM_SCO_PKT_TYPES_MASK_EV4
1225 ** BTM_SCO_PKT_TYPES_MASK_EV5
1226 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1227 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1228 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1229 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1231 *******************************************************************************/
1232 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
1234 #if (BTM_MAX_SCO_LINKS>0)
1235 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1237 /* Validity check */
1238 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1239 return (p->esco.setup.packet_types);
1247 /*******************************************************************************
1249 ** Function BTM_ReadScoDiscReason
1251 ** Description This function is returns the reason why an (e)SCO connection
1252 ** has been removed. It contains the value until read, or until
1253 ** another (e)SCO connection has disconnected.
1255 ** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
1257 *******************************************************************************/
1258 UINT16 BTM_ReadScoDiscReason (void)
1260 UINT16 res = btm_cb.sco_cb.sco_disc_reason;
1261 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
1265 /*******************************************************************************
1267 ** Function BTM_ReadDeviceScoPacketTypes
1269 ** Description This function is read the SCO packet types that
1270 ** the device supports.
1272 ** Returns Packet types supported by the device.
1273 ** One or more of the following (bitmask):
1274 ** BTM_SCO_PKT_TYPES_MASK_HV1
1275 ** BTM_SCO_PKT_TYPES_MASK_HV2
1276 ** BTM_SCO_PKT_TYPES_MASK_HV3
1277 ** BTM_SCO_PKT_TYPES_MASK_EV3
1278 ** BTM_SCO_PKT_TYPES_MASK_EV4
1279 ** BTM_SCO_PKT_TYPES_MASK_EV5
1280 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1281 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1282 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1283 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1285 *******************************************************************************/
1286 UINT16 BTM_ReadDeviceScoPacketTypes (void)
1288 return (btm_cb.btm_sco_pkt_types_supported);
1291 /*******************************************************************************
1293 ** Function BTM_ReadScoHandle
1295 ** Description This function is used to read the HCI handle used for a specific
1298 ** Returns handle for the connection, or 0xFFFF if invalid SCO index.
1300 *******************************************************************************/
1301 UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
1303 #if (BTM_MAX_SCO_LINKS>0)
1304 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1306 /* Validity check */
1307 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1308 return (p->hci_handle);
1310 return (BTM_INVALID_HCI_HANDLE);
1312 return (BTM_INVALID_HCI_HANDLE);
1316 /*******************************************************************************
1318 ** Function BTM_ReadScoBdAddr
1320 ** Description This function is read the remote BD Address for a specific
1323 ** Returns pointer to BD address or NULL if not known
1325 *******************************************************************************/
1326 UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx)
1328 #if (BTM_MAX_SCO_LINKS>0)
1329 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1331 /* Validity check */
1332 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1333 return (p->esco.data.bd_addr);
1341 /*******************************************************************************
1343 ** Function BTM_SetEScoMode
1345 ** Description This function sets up the negotiated parameters for SCO or
1346 ** eSCO, and sets as the default mode used for outgoing calls to
1347 ** BTM_CreateSco. It does not change any currently active (e)SCO links.
1348 ** Note: Incoming (e)SCO connections will always use packet types
1349 ** supported by the controller. If eSCO is not desired the
1350 ** feature should be disabled in the controller's feature mask.
1352 ** Returns BTM_SUCCESS if the successful.
1353 ** BTM_BUSY if there are one or more active (e)SCO links.
1355 *******************************************************************************/
1356 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
1358 tSCO_CB *p_esco = &btm_cb.sco_cb;
1359 tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms;
1361 if (p_esco->esco_supported)
1365 if (sco_mode == BTM_LINK_TYPE_ESCO)
1366 *p_def = *p_parms; /* Save as the default parameters */
1367 else /* Load only the SCO packet types */
1369 p_def->packet_types = p_parms->packet_types;
1370 p_def->tx_bw = BTM_64KBITS_RATE;
1371 p_def->rx_bw = BTM_64KBITS_RATE;
1372 p_def->max_latency = 0x000a;
1373 p_def->voice_contfmt = 0x0060;
1374 p_def->retrans_effort = 0;
1376 /* OR in any exception packet types */
1377 p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
1380 p_esco->desired_sco_mode = sco_mode;
1381 BTM_TRACE_API("BTM_SetEScoMode -> mode %d", sco_mode);
1385 p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO;
1386 p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
1387 p_def->retrans_effort = 0;
1388 BTM_TRACE_API("BTM_SetEScoMode -> mode SCO (eSCO not supported)");
1391 BTM_TRACE_DEBUG(" txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x",
1392 p_def->tx_bw, p_def->rx_bw, p_def->max_latency,
1393 p_def->voice_contfmt, p_def->packet_types,
1394 p_def->retrans_effort);
1396 return (BTM_SUCCESS);
1401 /*******************************************************************************
1403 ** Function BTM_RegForEScoEvts
1405 ** Description This function registers a SCO event callback with the
1406 ** specified instance. It should be used to received
1407 ** connection indication events and change of link parameter
1410 ** Returns BTM_SUCCESS if the successful.
1411 ** BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1412 ** BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1413 ** later or does not support eSCO.
1415 *******************************************************************************/
1416 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
1418 #if (BTM_MAX_SCO_LINKS>0)
1419 if (!btm_cb.sco_cb.esco_supported)
1421 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1422 return (BTM_MODE_UNSUPPORTED);
1425 if (sco_inx < BTM_MAX_SCO_LINKS &&
1426 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED)
1428 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1429 return (BTM_SUCCESS);
1431 return (BTM_ILLEGAL_VALUE);
1433 return (BTM_MODE_UNSUPPORTED);
1437 /*******************************************************************************
1439 ** Function BTM_ReadEScoLinkParms
1441 ** Description This function returns the current eSCO link parameters for
1442 ** the specified handle. This can be called anytime a connection
1443 ** is active, but is typically called after receiving the SCO
1446 ** Note: If called over a 1.1 controller, only the packet types
1447 ** field has meaning.
1449 ** Returns BTM_SUCCESS if returned data is valid connection.
1450 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
1452 *******************************************************************************/
1453 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
1455 #if (BTM_MAX_SCO_LINKS>0)
1458 BTM_TRACE_API("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx);
1460 if (sco_inx < BTM_MAX_SCO_LINKS &&
1461 btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED)
1463 *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
1464 return (BTM_SUCCESS);
1467 if (sco_inx == BTM_FIRST_ACTIVE_SCO_INDEX)
1469 for (index = 0; index < BTM_MAX_SCO_LINKS; index++)
1471 if (btm_cb.sco_cb.sco_db[index].state >= SCO_ST_CONNECTED)
1473 BTM_TRACE_API("BTM_ReadEScoLinkParms the first active SCO index is %d",index);
1474 *p_parms = btm_cb.sco_cb.sco_db[index].esco.data;
1475 return (BTM_SUCCESS);
1482 BTM_TRACE_API("BTM_ReadEScoLinkParms cannot find the SCO index!");
1483 memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
1484 return (BTM_WRONG_MODE);
1487 /*******************************************************************************
1489 ** Function BTM_ChangeEScoLinkParms
1491 ** Description This function requests renegotiation of the parameters on
1492 ** the current eSCO Link. If any of the changes are accepted
1493 ** by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1494 ** the tBTM_ESCO_CBACK function with the current settings of
1495 ** the link. The callback is registered through the call to
1498 ** Note: If called over a SCO link (including 1.1 controller),
1499 ** a change packet type request is sent out instead.
1501 ** Returns BTM_CMD_STARTED if command is successfully initiated.
1502 ** BTM_NO_RESOURCES - not enough resources to initiate command.
1503 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
1505 *******************************************************************************/
1506 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
1508 #if (BTM_MAX_SCO_LINKS>0)
1509 tBTM_ESCO_PARAMS *p_setup;
1511 UINT16 temp_pkt_types;
1513 /* Make sure sco handle is valid and on an active link */
1514 if (sco_inx >= BTM_MAX_SCO_LINKS ||
1515 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1516 return (BTM_WRONG_MODE);
1518 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1519 p_setup = &p_sco->esco.setup;
1521 /* If SCO connection OR eSCO not supported just send change packet types */
1522 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1523 !btm_cb.sco_cb.esco_supported)
1525 p_setup->packet_types = p_parms->packet_types &
1526 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1529 BTM_TRACE_API("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x",
1530 p_sco->hci_handle, p_setup->packet_types);
1532 if (!btsnd_hcic_change_conn_type (p_sco->hci_handle,
1533 BTM_ESCO_2_SCO(p_setup->packet_types)))
1534 return (BTM_NO_RESOURCES);
1538 temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1539 btm_cb.btm_sco_pkt_types_supported);
1541 /* OR in any exception packet types */
1542 temp_pkt_types |= ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
1543 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
1545 BTM_TRACE_API("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle);
1546 BTM_TRACE_API(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
1547 p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency,
1548 p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types);
1550 /* When changing an existing link, only change latency, retrans, and pkts */
1551 if (!btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw,
1552 p_setup->rx_bw, p_parms->max_latency,
1553 p_setup->voice_contfmt,
1554 p_parms->retrans_effort,
1556 return (BTM_NO_RESOURCES);
1558 p_parms->packet_types = temp_pkt_types;
1561 return (BTM_CMD_STARTED);
1563 return (BTM_WRONG_MODE);
1567 /*******************************************************************************
1569 ** Function BTM_EScoConnRsp
1571 ** Description This function is called upon receipt of an (e)SCO connection
1572 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1573 ** the request. Parameters used to negotiate eSCO links.
1574 ** If p_parms is NULL, then values set through BTM_SetEScoMode
1576 ** If the link type of the incoming request is SCO, then only
1577 ** the tx_bw, max_latency, content format, and packet_types are
1578 ** valid. The hci_status parameter should be
1579 ** ([0x0] to accept, [0x0d..0x0f] to reject)
1584 *******************************************************************************/
1585 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms)
1587 #if (BTM_MAX_SCO_LINKS>0)
1588 if (sco_inx < BTM_MAX_SCO_LINKS &&
1589 btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP)
1591 btm_esco_conn_rsp(sco_inx, hci_status,
1592 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr,
1598 /*******************************************************************************
1600 ** Function btm_read_def_esco_mode
1602 ** Description This function copies the current default esco settings into
1603 ** the return buffer.
1605 ** Returns tBTM_SCO_TYPE
1607 *******************************************************************************/
1608 tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms)
1610 #if (BTM_MAX_SCO_LINKS>0)
1611 *p_parms = btm_cb.sco_cb.def_esco_parms;
1612 return btm_cb.sco_cb.desired_sco_mode;
1614 return BTM_LINK_TYPE_SCO;
1618 /*******************************************************************************
1620 ** Function btm_esco_proc_conn_chg
1622 ** Description This function is called by BTIF when an SCO connection
1627 *******************************************************************************/
1628 void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval,
1629 UINT8 retrans_window, UINT16 rx_pkt_len,
1632 #if (BTM_MAX_SCO_LINKS>0)
1633 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1634 tBTM_CHG_ESCO_EVT_DATA data;
1637 BTM_TRACE_EVENT("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
1640 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1642 if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle)
1644 /* If upper layer wants notification */
1645 if (p->esco.p_esco_cback)
1647 memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
1648 data.hci_status = status;
1650 data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
1651 data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
1652 data.tx_interval = p->esco.data.tx_interval = tx_interval;
1653 data.retrans_window = p->esco.data.retrans_window = retrans_window;
1655 (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT,
1656 (tBTM_ESCO_EVT_DATA *)&data);
1664 /*******************************************************************************
1666 ** Function btm_is_sco_active
1668 ** Description This function is called to see if a SCO handle is already in
1673 *******************************************************************************/
1674 BOOLEAN btm_is_sco_active (UINT16 handle)
1676 #if (BTM_MAX_SCO_LINKS>0)
1678 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1680 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1682 if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED)
1689 /*******************************************************************************
1691 ** Function BTM_GetNumScoLinks
1693 ** Description This function returns the number of active sco links.
1697 *******************************************************************************/
1698 UINT8 BTM_GetNumScoLinks (void)
1700 #if (BTM_MAX_SCO_LINKS>0)
1701 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1705 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1709 case SCO_ST_W4_CONN_RSP:
1710 case SCO_ST_CONNECTING:
1711 case SCO_ST_CONNECTED:
1712 case SCO_ST_DISCONNECTING:
1713 case SCO_ST_PEND_UNPARK:
1724 /*******************************************************************************
1726 ** Function btm_is_sco_active_by_bdaddr
1728 ** Description This function is called to see if a SCO active to a bd address.
1732 *******************************************************************************/
1733 BOOLEAN btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda)
1735 #if (BTM_MAX_SCO_LINKS>0)
1737 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1739 /* If any SCO is being established to the remote BD address, refuse this */
1740 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1742 if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED))
1750 #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
1752 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig,
1753 UINT16 pkt_types, UINT16 *p_sco_inx,
1754 tBTM_SCO_CB *p_conn_cb,
1755 tBTM_SCO_CB *p_disc_cb) {return (BTM_NO_RESOURCES);}
1756 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx) {return (BTM_NO_RESOURCES);}
1757 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types) {return (BTM_NO_RESOURCES);}
1758 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx) {return (0);}
1759 UINT16 BTM_ReadDeviceScoPacketTypes (void) {return (0);}
1760 UINT16 BTM_ReadScoHandle (UINT16 sco_inx) {return (BTM_INVALID_HCI_HANDLE);}
1761 UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx) {return((UINT8 *) NULL);}
1762 UINT16 BTM_ReadScoDiscReason (void) {return (BTM_INVALID_SCO_DISC_REASON);}
1763 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) {return (BTM_MODE_UNSUPPORTED);}
1764 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback) { return (BTM_ILLEGAL_VALUE);}
1765 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms) { return (BTM_MODE_UNSUPPORTED);}
1766 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms) { return (BTM_MODE_UNSUPPORTED);}
1767 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) {}
1768 UINT8 BTM_GetNumScoLinks (void) {return (0);}
1770 #endif /* If SCO is being used */