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 #define LOG_TAG "btm_sco"
27
28 #include "stack/btm/btm_sco.h"
29
30 #include <base/strings/stringprintf.h>
31 #include <bluetooth/log.h>
32
33 #include <cstdint>
34 #include <cstring>
35 #include <string>
36 #include <vector>
37
38 #include "common/bidi_queue.h"
39 #include "device/include/device_iot_config.h"
40 #include "hci/class_of_device.h"
41 #include "hci/controller_interface.h"
42 #include "hci/hci_layer.h"
43 #include "hci/hci_packets.h"
44 #include "hci/include/hci_layer.h"
45 #include "internal_include/bt_target.h"
46 #include "main/shim/entry.h"
47 #include "main/shim/helpers.h"
48 #include "osi/include/properties.h"
49 #include "osi/include/stack_power_telemetry.h"
50 #include "stack/btm/btm_int_types.h"
51 #include "stack/btm/btm_sco_hfp_hal.h"
52 #include "stack/btm/btm_sec.h"
53 #include "stack/include/acl_api.h"
54 #include "stack/include/bt_dev_class.h"
55 #include "stack/include/btm_api.h"
56 #include "stack/include/btm_api_types.h"
57 #include "stack/include/btm_client_interface.h"
58 #include "stack/include/btm_log_history.h"
59 #include "stack/include/hci_error_code.h"
60 #include "stack/include/hcimsgs.h"
61 #include "stack/include/main_thread.h"
62 #include "stack/include/sdpdefs.h"
63 #include "stack/include/stack_metrics_logging.h"
64 #include "types/raw_address.h"
65
66 extern tBTM_CB btm_cb;
67
68 /* Default to allow enhanced connections where supported. */
69 constexpr bool kDefaultDisableEnhancedConnection = false;
70
71 /* Sysprops for SCO connection. */
72 static const char kPropertyDisableEnhancedConnection[] =
73 "bluetooth.sco.disable_enhanced_connection";
74
75 namespace {
76
77 /* Structure passed with SCO change command and events.
78 * Used by both Sync and Enhanced sync messaging
79 */
80 typedef struct {
81 uint16_t max_latency_ms;
82 uint16_t packet_types;
83 uint8_t retransmission_effort;
84 } tBTM_CHG_ESCO_PARAMS;
85
86 constexpr char kBtmLogTag[] = "SCO";
87
88 }; // namespace
89
90 using namespace bluetooth;
91 using bluetooth::legacy::hci::GetInterface;
92
93 // forward declaration for dequeueing packets
94 static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet);
95 void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
96 uint8_t link_type);
97 void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason);
98 bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason);
99
100 namespace cpp {
101 bluetooth::common::BidiQueueEnd<bluetooth::hci::ScoBuilder,
102 bluetooth::hci::ScoView>* hci_sco_queue_end =
103 nullptr;
104 static bluetooth::os::EnqueueBuffer<bluetooth::hci::ScoBuilder>*
105 pending_sco_data = nullptr;
106
sco_data_callback()107 static void sco_data_callback() {
108 if (hci_sco_queue_end == nullptr) {
109 return;
110 }
111 auto packet = hci_sco_queue_end->TryDequeue();
112 log::assert_that(packet != nullptr, "assert failed: packet != nullptr");
113 if (!packet->IsValid()) {
114 log::info("Dropping invalid packet of size {}", packet->size());
115 return;
116 }
117 if (do_in_main_thread(FROM_HERE, base::Bind(&btm_route_sco_data, *packet)) !=
118 BT_STATUS_SUCCESS) {
119 log::error("do_in_main_thread failed from sco_data_callback");
120 }
121 }
register_for_sco()122 static void register_for_sco() {
123 hci_sco_queue_end = bluetooth::shim::GetHciLayer()->GetScoQueueEnd();
124 hci_sco_queue_end->RegisterDequeue(
125 bluetooth::shim::GetGdShimHandler(),
126 bluetooth::common::Bind(sco_data_callback));
127 pending_sco_data =
128 new bluetooth::os::EnqueueBuffer<bluetooth::hci::ScoBuilder>(
129 hci_sco_queue_end);
130
131 // Register SCO for connection requests
132 bluetooth::shim::GetHciLayer()->RegisterForScoConnectionRequests(
133 get_main_thread()->Bind(
134 [](bluetooth::hci::Address peer, bluetooth::hci::ClassOfDevice cod,
135 bluetooth::hci::ConnectionRequestLinkType link_type) {
136 auto peer_raw_address = bluetooth::ToRawAddress(peer);
137 DEV_CLASS dev_class{cod.cod[0], cod.cod[1], cod.cod[2]};
138 if (link_type == bluetooth::hci::ConnectionRequestLinkType::ESCO) {
139 btm_sco_conn_req(peer_raw_address, dev_class,
140 android::bluetooth::LINK_TYPE_ESCO);
141 } else {
142 btm_sco_conn_req(peer_raw_address, dev_class,
143 android::bluetooth::LINK_TYPE_SCO);
144 }
145 }));
146 // Register SCO for disconnect notifications
147 bluetooth::shim::GetHciLayer()->RegisterForDisconnects(
148 get_main_thread()->Bind(
149 [](uint16_t handle, bluetooth::hci::ErrorCode error_code) {
150 auto reason = static_cast<tHCI_REASON>(error_code);
151 btm_sco_on_disconnected(handle, reason);
152 btm_sco_removed(handle, reason);
153 }));
154 }
155
shut_down_sco()156 static void shut_down_sco() {
157 if (pending_sco_data != nullptr) {
158 pending_sco_data->Clear();
159 delete pending_sco_data;
160 pending_sco_data = nullptr;
161 }
162 if (hci_sco_queue_end != nullptr) {
163 hci_sco_queue_end->UnregisterDequeue();
164 hci_sco_queue_end = nullptr;
165 }
166 }
167 }; // namespace cpp
168
Init()169 void tSCO_CB::Init() {
170 hfp_hal_interface::init();
171 def_esco_parms = esco_parameters_for_codec(
172 ESCO_CODEC_CVSD_S3, hfp_hal_interface::get_offload_enabled());
173 cpp::register_for_sco();
174 }
175
Free()176 void tSCO_CB::Free() {
177 cpp::shut_down_sco();
178 bluetooth::audio::sco::cleanup();
179 }
180 /******************************************************************************/
181 /* L O C A L D A T A D E F I N I T I O N S */
182 /******************************************************************************/
183
184 /* MACROs to convert from SCO packet types mask to ESCO and back */
185 #define BTM_SCO_PKT_TYPE_MASK \
186 (HCI_PKT_TYPES_MASK_HV1 | HCI_PKT_TYPES_MASK_HV2 | HCI_PKT_TYPES_MASK_HV3)
187
188 /* Mask defining only the SCO types of an esco packet type */
189 #define BTM_ESCO_PKT_TYPE_MASK \
190 (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | ESCO_PKT_TYPES_MASK_HV3)
191
192 #define BTM_ESCO_2_SCO(escotype) \
193 ((uint16_t)(((escotype)&BTM_ESCO_PKT_TYPE_MASK) << 5))
194
195 /* Define masks for supported and exception 2.0 SCO packet types */
196 #define BTM_SCO_SUPPORTED_PKTS_MASK \
197 (ESCO_PKT_TYPES_MASK_HV1 | ESCO_PKT_TYPES_MASK_HV2 | \
198 ESCO_PKT_TYPES_MASK_HV3 | ESCO_PKT_TYPES_MASK_EV3 | \
199 ESCO_PKT_TYPES_MASK_EV4 | ESCO_PKT_TYPES_MASK_EV5)
200
201 #define BTM_SCO_EXCEPTION_PKTS_MASK \
202 (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV3 | \
203 ESCO_PKT_TYPES_MASK_NO_2_EV5 | ESCO_PKT_TYPES_MASK_NO_3_EV5)
204
205 /* Buffer used for reading PCM data from audio server that will be encoded into
206 * mSBC packet. The BTM_SCO_DATA_SIZE_MAX should be set to a number divisible by
207 * BTM_MSBC_CODE_SIZE(240) */
208 static uint8_t btm_pcm_buf[BTM_SCO_DATA_SIZE_MAX] = {0};
209 static uint8_t packet_buf[BTM_SCO_DATA_SIZE_MAX] = {0};
210
211 /* The read and write offset for btm_pcm_buf.
212 * They are only used for WBS and the unit is byte. */
213 static size_t btm_pcm_buf_read_offset = 0;
214 static size_t btm_pcm_buf_write_offset = 0;
215
216 static bool btm_pcm_buf_write_mirror = false;
217 static bool btm_pcm_buf_read_mirror = false;
218
219 enum btm_pcm_buf_state {
220 DECODE_BUF_EMPTY,
221 DECODE_BUF_FULL,
222
223 // Neither empty nor full.
224 DECODE_BUF_PARTIAL,
225 };
226
incr_btm_pcm_buf_offset(size_t & offset,bool & mirror,size_t amount)227 void incr_btm_pcm_buf_offset(size_t& offset, bool& mirror, size_t amount) {
228 size_t bytes_remaining = BTM_SCO_DATA_SIZE_MAX - offset;
229 if (bytes_remaining > amount) {
230 offset += amount;
231 return;
232 }
233
234 mirror = !mirror;
235 offset = amount - bytes_remaining;
236 }
237
btm_pcm_buf_status()238 btm_pcm_buf_state btm_pcm_buf_status() {
239 if (btm_pcm_buf_read_offset == btm_pcm_buf_write_offset) {
240 if (btm_pcm_buf_read_mirror == btm_pcm_buf_write_mirror)
241 return DECODE_BUF_EMPTY;
242 return DECODE_BUF_FULL;
243 }
244 return DECODE_BUF_PARTIAL;
245 }
246
btm_pcm_buf_data_len()247 size_t btm_pcm_buf_data_len() {
248 switch (btm_pcm_buf_status()) {
249 case DECODE_BUF_EMPTY:
250 return 0;
251 case DECODE_BUF_FULL:
252 return BTM_SCO_DATA_SIZE_MAX;
253 case DECODE_BUF_PARTIAL:
254 default:
255 if (btm_pcm_buf_write_offset > btm_pcm_buf_read_offset)
256 return btm_pcm_buf_write_offset - btm_pcm_buf_read_offset;
257 return BTM_SCO_DATA_SIZE_MAX -
258 (btm_pcm_buf_read_offset - btm_pcm_buf_write_offset);
259 };
260 }
261
btm_pcm_buf_avail_len()262 size_t btm_pcm_buf_avail_len() {
263 return BTM_SCO_DATA_SIZE_MAX - btm_pcm_buf_data_len();
264 }
265
write_btm_pcm_buf(uint8_t * source,size_t amount)266 size_t write_btm_pcm_buf(uint8_t* source, size_t amount) {
267 if (btm_pcm_buf_avail_len() < amount) {
268 return 0;
269 }
270
271 size_t bytes_remaining = BTM_SCO_DATA_SIZE_MAX - btm_pcm_buf_write_offset;
272 if (bytes_remaining > amount) {
273 std::copy(source, source + amount, btm_pcm_buf + btm_pcm_buf_write_offset);
274 } else {
275 std::copy(source, source + bytes_remaining,
276 btm_pcm_buf + btm_pcm_buf_write_offset);
277 std::copy(source + bytes_remaining, source + amount, btm_pcm_buf);
278 }
279
280 incr_btm_pcm_buf_offset(btm_pcm_buf_write_offset, btm_pcm_buf_write_mirror,
281 amount);
282 return amount;
283 }
284
285 /******************************************************************************/
286 /* L O C A L F U N C T I O N P R O T O T Y P E S */
287 /******************************************************************************/
288 static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
289 tBTM_CHG_ESCO_PARAMS* p_parms);
290
291 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_parms);
292
293 /*******************************************************************************
294 *
295 * Function btm_esco_conn_rsp
296 *
297 * Description This function is called upon receipt of an (e)SCO connection
298 * request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
299 * the request. Parameters used to negotiate eSCO links.
300 * If p_parms is NULL, then default values are used.
301 * If the link type of the incoming request is SCO, then only
302 * the tx_bw, max_latency, content format, and packet_types are
303 * valid. The hci_status parameter should be
304 * ([0x0] to accept, [0x0d..0x0f] to reject)
305 *
306 * Returns void
307 *
308 ******************************************************************************/
btm_esco_conn_rsp(uint16_t sco_inx,uint8_t hci_status,const RawAddress & bda,enh_esco_params_t * p_parms)309 static void btm_esco_conn_rsp(uint16_t sco_inx, uint8_t hci_status,
310 const RawAddress& bda,
311 enh_esco_params_t* p_parms) {
312 tSCO_CONN* p_sco = NULL;
313
314 if (BTM_MAX_SCO_LINKS == 0) return;
315
316 if (sco_inx < BTM_MAX_SCO_LINKS) p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
317
318 /* Reject the connect request if refused by caller or wrong state */
319 if (hci_status != HCI_SUCCESS || p_sco == NULL) {
320 if (p_sco) {
321 p_sco->state = (p_sco->state == SCO_ST_W4_CONN_RSP) ? SCO_ST_LISTENING
322 : SCO_ST_UNUSED;
323 }
324 if (!btm_cb.sco_cb.esco_supported) {
325 btsnd_hcic_reject_conn(bda, hci_status);
326 } else {
327 btsnd_hcic_reject_esco_conn(bda, hci_status);
328 }
329 } else {
330 /* Connection is being accepted */
331 p_sco->state = SCO_ST_CONNECTING;
332 enh_esco_params_t* p_setup = &p_sco->esco.setup;
333 /* If parameters not specified use the default */
334 if (p_parms) {
335 *p_setup = *p_parms;
336 } else {
337 /* Use the last setup passed thru BTM_SetEscoMode (or defaults) */
338 *p_setup = btm_cb.sco_cb.def_esco_parms;
339 }
340 /* Use Enhanced Synchronous commands if supported */
341 if (bluetooth::shim::GetController()->IsSupported(
342 bluetooth::hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) &&
343 !osi_property_get_bool(kPropertyDisableEnhancedConnection,
344 kDefaultDisableEnhancedConnection)) {
345 log::verbose(
346 "txbw 0x{:x}, rxbw 0x{:x}, lat 0x{:x}, retrans 0x{:02x}, pkt "
347 "0x{:04x}, path {}",
348 p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
349 p_setup->max_latency_ms, p_setup->retransmission_effort,
350 p_setup->packet_types, p_setup->input_data_path);
351
352 btsnd_hcic_enhanced_accept_synchronous_connection(bda, p_setup);
353
354 } else {
355 /* Use legacy command if enhanced SCO setup is not supported */
356 uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
357 btsnd_hcic_accept_esco_conn(
358 bda, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
359 p_setup->max_latency_ms, voice_content_format,
360 p_setup->retransmission_effort, p_setup->packet_types);
361 }
362 }
363 }
364
365 /* Return the active (first connected) SCO connection block */
btm_get_active_sco()366 static tSCO_CONN* btm_get_active_sco() {
367 for (auto& link : btm_cb.sco_cb.sco_db) {
368 if (link.state == SCO_ST_CONNECTED) {
369 return &link;
370 }
371 }
372 return nullptr;
373 }
374
375 /*******************************************************************************
376 *
377 * Function btm_route_sco_data
378 *
379 * Description Route received SCO data.
380 * This function is triggered when we receive a packet of SCO
381 * data. It regards the received SCO packet as a clock tick to
382 * start the write and read to and from the audio server. It
383 * also tries to balance the write/read data rate between the
384 * Bluetooth and Audio stack by sending and receiving the same
385 * amount of PCM data to and from the audio server.
386 *
387 * Returns void
388 *
389 ******************************************************************************/
btm_route_sco_data(bluetooth::hci::ScoView valid_packet)390 static void btm_route_sco_data(bluetooth::hci::ScoView valid_packet) {
391 uint16_t handle = valid_packet.GetHandle();
392 if (handle > HCI_HANDLE_MAX) {
393 log::error("Dropping SCO data with invalid handle: 0x{:X} > 0x{:X},",
394 handle, HCI_HANDLE_MAX);
395 return;
396 }
397
398 tSCO_CONN* active_sco = btm_get_active_sco();
399 if (active_sco == nullptr) {
400 log::error("Received SCO data when there is no active SCO connection");
401 return;
402 }
403 if (active_sco->hci_handle != handle) {
404 log::error("Dropping packet with handle(0x{:X}) != active handle(0x{:X})",
405 handle, active_sco->hci_handle);
406 return;
407 }
408
409 const auto codec_type = active_sco->get_codec_type();
410 const std::string codec = sco_codec_type_text(codec_type);
411
412 auto data = valid_packet.GetData();
413 auto rx_data = data.data();
414 const uint8_t* decoded = nullptr;
415 size_t written = 0, rc = 0;
416
417 if (codec_type == BTM_SCO_CODEC_MSBC || codec_type == BTM_SCO_CODEC_LC3) {
418 auto status = valid_packet.GetPacketStatusFlag();
419
420 if (status != bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED) {
421 log::debug("{} packet corrupted with status({})", codec,
422 PacketStatusFlagText(status));
423 }
424 auto enqueue_packet = codec_type == BTM_SCO_CODEC_LC3
425 ? &bluetooth::audio::sco::swb::enqueue_packet
426 : &bluetooth::audio::sco::wbs::enqueue_packet;
427 rc = enqueue_packet(
428 data, status != bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED);
429 if (!rc) log::debug("Failed to enqueue {} packet", codec);
430
431 while (rc) {
432 auto decode = codec_type == BTM_SCO_CODEC_LC3
433 ? &bluetooth::audio::sco::swb::decode
434 : &bluetooth::audio::sco::wbs::decode;
435 rc = decode(&decoded);
436 if (rc == 0) break;
437
438 written += bluetooth::audio::sco::write(decoded, rc);
439 }
440 } else {
441 written = bluetooth::audio::sco::write(rx_data, data.size());
442 }
443
444 /* For Chrome OS, we send the outgoing data after receiving an incoming one.
445 * server, so that we can keep the data read/write rate balanced */
446 size_t read = 0;
447 const uint8_t* encoded = nullptr;
448
449 if (codec_type == BTM_SCO_CODEC_MSBC || codec_type == BTM_SCO_CODEC_LC3) {
450 while (written) {
451 size_t avail = btm_pcm_buf_avail_len();
452 if (avail) {
453 size_t to_read = written < avail ? written : avail;
454
455 // Read to the packet_buf first and then copy to the btm_pcm_buf.
456 read = bluetooth::audio::sco::read(packet_buf, to_read);
457
458 write_btm_pcm_buf(packet_buf, read);
459
460 if (read != to_read) {
461 log::info(
462 "Requested to read {} bytes of {} data but got {} bytes of PCM "
463 "data from audio server: WriteOffset:{} ReadOffset:{}",
464 (unsigned long)to_read, codec, (unsigned long)read,
465 (unsigned long)btm_pcm_buf_write_offset,
466 (unsigned long)btm_pcm_buf_read_offset);
467 if (read == 0) break;
468 }
469
470 written -= read;
471 } else {
472 /* We don't break here so that we can still decode the data in the
473 * buffer to spare the buffer space when the buffer is full */
474 log::warn(
475 "Buffer is full when we try to read {} packet from audio server",
476 codec);
477 }
478
479 auto encode = codec_type == BTM_SCO_CODEC_LC3
480 ? &bluetooth::audio::sco::swb::encode
481 : &bluetooth::audio::sco::wbs::encode;
482
483 size_t data_len = btm_pcm_buf_data_len();
484
485 if (data_len) {
486 // Copy all data to the packet_buf first and then call encode.
487 size_t bytes_remaining =
488 BTM_SCO_DATA_SIZE_MAX - btm_pcm_buf_read_offset;
489
490 if (bytes_remaining > data_len) {
491 std::copy(btm_pcm_buf + btm_pcm_buf_read_offset,
492 btm_pcm_buf + btm_pcm_buf_read_offset + data_len,
493 packet_buf);
494 } else {
495 std::copy(btm_pcm_buf + btm_pcm_buf_read_offset,
496 btm_pcm_buf + BTM_SCO_DATA_SIZE_MAX, packet_buf);
497 std::copy(btm_pcm_buf, btm_pcm_buf + data_len - bytes_remaining,
498 packet_buf + bytes_remaining);
499 }
500
501 rc = encode((int16_t*)packet_buf, data_len);
502 incr_btm_pcm_buf_offset(btm_pcm_buf_read_offset,
503 btm_pcm_buf_read_mirror, rc);
504
505 if (!rc)
506 log::debug(
507 "Failed to encode {} data starting at ReadOffset:{} to "
508 "WriteOffset:{}",
509 codec, (unsigned long)btm_pcm_buf_read_offset,
510 (unsigned long)btm_pcm_buf_write_offset);
511 }
512
513 /* Send all of the available SCO packets buffered in the queue */
514 while (1) {
515 auto dequeue_packet = codec_type == BTM_SCO_CODEC_LC3
516 ? &bluetooth::audio::sco::swb::dequeue_packet
517 : &bluetooth::audio::sco::wbs::dequeue_packet;
518 rc = dequeue_packet(&encoded);
519 if (!rc) break;
520
521 auto data = std::vector<uint8_t>(encoded, encoded + rc);
522 btm_send_sco_packet(std::move(data));
523 }
524 }
525 } else {
526 while (written) {
527 read = bluetooth::audio::sco::read(
528 btm_pcm_buf,
529 written < BTM_SCO_DATA_SIZE_MAX ? written : BTM_SCO_DATA_SIZE_MAX);
530 if (read == 0) {
531 log::info("Failed to read {} bytes of PCM data from audio server",
532 (unsigned long)(written < BTM_SCO_DATA_SIZE_MAX
533 ? written
534 : BTM_SCO_DATA_SIZE_MAX));
535 break;
536 }
537 written -= read;
538
539 /* In narrow-band, the CVSD encode is offloaded to controller so we can
540 * send PCM data directly to SCO.
541 * We don't maintain buffer read/write offset for NB as we send all data
542 * that we read from the audio server. */
543 auto data = std::vector<uint8_t>(btm_pcm_buf, btm_pcm_buf + read);
544 btm_send_sco_packet(std::move(data));
545 }
546 }
547 }
548
btm_send_sco_packet(std::vector<uint8_t> data)549 void btm_send_sco_packet(std::vector<uint8_t> data) {
550 auto* active_sco = btm_get_active_sco();
551 if (active_sco == nullptr || data.empty()) {
552 return;
553 }
554 log::assert_that(data.size() <= BTM_SCO_DATA_SIZE_MAX,
555 "Invalid SCO data size: {}", (unsigned long)data.size());
556
557 uint16_t handle_with_flags = active_sco->hci_handle;
558 uint16_t handle = HCID_GET_HANDLE(handle_with_flags);
559 log::assert_that(handle <= HCI_HANDLE_MAX,
560 "Require handle <= 0x{:X}, but is 0x{:X}", HCI_HANDLE_MAX,
561 handle);
562
563 auto sco_packet = bluetooth::hci::ScoBuilder::Create(
564 handle, bluetooth::hci::PacketStatusFlag::CORRECTLY_RECEIVED,
565 std::move(data));
566
567 cpp::pending_sco_data->Enqueue(std::move(sco_packet),
568 bluetooth::shim::GetGdShimHandler());
569 }
570
571 /*******************************************************************************
572 *
573 * Function btm_send_connect_request
574 *
575 * Description This function is called to respond to SCO connect
576 * indications
577 *
578 * Returns void
579 *
580 ******************************************************************************/
btm_send_connect_request(uint16_t acl_handle,enh_esco_params_t * p_setup)581 static tBTM_STATUS btm_send_connect_request(uint16_t acl_handle,
582 enh_esco_params_t* p_setup) {
583 /* Send connect request depending on version of spec */
584 if (!btm_cb.sco_cb.esco_supported) {
585 log::info("sending non-eSCO request for handle={}", unsigned(acl_handle));
586 btsnd_hcic_add_SCO_conn(acl_handle, BTM_ESCO_2_SCO(p_setup->packet_types));
587 } else {
588 /* Save the previous values in case command fails */
589 uint16_t saved_packet_types = p_setup->packet_types;
590 uint8_t saved_retransmission_effort = p_setup->retransmission_effort;
591 uint16_t saved_max_latency_ms = p_setup->max_latency_ms;
592
593 uint16_t temp_packet_types =
594 (p_setup->packet_types &
595 static_cast<uint16_t>(BTM_SCO_SUPPORTED_PKTS_MASK) &
596 btm_cb.btm_sco_pkt_types_supported);
597
598 /* OR in any exception packet types */
599 temp_packet_types |=
600 ((p_setup->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
601 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
602
603 /* Finally, remove EDR eSCO if the remote device doesn't support it */
604 /* UPF25: Only SCO was brought up in this case */
605 const RawAddress bd_addr = acl_address_from_handle(acl_handle);
606 if (bd_addr != RawAddress::kEmpty) {
607 if (!btm_peer_supports_esco_2m_phy(bd_addr)) {
608 log::verbose("BTM Remote does not support 2-EDR eSCO");
609 temp_packet_types |=
610 (ESCO_PKT_TYPES_MASK_NO_2_EV3 | ESCO_PKT_TYPES_MASK_NO_2_EV5);
611 }
612 if (!btm_peer_supports_esco_3m_phy(bd_addr)) {
613 log::verbose("BTM Remote does not support 3-EDR eSCO");
614 temp_packet_types |=
615 (ESCO_PKT_TYPES_MASK_NO_3_EV3 | ESCO_PKT_TYPES_MASK_NO_3_EV5);
616 }
617 if (!btm_peer_supports_esco_ev3(bd_addr)) {
618 log::verbose("BTM Remote does not support EV3 eSCO");
619 // If EV3 is not supported, EV4 and EV% are not supported, either.
620 temp_packet_types &= ~BTM_ESCO_LINK_ONLY_MASK;
621 p_setup->retransmission_effort = ESCO_RETRANSMISSION_OFF;
622 p_setup->max_latency_ms = 10;
623 }
624
625 /* Check to see if BR/EDR Secure Connections is being used
626 ** If so, we cannot use SCO-only packet types (HFP 1.7)
627 */
628 const bool local_supports_sc =
629 bluetooth::shim::GetController()->SupportsSecureConnections();
630 const bool remote_supports_sc =
631 BTM_PeerSupportsSecureConnections(bd_addr);
632
633 if (local_supports_sc && remote_supports_sc) {
634 temp_packet_types &= ~(BTM_SCO_PKT_TYPE_MASK);
635 if (temp_packet_types == 0) {
636 log::error(
637 "SCO connection cannot support any packet types for "
638 "acl_handle:0x{:04x}",
639 acl_handle);
640 return BTM_WRONG_MODE;
641 }
642 log::debug(
643 "Both local and remote controllers support SCO secure connections "
644 "handle:0x{:04x} pkt_types:0x{:04x}",
645 acl_handle, temp_packet_types);
646
647 } else if (!local_supports_sc && !remote_supports_sc) {
648 log::debug(
649 "Both local and remote controllers do not support secure "
650 "connections for handle:0x{:04x}",
651 acl_handle);
652 } else if (remote_supports_sc) {
653 log::debug(
654 "Only remote controller supports secure connections for "
655 "handle:0x{:04x}",
656 acl_handle);
657 } else {
658 log::debug(
659 "Only local controller supports secure connections for "
660 "handle:0x{:04x}",
661 acl_handle);
662 }
663 } else {
664 log::error("Received SCO connect from unknown peer:{}", bd_addr);
665 }
666
667 p_setup->packet_types = temp_packet_types;
668
669 /* Use Enhanced Synchronous commands if supported */
670 if (bluetooth::shim::GetController()->IsSupported(
671 bluetooth::hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) &&
672 !osi_property_get_bool(kPropertyDisableEnhancedConnection,
673 kDefaultDisableEnhancedConnection)) {
674 log::info("Sending enhanced SCO connect request over handle:0x{:04x}",
675 acl_handle);
676 log::info(
677 "enhanced parameter list txbw=0x{:x}, rxbw=0x{}, latency_ms=0x{}, "
678 "retransmit_effort=0x{}, pkt_type=0x{}, path=0x{}",
679 unsigned(p_setup->transmit_bandwidth),
680 unsigned(p_setup->receive_bandwidth),
681 unsigned(p_setup->max_latency_ms),
682 unsigned(p_setup->retransmission_effort),
683 unsigned(p_setup->packet_types), unsigned(p_setup->input_data_path));
684 btsnd_hcic_enhanced_set_up_synchronous_connection(acl_handle, p_setup);
685 p_setup->packet_types = saved_packet_types;
686 p_setup->retransmission_effort = saved_retransmission_effort;
687 p_setup->max_latency_ms = saved_max_latency_ms;
688 } else { /* Use older command */
689 log::info("Sending eSCO connect request over handle:0x{:04x}",
690 acl_handle);
691 uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
692 log::info(
693 "legacy parameter list txbw=0x{:x}, rxbw=0x{}, latency_ms=0x{}, "
694 "retransmit_effort=0x{}, voice_content_format=0x{}, pkt_type=0x{}",
695 unsigned(p_setup->transmit_bandwidth),
696 unsigned(p_setup->receive_bandwidth),
697 unsigned(p_setup->max_latency_ms),
698 unsigned(p_setup->retransmission_effort),
699 unsigned(voice_content_format), unsigned(p_setup->packet_types));
700 btsnd_hcic_setup_esco_conn(
701 acl_handle, p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
702 p_setup->max_latency_ms, voice_content_format,
703 p_setup->retransmission_effort, p_setup->packet_types);
704 }
705 }
706
707 return (BTM_CMD_STARTED);
708 }
709
710 /*******************************************************************************
711 *
712 * Function BTM_CreateSco
713 *
714 * Description This function is called to create an SCO connection. If the
715 * "is_orig" flag is true, the connection will be originated,
716 * otherwise BTM will wait for the other side to connect.
717 *
718 * NOTE: If BTM_IGNORE_SCO_PKT_TYPE is passed in the pkt_types
719 * parameter the default packet types is used.
720 *
721 * Returns BTM_UNKNOWN_ADDR if the ACL connection is not up
722 * BTM_BUSY if another SCO being set up to
723 * the same BD address
724 * BTM_NO_RESOURCES if the max SCO limit has been reached
725 * BTM_CMD_STARTED if the connection establishment is started.
726 * In this case, "*p_sco_inx" is filled in
727 * with the sco index used for the connection.
728 *
729 ******************************************************************************/
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)730 tBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,
731 uint16_t pkt_types, uint16_t* p_sco_inx,
732 tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {
733 enh_esco_params_t* p_setup;
734 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
735 uint16_t xx;
736 uint16_t acl_handle = HCI_INVALID_HANDLE;
737 *p_sco_inx = BTM_INVALID_SCO_INDEX;
738
739 if (BTM_MAX_SCO_LINKS == 0) {
740 return BTM_NO_RESOURCES;
741 }
742
743 /* If originating, ensure that there is an ACL connection to the BD Address */
744
745 if (is_orig) {
746 if (!remote_bda) {
747 log::error("remote_bda is null");
748 return BTM_ILLEGAL_VALUE;
749 }
750 acl_handle = BTM_GetHCIConnHandle(*remote_bda, BT_TRANSPORT_BR_EDR);
751 if (acl_handle == HCI_INVALID_HANDLE) {
752 log::error("cannot find ACL handle for remote device {}", *remote_bda);
753 return BTM_UNKNOWN_ADDR;
754 }
755 }
756
757 if (remote_bda) {
758 /* If any SCO is being established to the remote BD address, refuse this */
759 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
760 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
761 (p->state == SCO_ST_PEND_UNPARK)) &&
762 (p->esco.data.bd_addr == *remote_bda)) {
763 log::error("a sco connection is already going on for {}, at state {}",
764 *remote_bda, unsigned(p->state));
765 return BTM_BUSY;
766 }
767 }
768 } else {
769 /* Support only 1 wildcard BD address at a time */
770 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
771 if ((p->state == SCO_ST_LISTENING) && (!p->rem_bd_known)) {
772 log::error(
773 "remote_bda is null and not known and we are still listening");
774 return BTM_BUSY;
775 }
776 }
777 }
778
779 /* Try to find an unused control block, and kick off the SCO establishment */
780 for (xx = 0, p = &btm_cb.sco_cb.sco_db[0]; xx < BTM_MAX_SCO_LINKS;
781 xx++, p++) {
782 if (p->state == SCO_ST_UNUSED) {
783 if (remote_bda) {
784 if (is_orig) {
785 // can not create SCO link if in park mode
786 tBTM_PM_STATE state;
787 if (BTM_ReadPowerMode(*remote_bda, &state)) {
788 if (state == BTM_PM_ST_SNIFF || state == BTM_PM_ST_PARK ||
789 state == BTM_PM_ST_PENDING) {
790 log::info("{} in sniff, park or pending mode {}", *remote_bda,
791 unsigned(state));
792 if (!BTM_SetLinkPolicyActiveMode(*remote_bda)) {
793 log::warn("Unable to set link policy active");
794 }
795 p->state = SCO_ST_PEND_UNPARK;
796 }
797 } else {
798 log::error("failed to read power mode for {}", *remote_bda);
799 }
800 }
801 p->esco.data.bd_addr = *remote_bda;
802 p->rem_bd_known = true;
803 } else
804 p->rem_bd_known = false;
805
806 p_setup = &p->esco.setup;
807 *p_setup = btm_cb.sco_cb.def_esco_parms;
808
809 /* Determine the packet types */
810 p_setup->packet_types = pkt_types & BTM_SCO_SUPPORTED_PKTS_MASK &
811 btm_cb.btm_sco_pkt_types_supported;
812 /* OR in any exception packet types */
813 if (bluetooth::shim::GetController()
814 ->GetLocalVersionInformation()
815 .hci_version_ >= bluetooth::hci::HciVersion::V_2_0) {
816 p_setup->packet_types |=
817 (pkt_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
818 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK);
819 }
820
821 p->p_conn_cb = p_conn_cb;
822 p->p_disc_cb = p_disc_cb;
823 p->hci_handle = HCI_INVALID_HANDLE;
824 p->is_orig = is_orig;
825
826 if (p->state != SCO_ST_PEND_UNPARK) {
827 if (is_orig) {
828 /* If role change is in progress, do not proceed with SCO setup
829 * Wait till role change is complete */
830 if (!acl_is_switch_role_idle(*remote_bda, BT_TRANSPORT_BR_EDR)) {
831 log::verbose("Role Change is in progress for ACL handle 0x{:04x}",
832 acl_handle);
833 p->state = SCO_ST_PEND_ROLECHANGE;
834 }
835 }
836 }
837
838 if (p->state != SCO_ST_PEND_UNPARK &&
839 p->state != SCO_ST_PEND_ROLECHANGE) {
840 if (is_orig) {
841 log::debug("Initiating (e)SCO link for ACL handle:0x{:04x}",
842 acl_handle);
843
844 if ((btm_send_connect_request(acl_handle, p_setup)) !=
845 BTM_CMD_STARTED) {
846 log::error("failed to send connect request for {}", *remote_bda);
847 return (BTM_NO_RESOURCES);
848 }
849
850 p->state = SCO_ST_CONNECTING;
851 } else {
852 log::debug("Listening for (e)SCO on ACL handle:0x{:04x}", acl_handle);
853 p->state = SCO_ST_LISTENING;
854 }
855 }
856
857 *p_sco_inx = xx;
858 log::debug("SCO connection successfully requested");
859 if (p->state == SCO_ST_CONNECTING) {
860 BTM_LogHistory(
861 kBtmLogTag, *remote_bda, "Connecting",
862 base::StringPrintf("local initiated acl:0x%04x", acl_handle));
863 }
864 return BTM_CMD_STARTED;
865 }
866 }
867
868 /* If here, all SCO blocks in use */
869 log::error("all SCO control blocks are in use");
870 return BTM_NO_RESOURCES;
871 }
872
873 /*******************************************************************************
874 *
875 * Function btm_sco_chk_pend_unpark
876 *
877 * Description This function is called by BTIF when there is a mode change
878 * event to see if there are SCO commands waiting for the
879 * unpark.
880 *
881 * Returns void
882 *
883 ******************************************************************************/
btm_sco_chk_pend_unpark(tHCI_STATUS hci_status,uint16_t hci_handle)884 void btm_sco_chk_pend_unpark(tHCI_STATUS hci_status, uint16_t hci_handle) {
885 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
886 for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
887 uint16_t acl_handle =
888 BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR);
889 if ((p->state == SCO_ST_PEND_UNPARK) && (acl_handle == hci_handle)) {
890 log::info(
891 "{} unparked, sending connection request, acl_handle={}, "
892 "hci_status={}",
893 p->esco.data.bd_addr, unsigned(acl_handle), unsigned(hci_status));
894 if (btm_send_connect_request(acl_handle, &p->esco.setup) ==
895 BTM_CMD_STARTED) {
896 p->state = SCO_ST_CONNECTING;
897 } else {
898 log::error("failed to send connection request for {}",
899 p->esco.data.bd_addr);
900 }
901 }
902 }
903 }
904
905 /*******************************************************************************
906 *
907 * Function btm_sco_chk_pend_rolechange
908 *
909 * Description This function is called by BTIF when there is a role change
910 * event to see if there are SCO commands waiting for the role
911 * change.
912 *
913 * Returns void
914 *
915 ******************************************************************************/
btm_sco_chk_pend_rolechange(uint16_t hci_handle)916 void btm_sco_chk_pend_rolechange(uint16_t hci_handle) {
917 uint16_t xx;
918 uint16_t acl_handle;
919 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
920
921 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
922 if ((p->state == SCO_ST_PEND_ROLECHANGE) &&
923 ((acl_handle = BTM_GetHCIConnHandle(
924 p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) == hci_handle))
925
926 {
927 log::verbose(
928 "btm_sco_chk_pend_rolechange -> (e)SCO Link for ACL handle 0x{:04x}",
929 acl_handle);
930
931 if ((btm_send_connect_request(acl_handle, &p->esco.setup)) ==
932 BTM_CMD_STARTED)
933 p->state = SCO_ST_CONNECTING;
934 }
935 }
936 }
937
938 /*******************************************************************************
939 *
940 * Function btm_sco_disc_chk_pend_for_modechange
941 *
942 * Description This function is called by btm when there is a mode change
943 * event to see if there are SCO disconnect commands waiting
944 * for the mode change.
945 *
946 * Returns void
947 *
948 ******************************************************************************/
btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle)949 void btm_sco_disc_chk_pend_for_modechange(uint16_t hci_handle) {
950 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
951
952 log::debug(
953 "Checking for SCO pending mode change events hci_handle:0x{:04x} "
954 "p->state:{}",
955 hci_handle, sco_state_text(p->state));
956
957 for (uint16_t xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
958 if ((p->state == SCO_ST_PEND_MODECHANGE) &&
959 (BTM_GetHCIConnHandle(p->esco.data.bd_addr, BT_TRANSPORT_BR_EDR)) ==
960 hci_handle)
961
962 {
963 log::debug("Removing SCO Link handle 0x{:04x}", p->hci_handle);
964 if (get_btm_client_interface().sco.BTM_RemoveSco(xx) != BTM_SUCCESS) {
965 log::warn("Unable to remove SCO link:{}", xx);
966 }
967 }
968 }
969 }
970
971 /*******************************************************************************
972 *
973 * Function btm_sco_conn_req
974 *
975 * Description This function is called by BTU HCIF when an SCO connection
976 * request is received from a remote.
977 *
978 * Returns void
979 *
980 ******************************************************************************/
btm_sco_conn_req(const RawAddress & bda,const DEV_CLASS & dev_class,uint8_t link_type)981 void btm_sco_conn_req(const RawAddress& bda, const DEV_CLASS& dev_class,
982 uint8_t link_type) {
983 tSCO_CB* p_sco = &btm_cb.sco_cb;
984 tSCO_CONN* p = &p_sco->sco_db[0];
985 tBTM_ESCO_CONN_REQ_EVT_DATA evt_data = {};
986
987 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(bda, IOT_CONF_KEY_HFP_SCO_CONN_COUNT);
988
989 for (uint16_t sco_index = 0; sco_index < BTM_MAX_SCO_LINKS;
990 sco_index++, p++) {
991 /*
992 * If the sco state is in the SCO_ST_CONNECTING state, we still need
993 * to return accept sco to avoid race conditon for sco creation
994 */
995 bool rem_bd_matches = p->rem_bd_known && p->esco.data.bd_addr == bda;
996 if (((p->state == SCO_ST_CONNECTING) && rem_bd_matches) ||
997 ((p->state == SCO_ST_LISTENING) &&
998 (rem_bd_matches || !p->rem_bd_known))) {
999 /* If this was a wildcard, it is not one any more */
1000 p->rem_bd_known = true;
1001 p->esco.data.link_type = link_type;
1002 p->state = SCO_ST_W4_CONN_RSP;
1003 p->esco.data.bd_addr = bda;
1004
1005 /* If no callback, auto-accept the connection if packet types match */
1006 if (!p->esco.p_esco_cback) {
1007 /* If requesting eSCO reject if default parameters are SCO only */
1008 if ((link_type == BTM_LINK_TYPE_ESCO &&
1009 !(p_sco->def_esco_parms.packet_types & BTM_ESCO_LINK_ONLY_MASK) &&
1010 ((p_sco->def_esco_parms.packet_types &
1011 BTM_SCO_EXCEPTION_PKTS_MASK) == BTM_SCO_EXCEPTION_PKTS_MASK))
1012
1013 /* Reject request if SCO is desired but no SCO packets delected */
1014 ||
1015 (link_type == BTM_LINK_TYPE_SCO &&
1016 !(p_sco->def_esco_parms.packet_types & BTM_SCO_LINK_ONLY_MASK))) {
1017 btm_esco_conn_rsp(sco_index, HCI_ERR_HOST_REJECT_RESOURCES, bda,
1018 nullptr);
1019 } else {
1020 /* Accept the request */
1021 btm_esco_conn_rsp(sco_index, HCI_SUCCESS, bda, nullptr);
1022 }
1023 } else {
1024 /* Notify upper layer of connect indication */
1025 evt_data.bd_addr = bda;
1026 evt_data.dev_class = dev_class;
1027 evt_data.link_type = link_type;
1028 evt_data.sco_inx = sco_index;
1029 tBTM_ESCO_EVT_DATA btm_esco_evt_data = {};
1030 btm_esco_evt_data.conn_evt = evt_data;
1031 p->esco.p_esco_cback(BTM_ESCO_CONN_REQ_EVT, &btm_esco_evt_data);
1032 }
1033
1034 return;
1035 }
1036 }
1037
1038 /* If here, no one wants the SCO connection. Reject it */
1039 log::warn("rejecting SCO for {}", bda);
1040 btm_esco_conn_rsp(BTM_MAX_SCO_LINKS, HCI_ERR_HOST_REJECT_RESOURCES, bda,
1041 nullptr);
1042 }
1043
1044 /*******************************************************************************
1045 *
1046 * Function btm_sco_connected
1047 *
1048 * Description This function is called by BTIF when an (e)SCO connection
1049 * is connected.
1050 *
1051 * Returns void
1052 *
1053 ******************************************************************************/
btm_sco_connected(const RawAddress & bda,uint16_t hci_handle,tBTM_ESCO_DATA * p_esco_data)1054 void btm_sco_connected(const RawAddress& bda, uint16_t hci_handle,
1055 tBTM_ESCO_DATA* p_esco_data) {
1056 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1057 uint16_t xx;
1058 bool spt = false;
1059 tBTM_CHG_ESCO_PARAMS parms = {};
1060 int codec;
1061
1062 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1063 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
1064 (p->state == SCO_ST_W4_CONN_RSP)) &&
1065 (p->rem_bd_known) && (p->esco.data.bd_addr == bda)) {
1066 BTM_LogHistory(
1067 kBtmLogTag, bda, "Connection created",
1068 base::StringPrintf("sco_idx:%hu handle:0x%04x ", xx, hci_handle));
1069 power_telemetry::GetInstance().LogLinkDetails(hci_handle, bda, true,
1070 false);
1071
1072 if (p->state == SCO_ST_LISTENING) spt = true;
1073
1074 p->state = SCO_ST_CONNECTED;
1075 p->hci_handle = hci_handle;
1076
1077 BTM_LogHistory(kBtmLogTag, bda, "Connection success",
1078 base::StringPrintf("handle:0x%04x %s", hci_handle,
1079 (spt) ? "listener" : "initiator"));
1080 log::debug("Connected SCO link handle:0x{:04x} peer:{}", hci_handle, bda);
1081
1082 if (!btm_cb.sco_cb.esco_supported) {
1083 p->esco.data.link_type = BTM_LINK_TYPE_SCO;
1084 if (spt) {
1085 parms.packet_types = p->esco.setup.packet_types;
1086 /* Keep the other parameters the same for SCO */
1087 parms.max_latency_ms = p->esco.setup.max_latency_ms;
1088 parms.retransmission_effort = p->esco.setup.retransmission_effort;
1089
1090 BTM_ChangeEScoLinkParms(xx, &parms);
1091 }
1092 } else {
1093 if (p_esco_data) p->esco.data = *p_esco_data;
1094 }
1095
1096 (*p->p_conn_cb)(xx);
1097
1098 codec = hfp_hal_interface::esco_coding_to_codec(
1099 p->esco.setup.transmit_coding_format.coding_format);
1100 hfp_hal_interface::notify_sco_connection_change(
1101 bda, /*is_connected=*/true, codec);
1102
1103 /* In-band (non-offload) data path */
1104 if (p->is_inband()) {
1105 const auto codec_type = p->get_codec_type();
1106 if (codec_type == BTM_SCO_CODEC_MSBC ||
1107 codec_type == BTM_SCO_CODEC_LC3) {
1108 btm_pcm_buf_read_offset = 0;
1109 btm_pcm_buf_write_offset = 0;
1110 auto init = codec_type == BTM_SCO_CODEC_LC3
1111 ? &bluetooth::audio::sco::swb::init
1112 : &bluetooth::audio::sco::wbs::init;
1113 init(hfp_hal_interface::get_packet_size(codec));
1114 }
1115
1116 std::fill(std::begin(btm_pcm_buf), std::end(btm_pcm_buf), 0);
1117 bluetooth::audio::sco::open();
1118 }
1119 return;
1120 }
1121 }
1122 }
1123
1124 /*******************************************************************************
1125 *
1126 * Function btm_sco_connection_failed
1127 *
1128 * Description This function is called by BTIF when an (e)SCO connection
1129 * setup is failed.
1130 *
1131 * Returns void
1132 *
1133 ******************************************************************************/
btm_sco_connection_failed(tHCI_STATUS hci_status,const RawAddress & bda,uint16_t hci_handle,tBTM_ESCO_DATA *)1134 void btm_sco_connection_failed(tHCI_STATUS hci_status, const RawAddress& bda,
1135 uint16_t hci_handle,
1136 tBTM_ESCO_DATA* /* p_esco_data */) {
1137 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1138 uint16_t xx;
1139
1140 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1141 if (((p->state == SCO_ST_CONNECTING) || (p->state == SCO_ST_LISTENING) ||
1142 (p->state == SCO_ST_W4_CONN_RSP)) &&
1143 (p->rem_bd_known) &&
1144 (p->esco.data.bd_addr == bda || bda == RawAddress::kEmpty)) {
1145 /* Report the error if originator, otherwise remain in Listen mode */
1146 if (p->is_orig) {
1147 log::debug("SCO initiating connection failed handle:0x{:04x} reason:{}",
1148 hci_handle, hci_error_code_text(hci_status));
1149 switch (hci_status) {
1150 case HCI_ERR_ROLE_SWITCH_PENDING:
1151 /* If role switch is pending, we need try again after role switch
1152 * is complete */
1153 p->state = SCO_ST_PEND_ROLECHANGE;
1154 break;
1155 case HCI_ERR_LMP_ERR_TRANS_COLLISION:
1156 /* Avoid calling disconnect callback because of sco creation race
1157 */
1158 break;
1159 default: /* Notify client about SCO failure */
1160 p->state = SCO_ST_UNUSED;
1161 (*p->p_disc_cb)(xx);
1162 }
1163 BTM_LogHistory(
1164 kBtmLogTag, bda, "Connection failed",
1165 base::StringPrintf(
1166 "locally_initiated reason:%s",
1167 hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
1168 .c_str()));
1169 } else {
1170 log::debug(
1171 "SCO terminating connection failed handle:0x{:04x} reason:{}",
1172 hci_handle, hci_error_code_text(hci_status));
1173 if (p->state == SCO_ST_CONNECTING) {
1174 p->state = SCO_ST_UNUSED;
1175 (*p->p_disc_cb)(xx);
1176 } else {
1177 p->state = SCO_ST_LISTENING;
1178 if (bda != RawAddress::kEmpty)
1179 DEVICE_IOT_CONFIG_ADDR_INT_ADD_ONE(
1180 bda, IOT_CONF_KEY_HFP_SCO_CONN_FAIL_COUNT);
1181 }
1182 BTM_LogHistory(
1183 kBtmLogTag, bda, "Connection failed",
1184 base::StringPrintf(
1185 "remote_initiated reason:%s",
1186 hci_reason_code_text(static_cast<tHCI_REASON>(hci_status))
1187 .c_str()));
1188 }
1189 return;
1190 }
1191 }
1192 }
1193
1194 /*******************************************************************************
1195 *
1196 * Function BTM_RemoveSco
1197 *
1198 * Description This function is called to remove a specific SCO connection.
1199 *
1200 * Returns status of the operation
1201 *
1202 ******************************************************************************/
BTM_RemoveSco(uint16_t sco_inx)1203 tBTM_STATUS BTM_RemoveSco(uint16_t sco_inx) {
1204 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1205 tBTM_PM_STATE state = BTM_PM_ST_INVALID;
1206
1207 log::verbose("");
1208
1209 if (BTM_MAX_SCO_LINKS == 0) {
1210 return BTM_NO_RESOURCES;
1211 }
1212
1213 /* Validity check */
1214 if ((sco_inx >= BTM_MAX_SCO_LINKS) || (p->state == SCO_ST_UNUSED))
1215 return (BTM_UNKNOWN_ADDR);
1216
1217 /* If no HCI handle, simply drop the connection and return */
1218 if (p->hci_handle == HCI_INVALID_HANDLE || p->state == SCO_ST_PEND_UNPARK) {
1219 p->hci_handle = HCI_INVALID_HANDLE;
1220 p->state = SCO_ST_UNUSED;
1221 p->esco.p_esco_cback = NULL; /* Deregister the eSCO event callback */
1222 return (BTM_SUCCESS);
1223 }
1224
1225 if (BTM_ReadPowerMode(p->esco.data.bd_addr, &state) &&
1226 (state == BTM_PM_ST_PENDING)) {
1227 log::verbose("BTM_PM_ST_PENDING for ACL mapped with SCO Link 0x{:04x}",
1228 p->hci_handle);
1229 p->state = SCO_ST_PEND_MODECHANGE;
1230 return (BTM_CMD_STARTED);
1231 }
1232
1233 tSCO_STATE old_state = p->state;
1234 p->state = SCO_ST_DISCONNECTING;
1235
1236 GetInterface().Disconnect(p->Handle(), HCI_ERR_PEER_USER);
1237
1238 log::debug("Disconnecting link sco_handle:0x{:04x} peer:{}", p->Handle(),
1239 p->esco.data.bd_addr);
1240 BTM_LogHistory(
1241 kBtmLogTag, p->esco.data.bd_addr, "Disconnecting",
1242 base::StringPrintf("local initiated handle:0x%04x previous_state:%s",
1243 p->Handle(), sco_state_text(old_state).c_str()));
1244 return (BTM_CMD_STARTED);
1245 }
1246
BTM_RemoveSco(const RawAddress & bda)1247 void BTM_RemoveSco(const RawAddress& bda) {
1248 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1249 uint16_t xx;
1250
1251 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1252 if (p->rem_bd_known && p->esco.data.bd_addr == bda) {
1253 if (get_btm_client_interface().sco.BTM_RemoveSco(xx) != BTM_SUCCESS) {
1254 log::warn("Unable to remove SCO link:{}", xx);
1255 }
1256 }
1257 }
1258 }
1259
1260 /*******************************************************************************
1261 *
1262 * Function btm_sco_removed
1263 *
1264 * Description This function is called by lower layers when an
1265 * disconnect is received.
1266 *
1267 * Returns true if the link is known about, else false
1268 *
1269 ******************************************************************************/
btm_sco_removed(uint16_t hci_handle,tHCI_REASON reason)1270 bool btm_sco_removed(uint16_t hci_handle, tHCI_REASON reason) {
1271 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1272 uint16_t xx;
1273
1274 p = &btm_cb.sco_cb.sco_db[0];
1275 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1276 if ((p->state != SCO_ST_UNUSED) && (p->state != SCO_ST_LISTENING) &&
1277 (p->hci_handle == hci_handle)) {
1278 power_telemetry::GetInstance().LogLinkDetails(
1279 hci_handle, RawAddress::kEmpty, false, false);
1280 RawAddress bda(p->esco.data.bd_addr);
1281 p->state = SCO_ST_UNUSED;
1282 p->hci_handle = HCI_INVALID_HANDLE;
1283 p->rem_bd_known = false;
1284 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1285 (*p->p_disc_cb)(xx);
1286
1287 hfp_hal_interface::notify_sco_connection_change(
1288 bda, /*is_connected=*/false,
1289 hfp_hal_interface::esco_coding_to_codec(
1290 p->esco.setup.transmit_coding_format.coding_format));
1291
1292 log::debug("Disconnected SCO link handle:{} reason:{}", hci_handle,
1293 hci_reason_code_text(reason));
1294 return true;
1295 }
1296 }
1297 return false;
1298 }
1299
btm_sco_on_disconnected(uint16_t hci_handle,tHCI_REASON reason)1300 void btm_sco_on_disconnected(uint16_t hci_handle, tHCI_REASON reason) {
1301 tSCO_CONN* p_sco = btm_cb.sco_cb.get_sco_connection_from_handle(hci_handle);
1302 if (p_sco == nullptr) {
1303 log::debug("Unable to find sco connection");
1304 return;
1305 }
1306
1307 if (!p_sco->is_active()) {
1308 log::info("Connection is not active handle:0x{:04x} reason:{}", hci_handle,
1309 hci_reason_code_text(reason));
1310 return;
1311 }
1312
1313 if (p_sco->state == SCO_ST_LISTENING) {
1314 log::info("Connection is in listening state handle:0x{:04x} reason:{}",
1315 hci_handle, hci_reason_code_text(reason));
1316 return;
1317 }
1318
1319 const RawAddress bd_addr(p_sco->esco.data.bd_addr);
1320
1321 p_sco->state = SCO_ST_UNUSED;
1322 p_sco->hci_handle = HCI_INVALID_HANDLE;
1323 p_sco->rem_bd_known = false;
1324 p_sco->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1325 (*p_sco->p_disc_cb)(btm_cb.sco_cb.get_index(p_sco));
1326 log::debug("Disconnected SCO link handle:{} reason:{}", hci_handle,
1327 hci_reason_code_text(reason));
1328 BTM_LogHistory(kBtmLogTag, bd_addr, "Disconnected",
1329 base::StringPrintf("handle:0x%04x reason:%s", hci_handle,
1330 hci_reason_code_text(reason).c_str()));
1331
1332 hfp_hal_interface::notify_sco_connection_change(
1333 bd_addr, /*is_connected=*/false,
1334 hfp_hal_interface::esco_coding_to_codec(
1335 p_sco->esco.setup.transmit_coding_format.coding_format));
1336
1337 if (p_sco->is_inband()) {
1338 const auto codec_type = p_sco->get_codec_type();
1339 if (codec_type == BTM_SCO_CODEC_MSBC || codec_type == BTM_SCO_CODEC_LC3) {
1340 auto fill_plc_stats = codec_type == BTM_SCO_CODEC_LC3
1341 ? bluetooth::audio::sco::swb::fill_plc_stats
1342 : bluetooth::audio::sco::wbs::fill_plc_stats;
1343
1344 int num_decoded_frames;
1345 double packet_loss_ratio;
1346 if (fill_plc_stats(&num_decoded_frames, &packet_loss_ratio)) {
1347 const int16_t codec_id = sco_codec_type_to_id(codec_type);
1348 const std::string codec = sco_codec_type_text(codec_type);
1349 log_hfp_audio_packet_loss_stats(bd_addr, num_decoded_frames,
1350 packet_loss_ratio, codec_id);
1351 log::debug(
1352 "Stopped SCO codec:{}, num_decoded_frames:{}, "
1353 "packet_loss_ratio:{:f}",
1354 codec, num_decoded_frames, packet_loss_ratio);
1355 } else {
1356 log::warn("Failed to get the packet loss stats");
1357 }
1358
1359 auto cleanup = codec_type == BTM_SCO_CODEC_LC3
1360 ? bluetooth::audio::sco::swb::cleanup
1361 : bluetooth::audio::sco::wbs::cleanup;
1362
1363 cleanup();
1364 }
1365
1366 bluetooth::audio::sco::cleanup();
1367 }
1368 }
1369
1370 /*******************************************************************************
1371 *
1372 * Function btm_sco_acl_removed
1373 *
1374 * Description This function is called when an ACL connection is
1375 * removed. If the BD address is NULL, it is assumed that
1376 * the local device is down, and all SCO links are removed.
1377 * If a specific BD address is passed, only SCO connections
1378 * to that BD address are removed.
1379 *
1380 * Returns void
1381 *
1382 ******************************************************************************/
btm_sco_acl_removed(const RawAddress * bda)1383 void btm_sco_acl_removed(const RawAddress* bda) {
1384 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1385 uint16_t xx;
1386
1387 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1388 if (p->state != SCO_ST_UNUSED) {
1389 if ((!bda) || (p->esco.data.bd_addr == *bda && p->rem_bd_known)) {
1390 p->state = SCO_ST_UNUSED;
1391 p->esco.p_esco_cback = NULL; /* Deregister eSCO callback */
1392 (*p->p_disc_cb)(xx);
1393 }
1394 }
1395 }
1396 }
1397
1398 /*******************************************************************************
1399 *
1400 * Function BTM_ReadScoBdAddr
1401 *
1402 * Description This function is read the remote BD Address for a specific
1403 * SCO connection,
1404 *
1405 * Returns pointer to BD address or NULL if not known
1406 *
1407 ******************************************************************************/
BTM_ReadScoBdAddr(uint16_t sco_inx)1408 const RawAddress* BTM_ReadScoBdAddr(uint16_t sco_inx) {
1409 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[sco_inx];
1410
1411 /* Validity check */
1412 if ((sco_inx < BTM_MAX_SCO_LINKS) && (p->rem_bd_known))
1413 return &(p->esco.data.bd_addr);
1414 else
1415 return (NULL);
1416 }
1417
1418 /*******************************************************************************
1419 *
1420 * Function BTM_SetEScoMode
1421 *
1422 * Description This function sets up the negotiated parameters for SCO or
1423 * eSCO, and sets as the default mode used for outgoing calls
1424 * to BTM_CreateSco. It does not change any currently active
1425 * (e)SCO links.
1426 * Note: Incoming (e)SCO connections will always use packet
1427 * types supported by the controller. If eSCO is not
1428 * desired the feature should be disabled in the
1429 * controller's feature mask.
1430 *
1431 * Returns BTM_SUCCESS if the successful.
1432 * BTM_BUSY if there are one or more active (e)SCO links.
1433 *
1434 ******************************************************************************/
BTM_SetEScoMode(enh_esco_params_t * p_parms)1435 tBTM_STATUS BTM_SetEScoMode(enh_esco_params_t* p_parms) {
1436 log::assert_that(p_parms != nullptr, "eSCO parameters must have a value");
1437 enh_esco_params_t* p_def = &btm_cb.sco_cb.def_esco_parms;
1438
1439 if (btm_cb.sco_cb.esco_supported) {
1440 *p_def = *p_parms;
1441 log::debug(
1442 "Setting eSCO mode parameters txbw:0x{:08x} rxbw:0x{:08x} "
1443 "max_lat:0x{:04x} pkt:0x{:04x} rtx_effort:0x{:02x}",
1444 p_def->transmit_bandwidth, p_def->receive_bandwidth,
1445 p_def->max_latency_ms, p_def->packet_types,
1446 p_def->retransmission_effort);
1447 } else {
1448 /* Load defaults for SCO only */
1449 *p_def = esco_parameters_for_codec(
1450 SCO_CODEC_CVSD_D1, hfp_hal_interface::get_offload_enabled());
1451 log::warn("eSCO not supported so setting SCO parameters instead");
1452 log::debug(
1453 "Setting SCO mode parameters txbw:0x{:08x} rxbw:0x{:08x} "
1454 "max_lat:0x{:04x} pkt:0x{:04x} rtx_effort:0x{:02x}",
1455 p_def->transmit_bandwidth, p_def->receive_bandwidth,
1456 p_def->max_latency_ms, p_def->packet_types,
1457 p_def->retransmission_effort);
1458 }
1459 return BTM_SUCCESS;
1460 }
1461
1462 /*******************************************************************************
1463 *
1464 * Function BTM_RegForEScoEvts
1465 *
1466 * Description This function registers a SCO event callback with the
1467 * specified instance. It should be used to received
1468 * connection indication events and change of link parameter
1469 * events.
1470 *
1471 * Returns BTM_SUCCESS if the successful.
1472 * BTM_ILLEGAL_VALUE if there is an illegal sco_inx
1473 * BTM_MODE_UNSUPPORTED if controller version is not BT1.2 or
1474 * later or does not support eSCO.
1475 *
1476 ******************************************************************************/
BTM_RegForEScoEvts(uint16_t sco_inx,tBTM_ESCO_CBACK * p_esco_cback)1477 tBTM_STATUS BTM_RegForEScoEvts(uint16_t sco_inx,
1478 tBTM_ESCO_CBACK* p_esco_cback) {
1479 if (BTM_MAX_SCO_LINKS == 0) {
1480 return BTM_MODE_UNSUPPORTED;
1481 }
1482
1483 if (!btm_cb.sco_cb.esco_supported) {
1484 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = NULL;
1485 return (BTM_MODE_UNSUPPORTED);
1486 }
1487
1488 if (sco_inx < BTM_MAX_SCO_LINKS &&
1489 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_UNUSED) {
1490 btm_cb.sco_cb.sco_db[sco_inx].esco.p_esco_cback = p_esco_cback;
1491 return (BTM_SUCCESS);
1492 }
1493 return (BTM_ILLEGAL_VALUE);
1494 }
1495
1496 /*******************************************************************************
1497 *
1498 * Function BTM_ChangeEScoLinkParms
1499 *
1500 * Description This function requests renegotiation of the parameters on
1501 * the current eSCO Link. If any of the changes are accepted
1502 * by the controllers, the BTM_ESCO_CHG_EVT event is sent in
1503 * the tBTM_ESCO_CBACK function with the current settings of
1504 * the link. The callback is registered through the call to
1505 * BTM_SetEScoMode.
1506 *
1507 * Note: If called over a SCO link (including 1.1 controller),
1508 * a change packet type request is sent out instead.
1509 *
1510 * Returns BTM_CMD_STARTED if command is successfully initiated.
1511 * BTM_NO_RESOURCES - not enough resources to initiate command.
1512 * BTM_WRONG_MODE if no connection with a peer device or bad
1513 * sco_inx.
1514 *
1515 ******************************************************************************/
BTM_ChangeEScoLinkParms(uint16_t sco_inx,tBTM_CHG_ESCO_PARAMS * p_parms)1516 static tBTM_STATUS BTM_ChangeEScoLinkParms(uint16_t sco_inx,
1517 tBTM_CHG_ESCO_PARAMS* p_parms) {
1518 /* Make sure sco handle is valid and on an active link */
1519 if (sco_inx >= BTM_MAX_SCO_LINKS ||
1520 btm_cb.sco_cb.sco_db[sco_inx].state != SCO_ST_CONNECTED)
1521 return (BTM_WRONG_MODE);
1522
1523 tSCO_CONN* p_sco = &btm_cb.sco_cb.sco_db[sco_inx];
1524 enh_esco_params_t* p_setup = &p_sco->esco.setup;
1525
1526 /* Save the previous types in case command fails */
1527 uint16_t saved_packet_types = p_setup->packet_types;
1528
1529 /* If SCO connection OR eSCO not supported just send change packet types */
1530 if (p_sco->esco.data.link_type == BTM_LINK_TYPE_SCO ||
1531 !btm_cb.sco_cb.esco_supported) {
1532 p_setup->packet_types =
1533 p_parms->packet_types &
1534 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_LINK_ONLY_MASK);
1535
1536 log::verbose("SCO Link for handle 0x{:04x}, pkt 0x{:04x}",
1537 p_sco->hci_handle, p_setup->packet_types);
1538
1539 log::verbose("SCO Link for handle 0x{:04x}, pkt 0x{:04x}",
1540 p_sco->hci_handle, p_setup->packet_types);
1541
1542 GetInterface().ChangeConnectionPacketType(
1543 p_sco->hci_handle, BTM_ESCO_2_SCO(p_setup->packet_types));
1544 } else /* eSCO is supported and the link type is eSCO */
1545 {
1546 uint16_t temp_packet_types =
1547 (p_parms->packet_types & BTM_SCO_SUPPORTED_PKTS_MASK &
1548 btm_cb.btm_sco_pkt_types_supported);
1549
1550 /* OR in any exception packet types */
1551 temp_packet_types |=
1552 ((p_parms->packet_types & BTM_SCO_EXCEPTION_PKTS_MASK) |
1553 (btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK));
1554 p_setup->packet_types = temp_packet_types;
1555
1556 log::verbose("-> eSCO Link for handle 0x{:04x}", p_sco->hci_handle);
1557 log::verbose(
1558 "txbw 0x{:x}, rxbw 0x{:x}, lat 0x{:x}, retrans 0x{:02x}, pkt 0x{:04x}",
1559 p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1560 p_parms->max_latency_ms, p_parms->retransmission_effort,
1561 temp_packet_types);
1562
1563 /* Use Enhanced Synchronous commands if supported */
1564 if (bluetooth::shim::GetController()->IsSupported(
1565 bluetooth::hci::OpCode::ENHANCED_SETUP_SYNCHRONOUS_CONNECTION) &&
1566 !osi_property_get_bool(kPropertyDisableEnhancedConnection,
1567 kDefaultDisableEnhancedConnection)) {
1568 btsnd_hcic_enhanced_set_up_synchronous_connection(p_sco->hci_handle,
1569 p_setup);
1570 p_setup->packet_types = saved_packet_types;
1571 } else { /* Use older command */
1572 uint16_t voice_content_format = btm_sco_voice_settings_to_legacy(p_setup);
1573 /* When changing an existing link, only change latency, retrans, and
1574 * pkts */
1575 btsnd_hcic_setup_esco_conn(p_sco->hci_handle, p_setup->transmit_bandwidth,
1576 p_setup->receive_bandwidth,
1577 p_parms->max_latency_ms, voice_content_format,
1578 p_parms->retransmission_effort,
1579 p_setup->packet_types);
1580 }
1581
1582 log::verbose(
1583 "txbw 0x{:x}, rxbw 0x{:x}, lat 0x{:x}, retrans 0x{:02x}, pkt 0x{:04x}",
1584 p_setup->transmit_bandwidth, p_setup->receive_bandwidth,
1585 p_parms->max_latency_ms, p_parms->retransmission_effort,
1586 temp_packet_types);
1587 }
1588
1589 return (BTM_CMD_STARTED);
1590 }
1591
1592 /*******************************************************************************
1593 *
1594 * Function BTM_EScoConnRsp
1595 *
1596 * Description This function is called upon receipt of an (e)SCO connection
1597 * request event (BTM_ESCO_CONN_REQ_EVT) to accept or reject
1598 * the request. Parameters used to negotiate eSCO links.
1599 * If p_parms is NULL, then values set through BTM_SetEScoMode
1600 * are used.
1601 * If the link type of the incoming request is SCO, then only
1602 * the tx_bw, max_latency, content format, and packet_types are
1603 * valid. The hci_status parameter should be
1604 * ([0x0] to accept, [0x0d..0x0f] to reject)
1605 *
1606 *
1607 * Returns void
1608 *
1609 ******************************************************************************/
BTM_EScoConnRsp(uint16_t sco_inx,tHCI_STATUS hci_status,enh_esco_params_t * p_parms)1610 void BTM_EScoConnRsp(uint16_t sco_inx, tHCI_STATUS hci_status,
1611 enh_esco_params_t* p_parms) {
1612 if (sco_inx < BTM_MAX_SCO_LINKS &&
1613 btm_cb.sco_cb.sco_db[sco_inx].state == SCO_ST_W4_CONN_RSP) {
1614 btm_esco_conn_rsp(sco_inx, hci_status,
1615 btm_cb.sco_cb.sco_db[sco_inx].esco.data.bd_addr, p_parms);
1616 }
1617 }
1618
1619 /*******************************************************************************
1620 *
1621 * Function BTM_GetNumScoLinks
1622 *
1623 * Description This function returns the number of active sco links.
1624 *
1625 * Returns uint8_t
1626 *
1627 ******************************************************************************/
BTM_GetNumScoLinks(void)1628 uint8_t BTM_GetNumScoLinks(void) {
1629 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1630 uint16_t xx;
1631 uint8_t num_scos = 0;
1632
1633 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1634 switch (p->state) {
1635 case SCO_ST_W4_CONN_RSP:
1636 case SCO_ST_CONNECTING:
1637 case SCO_ST_CONNECTED:
1638 case SCO_ST_DISCONNECTING:
1639 case SCO_ST_PEND_UNPARK:
1640 num_scos++;
1641 break;
1642 default:
1643 break;
1644 }
1645 }
1646 return (num_scos);
1647 }
1648
1649 /*******************************************************************************
1650 *
1651 * Function BTM_IsScoActiveByBdaddr
1652 *
1653 * Description This function is called to see if a SCO connection is active
1654 * for a bd address.
1655 *
1656 * Returns bool
1657 *
1658 ******************************************************************************/
BTM_IsScoActiveByBdaddr(const RawAddress & remote_bda)1659 bool BTM_IsScoActiveByBdaddr(const RawAddress& remote_bda) {
1660 uint8_t xx;
1661 tSCO_CONN* p = &btm_cb.sco_cb.sco_db[0];
1662
1663 /* If any SCO is being established to the remote BD address, refuse this */
1664 for (xx = 0; xx < BTM_MAX_SCO_LINKS; xx++, p++) {
1665 if (p->esco.data.bd_addr == remote_bda && p->state == SCO_ST_CONNECTED) {
1666 return (true);
1667 }
1668 }
1669 return (false);
1670 }
1671
1672 /*******************************************************************************
1673 *
1674 * Function btm_sco_voice_settings_2_legacy
1675 *
1676 * Description This function is called to convert the Enhanced eSCO
1677 * parameters into voice setting parameter mask used
1678 * for legacy setup synchronous connection HCI commands
1679 *
1680 * Returns UINT16 - 16-bit mask for voice settings
1681 *
1682 * HCI_INP_CODING_LINEAR 0x0000 (0000000000)
1683 * HCI_INP_CODING_U_LAW 0x0100 (0100000000)
1684 * HCI_INP_CODING_A_LAW 0x0200 (1000000000)
1685 * HCI_INP_CODING_MASK 0x0300 (1100000000)
1686 *
1687 * HCI_INP_DATA_FMT_1S_COMPLEMENT 0x0000 (0000000000)
1688 * HCI_INP_DATA_FMT_2S_COMPLEMENT 0x0040 (0001000000)
1689 * HCI_INP_DATA_FMT_SIGN_MAGNITUDE 0x0080 (0010000000)
1690 * HCI_INP_DATA_FMT_UNSIGNED 0x00c0 (0011000000)
1691 * HCI_INP_DATA_FMT_MASK 0x00c0 (0011000000)
1692 *
1693 * HCI_INP_SAMPLE_SIZE_8BIT 0x0000 (0000000000)
1694 * HCI_INP_SAMPLE_SIZE_16BIT 0x0020 (0000100000)
1695 * HCI_INP_SAMPLE_SIZE_MASK 0x0020 (0000100000)
1696 *
1697 * HCI_INP_LINEAR_PCM_BIT_POS_MASK 0x001c (0000011100)
1698 * HCI_INP_LINEAR_PCM_BIT_POS_OFFS 2
1699 *
1700 * HCI_AIR_CODING_FORMAT_CVSD 0x0000 (0000000000)
1701 * HCI_AIR_CODING_FORMAT_U_LAW 0x0001 (0000000001)
1702 * HCI_AIR_CODING_FORMAT_A_LAW 0x0002 (0000000010)
1703 * HCI_AIR_CODING_FORMAT_TRANSPNT 0x0003 (0000000011)
1704 * HCI_AIR_CODING_FORMAT_MASK 0x0003 (0000000011)
1705 *
1706 * default (0001100000)
1707 * HCI_DEFAULT_VOICE_SETTINGS (HCI_INP_CODING_LINEAR \
1708 * | HCI_INP_DATA_FMT_2S_COMPLEMENT \
1709 * | HCI_INP_SAMPLE_SIZE_16BIT \
1710 * | HCI_AIR_CODING_FORMAT_CVSD)
1711 *
1712 ******************************************************************************/
btm_sco_voice_settings_to_legacy(enh_esco_params_t * p_params)1713 static uint16_t btm_sco_voice_settings_to_legacy(enh_esco_params_t* p_params) {
1714 uint16_t voice_settings = 0;
1715
1716 /* Convert Input Coding Format: If no uLaw or aLAW then Linear will be used
1717 * (0) */
1718 if (p_params->input_coding_format.coding_format == ESCO_CODING_FORMAT_ULAW)
1719 voice_settings |= HCI_INP_CODING_U_LAW;
1720 else if (p_params->input_coding_format.coding_format ==
1721 ESCO_CODING_FORMAT_ALAW)
1722 voice_settings |= HCI_INP_CODING_A_LAW;
1723 /* else default value of '0 is good 'Linear' */
1724
1725 /* Convert Input Data Format. Use 2's Compliment as the default */
1726 switch (p_params->input_pcm_data_format) {
1727 case ESCO_PCM_DATA_FORMAT_1_COMP:
1728 /* voice_settings |= HCI_INP_DATA_FMT_1S_COMPLEMENT; value is '0'
1729 * already */
1730 break;
1731
1732 case ESCO_PCM_DATA_FORMAT_SIGN:
1733 voice_settings |= HCI_INP_DATA_FMT_SIGN_MAGNITUDE;
1734 break;
1735
1736 case ESCO_PCM_DATA_FORMAT_UNSIGN:
1737 voice_settings |= HCI_INP_DATA_FMT_UNSIGNED;
1738 break;
1739
1740 default: /* 2's Compliment */
1741 voice_settings |= HCI_INP_DATA_FMT_2S_COMPLEMENT;
1742 break;
1743 }
1744
1745 /* Convert Over the Air Coding. Use CVSD as the default */
1746 switch (p_params->transmit_coding_format.coding_format) {
1747 case ESCO_CODING_FORMAT_ULAW:
1748 voice_settings |= HCI_AIR_CODING_FORMAT_U_LAW;
1749 break;
1750
1751 case ESCO_CODING_FORMAT_ALAW:
1752 voice_settings |= HCI_AIR_CODING_FORMAT_A_LAW;
1753 break;
1754
1755 case ESCO_CODING_FORMAT_TRANSPNT:
1756 case ESCO_CODING_FORMAT_MSBC:
1757 case ESCO_CODING_FORMAT_LC3:
1758 voice_settings |= HCI_AIR_CODING_FORMAT_TRANSPNT;
1759 break;
1760
1761 default: /* CVSD (0) */
1762 break;
1763 }
1764
1765 /* Convert PCM payload MSB position (0000011100) */
1766 voice_settings |= (uint16_t)(((p_params->input_pcm_payload_msb_position & 0x7)
1767 << HCI_INP_LINEAR_PCM_BIT_POS_OFFS));
1768
1769 /* Convert Input Sample Size (0000011100) */
1770 if (p_params->input_coded_data_size == 16)
1771 voice_settings |= HCI_INP_SAMPLE_SIZE_16BIT;
1772 else /* Use 8 bit for all others */
1773 voice_settings |= HCI_INP_SAMPLE_SIZE_8BIT;
1774
1775 log::verbose("voice setting for legacy 0x{:03x}", voice_settings);
1776
1777 return (voice_settings);
1778 }
1779 /*******************************************************************************
1780 *
1781 * Function BTM_GetScoDebugDump
1782 *
1783 * Description Get the status of SCO. This function is only used for
1784 * testing and debugging purposes.
1785 *
1786 * Returns Data with SCO related debug dump.
1787 *
1788 ******************************************************************************/
BTM_GetScoDebugDump()1789 tBTM_SCO_DEBUG_DUMP BTM_GetScoDebugDump() {
1790 tSCO_CONN* active_sco = btm_get_active_sco();
1791 tBTM_SCO_DEBUG_DUMP debug_dump = {};
1792
1793 debug_dump.is_active = active_sco != nullptr;
1794 if (!debug_dump.is_active) return debug_dump;
1795
1796 tBTM_SCO_CODEC_TYPE codec_type = active_sco->get_codec_type();
1797 debug_dump.codec_id = sco_codec_type_to_id(codec_type);
1798 if (debug_dump.codec_id != UUID_CODEC_MSBC &&
1799 debug_dump.codec_id != UUID_CODEC_LC3)
1800 return debug_dump;
1801
1802 auto fill_plc_stats = debug_dump.codec_id == UUID_CODEC_LC3
1803 ? &bluetooth::audio::sco::swb::fill_plc_stats
1804 : &bluetooth::audio::sco::wbs::fill_plc_stats;
1805
1806 if (!fill_plc_stats(&debug_dump.total_num_decoded_frames,
1807 &debug_dump.pkt_loss_ratio))
1808 return debug_dump;
1809
1810 auto get_pkt_status = debug_dump.codec_id == UUID_CODEC_LC3
1811 ? &bluetooth::audio::sco::swb::get_pkt_status
1812 : &bluetooth::audio::sco::wbs::get_pkt_status;
1813
1814 tBTM_SCO_PKT_STATUS* pkt_status = get_pkt_status();
1815 if (pkt_status == nullptr) return debug_dump;
1816
1817 tBTM_SCO_PKT_STATUS_DATA* data = &debug_dump.latest_data;
1818 data->begin_ts_raw_us = pkt_status->begin_ts_raw_us();
1819 data->end_ts_raw_us = pkt_status->end_ts_raw_us();
1820 data->status_in_hex = pkt_status->data_to_hex_string();
1821 data->status_in_binary = pkt_status->data_to_binary_string();
1822 return debug_dump;
1823 }
1824
btm_peer_supports_esco_2m_phy(RawAddress remote_bda)1825 bool btm_peer_supports_esco_2m_phy(RawAddress remote_bda) {
1826 uint8_t* features = BTM_ReadRemoteFeatures(remote_bda);
1827 if (features == nullptr) {
1828 log::warn("Checking remote features but remote feature read is incomplete");
1829 return false;
1830 }
1831 return HCI_EDR_ESCO_2MPS_SUPPORTED(features);
1832 }
1833
btm_peer_supports_esco_3m_phy(RawAddress remote_bda)1834 bool btm_peer_supports_esco_3m_phy(RawAddress remote_bda) {
1835 uint8_t* features = BTM_ReadRemoteFeatures(remote_bda);
1836 if (features == nullptr) {
1837 log::warn("Checking remote features but remote feature read is incomplete");
1838 return false;
1839 }
1840 return HCI_EDR_ESCO_3MPS_SUPPORTED(features);
1841 }
1842
btm_peer_supports_esco_ev3(RawAddress remote_bda)1843 bool btm_peer_supports_esco_ev3(RawAddress remote_bda) {
1844 uint8_t* features = BTM_ReadRemoteFeatures(remote_bda);
1845 if (features == nullptr) {
1846 log::warn("Checking remote features but remote feature read is incomplete");
1847 return false;
1848 }
1849 return HCI_ESCO_EV3_SUPPORTED(features);
1850 }
1851