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->xmit_data_q.p_first)
93 if ((p_buf = (BT_HDR *)GKI_dequeue (&p->xmit_data_q)) != NULL)
104 /*******************************************************************************
106 ** Function btm_sco_init
108 ** Description This function is called at BTM startup to initialize
112 *******************************************************************************/
113 void btm_sco_init (void)
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));
118 /* Initialize nonzero defaults */
119 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
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;
125 /*******************************************************************************
127 ** Function btm_esco_conn_rsp
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)
140 *******************************************************************************/
141 static void btm_esco_conn_rsp (UINT16 sco_inx, UINT8 hci_status, BD_ADDR bda,
142 tBTM_ESCO_PARAMS *p_parms)
144 #if (BTM_MAX_SCO_LINKS>0)
145 tSCO_CONN *p_sco = NULL;
146 tBTM_ESCO_PARAMS *p_setup;
147 UINT16 temp_pkt_types;
149 if (sco_inx < BTM_MAX_SCO_LINKS)
150 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
152 /* Reject the connect request if refused by caller or wrong state */
153 if (hci_status != HCI_SUCCESS || p_sco == NULL)
157 p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
161 if (!btm_cb.sco_cb.esco_supported)
163 if (!btsnd_hcic_reject_conn (bda, hci_status))
165 BTM_TRACE_ERROR0("Could not reject (e)SCO conn: No Buffer!!!");
170 if (!btsnd_hcic_reject_esco_conn (bda, hci_status))
172 BTM_TRACE_ERROR0("Could not reject (e)SCO conn: No Buffer!!!");
176 else /* Connection is being accepted */
178 p_sco->state = SCO_ST_CONNECTING;
179 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_1_2)
181 p_setup = &p_sco->esco.setup;
182 /* If parameters not specified use the default */
185 else /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
187 *p_setup = btm_cb.sco_cb.def_esco_parms;
190 temp_pkt_types = (p_setup->packet_types &
191 BTM_SCO_SUPPORTED_PKTS_MASK &
192 btm_cb.btm_sco_pkt_types_supported);
194 /* Make sure at least one eSCO packet type is sent, else might confuse peer */
195 /* Taking this out to confirm with BQB tests
196 ** Real application would like to include this though, as many devices
197 ** do not retry with SCO only if an eSCO connection fails.
198 if (!(temp_pkt_types & BTM_ESCO_LINK_ONLY_MASK))
200 temp_pkt_types |= BTM_SCO_PKT_TYPES_MASK_EV3;
203 /* If SCO request, remove eSCO packet types (conformance) */
204 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO)
206 temp_pkt_types &= BTM_SCO_LINK_ONLY_MASK;
208 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
210 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
213 /* OR in any exception packet types if at least 2.0 version of spec */
214 else if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
216 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
217 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
220 if (btsnd_hcic_accept_esco_conn (bda, p_setup->tx_bw, p_setup->rx_bw,
221 p_setup->max_latency, p_setup->voice_contfmt,
222 p_setup->retrans_effort, temp_pkt_types))
224 p_setup->packet_types = temp_pkt_types;
228 BTM_TRACE_ERROR0("Could not accept SCO conn: No Buffer!!!");
231 else /* Controller is version 1.1 or earlier */
233 btsnd_hcic_accept_conn (bda, 0);
240 #if BTM_SCO_HCI_INCLUDED == TRUE
241 /*******************************************************************************
243 ** Function btm_sco_check_send_pkts
245 ** Description This function is called to check if it can send packets
246 ** to the Host Controller.
250 *******************************************************************************/
251 void btm_sco_check_send_pkts (UINT16 sco_inx)
254 tSCO_CB *p_cb = &btm_cb.sco_cb;
255 tSCO_CONN *p_ccb = &p_cb->sco_db[sco_inx];
257 /* If there is data to send, send it now */
258 while (p_ccb->xmit_data_q.p_first != NULL)
262 #if BTM_SCO_HCI_DEBUG
263 BTM_TRACE_DEBUG1 ("btm: [%d] buf in xmit_data_q", p_ccb->xmit_data_q.count );
265 p_buf = (BT_HDR *)GKI_dequeue (&p_ccb->xmit_data_q);
267 HCI_SCO_DATA_TO_LOWER (p_buf);
270 #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
272 /*******************************************************************************
274 ** Function btm_route_sco_data
276 ** Description Route received SCO data.
280 *******************************************************************************/
281 void btm_route_sco_data(BT_HDR *p_msg)
283 #if BTM_SCO_HCI_INCLUDED == TRUE
284 UINT16 sco_inx, handle;
285 UINT8 *p = (UINT8 *)(p_msg + 1) + p_msg->offset;
287 UINT8 pkt_status = 0;
289 /* Extract Packet_Status_Flag and handle */
290 STREAM_TO_UINT16 (handle, p);
291 pkt_status = HCID_GET_EVENT(handle);
292 handle = HCID_GET_HANDLE (handle);
294 STREAM_TO_UINT8 (pkt_size, p);
296 if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS )
298 /* send data callback */
299 if (!btm_cb.sco_cb.p_data_cb )
300 /* if no data callback registered, just free the buffer */
304 (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status);
307 else /* no mapping handle SCO connection is active, free the buffer */
316 /*******************************************************************************
318 ** Function BTM_WriteScoData
320 ** Description This function write SCO data to a specified instance. The data
321 ** to be written p_buf needs to carry an offset of
322 ** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
323 ** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set
324 ** to 60 and is configurable. Data longer than the maximum bytes
325 ** will be truncated.
327 ** Returns BTM_SUCCESS: data write is successful
328 ** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
329 ** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet
331 ** BTM_NO_RESOURCES: no resources.
332 ** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not
336 *******************************************************************************/
337 tBTM_STATUS BTM_WriteScoData (UINT16 sco_inx, BT_HDR *p_buf)
339 #if (BTM_SCO_HCI_INCLUDED == TRUE) && (BTM_MAX_SCO_LINKS>0)
340 tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
342 tBTM_STATUS status = BTM_SUCCESS;
344 if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
345 p_ccb->state == SCO_ST_CONNECTED)
347 /* Ensure we have enough space in the buffer for the SCO and HCI headers */
348 if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE)
350 BTM_TRACE_ERROR1 ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset);
352 status = BTM_ILLEGAL_VALUE;
354 else /* write HCI header */
356 /* Step back 3 bytes to add the headers */
357 p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
358 /* Set the pointer to the beginning of the data */
359 p = (UINT8 *)(p_buf + 1) + p_buf->offset;
361 UINT16_TO_STREAM (p, p_ccb->hci_handle);
362 /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
363 and set warning status */
364 if (p_buf->len > BTM_SCO_DATA_SIZE_MAX)
366 p_buf->len = BTM_SCO_DATA_SIZE_MAX;
367 status = BTM_SCO_BAD_LENGTH;
370 UINT8_TO_STREAM (p, (UINT8)p_buf->len);
371 p_buf->len += HCI_SCO_PREAMBLE_SIZE;
373 GKI_enqueue (&p_ccb->xmit_data_q, p_buf);
375 btm_sco_check_send_pkts (sco_inx);
382 BTM_TRACE_WARNING2 ("BTM_WriteScoData, invalid sco index: %d at state [%d]",
383 sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state);
384 status = BTM_UNKNOWN_ADDR;
392 return (BTM_NO_RESOURCES);
396 #if (BTM_MAX_SCO_LINKS>0)
397 /*******************************************************************************
399 ** Function btm_send_connect_request
401 ** Description This function is called to respond to SCO connect indications
405 *******************************************************************************/
406 static tBTM_STATUS btm_send_connect_request(UINT16 acl_handle,
407 tBTM_ESCO_PARAMS *p_setup)
409 UINT16 temp_pkt_types;
413 /* Send connect request depending on version of spec */
414 if (!btm_cb.sco_cb.esco_supported)
416 if (!btsnd_hcic_add_SCO_conn (acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types)))
417 return (BTM_NO_RESOURCES);
421 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
422 btm_cb.btm_sco_pkt_types_supported);
424 /* OR in any exception packet types if at least 2.0 version of spec */
425 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
427 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
428 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
431 /* Finally, remove EDR eSCO if the remote device doesn't support it */
432 /* UPF25: Only SCO was brought up in this case */
433 btm_handle_to_acl_index(acl_handle);
434 if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS)
436 p_acl = &btm_cb.acl_db[xx];
437 if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
440 BTM_TRACE_WARNING0("BTM Remote does not support 2-EDR eSCO");
441 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 |
442 HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5);
444 if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
447 BTM_TRACE_WARNING0("BTM Remote does not support 3-EDR eSCO");
448 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
449 HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
454 BTM_TRACE_API6(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
455 p_setup->tx_bw, p_setup->rx_bw,
456 p_setup->max_latency, p_setup->voice_contfmt,
457 p_setup->retrans_effort, temp_pkt_types);
459 if (!btsnd_hcic_setup_esco_conn(acl_handle,
462 p_setup->max_latency,
463 p_setup->voice_contfmt,
464 p_setup->retrans_effort,
466 return (BTM_NO_RESOURCES);
468 p_setup->packet_types = temp_pkt_types;
471 return (BTM_CMD_STARTED);
475 /*******************************************************************************
477 ** Function btm_set_sco_ind_cback
479 ** Description This function is called to register for TCS SCO connect
484 *******************************************************************************/
485 void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb )
487 btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
490 /*******************************************************************************
492 ** Function btm_accept_sco_link
494 ** Description This function is called to respond to TCS SCO connect
499 *******************************************************************************/
500 void btm_accept_sco_link(UINT16 sco_inx, tBTM_ESCO_PARAMS *p_setup,
501 tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb)
503 #if (BTM_MAX_SCO_LINKS>0)
506 if (sco_inx >= BTM_MAX_SCO_LINKS)
508 BTM_TRACE_ERROR1("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
512 /* Link role is ignored in for this message */
513 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
514 p_sco->p_conn_cb = p_conn_cb;
515 p_sco->p_disc_cb = p_disc_cb;
516 p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
518 BTM_TRACE_DEBUG1("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
520 btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
522 btm_reject_sco_link(sco_inx);
526 /*******************************************************************************
528 ** Function btm_reject_sco_link
530 ** Description This function is called to respond to SCO connect indications
534 *******************************************************************************/
535 void btm_reject_sco_link( UINT16 sco_inx )
537 btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
538 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
541 /*******************************************************************************
543 ** Function BTM_CreateSco
545 ** Description This function is called to create an SCO connection. If the
546 ** "is_orig" flag is TRUE, the connection will be originated,
547 ** otherwise BTM will wait for the other side to connect.
549 ** NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
550 ** parameter the default packet types is used.
552 ** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
553 ** BTM_BUSY if another SCO being set up to
554 ** the same BD address
555 ** BTM_NO_RESOURCES if the max SCO limit has been reached
556 ** BTM_CMD_STARTED if the connection establishment is started.
557 ** In this case, "*p_sco_inx" is filled in
558 ** with the sco index used for the connection.
560 *******************************************************************************/
561 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig, UINT16 pkt_types,
562 UINT16 *p_sco_inx, tBTM_SCO_CB *p_conn_cb,
563 tBTM_SCO_CB *p_disc_cb)
565 #if (BTM_MAX_SCO_LINKS > 0)
566 tBTM_ESCO_PARAMS *p_setup;
567 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
569 UINT16 acl_handle = 0;
570 UINT16 temp_pkt_types;
573 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE)
580 *p_sco_inx = BTM_INVALID_SCO_INDEX;
582 /* If originating, ensure that there is an ACL connection to the BD Address */
585 if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda)) == 0xFFFF))
586 return (BTM_UNKNOWN_ADDR);
591 /* If any SCO is being established to the remote BD address, refuse this */
592 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
594 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING)
595 || (p->state == SCO_ST_PEND_UNPARK))
596 && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)))
604 /* Support only 1 wildcard BD address at a time */
605 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
607 if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known))
612 /* Now, try to find an unused control block, and kick off the SCO establishment */
613 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
615 if (p->state == SCO_ST_UNUSED)
621 /* can not create SCO link if in park mode */
622 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE)
623 if(BTM_ReadPowerMode(remote_bda, &md) == BTM_SUCCESS)
625 if (md == BTM_PM_MD_PARK || md == BTM_PM_MD_SNIFF)
627 memset( (void*)&pm, 0, sizeof(pm));
628 pm.mode = BTM_PM_MD_ACTIVE;
629 BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
630 p->state = SCO_ST_PEND_UNPARK;
633 #elif BTM_PWR_MGR_INCLUDED == TRUE
634 if( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) )
635 return (BTM_WRONG_MODE);
637 if( (BTM_ReadAclMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_ACL_MODE_PARK) )
638 return (BTM_WRONG_MODE);
641 memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
642 p->rem_bd_known = TRUE;
645 p->rem_bd_known = FALSE;
647 /* Link role is ignored in for this message */
648 if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE)
649 pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types;
651 p_setup = &p->esco.setup;
652 *p_setup = btm_cb.sco_cb.def_esco_parms;
653 p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO)
654 ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types;
656 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
657 btm_cb.btm_sco_pkt_types_supported);
659 /* OR in any exception packet types if at least 2.0 version of spec */
660 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
662 if (btm_cb.sco_cb.desired_sco_mode == HCI_LINK_TYPE_ESCO)
664 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
665 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
667 else /* Only using SCO packet types; turn off EDR also */
669 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
673 p_setup->packet_types = temp_pkt_types;
674 p->p_conn_cb = p_conn_cb;
675 p->p_disc_cb = p_disc_cb;
676 p->hci_handle = BTM_INVALID_HCI_HANDLE;
677 p->is_orig = is_orig;
679 if( p->state != SCO_ST_PEND_UNPARK )
683 /* If role change is in progress, do not proceed with SCO setup
684 * Wait till role change is complete */
685 p_acl = btm_bda_to_acl(remote_bda);
686 if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
688 BTM_TRACE_API1("Role Change is in progress for ACL handle 0x%04x",acl_handle);
689 p->state = SCO_ST_PEND_ROLECHANGE;
695 if( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE )
699 BTM_TRACE_API2("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d",
700 acl_handle, btm_cb.sco_cb.desired_sco_mode);
702 if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED)
703 return (BTM_NO_RESOURCES);
705 p->state = SCO_ST_CONNECTING;
708 p->state = SCO_ST_LISTENING;
713 return (BTM_CMD_STARTED);
718 /* If here, all SCO blocks in use */
719 return (BTM_NO_RESOURCES);
722 #if (BTM_PWR_MGR_INCLUDED == TRUE) && (BTM_SCO_WAKE_PARKED_LINK == TRUE)
723 /*******************************************************************************
725 ** Function btm_sco_chk_pend_unpark
727 ** Description This function is called by BTIF when there is a mode change
728 ** event to see if there are SCO commands waiting for the unpark.
732 *******************************************************************************/
733 void btm_sco_chk_pend_unpark (UINT8 hci_status, UINT16 hci_handle)
735 #if (BTM_MAX_SCO_LINKS>0)
738 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
740 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
742 if ((p->state == SCO_ST_PEND_UNPARK) &&
743 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
746 BTM_TRACE_API3("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
747 acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status);
749 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
750 p->state = SCO_ST_CONNECTING;
757 /*******************************************************************************
759 ** Function btm_sco_chk_pend_rolechange
761 ** Description This function is called by BTIF when there is a role change
762 ** event to see if there are SCO commands waiting for the role change.
766 *******************************************************************************/
767 void btm_sco_chk_pend_rolechange (UINT16 hci_handle)
769 #if (BTM_MAX_SCO_LINKS>0)
772 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
774 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
776 if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
777 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr)) == hci_handle))
780 BTM_TRACE_API1("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
782 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
783 p->state = SCO_ST_CONNECTING;
789 /*******************************************************************************
791 ** Function btm_sco_conn_req
793 ** Description This function is called by BTIF when an SCO connection
794 ** request is received from a remote.
798 *******************************************************************************/
799 void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, UINT8 link_type)
801 #if (BTM_MAX_SCO_LINKS>0)
802 tSCO_CB *p_sco = &btm_cb.sco_cb;
803 tSCO_CONN *p = &p_sco->sco_db[0];
805 tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
807 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
810 * If the sco state is in the SCO_ST_CONNECTING state, we still need
811 * to return accept sco to avoid race conditon for sco creation
813 if (((p->state == SCO_ST_LISTENING && p->rem_bd_known) || p->state == SCO_ST_CONNECTING)
814 && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
816 /* If this guy was a wildcard, he is not one any more */
817 p->rem_bd_known = TRUE;
818 p->esco.data.link_type = link_type;
819 p->state = SCO_ST_W4_CONN_RSP;
820 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
822 /* If no callback, auto-accept the connection if packet types match */
823 if (!p->esco.p_esco_cback)
825 /* If requesting eSCO reject if default parameters are SCO only */
826 if ((link_type == BTM_LINK_TYPE_ESCO
827 && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK)
828 && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK)
829 == BTM_SCO_EXCEPTION_PKTS_MASK))
831 /* Reject request if SCO is desired but no SCO packets delected */
832 || (link_type == BTM_LINK_TYPE_SCO
833 && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK)))
835 btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
837 else /* Accept the request */
839 btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
842 else /* Notify upper layer of connect indication */
844 memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
845 memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
846 evt_data.link_type = link_type;
847 evt_data.sco_inx = xx;
848 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data);
856 if (btm_cb.sco_cb.app_sco_ind_cb)
858 /* Now, try to find an unused control block */
859 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
861 if (p->state == SCO_ST_UNUSED)
864 p->state = SCO_ST_LISTENING;
866 p->esco.data.link_type = link_type;
867 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
868 p->rem_bd_known = TRUE;
872 if( xx < BTM_MAX_SCO_LINKS)
874 btm_cb.sco_cb.app_sco_ind_cb(xx);
880 /* If here, no one wants the SCO connection. Reject it */
881 BTM_TRACE_WARNING0("btm_sco_conn_req: No one wants this SCO connection; rejecting it");
882 btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
885 /*******************************************************************************
887 ** Function btm_sco_connected
889 ** Description This function is called by BTIF when an (e)SCO connection
894 *******************************************************************************/
895 void btm_sco_connected (UINT8 hci_status, BD_ADDR bda, UINT16 hci_handle,
896 tBTM_ESCO_DATA *p_esco_data)
898 #if (BTM_MAX_SCO_LINKS>0)
899 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
902 tBTM_CHG_ESCO_PARAMS parms;
905 btm_cb.sco_cb.sco_disc_reason = hci_status;
907 #if (BTM_MAX_SCO_LINKS>0)
908 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
910 if (((p->state == SCO_ST_CONNECTING) ||
911 (p->state == SCO_ST_LISTENING) ||
912 (p->state == SCO_ST_W4_CONN_RSP))
914 && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
916 if (hci_status != HCI_SUCCESS)
918 /* Report the error if originator, otherwise remain in Listen mode */
921 /* If role switch is pending, we need try again after role switch is complete */
922 if(hci_status == HCI_ERR_ROLE_SWITCH_PENDING)
924 BTM_TRACE_API1("Role Change pending for HCI handle 0x%04x",hci_handle);
925 p->state = SCO_ST_PEND_ROLECHANGE;
927 /* avoid calling disconnect callback because of sco creation race */
928 else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION)
930 p->state = SCO_ST_UNUSED;
936 /* Notify the upper layer that incoming sco connection has failed. */
937 if (p->state == SCO_ST_CONNECTING)
939 p->state = SCO_ST_UNUSED;
943 p->state = SCO_ST_LISTENING;
949 if (p->state == SCO_ST_LISTENING)
952 p->state = SCO_ST_CONNECTED;
953 p->hci_handle = hci_handle;
955 if (!btm_cb.sco_cb.esco_supported)
957 p->esco.data.link_type = BTM_LINK_TYPE_SCO;
960 parms.packet_types = p->esco.setup.packet_types;
961 /* Keep the other parameters the same for SCO */
962 parms.max_latency = p->esco.setup.max_latency;
963 parms.retrans_effort = p->esco.setup.retrans_effort;
965 BTM_ChangeEScoLinkParms(xx, &parms);
971 p->esco.data = *p_esco_data;
983 /*******************************************************************************
985 ** Function btm_find_scb_by_handle
987 ** Description Look through all active SCO connection for a match based on the
990 ** Returns index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
993 *******************************************************************************/
994 UINT16 btm_find_scb_by_handle (UINT16 handle)
997 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
999 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1001 if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle))
1007 /* If here, no match found */
1011 /*******************************************************************************
1013 ** Function BTM_RemoveSco
1015 ** Description This function is called to remove a specific SCO connection.
1017 ** Returns status of the operation
1019 *******************************************************************************/
1020 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx)
1022 #if (BTM_MAX_SCO_LINKS>0)
1023 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1026 /* Validity check */
1027 if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
1028 return (BTM_UNKNOWN_ADDR);
1030 /* If no HCI handle, simply drop the connection and return */
1031 if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK)
1033 p->hci_handle = BTM_INVALID_HCI_HANDLE;
1034 p->state = SCO_ST_UNUSED;
1035 p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
1036 return (BTM_SUCCESS);
1039 tempstate = p->state;
1040 p->state = SCO_ST_DISCONNECTING;
1042 if (!btsnd_hcic_disconnect (p->hci_handle, HCI_ERR_PEER_USER))
1044 p->state = tempstate;
1045 return (BTM_NO_RESOURCES);
1048 return (BTM_CMD_STARTED);
1050 return (BTM_NO_RESOURCES);
1054 /*******************************************************************************
1056 ** Function btm_remove_sco_links
1058 ** Description This function is called to remove all sco links for an ACL link.
1062 *******************************************************************************/
1063 void btm_remove_sco_links (BD_ADDR bda)
1065 #if (BTM_MAX_SCO_LINKS>0)
1066 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1069 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1071 if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
1079 /*******************************************************************************
1081 ** Function btm_sco_removed
1083 ** Description This function is called by BTIF when an SCO connection
1088 *******************************************************************************/
1089 void btm_sco_removed (UINT16 hci_handle, UINT8 reason)
1091 #if (BTM_MAX_SCO_LINKS>0)
1092 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1096 btm_cb.sco_cb.sco_disc_reason = reason;
1098 #if (BTM_MAX_SCO_LINKS>0)
1099 p = &btm_cb.sco_cb.sco_db[0];
1100 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1102 if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle))
1104 btm_sco_flush_sco_data(xx);
1106 p->state = SCO_ST_UNUSED;
1107 p->hci_handle = BTM_INVALID_HCI_HANDLE;
1108 p->rem_bd_known = FALSE;
1109 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1110 (*p->p_disc_cb)(xx);
1119 /*******************************************************************************
1121 ** Function btm_sco_acl_removed
1123 ** Description This function is called when an ACL connection is
1124 ** removed. If the BD address is NULL, it is assumed that
1125 ** the local device is down, and all SCO links are removed.
1126 ** If a specific BD address is passed, only SCO connections
1127 ** to that BD address are removed.
1131 *******************************************************************************/
1132 void btm_sco_acl_removed (BD_ADDR bda)
1134 #if (BTM_MAX_SCO_LINKS>0)
1135 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1138 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1140 if (p->state != SCO_ST_UNUSED)
1142 if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known))
1144 btm_sco_flush_sco_data(xx);
1146 p->state = SCO_ST_UNUSED;
1147 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1148 (*p->p_disc_cb)(xx);
1156 /*******************************************************************************
1158 ** Function BTM_SetScoPacketTypes
1160 ** Description This function is called to set the packet types used for
1161 ** a specific SCO connection,
1163 ** Parameters pkt_types - One or more of the following
1164 ** BTM_SCO_PKT_TYPES_MASK_HV1
1165 ** BTM_SCO_PKT_TYPES_MASK_HV2
1166 ** BTM_SCO_PKT_TYPES_MASK_HV3
1167 ** BTM_SCO_PKT_TYPES_MASK_EV3
1168 ** BTM_SCO_PKT_TYPES_MASK_EV4
1169 ** BTM_SCO_PKT_TYPES_MASK_EV5
1170 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1171 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1172 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1173 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1175 ** BTM_SCO_LINK_ALL_MASK - enables all supported types
1177 ** Returns status of the operation
1179 *******************************************************************************/
1180 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types)
1182 #if (BTM_MAX_SCO_LINKS>0)
1183 tBTM_CHG_ESCO_PARAMS parms;
1186 /* Validity check */
1187 if (sco_inx >= BTM_MAX_SCO_LINKS)
1188 return (BTM_UNKNOWN_ADDR);
1190 p = &btm_cb.sco_cb.sco_db[sco_inx];
1191 parms.packet_types = pkt_types;
1193 /* Keep the other parameters the same for SCO */
1194 parms.max_latency = p->esco.setup.max_latency;
1195 parms.retrans_effort = p->esco.setup.retrans_effort;
1197 return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
1199 return (BTM_UNKNOWN_ADDR);
1204 /*******************************************************************************
1206 ** Function BTM_ReadScoPacketTypes
1208 ** Description This function is read the packet types used for a specific
1211 ** Returns Packet types supported for the connection
1212 ** One or more of the following (bitmask):
1213 ** BTM_SCO_PKT_TYPES_MASK_HV1
1214 ** BTM_SCO_PKT_TYPES_MASK_HV2
1215 ** BTM_SCO_PKT_TYPES_MASK_HV3
1216 ** BTM_SCO_PKT_TYPES_MASK_EV3
1217 ** BTM_SCO_PKT_TYPES_MASK_EV4
1218 ** BTM_SCO_PKT_TYPES_MASK_EV5
1219 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1220 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1221 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1222 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1224 *******************************************************************************/
1225 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx)
1227 #if (BTM_MAX_SCO_LINKS>0)
1228 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1230 /* Validity check */
1231 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1232 return (p->esco.setup.packet_types);
1240 /*******************************************************************************
1242 ** Function BTM_ReadScoDiscReason
1244 ** Description This function is returns the reason why an (e)SCO connection
1245 ** has been removed. It contains the value until read, or until
1246 ** another (e)SCO connection has disconnected.
1248 ** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
1250 *******************************************************************************/
1251 UINT16 BTM_ReadScoDiscReason (void)
1253 UINT16 res = btm_cb.sco_cb.sco_disc_reason;
1254 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
1258 /*******************************************************************************
1260 ** Function BTM_ReadDeviceScoPacketTypes
1262 ** Description This function is read the SCO packet types that
1263 ** the device supports.
1265 ** Returns Packet types supported by the device.
1266 ** One or more of the following (bitmask):
1267 ** BTM_SCO_PKT_TYPES_MASK_HV1
1268 ** BTM_SCO_PKT_TYPES_MASK_HV2
1269 ** BTM_SCO_PKT_TYPES_MASK_HV3
1270 ** BTM_SCO_PKT_TYPES_MASK_EV3
1271 ** BTM_SCO_PKT_TYPES_MASK_EV4
1272 ** BTM_SCO_PKT_TYPES_MASK_EV5
1273 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1274 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1275 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1276 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1278 *******************************************************************************/
1279 UINT16 BTM_ReadDeviceScoPacketTypes (void)
1281 return (btm_cb.btm_sco_pkt_types_supported);
1284 /*******************************************************************************
1286 ** Function BTM_ReadScoHandle
1288 ** Description This function is used to read the HCI handle used for a specific
1291 ** Returns handle for the connection, or 0xFFFF if invalid SCO index.
1293 *******************************************************************************/
1294 UINT16 BTM_ReadScoHandle (UINT16 sco_inx)
1296 #if (BTM_MAX_SCO_LINKS>0)
1297 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1299 /* Validity check */
1300 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1301 return (p->hci_handle);
1303 return (BTM_INVALID_HCI_HANDLE);
1305 return (BTM_INVALID_HCI_HANDLE);
1309 /*******************************************************************************
1311 ** Function BTM_ReadScoBdAddr
1313 ** Description This function is read the remote BD Address for a specific
1316 ** Returns pointer to BD address or NULL if not known
1318 *******************************************************************************/
1319 UINT8 *BTM_ReadScoBdAddr (UINT16 sco_inx)
1321 #if (BTM_MAX_SCO_LINKS>0)
1322 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1324 /* Validity check */
1325 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1326 return (p->esco.data.bd_addr);
1334 /*******************************************************************************
1336 ** Function BTM_SetEScoMode
1338 ** Description This function sets up the negotiated parameters for SCO or
1339 ** eSCO, and sets as the default mode used for outgoing calls to
1340 ** BTM_CreateSco. It does not change any currently active (e)SCO links.
1341 ** Note: Incoming (e)SCO connections will always use packet types
1342 ** supported by the controller. If eSCO is not desired the
1343 ** feature should be disabled in the controller's feature mask.
1345 ** Returns BTM_SUCCESS if the successful.
1346 ** BTM_BUSY if there are one or more active (e)SCO links.
1348 *******************************************************************************/
1349 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
1351 tSCO_CB *p_esco = &btm_cb.sco_cb;
1352 tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms;
1354 if (p_esco->esco_supported)
1358 if (sco_mode == BTM_LINK_TYPE_ESCO)
1359 *p_def = *p_parms; /* Save as the default parameters */
1360 else /* Load only the SCO packet types */
1362 p_def->packet_types = p_parms->packet_types;
1363 p_def->tx_bw = BTM_64KBITS_RATE;
1364 p_def->rx_bw = BTM_64KBITS_RATE;
1365 p_def->max_latency = 0x000a;
1366 p_def->voice_contfmt = 0x0060;
1367 p_def->retrans_effort = 0;
1369 /* OR in any exception packet types if at least 2.0 version of spec */
1370 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
1372 p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
1376 p_esco->desired_sco_mode = sco_mode;
1377 BTM_TRACE_API1("BTM_SetEScoMode -> mode %d", sco_mode);
1381 p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO;
1382 p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
1383 p_def->retrans_effort = 0;
1384 BTM_TRACE_API0("BTM_SetEScoMode -> mode SCO (eSCO not supported)");
1387 BTM_TRACE_DEBUG6(" txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x",
1388 p_def->tx_bw, p_def->rx_bw, p_def->max_latency,
1389 p_def->voice_contfmt, p_def->packet_types,
1390 p_def->retrans_effort);
1392 return (BTM_SUCCESS);
1397 /*******************************************************************************
1399 ** Function BTM_RegForEScoEvts
1401 ** Description This function registers a SCO event callback with the
1402 ** specified instance. It should be used to received
1403 ** connection indication events and change of link parameter
1406 ** Returns BTM_SUCCESS if the successful.
1407 ** BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1408 ** BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1409 ** later or does not support eSCO.
1411 *******************************************************************************/
1412 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
1414 #if (BTM_MAX_SCO_LINKS>0)
1415 if (!btm_cb.sco_cb.esco_supported)
1417 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1418 return (BTM_MODE_UNSUPPORTED);
1421 if (sco_inx < BTM_MAX_SCO_LINKS &&
1422 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED)
1424 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1425 return (BTM_SUCCESS);
1427 return (BTM_ILLEGAL_VALUE);
1429 return (BTM_MODE_UNSUPPORTED);
1433 /*******************************************************************************
1435 ** Function BTM_ReadEScoLinkParms
1437 ** Description This function returns the current eSCO link parameters for
1438 ** the specified handle. This can be called anytime a connection
1439 ** is active, but is typically called after receiving the SCO
1442 ** Note: If called over a 1.1 controller, only the packet types
1443 ** field has meaning.
1445 ** Returns BTM_SUCCESS if returned data is valid connection.
1446 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
1448 *******************************************************************************/
1449 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms)
1451 #if (BTM_MAX_SCO_LINKS>0)
1454 BTM_TRACE_API1("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx);
1456 if (sco_inx < BTM_MAX_SCO_LINKS &&
1457 btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED)
1459 *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
1460 return (BTM_SUCCESS);
1463 if (sco_inx == BTM_FIRST_ACTIVE_SCO_INDEX)
1465 for (index = 0; index < BTM_MAX_SCO_LINKS; index++)
1467 if (btm_cb.sco_cb.sco_db[index].state >= SCO_ST_CONNECTED)
1469 BTM_TRACE_API1("BTM_ReadEScoLinkParms the first active SCO index is %d",index);
1470 *p_parms = btm_cb.sco_cb.sco_db[index].esco.data;
1471 return (BTM_SUCCESS);
1478 BTM_TRACE_API0("BTM_ReadEScoLinkParms cannot find the SCO index!");
1479 memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
1480 return (BTM_WRONG_MODE);
1483 /*******************************************************************************
1485 ** Function BTM_ChangeEScoLinkParms
1487 ** Description This function requests renegotiation of the parameters on
1488 ** the current eSCO Link. If any of the changes are accepted
1489 ** by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1490 ** the tBTM_ESCO_CBACK function with the current settings of
1491 ** the link. The callback is registered through the call to
1494 ** Note: If called over a SCO link (including 1.1 controller),
1495 ** a change packet type request is sent out instead.
1497 ** Returns BTM_CMD_STARTED if command is successfully initiated.
1498 ** BTM_NO_RESOURCES - not enough resources to initiate command.
1499 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
1501 *******************************************************************************/
1502 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
1504 #if (BTM_MAX_SCO_LINKS>0)
1505 tBTM_ESCO_PARAMS *p_setup;
1507 UINT16 temp_pkt_types;
1509 /* Make sure sco handle is valid and on an active link */
1510 if (sco_inx >= BTM_MAX_SCO_LINKS ||
1511 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1512 return (BTM_WRONG_MODE);
1514 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1515 p_setup = &p_sco->esco.setup;
1517 /* If SCO connection OR eSCO not supported just send change packet types */
1518 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1519 !btm_cb.sco_cb.esco_supported)
1521 p_setup->packet_types = p_parms->packet_types &
1522 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1525 BTM_TRACE_API2("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x",
1526 p_sco->hci_handle, p_setup->packet_types);
1528 if (!btsnd_hcic_change_conn_type (p_sco->hci_handle,
1529 BTM_ESCO_2_SCO(p_setup->packet_types)))
1530 return (BTM_NO_RESOURCES);
1534 temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1535 btm_cb.btm_sco_pkt_types_supported);
1537 /* OR in any exception packet types if at least 2.0 version of spec */
1538 if (btm_cb.devcb.local_version.hci_version >= HCI_PROTO_VERSION_2_0)
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));
1544 BTM_TRACE_API1("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle);
1545 BTM_TRACE_API6(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
1546 p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency,
1547 p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types);
1549 /* When changing an existing link, only change latency, retrans, and pkts */
1550 if (!btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw,
1551 p_setup->rx_bw, p_parms->max_latency,
1552 p_setup->voice_contfmt,
1553 p_parms->retrans_effort,
1555 return (BTM_NO_RESOURCES);
1557 p_parms->packet_types = temp_pkt_types;
1560 return (BTM_CMD_STARTED);
1562 return (BTM_WRONG_MODE);
1566 /*******************************************************************************
1568 ** Function BTM_EScoConnRsp
1570 ** Description This function is called upon receipt of an (e)SCO connection
1571 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1572 ** the request. Parameters used to negotiate eSCO links.
1573 ** If p_parms is NULL, then values set through BTM_SetEScoMode
1575 ** If the link type of the incoming request is SCO, then only
1576 ** the tx_bw, max_latency, content format, and packet_types are
1577 ** valid. The hci_status parameter should be
1578 ** ([0x0] to accept, [0x0d..0x0f] to reject)
1583 *******************************************************************************/
1584 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms)
1586 #if (BTM_MAX_SCO_LINKS>0)
1587 if (sco_inx < BTM_MAX_SCO_LINKS &&
1588 btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP)
1590 btm_esco_conn_rsp(sco_inx, hci_status,
1591 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr,
1597 /*******************************************************************************
1599 ** Function btm_read_def_esco_mode
1601 ** Description This function copies the current default esco settings into
1602 ** the return buffer.
1604 ** Returns tBTM_SCO_TYPE
1606 *******************************************************************************/
1607 tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms)
1609 #if (BTM_MAX_SCO_LINKS>0)
1610 *p_parms = btm_cb.sco_cb.def_esco_parms;
1611 return btm_cb.sco_cb.desired_sco_mode;
1613 return BTM_LINK_TYPE_SCO;
1617 /*******************************************************************************
1619 ** Function btm_esco_proc_conn_chg
1621 ** Description This function is called by BTIF when an SCO connection
1626 *******************************************************************************/
1627 void btm_esco_proc_conn_chg (UINT8 status, UINT16 handle, UINT8 tx_interval,
1628 UINT8 retrans_window, UINT16 rx_pkt_len,
1631 #if (BTM_MAX_SCO_LINKS>0)
1632 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1633 tBTM_CHG_ESCO_EVT_DATA data;
1636 BTM_TRACE_EVENT2("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
1639 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1641 if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle)
1643 /* If upper layer wants notification */
1644 if (p->esco.p_esco_cback)
1646 memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
1647 data.hci_status = status;
1649 data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
1650 data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
1651 data.tx_interval = p->esco.data.tx_interval = tx_interval;
1652 data.retrans_window = p->esco.data.retrans_window = retrans_window;
1654 (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT,
1655 (tBTM_ESCO_EVT_DATA *)&data);
1663 /*******************************************************************************
1665 ** Function btm_is_sco_active
1667 ** Description This function is called to see if a SCO handle is already in
1672 *******************************************************************************/
1673 BOOLEAN btm_is_sco_active (UINT16 handle)
1675 #if (BTM_MAX_SCO_LINKS>0)
1677 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1679 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1681 if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED)
1688 /*******************************************************************************
1690 ** Function BTM_GetNumScoLinks
1692 ** Description This function returns the number of active sco links.
1696 *******************************************************************************/
1697 UINT8 BTM_GetNumScoLinks (void)
1699 #if (BTM_MAX_SCO_LINKS>0)
1700 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1704 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1708 case SCO_ST_W4_CONN_RSP:
1709 case SCO_ST_CONNECTING:
1710 case SCO_ST_CONNECTED:
1711 case SCO_ST_DISCONNECTING:
1712 case SCO_ST_PEND_UNPARK:
1723 /*******************************************************************************
1725 ** Function btm_is_sco_active_by_bdaddr
1727 ** Description This function is called to see if a SCO active to a bd address.
1731 *******************************************************************************/
1732 BOOLEAN btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda)
1734 #if (BTM_MAX_SCO_LINKS>0)
1736 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1738 /* If any SCO is being established to the remote BD address, refuse this */
1739 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1741 if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED))
1749 #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
1751 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, BOOLEAN is_orig,
1752 UINT16 pkt_types, UINT16 *p_sco_inx,
1753 tBTM_SCO_CB *p_conn_cb,
1754 tBTM_SCO_CB *p_disc_cb) {return (BTM_NO_RESOURCES);}
1755 tBTM_STATUS BTM_RemoveSco (UINT16 sco_inx) {return (BTM_NO_RESOURCES);}
1756 tBTM_STATUS BTM_SetScoPacketTypes (UINT16 sco_inx, UINT16 pkt_types) {return (BTM_NO_RESOURCES);}
1757 UINT16 BTM_ReadScoPacketTypes (UINT16 sco_inx) {return (0);}
1758 UINT16 BTM_ReadDeviceScoPacketTypes (void) {return (0);}
1759 UINT16 BTM_ReadScoHandle (UINT16 sco_inx) {return (BTM_INVALID_HCI_HANDLE);}
1760 UINT8 *BTM_ReadScoBdAddr(UINT16 sco_inx) {return((UINT8 *) NULL);}
1761 UINT16 BTM_ReadScoDiscReason (void) {return (BTM_INVALID_SCO_DISC_REASON);}
1762 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) {return (BTM_MODE_UNSUPPORTED);}
1763 tBTM_STATUS BTM_RegForEScoEvts (UINT16 sco_inx, tBTM_ESCO_CBACK *p_esco_cback) { return (BTM_ILLEGAL_VALUE);}
1764 tBTM_STATUS BTM_ReadEScoLinkParms (UINT16 sco_inx, tBTM_ESCO_DATA *p_parms) { return (BTM_MODE_UNSUPPORTED);}
1765 tBTM_STATUS BTM_ChangeEScoLinkParms (UINT16 sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms) { return (BTM_MODE_UNSUPPORTED);}
1766 void BTM_EScoConnRsp (UINT16 sco_inx, UINT8 hci_status, tBTM_ESCO_PARAMS *p_parms) {}
1767 UINT8 BTM_GetNumScoLinks (void) {return (0);}
1769 #endif /* If SCO is being used */