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"
29 #include "bt_common.h"
37 #include "device/include/controller.h"
40 #if (BTM_SCO_INCLUDED == TRUE)
42 /********************************************************************************/
43 /* L O C A L D A T A D E F I N I T I O N S */
44 /********************************************************************************/
46 #define SCO_ST_UNUSED 0
47 #define SCO_ST_LISTENING 1
48 #define SCO_ST_W4_CONN_RSP 2
49 #define SCO_ST_CONNECTING 3
50 #define SCO_ST_CONNECTED 4
51 #define SCO_ST_DISCONNECTING 5
52 #define SCO_ST_PEND_UNPARK 6
53 #define SCO_ST_PEND_ROLECHANGE 7
54 #define SCO_ST_PEND_MODECHANGE 8
56 /********************************************************************************/
57 /* L O C A L F U N C T I O N P R O T O T Y P E S */
58 /********************************************************************************/
60 static const tBTM_ESCO_PARAMS btm_esco_defaults =
62 BTM_64KBITS_RATE, /* TX Bandwidth (64 kbits/sec) */
63 BTM_64KBITS_RATE, /* RX Bandwidth (64 kbits/sec) */
64 0x000c, /* 12 ms (HS/HF can use EV3, 2-EV3, 3-EV3) */
65 0x0060, /* Inp Linear, Air CVSD, 2s Comp, 16bit */
66 (BTM_SCO_PKT_TYPES_MASK_HV1 + /* Packet Types */
67 BTM_SCO_PKT_TYPES_MASK_HV2 +
68 BTM_SCO_PKT_TYPES_MASK_HV3 +
69 BTM_SCO_PKT_TYPES_MASK_EV3 +
70 BTM_SCO_PKT_TYPES_MASK_EV4 +
71 BTM_SCO_PKT_TYPES_MASK_EV5),
72 BTM_ESCO_RETRANS_QUALITY /* Retransmission Effort */
75 /*******************************************************************************
77 ** Function btm_sco_flush_sco_data
79 ** Description This function is called to flush the SCO data for this channel.
83 *******************************************************************************/
84 #if (BTM_SCO_HCI_INCLUDED == TRUE && BTM_MAX_SCO_LINKS>0)
85 void btm_sco_flush_sco_data(uint16_t sco_inx)
90 if (sco_inx < BTM_MAX_SCO_LINKS)
92 p = &btm_cb.sco_cb.sco_db[sco_inx];
93 while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p->xmit_data_q)) != NULL)
99 void btm_sco_flush_sco_data(UNUSED_ATTR uint16_t sco_inx)
103 /*******************************************************************************
105 ** Function btm_sco_init
107 ** Description This function is called at BTM startup to initialize
111 *******************************************************************************/
112 void btm_sco_init (void)
114 #if (BTM_SCO_HCI_INCLUDED == TRUE)
115 for (int i = 0; i < BTM_MAX_SCO_LINKS; i++)
116 btm_cb.sco_cb.sco_db[i].xmit_data_q = fixed_queue_new(SIZE_MAX);
119 /* Initialize nonzero defaults */
120 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
122 btm_cb.sco_cb.def_esco_parms = btm_esco_defaults; /* Initialize with defaults */
123 btm_cb.sco_cb.desired_sco_mode = BTM_DEFAULT_SCO_MODE;
126 /*******************************************************************************
128 ** Function btm_esco_conn_rsp
130 ** Description This function is called upon receipt of an (e)SCO connection
131 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
132 ** the request. Parameters used to negotiate eSCO links.
133 ** If p_parms is NULL, then default values are used.
134 ** If the link type of the incoming request is SCO, then only
135 ** the tx_bw, max_latency, content format, and packet_types are
136 ** valid. The hci_status parameter should be
137 ** ([0x0] to accept, [0x0d..0x0f] to reject)
141 *******************************************************************************/
142 static void btm_esco_conn_rsp (uint16_t sco_inx, uint8_t hci_status, BD_ADDR bda,
143 tBTM_ESCO_PARAMS *p_parms)
145 #if (BTM_MAX_SCO_LINKS>0)
146 tSCO_CONN *p_sco = NULL;
147 tBTM_ESCO_PARAMS *p_setup;
148 uint16_t temp_pkt_types;
150 if (sco_inx < BTM_MAX_SCO_LINKS)
151 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
153 /* Reject the connect request if refused by caller or wrong state */
154 if (hci_status != HCI_SUCCESS || p_sco == NULL)
158 p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
162 if (!btm_cb.sco_cb.esco_supported)
164 btsnd_hcic_reject_conn(bda, hci_status);
168 btsnd_hcic_reject_esco_conn(bda, hci_status);
171 else /* Connection is being accepted */
173 p_sco->state = SCO_ST_CONNECTING;
174 p_setup = &p_sco->esco.setup;
175 /* If parameters not specified use the default */
178 else /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
180 *p_setup = btm_cb.sco_cb.def_esco_parms;
183 temp_pkt_types = (p_setup->packet_types &
184 BTM_SCO_SUPPORTED_PKTS_MASK &
185 btm_cb.btm_sco_pkt_types_supported);
187 /* Make sure at least one eSCO packet type is sent, else might confuse peer */
188 /* Taking this out to confirm with BQB tests
189 ** Real application would like to include this though, as many devices
190 ** do not retry with SCO only if an eSCO connection fails.
191 if (!(temp_pkt_types & BTM_ESCO_LINK_ONLY_MASK))
193 temp_pkt_types |= BTM_SCO_PKT_TYPES_MASK_EV3;
196 /* If SCO request, remove eSCO packet types (conformance) */
197 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO)
199 temp_pkt_types &= BTM_SCO_LINK_ONLY_MASK;
200 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
204 /* OR in any exception packet types */
205 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
206 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
209 btsnd_hcic_accept_esco_conn(bda, p_setup->tx_bw, p_setup->rx_bw,
210 p_setup->max_latency, p_setup->voice_contfmt,
211 p_setup->retrans_effort, temp_pkt_types);
212 p_setup->packet_types = temp_pkt_types;
218 #if (BTM_SCO_HCI_INCLUDED == TRUE)
219 /*******************************************************************************
221 ** Function btm_sco_check_send_pkts
223 ** Description This function is called to check if it can send packets
224 ** to the Host Controller.
228 *******************************************************************************/
229 void btm_sco_check_send_pkts (uint16_t sco_inx)
231 tSCO_CB *p_cb = &btm_cb.sco_cb;
232 tSCO_CONN *p_ccb = &p_cb->sco_db[sco_inx];
234 /* If there is data to send, send it now */
236 while ((p_buf = (BT_HDR *)fixed_queue_try_dequeue(p_ccb->xmit_data_q)) != NULL)
238 #if (BTM_SCO_HCI_DEBUG == TRUE)
239 BTM_TRACE_DEBUG("btm: [%d] buf in xmit_data_q",
240 fixed_queue_length(p_ccb->xmit_data_q) + 1);
243 HCI_SCO_DATA_TO_LOWER(p_buf);
246 #endif /* BTM_SCO_HCI_INCLUDED == TRUE */
248 /*******************************************************************************
250 ** Function btm_route_sco_data
252 ** Description Route received SCO data.
256 *******************************************************************************/
257 void btm_route_sco_data(BT_HDR *p_msg)
259 #if (BTM_SCO_HCI_INCLUDED == TRUE)
260 uint16_t sco_inx, handle;
261 uint8_t *p = (uint8_t *)(p_msg + 1) + p_msg->offset;
262 uint8_t pkt_size = 0;
263 uint8_t pkt_status = 0;
265 /* Extract Packet_Status_Flag and handle */
266 STREAM_TO_UINT16 (handle, p);
267 pkt_status = HCID_GET_EVENT(handle);
268 handle = HCID_GET_HANDLE (handle);
270 STREAM_TO_UINT8 (pkt_size, p);
272 if ((sco_inx = btm_find_scb_by_handle(handle)) != BTM_MAX_SCO_LINKS )
274 /* send data callback */
275 if (!btm_cb.sco_cb.p_data_cb )
276 /* if no data callback registered, just free the buffer */
280 (*btm_cb.sco_cb.p_data_cb)(sco_inx, p_msg, (tBTM_SCO_DATA_FLAG) pkt_status);
283 else /* no mapping handle SCO connection is active, free the buffer */
292 /*******************************************************************************
294 ** Function BTM_WriteScoData
296 ** Description This function write SCO data to a specified instance. The data
297 ** to be written p_buf needs to carry an offset of
298 ** HCI_SCO_PREAMBLE_SIZE bytes, and the data length can not
299 ** exceed BTM_SCO_DATA_SIZE_MAX bytes, whose default value is set
300 ** to 60 and is configurable. Data longer than the maximum bytes
301 ** will be truncated.
303 ** Returns BTM_SUCCESS: data write is successful
304 ** BTM_ILLEGAL_VALUE: SCO data contains illegal offset value.
305 ** BTM_SCO_BAD_LENGTH: SCO data length exceeds the max SCO packet
307 ** BTM_NO_RESOURCES: no resources.
308 ** BTM_UNKNOWN_ADDR: unknown SCO connection handle, or SCO is not
312 *******************************************************************************/
313 #if (BTM_SCO_HCI_INCLUDED == TRUE && BTM_MAX_SCO_LINKS > 0)
314 tBTM_STATUS BTM_WriteScoData (uint16_t sco_inx, BT_HDR *p_buf)
316 tSCO_CONN *p_ccb = &btm_cb.sco_cb.sco_db[sco_inx];
318 tBTM_STATUS status = BTM_SUCCESS;
320 if (sco_inx < BTM_MAX_SCO_LINKS && btm_cb.sco_cb.p_data_cb &&
321 p_ccb->state == SCO_ST_CONNECTED)
323 /* Ensure we have enough space in the buffer for the SCO and HCI headers */
324 if (p_buf->offset < HCI_SCO_PREAMBLE_SIZE)
326 BTM_TRACE_ERROR ("BTM SCO - cannot send buffer, offset: %d", p_buf->offset);
328 status = BTM_ILLEGAL_VALUE;
330 else /* write HCI header */
332 /* Step back 3 bytes to add the headers */
333 p_buf->offset -= HCI_SCO_PREAMBLE_SIZE;
334 /* Set the pointer to the beginning of the data */
335 p = (uint8_t *)(p_buf + 1) + p_buf->offset;
337 UINT16_TO_STREAM (p, p_ccb->hci_handle);
338 /* only sent the first BTM_SCO_DATA_SIZE_MAX bytes data if more than max,
339 and set warning status */
340 if (p_buf->len > BTM_SCO_DATA_SIZE_MAX)
342 p_buf->len = BTM_SCO_DATA_SIZE_MAX;
343 status = BTM_SCO_BAD_LENGTH;
346 UINT8_TO_STREAM (p, (uint8_t)p_buf->len);
347 p_buf->len += HCI_SCO_PREAMBLE_SIZE;
349 fixed_queue_enqueue(p_ccb->xmit_data_q, p_buf);
351 btm_sco_check_send_pkts (sco_inx);
358 BTM_TRACE_WARNING ("BTM_WriteScoData, invalid sco index: %d at state [%d]",
359 sco_inx, btm_cb.sco_cb.sco_db[sco_inx].state);
360 status = BTM_UNKNOWN_ADDR;
367 tBTM_STATUS BTM_WriteScoData(UNUSED_ATTR uint16_t sco_inx,
368 UNUSED_ATTR BT_HDR *p_buf)
370 return (BTM_NO_RESOURCES);
374 #if (BTM_MAX_SCO_LINKS>0)
375 /*******************************************************************************
377 ** Function btm_send_connect_request
379 ** Description This function is called to respond to SCO connect indications
383 *******************************************************************************/
384 static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle,
385 tBTM_ESCO_PARAMS *p_setup)
387 uint16_t temp_pkt_types;
391 /* Send connect request depending on version of spec */
392 if (!btm_cb.sco_cb.esco_supported)
394 btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types));
398 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
399 btm_cb.btm_sco_pkt_types_supported);
401 /* OR in any exception packet types */
402 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
403 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
405 /* Finally, remove EDR eSCO if the remote device doesn't support it */
406 /* UPF25: Only SCO was brought up in this case */
407 btm_handle_to_acl_index(acl_handle);
408 if ((xx = btm_handle_to_acl_index(acl_handle)) < MAX_L2CAP_LINKS)
410 p_acl = &btm_cb.acl_db[xx];
411 if (!HCI_EDR_ESCO_2MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
414 BTM_TRACE_WARNING("BTM Remote does not support 2-EDR eSCO");
415 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_2_EV3 |
416 HCI_ESCO_PKT_TYPES_MASK_NO_2_EV5);
418 if (!HCI_EDR_ESCO_3MPS_SUPPORTED(p_acl->peer_lmp_features[HCI_EXT_FEATURES_PAGE_0]))
421 BTM_TRACE_WARNING("BTM Remote does not support 3-EDR eSCO");
422 temp_pkt_types |= (HCI_ESCO_PKT_TYPES_MASK_NO_3_EV3 |
423 HCI_ESCO_PKT_TYPES_MASK_NO_3_EV5);
426 /* Check to see if BR/EDR Secure Connections is being used
427 ** If so, we cannot use SCO-only packet types (HFP 1.7)
429 if (BTM_BothEndsSupportSecureConnections(p_acl->remote_addr))
431 temp_pkt_types &= ~(BTM_SCO_PKT_TYPE_MASK);
432 BTM_TRACE_DEBUG("%s: SCO Conn: pkt_types after removing SCO (0x%04x)", __func__,
435 /* Return error if no packet types left */
436 if (temp_pkt_types == 0)
438 BTM_TRACE_ERROR("%s: SCO Conn (BR/EDR SC): No packet types available",
440 return (BTM_WRONG_MODE);
445 BTM_TRACE_DEBUG("%s: SCO Conn(BR/EDR SC):local or peer does not support BR/EDR SC",
451 BTM_TRACE_API(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
452 p_setup->tx_bw, p_setup->rx_bw,
453 p_setup->max_latency, p_setup->voice_contfmt,
454 p_setup->retrans_effort, temp_pkt_types);
456 btsnd_hcic_setup_esco_conn(acl_handle,
459 p_setup->max_latency,
460 p_setup->voice_contfmt,
461 p_setup->retrans_effort,
463 p_setup->packet_types = temp_pkt_types;
466 return (BTM_CMD_STARTED);
470 /*******************************************************************************
472 ** Function btm_set_sco_ind_cback
474 ** Description This function is called to register for TCS SCO connect
479 *******************************************************************************/
480 void btm_set_sco_ind_cback( tBTM_SCO_IND_CBACK *sco_ind_cb )
482 btm_cb.sco_cb.app_sco_ind_cb = sco_ind_cb;
485 /*******************************************************************************
487 ** Function btm_accept_sco_link
489 ** Description This function is called to respond to TCS SCO connect
494 *******************************************************************************/
495 void btm_accept_sco_link(uint16_t sco_inx, tBTM_ESCO_PARAMS *p_setup,
496 tBTM_SCO_CB *p_conn_cb, tBTM_SCO_CB *p_disc_cb)
498 #if (BTM_MAX_SCO_LINKS>0)
501 if (sco_inx >= BTM_MAX_SCO_LINKS)
503 BTM_TRACE_ERROR("btm_accept_sco_link: Invalid sco_inx(%d)", sco_inx);
507 /* Link role is ignored in for this message */
508 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
509 p_sco->p_conn_cb = p_conn_cb;
510 p_sco->p_disc_cb = p_disc_cb;
511 p_sco->esco.data.link_type = BTM_LINK_TYPE_ESCO; /* Accept with all supported types */
513 BTM_TRACE_DEBUG("TCS accept SCO: Packet Types 0x%04x", p_setup->packet_types);
515 btm_esco_conn_rsp(sco_inx, HCI_SUCCESS, p_sco->esco.data.bd_addr, p_setup);
517 btm_reject_sco_link(sco_inx);
521 /*******************************************************************************
523 ** Function btm_reject_sco_link
525 ** Description This function is called to respond to SCO connect indications
529 *******************************************************************************/
530 void btm_reject_sco_link( uint16_t sco_inx )
532 btm_esco_conn_rsp(sco_inx, HCI_ERR_HOST_REJECT_RESOURCES,
533 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, NULL);
536 /*******************************************************************************
538 ** Function BTM_CreateSco
540 ** Description This function is called to create an SCO connection. If the
541 ** "is_orig" flag is true, the connection will be originated,
542 ** otherwise BTM will wait for the other side to connect.
544 ** NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
545 ** parameter the default packet types is used.
547 ** Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
548 ** BTM_BUSY if another SCO being set up to
549 ** the same BD address
550 ** BTM_NO_RESOURCES if the max SCO limit has been reached
551 ** BTM_CMD_STARTED if the connection establishment is started.
552 ** In this case, "*p_sco_inx" is filled in
553 ** with the sco index used for the connection.
555 *******************************************************************************/
556 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, bool is_orig, uint16_t pkt_types,
557 uint16_t *p_sco_inx, tBTM_SCO_CB *p_conn_cb,
558 tBTM_SCO_CB *p_disc_cb)
560 #if (BTM_MAX_SCO_LINKS > 0)
561 tBTM_ESCO_PARAMS *p_setup;
562 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
564 uint16_t acl_handle = 0;
565 uint16_t temp_pkt_types;
568 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
573 #endif // BTM_SCO_WAKE_PARKED_LINK
575 *p_sco_inx = BTM_INVALID_SCO_INDEX;
577 /* If originating, ensure that there is an ACL connection to the BD Address */
580 if ((!remote_bda) || ((acl_handle = BTM_GetHCIConnHandle (remote_bda, BT_TRANSPORT_BR_EDR)) == 0xFFFF))
581 return (BTM_UNKNOWN_ADDR);
586 /* If any SCO is being established to the remote BD address, refuse this */
587 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
589 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING)
590 || (p->state == SCO_ST_PEND_UNPARK))
591 && (!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)))
599 /* Support only 1 wildcard BD address at a time */
600 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
602 if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known))
607 /* Now, try to find an unused control block, and kick off the SCO establishment */
608 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
610 if (p->state == SCO_ST_UNUSED)
616 /* can not create SCO link if in park mode */
617 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
618 if ((btm_read_power_mode_state(p->esco.data.bd_addr, &state) == BTM_SUCCESS))
620 if (state == BTM_PM_ST_SNIFF || state == BTM_PM_ST_PARK ||
621 state == BTM_PM_ST_PENDING)
623 BTM_TRACE_DEBUG("%s In sniff, park or pend mode: %d", __func__, state);
624 memset( (void*)&pm, 0, sizeof(pm));
625 pm.mode = BTM_PM_MD_ACTIVE;
626 BTM_SetPowerMode(BTM_PM_SET_ONLY_ID, remote_bda, &pm);
627 p->state = SCO_ST_PEND_UNPARK;
630 #else // BTM_SCO_WAKE_PARKED_LINK
631 if( (BTM_ReadPowerMode(remote_bda, &mode) == BTM_SUCCESS) && (mode == BTM_PM_MD_PARK) )
632 return (BTM_WRONG_MODE);
633 #endif // BTM_SCO_WAKE_PARKED_LINK
635 memcpy (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN);
636 p->rem_bd_known = true;
639 p->rem_bd_known = false;
641 /* Link role is ignored in for this message */
642 if (pkt_types == BTM_IGNORE_SCO_PKT_TYPE)
643 pkt_types = btm_cb.sco_cb.def_esco_parms.packet_types;
645 p_setup = &p->esco.setup;
646 *p_setup = btm_cb.sco_cb.def_esco_parms;
647 p_setup->packet_types = (btm_cb.sco_cb.desired_sco_mode == BTM_LINK_TYPE_SCO)
648 ? (pkt_types & BTM_SCO_LINK_ONLY_MASK) : pkt_types;
650 temp_pkt_types = (p_setup->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
651 btm_cb.btm_sco_pkt_types_supported);
653 /* OR in any exception packet types */
654 if (controller_get_interface()->get_bt_version()->hci_version >= HCI_PROTO_VERSION_2_0)
656 temp_pkt_types |= ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
657 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
659 else /* Only using SCO packet types; turn off EDR also */
661 temp_pkt_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
664 p_setup->packet_types = temp_pkt_types;
665 p->p_conn_cb = p_conn_cb;
666 p->p_disc_cb = p_disc_cb;
667 p->hci_handle = BTM_INVALID_HCI_HANDLE;
668 p->is_orig = is_orig;
670 if( p->state != SCO_ST_PEND_UNPARK )
674 /* If role change is in progress, do not proceed with SCO setup
675 * Wait till role change is complete */
676 p_acl = btm_bda_to_acl(remote_bda, BT_TRANSPORT_BR_EDR);
677 if (p_acl && p_acl->switch_role_state != BTM_ACL_SWKEY_STATE_IDLE)
679 BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x",acl_handle);
680 p->state = SCO_ST_PEND_ROLECHANGE;
686 if( p->state != SCO_ST_PEND_UNPARK && p->state != SCO_ST_PEND_ROLECHANGE )
690 BTM_TRACE_API("BTM_CreateSco -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d",
691 acl_handle, btm_cb.sco_cb.desired_sco_mode);
693 if ((btm_send_connect_request(acl_handle, p_setup)) != BTM_CMD_STARTED)
694 return (BTM_NO_RESOURCES);
696 p->state = SCO_ST_CONNECTING;
699 p->state = SCO_ST_LISTENING;
704 return (BTM_CMD_STARTED);
709 /* If here, all SCO blocks in use */
710 return (BTM_NO_RESOURCES);
713 #if (BTM_SCO_WAKE_PARKED_LINK == TRUE)
714 /*******************************************************************************
716 ** Function btm_sco_chk_pend_unpark
718 ** Description This function is called by BTIF when there is a mode change
719 ** event to see if there are SCO commands waiting for the unpark.
723 *******************************************************************************/
724 void btm_sco_chk_pend_unpark (uint8_t hci_status, uint16_t hci_handle)
726 #if (BTM_MAX_SCO_LINKS>0)
729 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
731 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
733 if ((p->state == SCO_ST_PEND_UNPARK) &&
734 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
737 BTM_TRACE_API("btm_sco_chk_pend_unpark -> (e)SCO Link for ACL handle 0x%04x, Desired Type %d, hci_status 0x%02x",
738 acl_handle, btm_cb.sco_cb.desired_sco_mode, hci_status);
740 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
741 p->state = SCO_ST_CONNECTING;
744 #endif // BTM_MAX_SCO_LINKS
746 #endif // BTM_SCO_WAKE_PARKED_LINK
748 /*******************************************************************************
750 ** Function btm_sco_chk_pend_rolechange
752 ** Description This function is called by BTIF when there is a role change
753 ** event to see if there are SCO commands waiting for the role change.
757 *******************************************************************************/
758 void btm_sco_chk_pend_rolechange (uint16_t hci_handle)
760 #if (BTM_MAX_SCO_LINKS>0)
763 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
765 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
767 if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
768 ((acl_handle = BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
771 BTM_TRACE_API("btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x", acl_handle);
773 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) == BTM_CMD_STARTED)
774 p->state = SCO_ST_CONNECTING;
780 /*******************************************************************************
782 ** Function btm_sco_disc_chk_pend_for_modechange
784 ** Description This function is called by btm when there is a mode change
785 ** event to see if there are SCO disconnect commands waiting for the mode change.
789 *******************************************************************************/
790 void btm_sco_disc_chk_pend_for_modechange (uint16_t hci_handle)
792 #if (BTM_MAX_SCO_LINKS>0)
793 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
795 BTM_TRACE_DEBUG("%s: hci_handle 0x%04x, p->state 0x%02x", __func__,
796 hci_handle, p->state);
798 for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
800 if ((p->state == SCO_ST_PEND_MODECHANGE) &&
801 (BTM_GetHCIConnHandle (p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle)
804 BTM_TRACE_DEBUG("%s: SCO Link handle 0x%04x", __func__, p->hci_handle);
811 /*******************************************************************************
813 ** Function btm_sco_conn_req
815 ** Description This function is called by BTIF when an SCO connection
816 ** request is received from a remote.
820 *******************************************************************************/
821 void btm_sco_conn_req (BD_ADDR bda, DEV_CLASS dev_class, uint8_t link_type)
823 #if (BTM_MAX_SCO_LINKS>0)
824 tSCO_CB *p_sco = &btm_cb.sco_cb;
825 tSCO_CONN *p = &p_sco->sco_db[0];
827 tBTM_ESCO_CONN_REQ_EVT_DATA evt_data;
829 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
832 * If the sco state is in the SCO_ST_CONNECTING state, we still need
833 * to return accept sco to avoid race conditon for sco creation
835 int rem_bd_matches = p->rem_bd_known &&
836 !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
837 if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
838 ((p->state == SCO_ST_LISTENING) && (rem_bd_matches || !p->rem_bd_known)))
840 /* If this guy was a wildcard, he is not one any more */
841 p->rem_bd_known = true;
842 p->esco.data.link_type = link_type;
843 p->state = SCO_ST_W4_CONN_RSP;
844 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
846 /* If no callback, auto-accept the connection if packet types match */
847 if (!p->esco.p_esco_cback)
849 /* If requesting eSCO reject if default parameters are SCO only */
850 if ((link_type == BTM_LINK_TYPE_ESCO
851 && !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK)
852 && ((p_sco->def_esco_parms.packet_types & BTM_SCO_EXCEPTION_PKTS_MASK)
853 == BTM_SCO_EXCEPTION_PKTS_MASK))
855 /* Reject request if SCO is desired but no SCO packets delected */
856 || (link_type == BTM_LINK_TYPE_SCO
857 && !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK)))
859 btm_esco_conn_rsp(xx, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
861 else /* Accept the request */
863 btm_esco_conn_rsp(xx, HCI_SUCCESS, bda, NULL);
866 else /* Notify upper layer of connect indication */
868 memcpy(evt_data.bd_addr, bda, BD_ADDR_LEN);
869 memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
870 evt_data.link_type = link_type;
871 evt_data.sco_inx = xx;
872 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, (tBTM_ESCO_EVT_DATA *)&evt_data);
880 if (btm_cb.sco_cb.app_sco_ind_cb)
882 /* Now, try to find an unused control block */
883 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS; xx++, p++)
885 if (p->state == SCO_ST_UNUSED)
888 p->state = SCO_ST_LISTENING;
890 p->esco.data.link_type = link_type;
891 memcpy (p->esco.data.bd_addr, bda, BD_ADDR_LEN);
892 p->rem_bd_known = true;
896 if( xx < BTM_MAX_SCO_LINKS)
898 btm_cb.sco_cb.app_sco_ind_cb(xx);
904 /* If here, no one wants the SCO connection. Reject it */
905 BTM_TRACE_WARNING("btm_sco_conn_req: No one wants this SCO connection; rejecting it");
906 btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda, NULL);
909 /*******************************************************************************
911 ** Function btm_sco_connected
913 ** Description This function is called by BTIF when an (e)SCO connection
918 *******************************************************************************/
919 void btm_sco_connected (uint8_t hci_status, BD_ADDR bda, uint16_t hci_handle,
920 tBTM_ESCO_DATA *p_esco_data)
922 #if (BTM_MAX_SCO_LINKS>0)
923 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
926 tBTM_CHG_ESCO_PARAMS parms;
929 btm_cb.sco_cb.sco_disc_reason = hci_status;
931 #if (BTM_MAX_SCO_LINKS>0)
932 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
934 if (((p->state == SCO_ST_CONNECTING) ||
935 (p->state == SCO_ST_LISTENING) ||
936 (p->state == SCO_ST_W4_CONN_RSP))
938 && (!bda || !memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
940 if (hci_status != HCI_SUCCESS)
942 /* Report the error if originator, otherwise remain in Listen mode */
945 /* If role switch is pending, we need try again after role switch is complete */
946 if(hci_status == HCI_ERR_ROLE_SWITCH_PENDING)
948 BTM_TRACE_API("Role Change pending for HCI handle 0x%04x",hci_handle);
949 p->state = SCO_ST_PEND_ROLECHANGE;
951 /* avoid calling disconnect callback because of sco creation race */
952 else if (hci_status != HCI_ERR_LMP_ERR_TRANS_COLLISION)
954 p->state = SCO_ST_UNUSED;
960 /* Notify the upper layer that incoming sco connection has failed. */
961 if (p->state == SCO_ST_CONNECTING)
963 p->state = SCO_ST_UNUSED;
967 p->state = SCO_ST_LISTENING;
973 if (p->state == SCO_ST_LISTENING)
976 p->state = SCO_ST_CONNECTED;
977 p->hci_handle = hci_handle;
979 if (!btm_cb.sco_cb.esco_supported)
981 p->esco.data.link_type = BTM_LINK_TYPE_SCO;
984 parms.packet_types = p->esco.setup.packet_types;
985 /* Keep the other parameters the same for SCO */
986 parms.max_latency = p->esco.setup.max_latency;
987 parms.retrans_effort = p->esco.setup.retrans_effort;
989 BTM_ChangeEScoLinkParms(xx, &parms);
995 p->esco.data = *p_esco_data;
1007 /*******************************************************************************
1009 ** Function btm_find_scb_by_handle
1011 ** Description Look through all active SCO connection for a match based on the
1014 ** Returns index to matched SCO connection CB, or BTM_MAX_SCO_LINKS if
1017 *******************************************************************************/
1018 uint16_t btm_find_scb_by_handle (uint16_t handle)
1021 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1023 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1025 if ((p->state == SCO_ST_CONNECTED) && (p->hci_handle == handle))
1031 /* If here, no match found */
1035 /*******************************************************************************
1037 ** Function BTM_RemoveSco
1039 ** Description This function is called to remove a specific SCO connection.
1041 ** Returns status of the operation
1043 *******************************************************************************/
1044 tBTM_STATUS BTM_RemoveSco (uint16_t sco_inx)
1046 #if (BTM_MAX_SCO_LINKS>0)
1047 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1049 tBTM_PM_STATE state = BTM_PM_ST_INVALID;
1051 BTM_TRACE_DEBUG("%s", __func__);
1053 /* Validity check */
1054 if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
1055 return (BTM_UNKNOWN_ADDR);
1057 /* If no HCI handle, simply drop the connection and return */
1058 if (p->hci_handle == BTM_INVALID_HCI_HANDLE || p->state == SCO_ST_PEND_UNPARK)
1060 p->hci_handle = BTM_INVALID_HCI_HANDLE;
1061 p->state = SCO_ST_UNUSED;
1062 p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
1063 return (BTM_SUCCESS);
1066 if ((btm_read_power_mode_state(p->esco.data.bd_addr, &state) == BTM_SUCCESS)
1067 && state == BTM_PM_ST_PENDING)
1069 BTM_TRACE_DEBUG("%s: BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x%04x",
1070 __func__, p->hci_handle);
1071 p->state = SCO_ST_PEND_MODECHANGE;
1072 return (BTM_CMD_STARTED);
1075 tempstate = p->state;
1076 p->state = SCO_ST_DISCONNECTING;
1078 btsnd_hcic_disconnect(p->hci_handle, HCI_ERR_PEER_USER);
1080 return (BTM_CMD_STARTED);
1082 return (BTM_NO_RESOURCES);
1086 /*******************************************************************************
1088 ** Function btm_remove_sco_links
1090 ** Description This function is called to remove all sco links for an ACL link.
1094 *******************************************************************************/
1095 void btm_remove_sco_links (BD_ADDR bda)
1097 #if (BTM_MAX_SCO_LINKS>0)
1098 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1101 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1103 if (p->rem_bd_known && (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN)))
1111 /*******************************************************************************
1113 ** Function btm_sco_removed
1115 ** Description This function is called by BTIF when an SCO connection
1120 *******************************************************************************/
1121 void btm_sco_removed (uint16_t hci_handle, uint8_t reason)
1123 #if (BTM_MAX_SCO_LINKS>0)
1124 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1128 btm_cb.sco_cb.sco_disc_reason = reason;
1130 #if (BTM_MAX_SCO_LINKS>0)
1131 p = &btm_cb.sco_cb.sco_db[0];
1132 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1134 if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) && (p->hci_handle == hci_handle))
1136 btm_sco_flush_sco_data(xx);
1138 p->state = SCO_ST_UNUSED;
1139 p->hci_handle = BTM_INVALID_HCI_HANDLE;
1140 p->rem_bd_known = false;
1141 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1142 (*p->p_disc_cb)(xx);
1151 /*******************************************************************************
1153 ** Function btm_sco_acl_removed
1155 ** Description This function is called when an ACL connection is
1156 ** removed. If the BD address is NULL, it is assumed that
1157 ** the local device is down, and all SCO links are removed.
1158 ** If a specific BD address is passed, only SCO connections
1159 ** to that BD address are removed.
1163 *******************************************************************************/
1164 void btm_sco_acl_removed (BD_ADDR bda)
1166 #if (BTM_MAX_SCO_LINKS>0)
1167 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1170 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1172 if (p->state != SCO_ST_UNUSED)
1174 if ((!bda) || (!memcmp (p->esco.data.bd_addr, bda, BD_ADDR_LEN) && p->rem_bd_known))
1176 btm_sco_flush_sco_data(xx);
1178 p->state = SCO_ST_UNUSED;
1179 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1180 (*p->p_disc_cb)(xx);
1188 /*******************************************************************************
1190 ** Function BTM_SetScoPacketTypes
1192 ** Description This function is called to set the packet types used for
1193 ** a specific SCO connection,
1195 ** Parameters pkt_types - One or more of the following
1196 ** BTM_SCO_PKT_TYPES_MASK_HV1
1197 ** BTM_SCO_PKT_TYPES_MASK_HV2
1198 ** BTM_SCO_PKT_TYPES_MASK_HV3
1199 ** BTM_SCO_PKT_TYPES_MASK_EV3
1200 ** BTM_SCO_PKT_TYPES_MASK_EV4
1201 ** BTM_SCO_PKT_TYPES_MASK_EV5
1202 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1203 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1204 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1205 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1207 ** BTM_SCO_LINK_ALL_MASK - enables all supported types
1209 ** Returns status of the operation
1211 *******************************************************************************/
1212 tBTM_STATUS BTM_SetScoPacketTypes (uint16_t sco_inx, uint16_t pkt_types)
1214 #if (BTM_MAX_SCO_LINKS>0)
1215 tBTM_CHG_ESCO_PARAMS parms;
1218 /* Validity check */
1219 if (sco_inx >= BTM_MAX_SCO_LINKS)
1220 return (BTM_UNKNOWN_ADDR);
1222 p = &btm_cb.sco_cb.sco_db[sco_inx];
1223 parms.packet_types = pkt_types;
1225 /* Keep the other parameters the same for SCO */
1226 parms.max_latency = p->esco.setup.max_latency;
1227 parms.retrans_effort = p->esco.setup.retrans_effort;
1229 return (BTM_ChangeEScoLinkParms(sco_inx, &parms));
1231 return (BTM_UNKNOWN_ADDR);
1236 /*******************************************************************************
1238 ** Function BTM_ReadScoPacketTypes
1240 ** Description This function is read the packet types used for a specific
1243 ** Returns Packet types supported for the connection
1244 ** One or more of the following (bitmask):
1245 ** BTM_SCO_PKT_TYPES_MASK_HV1
1246 ** BTM_SCO_PKT_TYPES_MASK_HV2
1247 ** BTM_SCO_PKT_TYPES_MASK_HV3
1248 ** BTM_SCO_PKT_TYPES_MASK_EV3
1249 ** BTM_SCO_PKT_TYPES_MASK_EV4
1250 ** BTM_SCO_PKT_TYPES_MASK_EV5
1251 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1252 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1253 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1254 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1256 *******************************************************************************/
1257 uint16_t BTM_ReadScoPacketTypes (uint16_t sco_inx)
1259 #if (BTM_MAX_SCO_LINKS>0)
1260 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1262 /* Validity check */
1263 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->state == SCO_ST_CONNECTED))
1264 return (p->esco.setup.packet_types);
1272 /*******************************************************************************
1274 ** Function BTM_ReadScoDiscReason
1276 ** Description This function is returns the reason why an (e)SCO connection
1277 ** has been removed. It contains the value until read, or until
1278 ** another (e)SCO connection has disconnected.
1280 ** Returns HCI reason or BTM_INVALID_SCO_DISC_REASON if not set.
1282 *******************************************************************************/
1283 uint16_t BTM_ReadScoDiscReason (void)
1285 uint16_t res = btm_cb.sco_cb.sco_disc_reason;
1286 btm_cb.sco_cb.sco_disc_reason = BTM_INVALID_SCO_DISC_REASON;
1290 /*******************************************************************************
1292 ** Function BTM_ReadDeviceScoPacketTypes
1294 ** Description This function is read the SCO packet types that
1295 ** the device supports.
1297 ** Returns Packet types supported by the device.
1298 ** One or more of the following (bitmask):
1299 ** BTM_SCO_PKT_TYPES_MASK_HV1
1300 ** BTM_SCO_PKT_TYPES_MASK_HV2
1301 ** BTM_SCO_PKT_TYPES_MASK_HV3
1302 ** BTM_SCO_PKT_TYPES_MASK_EV3
1303 ** BTM_SCO_PKT_TYPES_MASK_EV4
1304 ** BTM_SCO_PKT_TYPES_MASK_EV5
1305 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV3
1306 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV3
1307 ** BTM_SCO_PKT_TYPES_MASK_NO_2_EV5
1308 ** BTM_SCO_PKT_TYPES_MASK_NO_3_EV5
1310 *******************************************************************************/
1311 uint16_t BTM_ReadDeviceScoPacketTypes (void)
1313 return (btm_cb.btm_sco_pkt_types_supported);
1316 /*******************************************************************************
1318 ** Function BTM_ReadScoHandle
1320 ** Description This function is used to read the HCI handle used for a specific
1323 ** Returns handle for the connection, or 0xFFFF if invalid SCO index.
1325 *******************************************************************************/
1326 uint16_t BTM_ReadScoHandle (uint16_t 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->state == SCO_ST_CONNECTED))
1333 return (p->hci_handle);
1335 return (BTM_INVALID_HCI_HANDLE);
1337 return (BTM_INVALID_HCI_HANDLE);
1341 /*******************************************************************************
1343 ** Function BTM_ReadScoBdAddr
1345 ** Description This function is read the remote BD Address for a specific
1348 ** Returns pointer to BD address or NULL if not known
1350 *******************************************************************************/
1351 uint8_t *BTM_ReadScoBdAddr (uint16_t sco_inx)
1353 #if (BTM_MAX_SCO_LINKS>0)
1354 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[sco_inx];
1356 /* Validity check */
1357 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1358 return (p->esco.data.bd_addr);
1366 /*******************************************************************************
1368 ** Function BTM_SetEScoMode
1370 ** Description This function sets up the negotiated parameters for SCO or
1371 ** eSCO, and sets as the default mode used for outgoing calls to
1372 ** BTM_CreateSco. It does not change any currently active (e)SCO links.
1373 ** Note: Incoming (e)SCO connections will always use packet types
1374 ** supported by the controller. If eSCO is not desired the
1375 ** feature should be disabled in the controller's feature mask.
1377 ** Returns BTM_SUCCESS if the successful.
1378 ** BTM_BUSY if there are one or more active (e)SCO links.
1380 *******************************************************************************/
1381 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms)
1383 tSCO_CB *p_esco = &btm_cb.sco_cb;
1384 tBTM_ESCO_PARAMS *p_def = &p_esco->def_esco_parms;
1386 if (p_esco->esco_supported)
1390 if (sco_mode == BTM_LINK_TYPE_ESCO)
1391 *p_def = *p_parms; /* Save as the default parameters */
1392 else /* Load only the SCO packet types */
1394 p_def->packet_types = p_parms->packet_types;
1395 p_def->tx_bw = BTM_64KBITS_RATE;
1396 p_def->rx_bw = BTM_64KBITS_RATE;
1397 p_def->max_latency = 0x000a;
1398 p_def->voice_contfmt = 0x0060;
1399 p_def->retrans_effort = 0;
1401 /* OR in any exception packet types */
1402 p_def->packet_types |= BTM_SCO_EXCEPTION_PKTS_MASK;
1405 p_esco->desired_sco_mode = sco_mode;
1406 BTM_TRACE_API("BTM_SetEScoMode -> mode %d", sco_mode);
1410 p_esco->desired_sco_mode = BTM_LINK_TYPE_SCO;
1411 p_def->packet_types &= BTM_SCO_LINK_ONLY_MASK;
1412 p_def->retrans_effort = 0;
1413 BTM_TRACE_API("BTM_SetEScoMode -> mode SCO (eSCO not supported)");
1416 BTM_TRACE_DEBUG(" txbw 0x%08x, rxbw 0x%08x, max_lat 0x%04x, voice 0x%04x, pkt 0x%04x, rtx effort 0x%02x",
1417 p_def->tx_bw, p_def->rx_bw, p_def->max_latency,
1418 p_def->voice_contfmt, p_def->packet_types,
1419 p_def->retrans_effort);
1421 return (BTM_SUCCESS);
1426 /*******************************************************************************
1428 ** Function BTM_RegForEScoEvts
1430 ** Description This function registers a SCO event callback with the
1431 ** specified instance. It should be used to received
1432 ** connection indication events and change of link parameter
1435 ** Returns BTM_SUCCESS if the successful.
1436 ** BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1437 ** BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1438 ** later or does not support eSCO.
1440 *******************************************************************************/
1441 tBTM_STATUS BTM_RegForEScoEvts (uint16_t sco_inx, tBTM_ESCO_CBACK *p_esco_cback)
1443 #if (BTM_MAX_SCO_LINKS>0)
1444 if (!btm_cb.sco_cb.esco_supported)
1446 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1447 return (BTM_MODE_UNSUPPORTED);
1450 if (sco_inx < BTM_MAX_SCO_LINKS &&
1451 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED)
1453 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1454 return (BTM_SUCCESS);
1456 return (BTM_ILLEGAL_VALUE);
1458 return (BTM_MODE_UNSUPPORTED);
1462 /*******************************************************************************
1464 ** Function BTM_ReadEScoLinkParms
1466 ** Description This function returns the current eSCO link parameters for
1467 ** the specified handle. This can be called anytime a connection
1468 ** is active, but is typically called after receiving the SCO
1471 ** Note: If called over a 1.1 controller, only the packet types
1472 ** field has meaning.
1474 ** Returns BTM_SUCCESS if returned data is valid connection.
1475 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
1477 *******************************************************************************/
1478 tBTM_STATUS BTM_ReadEScoLinkParms (uint16_t sco_inx, tBTM_ESCO_DATA *p_parms)
1480 #if (BTM_MAX_SCO_LINKS>0)
1483 BTM_TRACE_API("BTM_ReadEScoLinkParms -> sco_inx 0x%04x", sco_inx);
1485 if (sco_inx < BTM_MAX_SCO_LINKS &&
1486 btm_cb.sco_cb.sco_db[sco_inx].state >= SCO_ST_CONNECTED)
1488 *p_parms = btm_cb.sco_cb.sco_db[sco_inx].esco.data;
1489 return (BTM_SUCCESS);
1492 if (sco_inx == BTM_FIRST_ACTIVE_SCO_INDEX)
1494 for (index = 0; index < BTM_MAX_SCO_LINKS; index++)
1496 if (btm_cb.sco_cb.sco_db[index].state >= SCO_ST_CONNECTED)
1498 BTM_TRACE_API("BTM_ReadEScoLinkParms the first active SCO index is %d",index);
1499 *p_parms = btm_cb.sco_cb.sco_db[index].esco.data;
1500 return (BTM_SUCCESS);
1507 BTM_TRACE_API("BTM_ReadEScoLinkParms cannot find the SCO index!");
1508 memset(p_parms, 0, sizeof(tBTM_ESCO_DATA));
1509 return (BTM_WRONG_MODE);
1512 /*******************************************************************************
1514 ** Function BTM_ChangeEScoLinkParms
1516 ** Description This function requests renegotiation of the parameters on
1517 ** the current eSCO Link. If any of the changes are accepted
1518 ** by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1519 ** the tBTM_ESCO_CBACK function with the current settings of
1520 ** the link. The callback is registered through the call to
1523 ** Note: If called over a SCO link (including 1.1 controller),
1524 ** a change packet type request is sent out instead.
1526 ** Returns BTM_CMD_STARTED if command is successfully initiated.
1527 ** BTM_NO_RESOURCES - not enough resources to initiate command.
1528 ** BTM_WRONG_MODE if no connection with a peer device or bad sco_inx.
1530 *******************************************************************************/
1531 tBTM_STATUS BTM_ChangeEScoLinkParms (uint16_t sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms)
1533 #if (BTM_MAX_SCO_LINKS>0)
1534 tBTM_ESCO_PARAMS *p_setup;
1536 uint16_t temp_pkt_types;
1538 /* Make sure sco handle is valid and on an active link */
1539 if (sco_inx >= BTM_MAX_SCO_LINKS ||
1540 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1541 return (BTM_WRONG_MODE);
1543 p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1544 p_setup = &p_sco->esco.setup;
1546 /* If SCO connection OR eSCO not supported just send change packet types */
1547 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1548 !btm_cb.sco_cb.esco_supported)
1550 p_setup->packet_types = p_parms->packet_types &
1551 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1554 BTM_TRACE_API("BTM_ChangeEScoLinkParms -> SCO Link for handle 0x%04x, pkt 0x%04x",
1555 p_sco->hci_handle, p_setup->packet_types);
1557 btsnd_hcic_change_conn_type(p_sco->hci_handle,
1558 BTM_ESCO_2_SCO(p_setup->packet_types));
1562 temp_pkt_types = (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1563 btm_cb.btm_sco_pkt_types_supported);
1565 /* OR in any exception packet types */
1566 temp_pkt_types |= ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
1567 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
1569 BTM_TRACE_API("BTM_ChangeEScoLinkParms -> eSCO Link for handle 0x%04x", p_sco->hci_handle);
1570 BTM_TRACE_API(" txbw 0x%x, rxbw 0x%x, lat 0x%x, voice 0x%x, retrans 0x%02x, pkt 0x%04x",
1571 p_setup->tx_bw, p_setup->rx_bw, p_parms->max_latency,
1572 p_setup->voice_contfmt, p_parms->retrans_effort, temp_pkt_types);
1574 /* When changing an existing link, only change latency, retrans, and pkts */
1575 btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->tx_bw,
1576 p_setup->rx_bw, p_parms->max_latency,
1577 p_setup->voice_contfmt,
1578 p_parms->retrans_effort,
1580 p_parms->packet_types = temp_pkt_types;
1583 return (BTM_CMD_STARTED);
1585 return (BTM_WRONG_MODE);
1589 /*******************************************************************************
1591 ** Function BTM_EScoConnRsp
1593 ** Description This function is called upon receipt of an (e)SCO connection
1594 ** request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1595 ** the request. Parameters used to negotiate eSCO links.
1596 ** If p_parms is NULL, then values set through BTM_SetEScoMode
1598 ** If the link type of the incoming request is SCO, then only
1599 ** the tx_bw, max_latency, content format, and packet_types are
1600 ** valid. The hci_status parameter should be
1601 ** ([0x0] to accept, [0x0d..0x0f] to reject)
1606 *******************************************************************************/
1607 void BTM_EScoConnRsp (uint16_t sco_inx, uint8_t hci_status, tBTM_ESCO_PARAMS *p_parms)
1609 #if (BTM_MAX_SCO_LINKS>0)
1610 if (sco_inx < BTM_MAX_SCO_LINKS &&
1611 btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP)
1613 btm_esco_conn_rsp(sco_inx, hci_status,
1614 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr,
1620 /*******************************************************************************
1622 ** Function btm_read_def_esco_mode
1624 ** Description This function copies the current default esco settings into
1625 ** the return buffer.
1627 ** Returns tBTM_SCO_TYPE
1629 *******************************************************************************/
1630 tBTM_SCO_TYPE btm_read_def_esco_mode (tBTM_ESCO_PARAMS *p_parms)
1632 #if (BTM_MAX_SCO_LINKS>0)
1633 *p_parms = btm_cb.sco_cb.def_esco_parms;
1634 return btm_cb.sco_cb.desired_sco_mode;
1636 return BTM_LINK_TYPE_SCO;
1640 /*******************************************************************************
1642 ** Function btm_esco_proc_conn_chg
1644 ** Description This function is called by BTIF when an SCO connection
1649 *******************************************************************************/
1650 void btm_esco_proc_conn_chg (uint8_t status, uint16_t handle, uint8_t tx_interval,
1651 uint8_t retrans_window, uint16_t rx_pkt_len,
1652 uint16_t tx_pkt_len)
1654 #if (BTM_MAX_SCO_LINKS>0)
1655 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1656 tBTM_CHG_ESCO_EVT_DATA data;
1659 BTM_TRACE_EVENT("btm_esco_proc_conn_chg -> handle 0x%04x, status 0x%02x",
1662 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1664 if (p->state == SCO_ST_CONNECTED && handle == p->hci_handle)
1666 /* If upper layer wants notification */
1667 if (p->esco.p_esco_cback)
1669 memcpy(data.bd_addr, p->esco.data.bd_addr, BD_ADDR_LEN);
1670 data.hci_status = status;
1672 data.rx_pkt_len = p->esco.data.rx_pkt_len = rx_pkt_len;
1673 data.tx_pkt_len = p->esco.data.tx_pkt_len = tx_pkt_len;
1674 data.tx_interval = p->esco.data.tx_interval = tx_interval;
1675 data.retrans_window = p->esco.data.retrans_window = retrans_window;
1677 (*p->esco.p_esco_cback)(BTM_ESCO_CHG_EVT,
1678 (tBTM_ESCO_EVT_DATA *)&data);
1686 /*******************************************************************************
1688 ** Function btm_is_sco_active
1690 ** Description This function is called to see if a SCO handle is already in
1695 *******************************************************************************/
1696 bool btm_is_sco_active (uint16_t handle)
1698 #if (BTM_MAX_SCO_LINKS>0)
1700 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1702 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1704 if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED)
1711 /*******************************************************************************
1713 ** Function BTM_GetNumScoLinks
1715 ** Description This function returns the number of active sco links.
1719 *******************************************************************************/
1720 uint8_t BTM_GetNumScoLinks (void)
1722 #if (BTM_MAX_SCO_LINKS>0)
1723 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1725 uint8_t num_scos = 0;
1727 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1731 case SCO_ST_W4_CONN_RSP:
1732 case SCO_ST_CONNECTING:
1733 case SCO_ST_CONNECTED:
1734 case SCO_ST_DISCONNECTING:
1735 case SCO_ST_PEND_UNPARK:
1746 /*******************************************************************************
1748 ** Function btm_is_sco_active_by_bdaddr
1750 ** Description This function is called to see if a SCO active to a bd address.
1754 *******************************************************************************/
1755 bool btm_is_sco_active_by_bdaddr (BD_ADDR remote_bda)
1757 #if (BTM_MAX_SCO_LINKS>0)
1759 tSCO_CONN *p = &btm_cb.sco_cb.sco_db[0];
1761 /* If any SCO is being established to the remote BD address, refuse this */
1762 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++)
1764 if ((!memcmp (p->esco.data.bd_addr, remote_bda, BD_ADDR_LEN)) && (p->state == SCO_ST_CONNECTED))
1772 #else /* SCO_EXCLUDED == TRUE (Link in stubs) */
1774 tBTM_STATUS BTM_CreateSco (BD_ADDR remote_bda, bool is_orig,
1775 uint16_t pkt_types, uint16_t *p_sco_inx,
1776 tBTM_SCO_CB *p_conn_cb,
1777 tBTM_SCO_CB *p_disc_cb) {return (BTM_NO_RESOURCES);}
1778 tBTM_STATUS BTM_RemoveSco (uint16_t sco_inx) {return (BTM_NO_RESOURCES);}
1779 tBTM_STATUS BTM_SetScoPacketTypes (uint16_t sco_inx, uint16_t pkt_types) {return (BTM_NO_RESOURCES);}
1780 uint16_t BTM_ReadScoPacketTypes (uint16_t sco_inx) {return (0);}
1781 uint16_t BTM_ReadDeviceScoPacketTypes (void) {return (0);}
1782 uint16_t BTM_ReadScoHandle (uint16_t sco_inx) {return (BTM_INVALID_HCI_HANDLE);}
1783 uint8_t *BTM_ReadScoBdAddr(uint16_t sco_inx) {return((uint8_t *) NULL);}
1784 uint16_t BTM_ReadScoDiscReason (void) {return (BTM_INVALID_SCO_DISC_REASON);}
1785 tBTM_STATUS BTM_SetEScoMode (tBTM_SCO_TYPE sco_mode, tBTM_ESCO_PARAMS *p_parms) {return (BTM_MODE_UNSUPPORTED);}
1786 tBTM_STATUS BTM_RegForEScoEvts (uint16_t sco_inx, tBTM_ESCO_CBACK *p_esco_cback) { return (BTM_ILLEGAL_VALUE);}
1787 tBTM_STATUS BTM_ReadEScoLinkParms (uint16_t sco_inx, tBTM_ESCO_DATA *p_parms) { return (BTM_MODE_UNSUPPORTED);}
1788 tBTM_STATUS BTM_ChangeEScoLinkParms (uint16_t sco_inx, tBTM_CHG_ESCO_PARAMS *p_parms) { return (BTM_MODE_UNSUPPORTED);}
1789 void BTM_EScoConnRsp (uint16_t sco_inx, uint8_t hci_status, tBTM_ESCO_PARAMS *p_parms) {}
1790 uint8_t BTM_GetNumScoLinks (void) {return (0);}
1792 #endif /* If SCO is being used */