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