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 <base/logging.h>
27 #include <base/strings/stringprintf.h>
28
29 #include <cstdint>
30 #include <string>
31
32 #include "device/include/controller.h"
33 #include "osi/include/allocator.h"
34 #include "osi/include/log.h"
35 #include "osi/include/osi.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/btm/security_device_record.h"
38 #include "stack/include/acl_api.h"
39 #include "stack/include/bt_hdr.h"
40 #include "stack/include/btm_api.h"
41 #include "stack/include/btm_api_types.h"
42 #include "stack/include/hci_error_code.h"
43 #include "types/class_of_device.h"
44 #include "types/raw_address.h"
45
46 extern tBTM_CB btm_cb;
47
48 namespace {
49 constexpr char kBtmLogTag[] = "SCO";
50
GetLegacyHciInterface()51 const bluetooth::legacy::hci::Interface& GetLegacyHciInterface() {
52 return bluetooth::legacy::hci::GetInterface();
53 }
54
55 }; // namespace
56
57 /******************************************************************************/
58 /* L O C A L D A T A D E F I N I T I O N S */
59 /******************************************************************************/
60
61 /* MACROs to convert from SCO packet types mask to ESCO and back */
62 #define BTM_SCO_PKT_TYPE_MASK \
63 (HCI_PKT_TYPES_MASK_HV1 | HCI_PKT_TYPES_MASK_HV2 | HCI_PKT_TYPES_MASK_HV3)
64
65 /* Mask defining only the SCO types of an esco packet type */
66 #define BTM_ESCO_PKT_TYPE_MASK \
67 (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | ESCO_PKT_TYPES_MASK_HV3)
68
69 #define BTM_ESCO_2_SCO(escotype) \
70 ((uint16_t)(((escotype)&BTM_ESCO_PKT_TYPE_MASK) << 5))
71
72 /* Define masks for supported and exception 2.0 SCO packet types
73 */
74 #define BTM_SCO_SUPPORTED_PKTS_MASK \
75 (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | \
76 ESCO_PKT_TYPES_MASK_HV3 | ESCO_PKT_TYPES_MASK_EV3 | \
77 ESCO_PKT_TYPES_MASK_EV4 | ESCO_PKT_TYPES_MASK_EV5)
78
79 #define BTM_SCO_EXCEPTION_PKTS_MASK \
80 (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \
81 ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5)
82
83 /******************************************************************************/
84 /* L O C A L F U N C T I O N P R O T O T Y P E S */
85 /******************************************************************************/
86 static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
87 tBTM_CHG_ESCO_PARAMS* p_parms);
88
89 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_parms);
90
91 /*******************************************************************************
92 *
93 * Function btm_esco_conn_rsp
94 *
95 * Description This function is called upon receipt of an (e)SCO connection
96 * request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
97 * the request. Parameters used to negotiate eSCO links.
98 * If p_parms is NULL, then default values are used.
99 * If the link type of the incoming request is SCO, then only
100 * the tx_bw, max_latency, content format, and packet_types are
101 * valid. The hci_status parameter should be
102 * ([0x0] to accept, [0x0d..0x0f] to reject)
103 *
104 * Returns void
105 *
106 ******************************************************************************/
btm_esco_conn_rsp(uint16_t sco_inx,uint8_t hci_status,const RawAddress & bda,enh_esco_params_t * p_parms)107 static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status,
108 const RawAddress& bda,
109 enh_esco_params_t* p_parms) {
110 tSCO_CONN* p_sco = NULL;
111
112 if (BTM_MAX_SCO_LINKS == 0) return;
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 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
135 !sco_peer_supports_esco_ev3(bda)) {
136 *p_setup = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
137 } else {
138 /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
139 *p_setup = btm_cb.sco_cb.def_esco_parms;
140 }
141 /* Use Enhanced Synchronous commands if supported */
142 if (controller_get_interface()
143 ->supports_enhanced_setup_synchronous_connection()) {
144 /* Use the saved SCO routing */
145 p_setup->input_data_path = p_setup->output_data_path = ESCO_DATA_PATH;
146
147 BTM_TRACE_DEBUG(
148 "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, "
149 "pkt 0x%04x, path %u",
150 __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
151 p_setup->max_latency_ms, p_setup->retransmission_effort,
152 p_setup->packet_types, p_setup->input_data_path);
153
154 btsnd_hcic_enhanced_accept_synchronous_connection(bda, p_setup);
155
156 } else {
157 /* Use legacy command if enhanced SCO setup is not supported */
158 uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
159 btsnd_hcic_accept_esco_conn(
160 bda, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
161 p_setup->max_latency_ms, voice_content_format,
162 p_setup->retransmission_effort, p_setup->packet_types);
163 }
164 }
165 }
166
167 // Return the active (first connected) SCO connection block
btm_get_active_sco()168 static tSCO_CONN* btm_get_active_sco() {
169 for (auto& link : btm_cb.sco_cb.sco_db) {
170 if (link.state == SCO_ST_CONNECTED) {
171 return &link;
172 }
173 }
174 return nullptr;
175 }
176
177 /*******************************************************************************
178 *
179 * Function btm_route_sco_data
180 *
181 * Description Route received SCO data.
182 *
183 * Returns void
184 *
185 ******************************************************************************/
btm_route_sco_data(BT_HDR * p_msg)186 void btm_route_sco_data(BT_HDR* p_msg) {
187 if (p_msg->len < 3) {
188 LOG_ERROR("Received incomplete SCO header");
189 osi_free(p_msg);
190 return;
191 }
192 uint8_t* payload = p_msg->data;
193 uint16_t handle_with_flags = 0;
194 uint8_t length = 0;
195 STREAM_TO_UINT16(handle_with_flags, payload);
196 STREAM_TO_UINT8(length, payload);
197 if (p_msg->len != length + 3) {
198 LOG_ERROR("Received invalid SCO data of size: %hhu, dropping", length);
199 osi_free(p_msg);
200 return;
201 }
202 uint16_t handle = handle_with_flags & 0xFFF;
203 ASSERT_LOG(handle <= 0xEFF, "Require handle <= 0xEFF, but is 0x%X", handle);
204 auto* active_sco = btm_get_active_sco();
205 if (active_sco != nullptr && active_sco->hci_handle == handle) {
206 // TODO: For MSBC, we need to decode here
207 bluetooth::audio::sco::write(payload, length);
208 }
209 osi_free(p_msg);
210 // For Chrome OS, we send the outgoing data after receiving an incoming one
211 uint8_t out_buf[BTM_SCO_DATA_SIZE_MAX];
212 auto size_read = bluetooth::audio::sco::read(out_buf, length);
213 auto data = std::vector<uint8_t>(out_buf, out_buf + size_read);
214 // TODO: For MSBC, we need to encode here
215 btm_send_sco_packet(std::move(data));
216 }
217
btm_send_sco_packet(std::vector<uint8_t> data)218 void btm_send_sco_packet(std::vector<uint8_t> data) {
219 auto* active_sco = btm_get_active_sco();
220 if (active_sco == nullptr || data.empty()) {
221 return;
222 }
223 BT_HDR* packet = btm_sco_make_packet(std::move(data), active_sco->hci_handle);
224 bte_main_hci_send(packet, BT_EVT_TO_LM_HCI_SCO);
225 }
226
227 // Build a SCO packet from uint8
btm_sco_make_packet(std::vector<uint8_t> data,uint16_t sco_handle)228 BT_HDR* btm_sco_make_packet(std::vector<uint8_t> data, uint16_t sco_handle) {
229 ASSERT_LOG(data.size() <= BTM_SCO_DATA_SIZE_MAX, "Invalid SCO data size: %zu",
230 data.size());
231 BT_HDR* p_buf = (BT_HDR*)osi_calloc(BT_SMALL_BUFFER_SIZE);
232 p_buf->event = BT_EVT_TO_LM_HCI_SCO;
233 // SCO header size is 3 per Core 5.2 Vol 4 Part E 5.4.3 figure 5.3
234 p_buf->len = data.size() + 3;
235 uint8_t* payload = p_buf->data;
236 UINT16_TO_STREAM(payload, sco_handle);
237 UINT8_TO_STREAM(payload, data.size());
238 ARRAY_TO_STREAM(payload, data.data(), static_cast<int>(data.size()));
239 return p_buf;
240 }
241
242 /*******************************************************************************
243 *
244 * Function btm_send_connect_request
245 *
246 * Description This function is called to respond to SCO connect
247 * indications
248 *
249 * Returns void
250 *
251 ******************************************************************************/
btm_send_connect_request(uint16_t acl_handle,enh_esco_params_t * p_setup)252 static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle,
253 enh_esco_params_t* p_setup) {
254 /* Send connect request depending on version of spec */
255 if (!btm_cb.sco_cb.esco_supported) {
256 LOG(INFO) << __func__ << ": sending non-eSCO request for handle="
257 << unsigned(acl_handle);
258 btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types));
259 } else {
260 /* Save the previous values in case command fails */
261 uint16_t saved_packet_types = p_setup->packet_types;
262 uint8_t saved_retransmission_effort = p_setup->retransmission_effort;
263 uint16_t saved_max_latency_ms = p_setup->max_latency_ms;
264
265 uint16_t temp_packet_types =
266 (p_setup->packet_types &
267 static_cast<uint16_t>(BTM_SCO_SUPPORTED_PKTS_MASK) &
268 btm_cb.btm_sco_pkt_types_supported);
269
270 /* OR in any exception packet types */
271 temp_packet_types |=
272 ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
273 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
274
275 /* Finally, remove EDR eSCO if the remote device doesn't support it */
276 /* UPF25: Only SCO was brought up in this case */
277 const RawAddress bd_addr = acl_address_from_handle(acl_handle);
278 if (bd_addr != RawAddress::kEmpty) {
279 if (!sco_peer_supports_esco_2m_phy(bd_addr)) {
280 BTM_TRACE_DEBUG("BTM Remote does not support 2-EDR eSCO");
281 temp_packet_types |=
282 (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5);
283 }
284 if (!sco_peer_supports_esco_3m_phy(bd_addr)) {
285 BTM_TRACE_DEBUG("BTM Remote does not support 3-EDR eSCO");
286 temp_packet_types |=
287 (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV5);
288 }
289 if (!sco_peer_supports_esco_ev3(bd_addr)) {
290 BTM_TRACE_DEBUG("BTM Remote does not support EV3 eSCO");
291 // If EV3 is not supported, EV4 and EV% are not supported, either.
292 temp_packet_types &= ~BTM_ESCO_LINK_ONLY_MASK;
293 p_setup->retransmission_effort = ESCO_RETRANSMISSION_OFF;
294 p_setup->max_latency_ms = 10;
295 }
296
297 /* Check to see if BR/EDR Secure Connections is being used
298 ** If so, we cannot use SCO-only packet types (HFP 1.7)
299 */
300 const bool local_supports_sc =
301 controller_get_interface()->supports_secure_connections();
302 const bool remote_supports_sc =
303 BTM_PeerSupportsSecureConnections(bd_addr);
304
305 if (local_supports_sc && remote_supports_sc) {
306 temp_packet_types &= ~(BTM_SCO_PKT_TYPE_MASK);
307 if (temp_packet_types == 0) {
308 LOG_ERROR(
309 "SCO connection cannot support any packet types for "
310 "acl_handle:0x%04x",
311 acl_handle);
312 return BTM_WRONG_MODE;
313 }
314 LOG_DEBUG(
315 "Both local and remote controllers support SCO secure connections "
316 "handle:0x%04x pkt_types:0x%04x",
317 acl_handle, temp_packet_types);
318
319 } else if (!local_supports_sc && !remote_supports_sc) {
320 LOG_DEBUG(
321 "Both local and remote controllers do not support secure "
322 "connections for handle:0x%04x",
323 acl_handle);
324 } else if (remote_supports_sc) {
325 LOG_DEBUG(
326 "Only remote controller supports secure connections for "
327 "handle:0x%04x",
328 acl_handle);
329 } else {
330 LOG_DEBUG(
331 "Only local controller supports secure connections for "
332 "handle:0x%04x",
333 acl_handle);
334 }
335 } else {
336 LOG_ERROR("Received SCO connect from unknown peer:%s",
337 PRIVATE_ADDRESS(bd_addr));
338 }
339
340 p_setup->packet_types = temp_packet_types;
341
342 /* Use Enhanced Synchronous commands if supported */
343 if (controller_get_interface()
344 ->supports_enhanced_setup_synchronous_connection()) {
345 LOG_INFO("Sending enhanced SCO connect request over handle:0x%04x",
346 acl_handle);
347 /* Use the saved SCO routing */
348 p_setup->input_data_path = p_setup->output_data_path = ESCO_DATA_PATH;
349 LOG(INFO) << __func__ << std::hex << ": enhanced parameter list"
350 << " txbw=0x" << unsigned(p_setup->transmit_bandwidth)
351 << ", rxbw=0x" << unsigned(p_setup->receive_bandwidth)
352 << ", latency_ms=0x" << unsigned(p_setup->max_latency_ms)
353 << ", retransmit_effort=0x"
354 << unsigned(p_setup->retransmission_effort) << ", pkt_type=0x"
355 << unsigned(p_setup->packet_types) << ", path=0x"
356 << unsigned(p_setup->input_data_path);
357 btsnd_hcic_enhanced_set_up_synchronous_connection(acl_handle, p_setup);
358 p_setup->packet_types = saved_packet_types;
359 p_setup->retransmission_effort = saved_retransmission_effort;
360 p_setup->max_latency_ms = saved_max_latency_ms;
361 } else { /* Use older command */
362 LOG_INFO("Sending eSCO connect request over handle:0x%04x", acl_handle);
363 uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
364 LOG(INFO) << __func__ << std::hex << ": legacy parameter list"
365 << " txbw=0x" << unsigned(p_setup->transmit_bandwidth)
366 << ", rxbw=0x" << unsigned(p_setup->receive_bandwidth)
367 << ", latency_ms=0x" << unsigned(p_setup->max_latency_ms)
368 << ", retransmit_effort=0x"
369 << unsigned(p_setup->retransmission_effort)
370 << ", voice_content_format=0x" << unsigned(voice_content_format)
371 << ", pkt_type=0x" << unsigned(p_setup->packet_types);
372 btsnd_hcic_setup_esco_conn(
373 acl_handle, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
374 p_setup->max_latency_ms, voice_content_format,
375 p_setup->retransmission_effort, p_setup->packet_types);
376 }
377 }
378
379 return (BTM_CMD_STARTED);
380 }
381
382 /*******************************************************************************
383 *
384 * Function BTM_CreateSco
385 *
386 * Description This function is called to create an SCO connection. If the
387 * "is_orig" flag is true, the connection will be originated,
388 * otherwise BTM will wait for the other side to connect.
389 *
390 * NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
391 * parameter the default packet types is used.
392 *
393 * Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
394 * BTM_BUSY if another SCO being set up to
395 * the same BD address
396 * BTM_NO_RESOURCES if the max SCO limit has been reached
397 * BTM_CMD_STARTED if the connection establishment is started.
398 * In this case, "*p_sco_inx" is filled in
399 * with the sco index used for the connection.
400 *
401 ******************************************************************************/
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)402 tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,
403 uint16_t pkt_types, uint16_t* p_sco_inx,
404 tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {
405 enh_esco_params_t* p_setup;
406 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
407 uint16_t xx;
408 uint16_t acl_handle = HCI_INVALID_HANDLE;
409 *p_sco_inx = BTM_INVALID_SCO_INDEX;
410
411 if (BTM_MAX_SCO_LINKS == 0) {
412 return BTM_NO_RESOURCES;
413 }
414
415 /* If originating, ensure that there is an ACL connection to the BD Address */
416
417 if (is_orig) {
418 if (!remote_bda) {
419 LOG(ERROR) << __func__ << ": remote_bda is null";
420 return BTM_ILLEGAL_VALUE;
421 }
422 acl_handle = BTM_GetHCIConnHandle(*remote_bda, BT_TRANSPORT_BR_EDR);
423 if (acl_handle == HCI_INVALID_HANDLE) {
424 LOG(ERROR) << __func__ << ": cannot find ACL handle for remote device "
425 << remote_bda;
426 return BTM_UNKNOWN_ADDR;
427 }
428 }
429
430 if (remote_bda) {
431 /* If any SCO is being established to the remote BD address, refuse this */
432 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
433 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
434 (p->state == SCO_ST_PEND_UNPARK)) &&
435 (p->esco.data.bd_addr == *remote_bda)) {
436 LOG(ERROR) << __func__ << ": a sco connection is already going on for "
437 << *remote_bda << ", at state " << unsigned(p->state);
438 return BTM_BUSY;
439 }
440 }
441 } else {
442 /* Support only 1 wildcard BD address at a time */
443 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
444 if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) {
445 LOG(ERROR)
446 << __func__
447 << ": remote_bda is null and not known and we are still listening";
448 return BTM_BUSY;
449 }
450 }
451 }
452
453 /* Try to find an unused control block, and kick off the SCO establishment */
454 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS;
455 xx++, p++) {
456 if (p->state == SCO_ST_UNUSED) {
457 if (remote_bda) {
458 if (is_orig) {
459 // can not create SCO link if in park mode
460 tBTM_PM_STATE state;
461 if (BTM_ReadPowerMode(*remote_bda, &state)) {
462 if (state == BTM_PM_ST_SNIFF || state == BTM_PM_ST_PARK ||
463 state == BTM_PM_ST_PENDING) {
464 LOG(INFO) << __func__ << ": " << *remote_bda
465 << " in sniff, park or pending mode "
466 << unsigned(state);
467 if (!BTM_SetLinkPolicyActiveMode(*remote_bda)) {
468 LOG_WARN("Unable to set link policy active");
469 }
470 p->state = SCO_ST_PEND_UNPARK;
471 }
472 } else {
473 LOG(ERROR) << __func__ << ": failed to read power mode for "
474 << *remote_bda;
475 }
476 }
477 p->esco.data.bd_addr = *remote_bda;
478 p->rem_bd_known = true;
479 } else
480 p->rem_bd_known = false;
481
482 p_setup = &p->esco.setup;
483 *p_setup = btm_cb.sco_cb.def_esco_parms;
484
485 /* Determine the packet types */
486 p_setup->packet_types = pkt_types & BTM_SCO_SUPPORTED_PKTS_MASK &
487 btm_cb.btm_sco_pkt_types_supported;
488 /* OR in any exception packet types */
489 if (controller_get_interface()->get_bt_version()->hci_version >=
490 HCI_PROTO_VERSION_2_0) {
491 p_setup->packet_types |=
492 (pkt_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
493 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK);
494 }
495
496 p->p_conn_cb = p_conn_cb;
497 p->p_disc_cb = p_disc_cb;
498 p->hci_handle = HCI_INVALID_HANDLE;
499 p->is_orig = is_orig;
500
501 if (p->state != SCO_ST_PEND_UNPARK) {
502 if (is_orig) {
503 /* If role change is in progress, do not proceed with SCO setup
504 * Wait till role change is complete */
505 if (!acl_is_switch_role_idle(*remote_bda, BT_TRANSPORT_BR_EDR)) {
506 BTM_TRACE_API("Role Change is in progress for ACL handle 0x%04x",
507 acl_handle);
508 p->state = SCO_ST_PEND_ROLECHANGE;
509 }
510 }
511 }
512
513 if (p->state != SCO_ST_PEND_UNPARK &&
514 p->state != SCO_ST_PEND_ROLECHANGE) {
515 if (is_orig) {
516 LOG_DEBUG("Initiating (e)SCO link for ACL handle:0x%04x", acl_handle);
517
518 if ((btm_send_connect_request(acl_handle, p_setup)) !=
519 BTM_CMD_STARTED) {
520 LOG(ERROR) << __func__ << ": failed to send connect request for "
521 << *remote_bda;
522 return (BTM_NO_RESOURCES);
523 }
524
525 p->state = SCO_ST_CONNECTING;
526 } else {
527 LOG_DEBUG("Listening for (e)SCO on ACL handle:0x%04x", acl_handle);
528 p->state = SCO_ST_LISTENING;
529 }
530 }
531
532 *p_sco_inx = xx;
533 LOG_DEBUG("SCO connection successfully requested");
534 if (p->state == SCO_ST_CONNECTING) {
535 BTM_LogHistory(
536 kBtmLogTag, *remote_bda, "Connecting",
537 base::StringPrintf("local initiated acl:0x%04x", acl_handle));
538 }
539 return BTM_CMD_STARTED;
540 }
541 }
542
543 /* If here, all SCO blocks in use */
544 LOG(ERROR) << __func__ << ": all SCO control blocks are in use";
545 return BTM_NO_RESOURCES;
546 }
547
548 /*******************************************************************************
549 *
550 * Function btm_sco_chk_pend_unpark
551 *
552 * Description This function is called by BTIF when there is a mode change
553 * event to see if there are SCO commands waiting for the
554 * unpark.
555 *
556 * Returns void
557 *
558 ******************************************************************************/
btm_sco_chk_pend_unpark(tHCI_STATUS hci_status,uint16_t hci_handle)559 void btm_sco_chk_pend_unpark(tHCI_STATUS hci_status, uint16_t hci_handle) {
560 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
561 for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
562 uint16_t acl_handle =
563 BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR);
564 if ((p->state == SCO_ST_PEND_UNPARK) && (acl_handle == hci_handle)) {
565 LOG(INFO) << __func__ << ": " << p->esco.data.bd_addr
566 << " unparked, sending connection request, acl_handle="
567 << unsigned(acl_handle)
568 << ", hci_status=" << unsigned(hci_status);
569 if (btm_send_connect_request(acl_handle, &p->esco.setup) ==
570 BTM_CMD_STARTED) {
571 p->state = SCO_ST_CONNECTING;
572 } else {
573 LOG(ERROR) << __func__ << ": failed to send connection request for "
574 << p->esco.data.bd_addr;
575 }
576 }
577 }
578 }
579
580 /*******************************************************************************
581 *
582 * Function btm_sco_chk_pend_rolechange
583 *
584 * Description This function is called by BTIF when there is a role change
585 * event to see if there are SCO commands waiting for the role
586 * change.
587 *
588 * Returns void
589 *
590 ******************************************************************************/
btm_sco_chk_pend_rolechange(uint16_t hci_handle)591 void btm_sco_chk_pend_rolechange(uint16_t hci_handle) {
592 uint16_t xx;
593 uint16_t acl_handle;
594 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
595
596 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
597 if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
598 ((acl_handle = BTM_GetHCIConnHandle(
599 p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
600
601 {
602 BTM_TRACE_API(
603 "btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x%04x",
604 acl_handle);
605
606 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) ==
607 BTM_CMD_STARTED)
608 p->state = SCO_ST_CONNECTING;
609 }
610 }
611 }
612
613 /*******************************************************************************
614 *
615 * Function btm_sco_disc_chk_pend_for_modechange
616 *
617 * Description This function is called by btm when there is a mode change
618 * event to see if there are SCO disconnect commands waiting
619 * for the mode change.
620 *
621 * Returns void
622 *
623 ******************************************************************************/
btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle)624 void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle) {
625 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
626
627 LOG_DEBUG(
628 "Checking for SCO pending mode change events hci_handle:0x%04x "
629 "p->state:%s",
630 hci_handle, sco_state_text(p->state).c_str());
631
632 for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
633 if ((p->state == SCO_ST_PEND_MODECHANGE) &&
634 (BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) ==
635 hci_handle)
636
637 {
638 LOG_DEBUG("Removing SCO Link handle 0x%04x", p->hci_handle);
639 BTM_RemoveSco(xx);
640 }
641 }
642 }
643
644 /*******************************************************************************
645 *
646 * Function btm_sco_conn_req
647 *
648 * Description This function is called by BTU HCIF when an SCO connection
649 * request is received from a remote.
650 *
651 * Returns void
652 *
653 ******************************************************************************/
btm_sco_conn_req(const RawAddress & bda,const DEV_CLASS & dev_class,uint8_t link_type)654 void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
655 uint8_t link_type) {
656 tSCO_CB* p_sco = &btm_cb.sco_cb;
657 tSCO_CONN* p = &p_sco->sco_db[0];
658 tBTM_ESCO_CONN_REQ_EVT_DATA evt_data = {};
659
660 for (uint16_t sco_index = 0; sco_index < BTM_MAX_SCO_LINKS;
661 sco_index++, p++) {
662 /*
663 * If the sco state is in the SCO_ST_CONNECTING state, we still need
664 * to return accept sco to avoid race conditon for sco creation
665 */
666 bool rem_bd_matches = p->rem_bd_known && p->esco.data.bd_addr == bda;
667 if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
668 ((p->state == SCO_ST_LISTENING) &&
669 (rem_bd_matches || !p->rem_bd_known))) {
670 /* If this was a wildcard, it is not one any more */
671 p->rem_bd_known = true;
672 p->esco.data.link_type = link_type;
673 p->state = SCO_ST_W4_CONN_RSP;
674 p->esco.data.bd_addr = bda;
675
676 /* If no callback, auto-accept the connection if packet types match */
677 if (!p->esco.p_esco_cback) {
678 /* If requesting eSCO reject if default parameters are SCO only */
679 if ((link_type == BTM_LINK_TYPE_ESCO &&
680 !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK) &&
681 ((p_sco->def_esco_parms.packet_types &
682 BTM_SCO_EXCEPTION_PKTS_MASK) == BTM_SCO_EXCEPTION_PKTS_MASK))
683
684 /* Reject request if SCO is desired but no SCO packets delected */
685 ||
686 (link_type == BTM_LINK_TYPE_SCO &&
687 !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) {
688 btm_esco_conn_rsp(sco_index, HCI_ERR_HOST_REJECT_RESOURCES, bda,
689 nullptr);
690 } else {
691 /* Accept the request */
692 btm_esco_conn_rsp(sco_index, HCI_SUCCESS, bda, nullptr);
693 }
694 } else {
695 /* Notify upper layer of connect indication */
696 evt_data.bd_addr = bda;
697 memcpy(evt_data.dev_class, dev_class, DEV_CLASS_LEN);
698 evt_data.link_type = link_type;
699 evt_data.sco_inx = sco_index;
700 tBTM_ESCO_EVT_DATA btm_esco_evt_data = {};
701 btm_esco_evt_data.conn_evt = evt_data;
702 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, &btm_esco_evt_data);
703 }
704
705 return;
706 }
707 }
708
709 /* If here, no one wants the SCO connection. Reject it */
710 BTM_TRACE_WARNING("%s: rejecting SCO for %s", __func__,
711 bda.ToString().c_str());
712 btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda,
713 nullptr);
714 }
715
716 /*******************************************************************************
717 *
718 * Function btm_sco_connected
719 *
720 * Description This function is called by BTIF when an (e)SCO connection
721 * is connected.
722 *
723 * Returns void
724 *
725 ******************************************************************************/
btm_sco_connected(const RawAddress & bda,uint16_t hci_handle,tBTM_ESCO_DATA * p_esco_data)726 void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle,
727 tBTM_ESCO_DATA* p_esco_data) {
728 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
729 uint16_t xx;
730 bool spt = false;
731 tBTM_CHG_ESCO_PARAMS parms = {};
732
733 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
734 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
735 (p->state == SCO_ST_W4_CONN_RSP)) &&
736 (p->rem_bd_known) && (p->esco.data.bd_addr == bda)) {
737 BTM_LogHistory(
738 kBtmLogTag, bda, "Connection created",
739 base::StringPrintf("sco_idx:%hu handle:0x%04x ", xx, hci_handle));
740
741 if (p->state == SCO_ST_LISTENING) spt = true;
742
743 p->state = SCO_ST_CONNECTED;
744 p->hci_handle = hci_handle;
745
746 BTM_LogHistory(kBtmLogTag, bda, "Connection success",
747 base::StringPrintf("handle:0x%04x %s", hci_handle,
748 (spt) ? "listener" : "initiator"));
749
750 if (!btm_cb.sco_cb.esco_supported) {
751 p->esco.data.link_type = BTM_LINK_TYPE_SCO;
752 if (spt) {
753 parms.packet_types = p->esco.setup.packet_types;
754 /* Keep the other parameters the same for SCO */
755 parms.max_latency_ms = p->esco.setup.max_latency_ms;
756 parms.retransmission_effort = p->esco.setup.retransmission_effort;
757
758 BTM_ChangeEScoLinkParms(xx, &parms);
759 }
760 } else {
761 if (p_esco_data) p->esco.data = *p_esco_data;
762 }
763
764 (*p->p_conn_cb)(xx);
765
766 bluetooth::audio::sco::open();
767
768 return;
769 }
770 }
771 }
772
773 /*******************************************************************************
774 *
775 * Function btm_sco_connection_failed
776 *
777 * Description This function is called by BTIF when an (e)SCO connection
778 * setup is failed.
779 *
780 * Returns void
781 *
782 ******************************************************************************/
btm_sco_connection_failed(tHCI_STATUS hci_status,const RawAddress & bda,uint16_t hci_handle,tBTM_ESCO_DATA * p_esco_data)783 void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda,
784 uint16_t hci_handle,
785 tBTM_ESCO_DATA* p_esco_data) {
786 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
787 uint16_t xx;
788
789 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
790 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
791 (p->state == SCO_ST_W4_CONN_RSP)) &&
792 (p->rem_bd_known) &&
793 (p->esco.data.bd_addr == bda || bda == RawAddress::kEmpty)) {
794 /* Report the error if originator, otherwise remain in Listen mode */
795 if (p->is_orig) {
796 LOG_DEBUG("SCO initiating connection failed handle:0x%04x reason:%s",
797 hci_handle, hci_error_code_text(hci_status).c_str());
798 switch (hci_status) {
799 case HCI_ERR_ROLE_SWITCH_PENDING:
800 /* If role switch is pending, we need try again after role switch
801 * is complete */
802 p->state = SCO_ST_PEND_ROLECHANGE;
803 break;
804 case HCI_ERR_LMP_ERR_TRANS_COLLISION:
805 /* Avoid calling disconnect callback because of sco creation race
806 */
807 break;
808 default: /* Notify client about SCO failure */
809 p->state = SCO_ST_UNUSED;
810 (*p->p_disc_cb)(xx);
811 }
812 BTM_LogHistory(
813 kBtmLogTag, bda, "Connection failed",
814 base::StringPrintf(
815 "locally_initiated reason:%s",
816 hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
817 .c_str()));
818 } else {
819 LOG_DEBUG("SCO terminating connection failed handle:0x%04x reason:%s",
820 hci_handle, hci_error_code_text(hci_status).c_str());
821 if (p->state == SCO_ST_CONNECTING) {
822 p->state = SCO_ST_UNUSED;
823 (*p->p_disc_cb)(xx);
824 } else
825 p->state = SCO_ST_LISTENING;
826 BTM_LogHistory(
827 kBtmLogTag, bda, "Connection failed",
828 base::StringPrintf(
829 "remote_initiated reason:%s",
830 hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
831 .c_str()));
832 }
833 return;
834 }
835 }
836 }
837
838 /*******************************************************************************
839 *
840 * Function BTM_RemoveSco
841 *
842 * Description This function is called to remove a specific SCO connection.
843 *
844 * Returns status of the operation
845 *
846 ******************************************************************************/
BTM_RemoveSco(uint16_t sco_inx)847 tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) {
848 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
849 tBTM_PM_STATE state = BTM_PM_ST_INVALID;
850
851 BTM_TRACE_DEBUG("%s", __func__);
852
853 if (BTM_MAX_SCO_LINKS == 0) {
854 return BTM_NO_RESOURCES;
855 }
856
857 /* Validity check */
858 if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
859 return (BTM_UNKNOWN_ADDR);
860
861 /* If no HCI handle, simply drop the connection and return */
862 if (p->hci_handle == HCI_INVALID_HANDLE || p->state == SCO_ST_PEND_UNPARK) {
863 p->hci_handle = HCI_INVALID_HANDLE;
864 p->state = SCO_ST_UNUSED;
865 p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
866 return (BTM_SUCCESS);
867 }
868
869 if (BTM_ReadPowerMode(p->esco.data.bd_addr, &state) &&
870 (state == BTM_PM_ST_PENDING)) {
871 BTM_TRACE_DEBUG("%s: BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x%04x",
872 __func__, p->hci_handle);
873 p->state = SCO_ST_PEND_MODECHANGE;
874 return (BTM_CMD_STARTED);
875 }
876
877 tSCO_STATE old_state = p->state;
878 p->state = SCO_ST_DISCONNECTING;
879
880 GetLegacyHciInterface().Disconnect(p->Handle(), HCI_ERR_PEER_USER);
881
882 LOG_DEBUG("Disconnecting link sco_handle:0x%04x peer:%s", p->Handle(),
883 PRIVATE_ADDRESS(p->esco.data.bd_addr));
884 BTM_LogHistory(
885 kBtmLogTag, p->esco.data.bd_addr, "Disconnecting",
886 base::StringPrintf("local initiated handle:0x%04x previous_state:%s",
887 p->Handle(), sco_state_text(old_state).c_str()));
888 return (BTM_CMD_STARTED);
889 }
890
BTM_RemoveSco(const RawAddress & bda)891 void BTM_RemoveSco(const RawAddress& bda) {
892 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
893 uint16_t xx;
894
895 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
896 if (p->rem_bd_known && p->esco.data.bd_addr == bda) {
897 BTM_RemoveSco(xx);
898 }
899 }
900 }
901
902 /*******************************************************************************
903 *
904 * Function btm_sco_removed
905 *
906 * Description This function is called by lower layers when an
907 * disconnect is received.
908 *
909 * Returns true if the link is known about, else false
910 *
911 ******************************************************************************/
btm_sco_removed(uint16_t hci_handle,tHCI_REASON reason)912 bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason) {
913 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
914 uint16_t xx;
915
916 p = &btm_cb.sco_cb.sco_db[0];
917 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
918 if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) &&
919 (p->hci_handle == hci_handle)) {
920 p->state = SCO_ST_UNUSED;
921 p->hci_handle = HCI_INVALID_HANDLE;
922 p->rem_bd_known = false;
923 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
924 (*p->p_disc_cb)(xx);
925 LOG_DEBUG("Disconnected SCO link handle:%hu reason:%s", hci_handle,
926 hci_reason_code_text(reason).c_str());
927 return true;
928 }
929 }
930 return false;
931 }
932
btm_sco_on_esco_connect_request(const RawAddress & bda,const bluetooth::types::ClassOfDevice & cod)933 void btm_sco_on_esco_connect_request(
934 const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod) {
935 LOG_DEBUG("Remote ESCO connect request remote:%s cod:%s",
936 PRIVATE_ADDRESS(bda), cod.ToString().c_str());
937 btm_sco_conn_req(bda, cod.cod, BTM_LINK_TYPE_ESCO);
938 }
939
btm_sco_on_sco_connect_request(const RawAddress & bda,const bluetooth::types::ClassOfDevice & cod)940 void btm_sco_on_sco_connect_request(
941 const RawAddress& bda, const bluetooth::types::ClassOfDevice& cod) {
942 LOG_DEBUG("Remote SCO connect request remote:%s cod:%s", PRIVATE_ADDRESS(bda),
943 cod.ToString().c_str());
944 btm_sco_conn_req(bda, cod.cod, BTM_LINK_TYPE_SCO);
945 }
946
btm_sco_on_disconnected(uint16_t hci_handle,tHCI_REASON reason)947 void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) {
948 tSCO_CONN* p_sco = btm_cb.sco_cb.get_sco_connection_from_handle(hci_handle);
949 if (p_sco == nullptr) {
950 LOG_ERROR("Unable to find sco connection");
951 return;
952 }
953
954 if (!p_sco->is_active()) {
955 LOG_ERROR("Connection is not active handle:0x%04x reason:%s", hci_handle,
956 hci_reason_code_text(reason).c_str());
957 return;
958 }
959
960 if (p_sco->state == SCO_ST_LISTENING) {
961 LOG_ERROR("Connection is in listening state handle:0x%04x reason:%s",
962 hci_handle, hci_reason_code_text(reason).c_str());
963 return;
964 }
965
966 const RawAddress bd_addr(p_sco->esco.data.bd_addr);
967
968 p_sco->state = SCO_ST_UNUSED;
969 p_sco->hci_handle = HCI_INVALID_HANDLE;
970 p_sco->rem_bd_known = false;
971 p_sco->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
972 (*p_sco->p_disc_cb)(btm_cb.sco_cb.get_index(p_sco));
973 LOG_DEBUG("Disconnected SCO link handle:%hu reason:%s", hci_handle,
974 hci_reason_code_text(reason).c_str());
975 BTM_LogHistory(kBtmLogTag, bd_addr, "Disconnected",
976 base::StringPrintf("handle:0x%04x reason:%s", hci_handle,
977 hci_reason_code_text(reason).c_str()));
978
979 bluetooth::audio::sco::cleanup();
980 }
981
982 /*******************************************************************************
983 *
984 * Function btm_sco_acl_removed
985 *
986 * Description This function is called when an ACL connection is
987 * removed. If the BD address is NULL, it is assumed that
988 * the local device is down, and all SCO links are removed.
989 * If a specific BD address is passed, only SCO connections
990 * to that BD address are removed.
991 *
992 * Returns void
993 *
994 ******************************************************************************/
btm_sco_acl_removed(const RawAddress * bda)995 void btm_sco_acl_removed(const RawAddress* bda) {
996 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
997 uint16_t xx;
998
999 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1000 if (p->state != SCO_ST_UNUSED) {
1001 if ((!bda) || (p->esco.data.bd_addr == *bda && p->rem_bd_known)) {
1002 p->state = SCO_ST_UNUSED;
1003 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1004 (*p->p_disc_cb)(xx);
1005 }
1006 }
1007 }
1008 }
1009
1010 /*******************************************************************************
1011 *
1012 * Function BTM_ReadScoBdAddr
1013 *
1014 * Description This function is read the remote BD Address for a specific
1015 * SCO connection,
1016 *
1017 * Returns pointer to BD address or NULL if not known
1018 *
1019 ******************************************************************************/
BTM_ReadScoBdAddr(uint16_t sco_inx)1020 const RawAddress* BTM_ReadScoBdAddr(uint16_t sco_inx) {
1021 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1022
1023 /* Validity check */
1024 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1025 return &(p->esco.data.bd_addr);
1026 else
1027 return (NULL);
1028 }
1029
1030 /*******************************************************************************
1031 *
1032 * Function BTM_SetEScoMode
1033 *
1034 * Description This function sets up the negotiated parameters for SCO or
1035 * eSCO, and sets as the default mode used for outgoing calls
1036 * to BTM_CreateSco. It does not change any currently active
1037 * (e)SCO links.
1038 * Note: Incoming (e)SCO connections will always use packet
1039 * types supported by the controller. If eSCO is not
1040 * desired the feature should be disabled in the
1041 * controller's feature mask.
1042 *
1043 * Returns BTM_SUCCESS if the successful.
1044 * BTM_BUSY if there are one or more active (e)SCO links.
1045 *
1046 ******************************************************************************/
BTM_SetEScoMode(enh_esco_params_t * p_parms)1047 tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) {
1048 ASSERT_LOG(p_parms != nullptr, "eSCO parameters must have a value");
1049 enh_esco_params_t* p_def = &btm_cb.sco_cb.def_esco_parms;
1050
1051 if (btm_cb.sco_cb.esco_supported) {
1052 *p_def = *p_parms;
1053 LOG_DEBUG(
1054 "Setting eSCO mode parameters txbw:0x%08x rxbw:0x%08x max_lat:0x%04x"
1055 " pkt:0x%04x rtx_effort:0x%02x",
1056 p_def->transmit_bandwidth, p_def->receive_bandwidth,
1057 p_def->max_latency_ms, p_def->packet_types,
1058 p_def->retransmission_effort);
1059 } else {
1060 /* Load defaults for SCO only */
1061 *p_def = esco_parameters_for_codec(SCO_CODEC_CVSD_D1);
1062 LOG_WARN("eSCO not supported so setting SCO parameters instead");
1063 LOG_DEBUG(
1064 "Setting SCO mode parameters txbw:0x%08x rxbw:0x%08x max_lat:0x%04x"
1065 " pkt:0x%04x rtx_effort:0x%02x",
1066 p_def->transmit_bandwidth, p_def->receive_bandwidth,
1067 p_def->max_latency_ms, p_def->packet_types,
1068 p_def->retransmission_effort);
1069 }
1070 return BTM_SUCCESS;
1071 }
1072
1073 /*******************************************************************************
1074 *
1075 * Function BTM_RegForEScoEvts
1076 *
1077 * Description This function registers a SCO event callback with the
1078 * specified instance. It should be used to received
1079 * connection indication events and change of link parameter
1080 * events.
1081 *
1082 * Returns BTM_SUCCESS if the successful.
1083 * BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1084 * BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1085 * later or does not support eSCO.
1086 *
1087 ******************************************************************************/
BTM_RegForEScoEvts(uint16_t sco_inx,tBTM_ESCO_CBACK * p_esco_cback)1088 tBTM_STATUS BTM_RegForEScoEvts(uint16_t sco_inx,
1089 tBTM_ESCO_CBACK* p_esco_cback) {
1090 if (BTM_MAX_SCO_LINKS == 0) {
1091 return BTM_MODE_UNSUPPORTED;
1092 }
1093
1094 if (!btm_cb.sco_cb.esco_supported) {
1095 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1096 return (BTM_MODE_UNSUPPORTED);
1097 }
1098
1099 if (sco_inx < BTM_MAX_SCO_LINKS &&
1100 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) {
1101 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1102 return (BTM_SUCCESS);
1103 }
1104 return (BTM_ILLEGAL_VALUE);
1105 }
1106
1107 /*******************************************************************************
1108 *
1109 * Function BTM_ChangeEScoLinkParms
1110 *
1111 * Description This function requests renegotiation of the parameters on
1112 * the current eSCO Link. If any of the changes are accepted
1113 * by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1114 * the tBTM_ESCO_CBACK function with the current settings of
1115 * the link. The callback is registered through the call to
1116 * BTM_SetEScoMode.
1117 *
1118 * Note: If called over a SCO link (including 1.1 controller),
1119 * a change packet type request is sent out instead.
1120 *
1121 * Returns BTM_CMD_STARTED if command is successfully initiated.
1122 * BTM_NO_RESOURCES - not enough resources to initiate command.
1123 * BTM_WRONG_MODE if no connection with a peer device or bad
1124 * sco_inx.
1125 *
1126 ******************************************************************************/
BTM_ChangeEScoLinkParms(uint16_t sco_inx,tBTM_CHG_ESCO_PARAMS * p_parms)1127 static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
1128 tBTM_CHG_ESCO_PARAMS* p_parms) {
1129 /* Make sure sco handle is valid and on an active link */
1130 if (sco_inx >= BTM_MAX_SCO_LINKS ||
1131 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1132 return (BTM_WRONG_MODE);
1133
1134 tSCO_CONN* p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1135 enh_esco_params_t* p_setup = &p_sco->esco.setup;
1136
1137 /* Save the previous types in case command fails */
1138 uint16_t saved_packet_types = p_setup->packet_types;
1139
1140 /* If SCO connection OR eSCO not supported just send change packet types */
1141 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1142 !btm_cb.sco_cb.esco_supported) {
1143 p_setup->packet_types =
1144 p_parms->packet_types &
1145 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1146
1147 BTM_TRACE_API("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__,
1148 p_sco->hci_handle, p_setup->packet_types);
1149
1150 BTM_TRACE_API("%s: SCO Link for handle 0x%04x, pkt 0x%04x", __func__,
1151 p_sco->hci_handle, p_setup->packet_types);
1152
1153 btsnd_hcic_change_conn_type(p_sco->hci_handle,
1154 BTM_ESCO_2_SCO(p_setup->packet_types));
1155 } else /* eSCO is supported and the link type is eSCO */
1156 {
1157 uint16_t temp_packet_types =
1158 (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1159 btm_cb.btm_sco_pkt_types_supported);
1160
1161 /* OR in any exception packet types */
1162 temp_packet_types |=
1163 ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
1164 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
1165 p_setup->packet_types = temp_packet_types;
1166
1167 BTM_TRACE_API("%s -> eSCO Link for handle 0x%04x", __func__,
1168 p_sco->hci_handle);
1169 BTM_TRACE_API(
1170 " txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x",
1171 p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1172 p_parms->max_latency_ms, p_parms->retransmission_effort,
1173 temp_packet_types);
1174
1175 /* Use Enhanced Synchronous commands if supported */
1176 if (controller_get_interface()
1177 ->supports_enhanced_setup_synchronous_connection()) {
1178 /* Use the saved SCO routing */
1179 p_setup->input_data_path = p_setup->output_data_path = ESCO_DATA_PATH;
1180
1181 btsnd_hcic_enhanced_set_up_synchronous_connection(p_sco->hci_handle,
1182 p_setup);
1183 p_setup->packet_types = saved_packet_types;
1184 } else { /* Use older command */
1185 uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
1186 /* When changing an existing link, only change latency, retrans, and
1187 * pkts */
1188 btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->transmit_bandwidth,
1189 p_setup->receive_bandwidth,
1190 p_parms->max_latency_ms, voice_content_format,
1191 p_parms->retransmission_effort,
1192 p_setup->packet_types);
1193 }
1194
1195 BTM_TRACE_API(
1196 "%s: txbw 0x%x, rxbw 0x%x, lat 0x%x, retrans 0x%02x, pkt 0x%04x",
1197 __func__, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1198 p_parms->max_latency_ms, p_parms->retransmission_effort,
1199 temp_packet_types);
1200 }
1201
1202 return (BTM_CMD_STARTED);
1203 }
1204
1205 /*******************************************************************************
1206 *
1207 * Function BTM_EScoConnRsp
1208 *
1209 * Description This function is called upon receipt of an (e)SCO connection
1210 * request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1211 * the request. Parameters used to negotiate eSCO links.
1212 * If p_parms is NULL, then values set through BTM_SetEScoMode
1213 * are used.
1214 * If the link type of the incoming request is SCO, then only
1215 * the tx_bw, max_latency, content format, and packet_types are
1216 * valid. The hci_status parameter should be
1217 * ([0x0] to accept, [0x0d..0x0f] to reject)
1218 *
1219 *
1220 * Returns void
1221 *
1222 ******************************************************************************/
BTM_EScoConnRsp(uint16_t sco_inx,uint8_t hci_status,enh_esco_params_t * p_parms)1223 void BTM_EScoConnRsp(uint16_t sco_inx, uint8_t hci_status,
1224 enh_esco_params_t* p_parms) {
1225 if (sco_inx < BTM_MAX_SCO_LINKS &&
1226 btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) {
1227 btm_esco_conn_rsp(sco_inx, hci_status,
1228 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, p_parms);
1229 }
1230 }
1231
1232 /*******************************************************************************
1233 *
1234 * Function btm_is_sco_active
1235 *
1236 * Description This function is called to see if a SCO handle is already in
1237 * use.
1238 *
1239 * Returns bool
1240 *
1241 ******************************************************************************/
btm_is_sco_active(uint16_t handle)1242 bool btm_is_sco_active(uint16_t handle) {
1243 uint16_t xx;
1244 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1245
1246 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1247 if (handle == p->hci_handle && p->state == SCO_ST_CONNECTED) return (true);
1248 }
1249 return (false);
1250 }
1251
1252 /*******************************************************************************
1253 *
1254 * Function BTM_GetNumScoLinks
1255 *
1256 * Description This function returns the number of active sco links.
1257 *
1258 * Returns uint8_t
1259 *
1260 ******************************************************************************/
BTM_GetNumScoLinks(void)1261 uint8_t BTM_GetNumScoLinks(void) {
1262 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1263 uint16_t xx;
1264 uint8_t num_scos = 0;
1265
1266 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1267 switch (p->state) {
1268 case SCO_ST_W4_CONN_RSP:
1269 case SCO_ST_CONNECTING:
1270 case SCO_ST_CONNECTED:
1271 case SCO_ST_DISCONNECTING:
1272 case SCO_ST_PEND_UNPARK:
1273 num_scos++;
1274 break;
1275 default:
1276 break;
1277 }
1278 }
1279 return (num_scos);
1280 }
1281
1282 /*******************************************************************************
1283 *
1284 * Function BTM_IsScoActiveByBdaddr
1285 *
1286 * Description This function is called to see if a SCO connection is active
1287 * for a bd address.
1288 *
1289 * Returns bool
1290 *
1291 ******************************************************************************/
BTM_IsScoActiveByBdaddr(const RawAddress & remote_bda)1292 bool BTM_IsScoActiveByBdaddr(const RawAddress& remote_bda) {
1293 uint8_t xx;
1294 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1295
1296 /* If any SCO is being established to the remote BD address, refuse this */
1297 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1298 if (p->esco.data.bd_addr == remote_bda && p->state == SCO_ST_CONNECTED) {
1299 return (true);
1300 }
1301 }
1302 return (false);
1303 }
1304
1305 /*******************************************************************************
1306 *
1307 * Function btm_sco_voice_settings_2_legacy
1308 *
1309 * Description This function is called to convert the Enhanced eSCO
1310 * parameters into voice setting parameter mask used
1311 * for legacy setup synchronous connection HCI commands
1312 *
1313 * Returns UINT16 - 16-bit mask for voice settings
1314 *
1315 * HCI_INP_CODING_LINEAR 0x0000 (0000000000)
1316 * HCI_INP_CODING_U_LAW 0x0100 (0100000000)
1317 * HCI_INP_CODING_A_LAW 0x0200 (1000000000)
1318 * HCI_INP_CODING_MASK 0x0300 (1100000000)
1319 *
1320 * HCI_INP_DATA_FMT_1S_COMPLEMENT 0x0000 (0000000000)
1321 * HCI_INP_DATA_FMT_2S_COMPLEMENT 0x0040 (0001000000)
1322 * HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 (0010000000)
1323 * HCI_INP_DATA_FMT_UNSIGNED 0x00c0 (0011000000)
1324 * HCI_INP_DATA_FMT_MASK 0x00c0 (0011000000)
1325 *
1326 * HCI_INP_SAMPLE_SIZE_8BIT 0x0000 (0000000000)
1327 * HCI_INP_SAMPLE_SIZE_16BIT 0x0020 (0000100000)
1328 * HCI_INP_SAMPLE_SIZE_MASK 0x0020 (0000100000)
1329 *
1330 * HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c (0000011100)
1331 * HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
1332 *
1333 * HCI_AIR_CODING_FORMAT_CVSD 0x0000 (0000000000)
1334 * HCI_AIR_CODING_FORMAT_U_LAW 0x0001 (0000000001)
1335 * HCI_AIR_CODING_FORMAT_A_LAW 0x0002 (0000000010)
1336 * HCI_AIR_CODING_FORMAT_TRANSPNT 0x0003 (0000000011)
1337 * HCI_AIR_CODING_FORMAT_MASK 0x0003 (0000000011)
1338 *
1339 * default (0001100000)
1340 * HCI_DEFAULT_VOICE_SETTINGS (HCI_INP_CODING_LINEAR \
1341 * | HCI_INP_DATA_FMT_2S_COMPLEMENT \
1342 * | HCI_INP_SAMPLE_SIZE_16BIT \
1343 * | HCI_AIR_CODING_FORMAT_CVSD)
1344 *
1345 ******************************************************************************/
btm_sco_voice_settings_to_legacy(enh_esco_params_t * p_params)1346 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_params) {
1347 uint16_t voice_settings = 0;
1348
1349 /* Convert Input Coding Format: If no uLaw or aLAW then Linear will be used
1350 * (0) */
1351 if (p_params->input_coding_format.coding_format == ESCO_CODING_FORMAT_ULAW)
1352 voice_settings |= HCI_INP_CODING_U_LAW;
1353 else if (p_params->input_coding_format.coding_format ==
1354 ESCO_CODING_FORMAT_ALAW)
1355 voice_settings |= HCI_INP_CODING_A_LAW;
1356 /* else default value of '0 is good 'Linear' */
1357
1358 /* Convert Input Data Format. Use 2's Compliment as the default */
1359 switch (p_params->input_pcm_data_format) {
1360 case ESCO_PCM_DATA_FORMAT_1_COMP:
1361 /* voice_settings |= HCI_INP_DATA_FMT_1S_COMPLEMENT; value is '0'
1362 * already */
1363 break;
1364
1365 case ESCO_PCM_DATA_FORMAT_SIGN:
1366 voice_settings |= HCI_INP_DATA_FMT_SIGN_MAGNITUDE;
1367 break;
1368
1369 case ESCO_PCM_DATA_FORMAT_UNSIGN:
1370 voice_settings |= HCI_INP_DATA_FMT_UNSIGNED;
1371 break;
1372
1373 default: /* 2's Compliment */
1374 voice_settings |= HCI_INP_DATA_FMT_2S_COMPLEMENT;
1375 break;
1376 }
1377
1378 /* Convert Over the Air Coding. Use CVSD as the default */
1379 switch (p_params->transmit_coding_format.coding_format) {
1380 case ESCO_CODING_FORMAT_ULAW:
1381 voice_settings |= HCI_AIR_CODING_FORMAT_U_LAW;
1382 break;
1383
1384 case ESCO_CODING_FORMAT_ALAW:
1385 voice_settings |= HCI_AIR_CODING_FORMAT_A_LAW;
1386 break;
1387
1388 case ESCO_CODING_FORMAT_MSBC:
1389 voice_settings |= HCI_AIR_CODING_FORMAT_TRANSPNT;
1390 break;
1391
1392 default: /* CVSD (0) */
1393 break;
1394 }
1395
1396 /* Convert PCM payload MSB position (0000011100) */
1397 voice_settings |= (uint16_t)(((p_params->input_pcm_payload_msb_position & 0x7)
1398 << HCI_INP_LINEAR_PCM_BIT_POS_OFFS));
1399
1400 /* Convert Input Sample Size (0000011100) */
1401 if (p_params->input_coded_data_size == 16)
1402 voice_settings |= HCI_INP_SAMPLE_SIZE_16BIT;
1403 else /* Use 8 bit for all others */
1404 voice_settings |= HCI_INP_SAMPLE_SIZE_8BIT;
1405
1406 BTM_TRACE_DEBUG("%s: voice setting for legacy 0x%03x", __func__,
1407 voice_settings);
1408
1409 return (voice_settings);
1410 }
1411