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