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