• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /******************************************************************************
2  *
3  *  Copyright 2018 The Android Open Source Project
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 #define LOG_TAG "bluetooth-asha"
20 
21 #include <base/functional/bind.h>
22 #include <base/functional/callback.h>
23 #include <base/strings/string_number_conversions.h>  // HexEncode
24 #include <bluetooth/log.h>
25 #include <com_android_bluetooth_flags.h>
26 #include <stdio.h>
27 #include <string.h>
28 #include <time.h>
29 
30 #include <algorithm>
31 #include <chrono>
32 #include <cstddef>
33 #include <cstdint>
34 #include <cstdio>
35 #include <cstring>
36 #include <ctime>
37 #include <deque>
38 #include <functional>
39 #include <list>
40 #include <memory>
41 #include <mutex>
42 #include <ostream>
43 #include <sstream>
44 #include <utility>
45 #include <vector>
46 
47 #include "audio/asrc/asrc_resampler.h"
48 #include "bta/include/bta_gatt_api.h"
49 #include "bta/include/bta_gatt_queue.h"
50 #include "bta/include/bta_hearing_aid_api.h"
51 #include "btm_api_types.h"
52 #include "btm_ble_api_types.h"
53 #include "btm_iso_api.h"
54 #include "btm_sec_api_types.h"
55 #include "embdrv/g722/g722_enc_dec.h"
56 #include "gap_api.h"
57 #include "gatt/database.h"
58 #include "gatt_api.h"
59 #include "gattdefs.h"
60 #include "hardware/bt_gatt_types.h"
61 #include "hardware/bt_hearing_aid.h"
62 #include "hci/controller_interface.h"
63 #include "internal_include/bt_trace.h"
64 #include "l2cap_types.h"
65 #include "main/shim/entry.h"
66 #include "osi/include/allocator.h"
67 #include "osi/include/properties.h"
68 #include "profiles_api.h"
69 #include "stack/btm/btm_sec.h"
70 #include "stack/include/acl_api_types.h"  // tBTM_RSSI_RESULT
71 #include "stack/include/bt_hdr.h"
72 #include "stack/include/bt_types.h"
73 #include "stack/include/bt_uuid16.h"
74 #include "stack/include/btm_client_interface.h"
75 #include "stack/include/btm_status.h"
76 #include "stack/include/l2cap_interface.h"
77 #include "stack/include/main_thread.h"
78 #include "types/bluetooth/uuid.h"
79 #include "types/bt_transport.h"
80 #include "types/raw_address.h"
81 
82 using base::Closure;
83 using bluetooth::Uuid;
84 using bluetooth::hci::IsoManager;
85 using bluetooth::hearing_aid::ConnectionState;
86 using namespace bluetooth;
87 
88 // The MIN_CE_LEN parameter for Connection Parameters based on the current
89 // Connection Interval
90 constexpr uint16_t MIN_CE_LEN_10MS_CI = 0x0006;
91 constexpr uint16_t MIN_CE_LEN_20MS_CI = 0x000C;
92 constexpr uint16_t MAX_CE_LEN_20MS_CI = 0x000C;
93 constexpr uint16_t CE_LEN_20MS_CI_ISO_RUNNING = 0x0000;
94 constexpr uint16_t CONNECTION_INTERVAL_10MS_PARAM = 0x0008;
95 constexpr uint16_t CONNECTION_INTERVAL_20MS_PARAM = 0x0010;
96 
97 void btif_storage_add_hearing_aid(const HearingDevice& dev_info);
98 bool btif_storage_get_hearing_aid_prop(const RawAddress& address, uint8_t* capabilities,
99                                        uint64_t* hi_sync_id, uint16_t* render_delay,
100                                        uint16_t* preparation_delay, uint16_t* codecs);
101 
102 constexpr uint8_t CODEC_G722_16KHZ = 0x01;
103 constexpr uint8_t CODEC_G722_24KHZ = 0x02;
104 
105 // audio control point opcodes
106 constexpr uint8_t CONTROL_POINT_OP_START = 0x01;
107 constexpr uint8_t CONTROL_POINT_OP_STOP = 0x02;
108 constexpr uint8_t CONTROL_POINT_OP_STATE_CHANGE = 0x03;
109 
110 constexpr uint8_t STATE_CHANGE_OTHER_SIDE_DISCONNECTED = 0x00;
111 constexpr uint8_t STATE_CHANGE_OTHER_SIDE_CONNECTED = 0x01;
112 constexpr uint8_t STATE_CHANGE_CONN_UPDATE = 0x02;
113 
114 // used to mark current_volume as not yet known, or possibly old
115 constexpr int8_t VOLUME_UNKNOWN = 127;
116 constexpr int8_t VOLUME_MIN = -127;
117 
118 // audio type
119 constexpr uint8_t AUDIOTYPE_UNKNOWN = 0x00;
120 
121 // Status of the other side Hearing Aids device
122 constexpr uint8_t OTHER_SIDE_NOT_STREAMING = 0x00;
123 constexpr uint8_t OTHER_SIDE_IS_STREAMING = 0x01;
124 
125 // This ADD_RENDER_DELAY_INTERVALS is the number of connection intervals when
126 // the audio data packet is send by Audio Engine to when the Hearing Aids device
127 // received it from the air. We assumed that there is 2 data buffer queued from
128 // audio subsystem to bluetooth chip. Then the estimated OTA delay is two
129 // connnection intervals.
130 constexpr uint16_t ADD_RENDER_DELAY_INTERVALS = 4;
131 
132 constexpr tCONN_ID INVALID_CONN_ID = 0;
133 
134 namespace {
135 
136 // clang-format off
137 Uuid HEARING_AID_UUID          = Uuid::FromString("FDF0");
138 Uuid READ_ONLY_PROPERTIES_UUID = Uuid::FromString("6333651e-c481-4a3e-9169-7c902aad37bb");
139 Uuid AUDIO_CONTROL_POINT_UUID  = Uuid::FromString("f0d4de7e-4a88-476c-9d9f-1937b0996cc0");
140 Uuid AUDIO_STATUS_UUID         = Uuid::FromString("38663f1a-e711-4cac-b641-326b56404837");
141 Uuid VOLUME_UUID               = Uuid::FromString("00e4ca9e-ab14-41e4-8823-f9e70c7e91df");
142 Uuid LE_PSM_UUID               = Uuid::FromString("2d410339-82b6-42aa-b34e-e2e01df8cc1a");
143 // clang-format on
144 
145 static void read_rssi_callback(void* p_void);
146 static void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
147 static void encryption_callback(RawAddress, tBT_TRANSPORT, void*, tBTM_STATUS);
148 
malloc_l2cap_buf(uint16_t len)149 inline BT_HDR* malloc_l2cap_buf(uint16_t len) {
150   BT_HDR* msg = (BT_HDR*)osi_malloc(BT_HDR_SIZE + L2CAP_MIN_OFFSET +
151                                     len /* LE-only, no need for FCS here */);
152   msg->offset = L2CAP_MIN_OFFSET;
153   msg->len = len;
154   return msg;
155 }
156 
get_l2cap_sdu_start_ptr(BT_HDR * msg)157 inline uint8_t* get_l2cap_sdu_start_ptr(BT_HDR* msg) {
158   return (uint8_t*)(msg) + BT_HDR_SIZE + L2CAP_MIN_OFFSET;
159 }
160 
161 class HearingAidImpl;
162 HearingAidImpl* instance;
163 std::mutex instance_mutex;
164 HearingAidAudioReceiver* audioReceiver;
165 
166 class HearingDevices {
167 public:
Add(HearingDevice device)168   void Add(HearingDevice device) {
169     if (FindByAddress(device.address) != nullptr) {
170       return;
171     }
172 
173     devices.push_back(device);
174   }
175 
Remove(const RawAddress & address)176   void Remove(const RawAddress& address) {
177     for (auto it = devices.begin(); it != devices.end();) {
178       if (it->address != address) {
179         ++it;
180         continue;
181       }
182 
183       it = devices.erase(it);
184       return;
185     }
186   }
187 
FindByAddress(const RawAddress & address)188   HearingDevice* FindByAddress(const RawAddress& address) {
189     auto iter = std::find_if(
190             devices.begin(), devices.end(),
191             [&address](const HearingDevice& device) { return device.address == address; });
192 
193     return (iter == devices.end()) ? nullptr : &(*iter);
194   }
195 
FindOtherConnectedDeviceFromSet(const HearingDevice & device)196   HearingDevice* FindOtherConnectedDeviceFromSet(const HearingDevice& device) {
197     auto iter = std::find_if(devices.begin(), devices.end(), [&device](const HearingDevice& other) {
198       return &device != &other && device.hi_sync_id == other.hi_sync_id &&
199              other.conn_id != INVALID_CONN_ID;
200     });
201 
202     return (iter == devices.end()) ? nullptr : &(*iter);
203   }
204 
FindByConnId(tCONN_ID conn_id)205   HearingDevice* FindByConnId(tCONN_ID conn_id) {
206     auto iter = std::find_if(
207             devices.begin(), devices.end(),
208             [&conn_id](const HearingDevice& device) { return device.conn_id == conn_id; });
209 
210     return (iter == devices.end()) ? nullptr : &(*iter);
211   }
212 
FindByGapHandle(uint16_t gap_handle)213   HearingDevice* FindByGapHandle(uint16_t gap_handle) {
214     auto iter = std::find_if(
215             devices.begin(), devices.end(),
216             [&gap_handle](const HearingDevice& device) { return device.gap_handle == gap_handle; });
217 
218     return (iter == devices.end()) ? nullptr : &(*iter);
219   }
220 
StartRssiLog()221   void StartRssiLog() {
222     int read_rssi_start_interval_count = 0;
223 
224     for (auto& d : devices) {
225       log::debug("bd_addr={} read_rssi_count={}", d.address, d.read_rssi_count);
226 
227       // Reset the count
228       if (d.read_rssi_count <= 0) {
229         d.read_rssi_count = READ_RSSI_NUM_TRIES;
230         d.num_intervals_since_last_rssi_read = read_rssi_start_interval_count;
231 
232         // Spaced apart the Read RSSI commands to the BT controller.
233         read_rssi_start_interval_count += PERIOD_TO_READ_RSSI_IN_INTERVALS / 2;
234         read_rssi_start_interval_count %= PERIOD_TO_READ_RSSI_IN_INTERVALS;
235 
236         std::deque<rssi_log>& rssi_logs = d.audio_stats.rssi_history;
237         if (rssi_logs.size() >= MAX_RSSI_HISTORY) {
238           rssi_logs.pop_front();
239         }
240         rssi_logs.emplace_back();
241       }
242     }
243   }
244 
size()245   size_t size() { return devices.size(); }
246 
247   std::vector<HearingDevice> devices;
248 };
249 
write_rpt_ctl_cfg_cb(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t *,void *)250 static void write_rpt_ctl_cfg_cb(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle,
251                                  uint16_t len, const uint8_t* /*value*/, void* /*data*/) {
252   if (status != GATT_SUCCESS) {
253     log::error("handle= {}, conn_id={}, status= 0x{:x}, length={}", handle, conn_id,
254                static_cast<uint8_t>(status), len);
255   }
256 }
257 
258 g722_encode_state_t* encoder_state_left = nullptr;
259 g722_encode_state_t* encoder_state_right = nullptr;
260 
encoder_state_init()261 inline void encoder_state_init() {
262   if (encoder_state_left != nullptr) {
263     log::warn("encoder already initialized");
264     return;
265   }
266   encoder_state_left = g722_encode_init(nullptr, 64000, G722_PACKED);
267   encoder_state_right = g722_encode_init(nullptr, 64000, G722_PACKED);
268 }
269 
encoder_state_release()270 inline void encoder_state_release() {
271   if (encoder_state_left != nullptr) {
272     g722_encode_release(encoder_state_left);
273     encoder_state_left = nullptr;
274     g722_encode_release(encoder_state_right);
275     encoder_state_right = nullptr;
276   }
277 }
278 
279 class HearingAidImpl : public HearingAid {
280 private:
281   // Keep track of whether the Audio Service has resumed audio playback
282   bool audio_running;
283   bool is_iso_running = false;
284   // For Testing: overwrite the MIN_CE_LEN and MAX_CE_LEN during connection
285   // parameter updates
286   int16_t overwrite_min_ce_len = -1;
287   int16_t overwrite_max_ce_len = -1;
288   const std::string PERSIST_MIN_CE_LEN_NAME = "persist.bluetooth.hearing_aid_min_ce_len";
289   const std::string PERSIST_MAX_CE_LEN_NAME = "persist.bluetooth.hearing_aid_max_ce_len";
290   // Record whether the connection parameter needs to update to a better one
291   bool needs_parameter_update = false;
292   std::chrono::time_point<std::chrono::steady_clock> last_drop_time_point =
293           std::chrono::steady_clock::now();
294   // at most 1 packet DROP per kDropFrequencyThreshold seconds
295   static constexpr int64_t kDropFrequencyThreshold = 60;
296 
297   // Resampler context for audio stream.
298   // Clock recovery uses L2CAP Flow Control Credit Ind acknowledgments
299   // from either the left or right connection, whichever is first
300   // connected.
301   std::unique_ptr<bluetooth::audio::asrc::SourceAudioHalAsrc> asrc;
302 
303 public:
304   ~HearingAidImpl() override = default;
305 
HearingAidImpl(bluetooth::hearing_aid::HearingAidCallbacks * callbacks,Closure initCb)306   HearingAidImpl(bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb)
307       : audio_running(false),
308         overwrite_min_ce_len(-1),
309         overwrite_max_ce_len(-1),
310         gatt_if(0),
311         seq_counter(0),
312         current_volume(VOLUME_UNKNOWN),
313         callbacks(callbacks),
314         codec_in_use(0) {
315     default_data_interval_ms = (uint16_t)osi_property_get_int32(
316             "persist.bluetooth.hearingaid.interval", (int32_t)HA_INTERVAL_20_MS);
317 
318     if ((default_data_interval_ms != HA_INTERVAL_10_MS) &&
319         (default_data_interval_ms != HA_INTERVAL_20_MS)) {
320       log::error("invalid interval={}ms. Overwrriting back to default", default_data_interval_ms);
321       default_data_interval_ms = HA_INTERVAL_20_MS;
322     }
323 
324     overwrite_min_ce_len = (int16_t)osi_property_get_int32(PERSIST_MIN_CE_LEN_NAME.c_str(), -1);
325     overwrite_max_ce_len = (int16_t)osi_property_get_int32(PERSIST_MAX_CE_LEN_NAME.c_str(), -1);
326 
327     log::info("default_data_interval_ms={} overwrite_min_ce_len={} overwrite_max_ce_len={}",
328               default_data_interval_ms, overwrite_min_ce_len, overwrite_max_ce_len);
329 
330     BTA_GATTC_AppRegister(
331             "asha", hearingaid_gattc_callback,
332             base::Bind(
333                     [](Closure initCb, uint8_t client_id, uint8_t status) {
334                       if (status != GATT_SUCCESS) {
335                         log::error("Can't start Hearing Aid profile - no gatt clients left!");
336                         return;
337                       }
338                       instance->gatt_if = client_id;
339                       initCb.Run();
340                     },
341                     initCb),
342             false);
343 
344     IsoManager::GetInstance()->Start();
345     IsoManager::GetInstance()->RegisterOnIsoTrafficActiveCallback([](bool is_active) {
346       if (!instance) {
347         return;
348       }
349       instance->IsoTrafficEventCb(is_active);
350     });
351   }
352 
IsoTrafficEventCb(bool is_active)353   void IsoTrafficEventCb(bool is_active) {
354     if (is_active) {
355       is_iso_running = true;
356       needs_parameter_update = true;
357     } else {
358       is_iso_running = false;
359     }
360 
361     log::info("is_iso_running={} needs_parameter_update={}", is_iso_running,
362               needs_parameter_update);
363 
364     if (needs_parameter_update) {
365       for (auto& device : hearingDevices.devices) {
366         if (device.conn_id != INVALID_CONN_ID) {
367           device.connection_update_status = STARTED;
368           device.requested_connection_interval = UpdateBleConnParams(device.address);
369         }
370       }
371     }
372   }
373 
374   // Reset and configure the ASHA resampling context using the input device
375   // devices as reference for the BT clock estimation.
ConfigureAsrc()376   void ConfigureAsrc() {
377     // Create a new ASRC context if required.
378     if (asrc == nullptr) {
379       log::info("Configuring Asha resampler");
380       asrc = std::make_unique<bluetooth::audio::asrc::SourceAudioHalAsrc>(
381               /*thread*/ get_main_thread(),
382               /*channels*/ 2,
383               /*sample_rate*/ codec_in_use == CODEC_G722_24KHZ ? 24000 : 16000,
384               /*bit_depth*/ 16,
385               /*interval_us*/ default_data_interval_ms * 1000,
386               /*num_burst_buffers*/ 0,
387               /*burst_delay*/ 0);
388     }
389   }
390 
391   // Reset the ASHA resampling context.
ResetAsrc()392   void ResetAsrc() {
393     log::info("Resetting the Asha resampling context");
394     asrc = nullptr;
395   }
396 
UpdateBleConnParams(const RawAddress & address)397   uint16_t UpdateBleConnParams(const RawAddress& address) {
398     /* List of parameters that depends on the chosen Connection Interval */
399     uint16_t min_ce_len = MIN_CE_LEN_20MS_CI;
400     uint16_t max_ce_len = MAX_CE_LEN_20MS_CI;
401     uint16_t connection_interval;
402 
403     switch (default_data_interval_ms) {
404       case HA_INTERVAL_10_MS:
405         min_ce_len = MIN_CE_LEN_10MS_CI;
406         connection_interval = CONNECTION_INTERVAL_10MS_PARAM;
407         break;
408 
409       case HA_INTERVAL_20_MS:
410         // When ISO is connected, the controller might not be able to
411         // update the connection event length successfully.
412         // So if ISO is running, we use a small ce length to connect first,
413         // then update to a better value later on
414         if (is_iso_running) {
415           min_ce_len = CE_LEN_20MS_CI_ISO_RUNNING;
416           max_ce_len = CE_LEN_20MS_CI_ISO_RUNNING;
417           needs_parameter_update = true;
418         } else {
419           min_ce_len = MIN_CE_LEN_20MS_CI;
420           max_ce_len = MAX_CE_LEN_20MS_CI;
421           needs_parameter_update = false;
422         }
423         connection_interval = CONNECTION_INTERVAL_20MS_PARAM;
424         break;
425 
426       default:
427         log::error("invalid default_data_interval_ms={}", default_data_interval_ms);
428         min_ce_len = MIN_CE_LEN_10MS_CI;
429         connection_interval = CONNECTION_INTERVAL_10MS_PARAM;
430     }
431 
432     if (overwrite_min_ce_len != -1) {
433       log::warn("min_ce_len={} for device {} is overwritten to {}", min_ce_len, address,
434                 overwrite_min_ce_len);
435       min_ce_len = overwrite_min_ce_len;
436     }
437     if (overwrite_max_ce_len != -1) {
438       log::warn("max_ce_len={} for device {} is overwritten to {}", max_ce_len, address,
439                 overwrite_max_ce_len);
440       max_ce_len = overwrite_max_ce_len;
441     }
442 
443     log::info("L2CA_UpdateBleConnParams for device {} min_ce_len:{} max_ce_len:{}", address,
444               min_ce_len, max_ce_len);
445     if (!stack::l2cap::get_interface().L2CA_UpdateBleConnParams(
446                 address, connection_interval, connection_interval, 0x000A, 0x0064 /*1s*/,
447                 min_ce_len, max_ce_len)) {
448       log::warn("Unable to update L2CAP ble connection parameters peer:{}", address);
449     }
450     return connection_interval;
451   }
452 
IsBelowDropFrequency(std::chrono::time_point<std::chrono::steady_clock> tp)453   bool IsBelowDropFrequency(std::chrono::time_point<std::chrono::steady_clock> tp) {
454     auto duration = tp - last_drop_time_point;
455     bool droppable = std::chrono::duration_cast<std::chrono::seconds>(duration).count() >=
456                      kDropFrequencyThreshold;
457     log::info("IsBelowDropFrequency {}", droppable);
458     return droppable;
459   }
460 
Connect(const RawAddress & address)461   void Connect(const RawAddress& address) {
462     log::info("bd_addr={}", address);
463     hearingDevices.Add(HearingDevice(address, true));
464     BTA_GATTC_Open(gatt_if, address, BTM_BLE_DIRECT_CONNECTION, false);
465   }
466 
AddToAcceptlist(const RawAddress & address)467   void AddToAcceptlist(const RawAddress& address) {
468     log::info("bd_addr={}", address);
469     hearingDevices.Add(HearingDevice(address, true));
470     BTA_GATTC_Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
471   }
472 
AddFromStorage(const HearingDevice & dev_info,bool is_acceptlisted)473   void AddFromStorage(const HearingDevice& dev_info, bool is_acceptlisted) {
474     log::info("bd_addr={} hi_sync_id=0x{:x} is_acceptlisted={}", dev_info.address,
475               dev_info.hi_sync_id, is_acceptlisted);
476     if (is_acceptlisted) {
477       hearingDevices.Add(dev_info);
478 
479       // TODO: we should increase the scanning window for few seconds, to get
480       // faster initial connection, same after hearing aid disconnects, i.e.
481       // BTM_BleSetConnScanParams(2048, 1024);
482 
483       /* add device into BG connection to accept remote initiated connection */
484       BTA_GATTC_Open(gatt_if, dev_info.address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
485     }
486 
487     callbacks->OnDeviceAvailable(dev_info.capabilities, dev_info.hi_sync_id, dev_info.address);
488   }
489 
GetDeviceCount()490   int GetDeviceCount() { return hearingDevices.size(); }
491 
OnGattConnected(tGATT_STATUS status,tCONN_ID conn_id,tGATT_IF,RawAddress address,tBT_TRANSPORT,uint16_t)492   void OnGattConnected(tGATT_STATUS status, tCONN_ID conn_id, tGATT_IF /*client_if*/,
493                        RawAddress address, tBT_TRANSPORT /*transport*/, uint16_t /*mtu*/) {
494     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
495     if (!hearingDevice) {
496       /* When Hearing Aid is quickly disabled and enabled in settings, this case
497        * might happen */
498       log::warn("Closing connection to non hearing-aid device: bd_addr={}", address);
499       BTA_GATTC_Close(conn_id);
500       return;
501     }
502 
503     log::info("address={}, conn_id={}", address, conn_id);
504 
505     if (status != GATT_SUCCESS) {
506       if (!hearingDevice->connecting_actively) {
507         // acceptlist connection failed, that's ok.
508         return;
509       }
510 
511       if (hearingDevice->switch_to_background_connection_after_failure) {
512         hearingDevice->connecting_actively = false;
513         hearingDevice->switch_to_background_connection_after_failure = false;
514         BTA_GATTC_Open(gatt_if, address, BTM_BLE_BKG_CONNECT_ALLOW_LIST, false);
515       } else {
516         log::info("Failed to connect to Hearing Aid device, bda={}", address);
517 
518         hearingDevices.Remove(address);
519         callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
520       }
521       return;
522     }
523 
524     hearingDevice->conn_id = conn_id;
525 
526     if (com::android::bluetooth::flags::gatt_queue_cleanup_connected()) {
527       BtaGattQueue::Clean(conn_id);
528     }
529 
530     uint64_t hi_sync_id = hearingDevice->hi_sync_id;
531 
532     // If there a background connection to the other device of a pair, promote
533     // it to a direct connection to scan more aggressively for it
534     if (hi_sync_id != 0) {
535       for (auto& device : hearingDevices.devices) {
536         if (device.hi_sync_id == hi_sync_id && device.conn_id == INVALID_CONN_ID &&
537             !device.connecting_actively) {
538           log::info("Promoting device from the set from background to direct connection, bda={}",
539                     device.address);
540           device.connecting_actively = true;
541           device.switch_to_background_connection_after_failure = true;
542           BTA_GATTC_Open(gatt_if, device.address, BTM_BLE_DIRECT_CONNECTION, false);
543         }
544       }
545     }
546 
547     hearingDevice->connection_update_status = STARTED;
548     hearingDevice->requested_connection_interval = UpdateBleConnParams(address);
549 
550     if (bluetooth::shim::GetController()->SupportsBle2mPhy()) {
551       log::info("{} set preferred 2M PHY", address);
552       get_btm_client_interface().ble.BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
553     }
554 
555     // Set data length
556     // TODO(jpawlowski: for 16khz only 87 is required, optimize
557     if (get_btm_client_interface().ble.BTM_SetBleDataLength(address, 167) !=
558         tBTM_STATUS::BTM_SUCCESS) {
559       log::warn("Unable to set BLE data length peer:{} size:{}", address, 167);
560     }
561 
562     if (BTM_SecIsLeSecurityPending(address)) {
563       /* if security collision happened, wait for encryption done
564        * (BTA_GATTC_ENC_CMPL_CB_EVT) */
565       return;
566     }
567 
568     /* verify bond */
569     if (BTM_IsEncrypted(address, BT_TRANSPORT_LE)) {
570       /* if link has been encrypted */
571       OnEncryptionComplete(address, true);
572       return;
573     }
574 
575     if (BTM_IsBonded(address, BT_TRANSPORT_LE)) {
576       /* if bonded and link not encrypted */
577       BTM_SetEncryption(address, BT_TRANSPORT_LE, encryption_callback, nullptr,
578                         BTM_BLE_SEC_ENCRYPT);
579       return;
580     }
581 
582     /* otherwise let it go through */
583     OnEncryptionComplete(address, true);
584   }
585 
OnConnectionUpdateComplete(tCONN_ID conn_id,tBTA_GATTC * p_data)586   void OnConnectionUpdateComplete(tCONN_ID conn_id, tBTA_GATTC* p_data) {
587     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
588     if (!hearingDevice) {
589       log::error("unknown device: conn_id=0x{:x}", conn_id);
590       return;
591     }
592 
593     if (p_data) {
594       if (p_data->conn_update.status == 0) {
595         bool same_conn_interval =
596                 (hearingDevice->requested_connection_interval == p_data->conn_update.interval);
597 
598         switch (hearingDevice->connection_update_status) {
599           case COMPLETED:
600             if (!same_conn_interval) {
601               log::warn(
602                       "Unexpected change. Redo. connection interval={}, "
603                       "expected={}, conn_id={}, connection_update_status={}",
604                       p_data->conn_update.interval, hearingDevice->requested_connection_interval,
605                       conn_id, hearingDevice->connection_update_status);
606               // Redo this connection interval change.
607               hearingDevice->connection_update_status = AWAITING;
608             }
609             break;
610           case STARTED:
611             if (same_conn_interval) {
612               log::info("Connection update completed: conn_id={} bd_addr={}", conn_id,
613                         hearingDevice->address);
614               hearingDevice->connection_update_status = COMPLETED;
615             } else {
616               log::warn(
617                       "Ignored. Different connection interval={}, expected={}, "
618                       "conn_id={}, connection_update_status={}",
619                       p_data->conn_update.interval, hearingDevice->requested_connection_interval,
620                       conn_id, hearingDevice->connection_update_status);
621               // Wait for the right Connection Update Completion.
622               return;
623             }
624             break;
625           case AWAITING:
626           case NONE:
627             break;
628         }
629 
630         // Inform this side and other side device (if any) of Connection
631         // Updates.
632         std::vector<uint8_t> conn_update({CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_CONN_UPDATE,
633                                           (uint8_t)p_data->conn_update.interval});
634         send_state_change_to_other_side(hearingDevice, conn_update);
635         send_state_change(hearingDevice, conn_update);
636       } else {
637         log::info("error status=0x{:x}, conn_id={} bd_addr={}, connection_update_status={}",
638                   static_cast<uint8_t>(p_data->conn_update.status), conn_id, hearingDevice->address,
639                   hearingDevice->connection_update_status);
640         if (hearingDevice->connection_update_status == STARTED) {
641           // Redo this connection interval change.
642           log::error("Redo Connection Interval change");
643           hearingDevice->connection_update_status = AWAITING;
644         }
645       }
646     } else {
647       hearingDevice->connection_update_status = NONE;
648     }
649 
650     if (!hearingDevice->accepting_audio && hearingDevice->connection_update_status == COMPLETED &&
651         hearingDevice->gap_opened) {
652       OnDeviceReady(hearingDevice->address);
653     }
654 
655     for (auto& device : hearingDevices.devices) {
656       if (device.conn_id != INVALID_CONN_ID && (device.connection_update_status == AWAITING)) {
657         device.connection_update_status = STARTED;
658         device.requested_connection_interval = UpdateBleConnParams(device.address);
659         return;
660       }
661     }
662   }
663 
664   // Completion Callback for the RSSI read operation.
OnReadRssiComplete(const RawAddress & address,int8_t rssi_value)665   void OnReadRssiComplete(const RawAddress& address, int8_t rssi_value) {
666     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
667     if (!hearingDevice) {
668       log::info("Skipping unknown device {}", address);
669       return;
670     }
671 
672     log::debug("bd_addr={} rssi={}", address, (int)rssi_value);
673 
674     if (hearingDevice->read_rssi_count <= 0) {
675       log::error("bd_addr={}, invalid read_rssi_count={}", address, hearingDevice->read_rssi_count);
676       return;
677     }
678 
679     rssi_log& last_log_set = hearingDevice->audio_stats.rssi_history.back();
680 
681     if (hearingDevice->read_rssi_count == READ_RSSI_NUM_TRIES) {
682       // Store the timestamp only for the first one after packet flush
683       clock_gettime(CLOCK_REALTIME, &last_log_set.timestamp);
684       log::info("store time, bd_addr={}, rssi={}", address, (int)rssi_value);
685     }
686 
687     last_log_set.rssi.emplace_back(rssi_value);
688     hearingDevice->read_rssi_count--;
689   }
690 
OnEncryptionComplete(const RawAddress & address,bool success)691   void OnEncryptionComplete(const RawAddress& address, bool success) {
692     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
693     if (!hearingDevice) {
694       log::error("unknown device: bd_addr={}", address);
695       return;
696     }
697 
698     if (!success) {
699       log::error("encryption failed: bd_addr={}", address);
700       BTA_GATTC_Close(hearingDevice->conn_id);
701       if (hearingDevice->first_connection) {
702         callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
703       }
704       return;
705     }
706 
707     log::info("encryption successful: bd_addr={}", address);
708 
709     if (hearingDevice->audio_control_point_handle && hearingDevice->audio_status_handle &&
710         hearingDevice->audio_status_ccc_handle && hearingDevice->volume_handle &&
711         hearingDevice->read_psm_handle) {
712       // Use cached data, jump to read PSM
713       ReadPSM(hearingDevice);
714     } else {
715       log::info("starting service search request for ASHA: bd_addr={}", address);
716       hearingDevice->first_connection = true;
717       BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, HEARING_AID_UUID);
718     }
719   }
720 
721   // Just take care phy update successful case to avoid loop executing.
OnPhyUpdateEvent(tCONN_ID conn_id,uint8_t tx_phys,uint8_t rx_phys,tGATT_STATUS status)722   void OnPhyUpdateEvent(tCONN_ID conn_id, uint8_t tx_phys, uint8_t rx_phys, tGATT_STATUS status) {
723     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
724     if (!hearingDevice) {
725       log::error("unknown device: conn_id=0x{:x}", conn_id);
726       return;
727     }
728 
729     if (status != GATT_SUCCESS) {
730       log::warn("phy update failed: bd_addr={} status={}", hearingDevice->address, status);
731       return;
732     }
733 
734     if (tx_phys == PHY_LE_2M && rx_phys == PHY_LE_2M) {
735       log::info("phy update to 2M successful: bd_addr={}", hearingDevice->address);
736       hearingDevice->phy_update_retry_remain = kPhyUpdateRetryLimit;
737       return;
738     }
739 
740     if (hearingDevice->phy_update_retry_remain > 0) {
741       log::info(
742               "phy update successful with unexpected phys, retrying:"
743               " bd_addr={} tx_phy=0x{:x} rx_phy=0x{:x}",
744               hearingDevice->address, tx_phys, rx_phys);
745       get_btm_client_interface().ble.BTM_BleSetPhy(hearingDevice->address, PHY_LE_2M, PHY_LE_2M, 0);
746       hearingDevice->phy_update_retry_remain--;
747     } else {
748       log::warn(
749               "phy update successful with unexpected phys, exceeded retry count:"
750               " bd_addr={} tx_phy=0x{:x} rx_phy=0x{:x}",
751               hearingDevice->address, tx_phys, rx_phys);
752     }
753   }
754 
OnServiceChangeEvent(const RawAddress & address)755   void OnServiceChangeEvent(const RawAddress& address) {
756     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
757     if (!hearingDevice) {
758       log::error("unknown device: bd_addr={}", address);
759       return;
760     }
761 
762     log::info("bd_addr={}", address);
763 
764     hearingDevice->first_connection = true;
765     hearingDevice->service_changed_rcvd = true;
766     BtaGattQueue::Clean(hearingDevice->conn_id);
767 
768     if (hearingDevice->gap_handle != GAP_INVALID_HANDLE) {
769       GAP_ConnClose(hearingDevice->gap_handle);
770       hearingDevice->gap_handle = GAP_INVALID_HANDLE;
771     }
772   }
773 
OnServiceDiscDoneEvent(const RawAddress & address)774   void OnServiceDiscDoneEvent(const RawAddress& address) {
775     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
776     if (!hearingDevice) {
777       log::error("unknown device: bd_addr={}", address);
778       return;
779     }
780 
781     log::info("bd_addr={}", address);
782 
783     if (hearingDevice->service_changed_rcvd ||
784         !(hearingDevice->audio_control_point_handle && hearingDevice->audio_status_handle &&
785           hearingDevice->audio_status_ccc_handle && hearingDevice->volume_handle &&
786           hearingDevice->read_psm_handle)) {
787       log::info("starting service search request for ASHA: bd_addr={}", address);
788       BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, HEARING_AID_UUID);
789     }
790   }
791 
OnServiceSearchComplete(tCONN_ID conn_id,tGATT_STATUS status)792   void OnServiceSearchComplete(tCONN_ID conn_id, tGATT_STATUS status) {
793     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
794     if (!hearingDevice) {
795       log::error("unknown device: conn_id=0x{:x}", conn_id);
796       return;
797     }
798 
799     // Known device, nothing to do.
800     if (!hearingDevice->first_connection) {
801       log::info("service discovery result ignored: bd_addr={}", hearingDevice->address);
802       return;
803     }
804 
805     if (status != GATT_SUCCESS) {
806       /* close connection and report service discovery complete with error */
807       log::error("service discovery failed: bd_addr={} status={}", hearingDevice->address, status);
808 
809       if (hearingDevice->first_connection) {
810         callbacks->OnConnectionState(ConnectionState::DISCONNECTED, hearingDevice->address);
811       }
812       return;
813     }
814 
815     log::info("service discovery successful: bd_addr={}", hearingDevice->address);
816 
817     const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
818 
819     const gatt::Service* service = nullptr;
820     for (const gatt::Service& tmp : *services) {
821       if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) {
822         log::info("Found UUID_SERVCLASS_GATT_SERVER, handle=0x{:x}", tmp.handle);
823         const gatt::Service* service_changed_service = &tmp;
824         find_server_changed_ccc_handle(conn_id, service_changed_service);
825       } else if (tmp.uuid == HEARING_AID_UUID) {
826         log::info("Found Hearing Aid service, handle=0x{:x}", tmp.handle);
827         service = &tmp;
828       }
829     }
830 
831     if (!service) {
832       log::error("No Hearing Aid service found");
833       callbacks->OnConnectionState(ConnectionState::DISCONNECTED, hearingDevice->address);
834       return;
835     }
836 
837     for (const gatt::Characteristic& charac : service->characteristics) {
838       if (charac.uuid == READ_ONLY_PROPERTIES_UUID) {
839         if (!btif_storage_get_hearing_aid_prop(
840                     hearingDevice->address, &hearingDevice->capabilities,
841                     &hearingDevice->hi_sync_id, &hearingDevice->render_delay,
842                     &hearingDevice->preparation_delay, &hearingDevice->codecs)) {
843           log::debug("Reading read only properties 0x{:x}", charac.value_handle);
844           BtaGattQueue::ReadCharacteristic(conn_id, charac.value_handle,
845                                            HearingAidImpl::OnReadOnlyPropertiesReadStatic, nullptr);
846         }
847       } else if (charac.uuid == AUDIO_CONTROL_POINT_UUID) {
848         hearingDevice->audio_control_point_handle = charac.value_handle;
849         // store audio control point!
850       } else if (charac.uuid == AUDIO_STATUS_UUID) {
851         hearingDevice->audio_status_handle = charac.value_handle;
852 
853         hearingDevice->audio_status_ccc_handle = find_ccc_handle(conn_id, charac.value_handle);
854         if (!hearingDevice->audio_status_ccc_handle) {
855           log::error("cannot find Audio Status CCC descriptor");
856           continue;
857         }
858 
859         log::info("audio_status_handle=0x{:x}, ccc=0x{:x}", charac.value_handle,
860                   hearingDevice->audio_status_ccc_handle);
861       } else if (charac.uuid == VOLUME_UUID) {
862         hearingDevice->volume_handle = charac.value_handle;
863       } else if (charac.uuid == LE_PSM_UUID) {
864         hearingDevice->read_psm_handle = charac.value_handle;
865       } else {
866         log::warn("Unknown characteristic found:{}", charac.uuid.ToString());
867       }
868     }
869 
870     if (hearingDevice->service_changed_rcvd) {
871       hearingDevice->service_changed_rcvd = false;
872     }
873 
874     ReadPSM(hearingDevice);
875   }
876 
ReadPSM(HearingDevice * hearingDevice)877   void ReadPSM(HearingDevice* hearingDevice) {
878     if (hearingDevice->read_psm_handle) {
879       log::info("bd_addr={} handle=0x{:x}", hearingDevice->address, hearingDevice->read_psm_handle);
880       BtaGattQueue::ReadCharacteristic(hearingDevice->conn_id, hearingDevice->read_psm_handle,
881                                        HearingAidImpl::OnPsmReadStatic, nullptr);
882     }
883   }
884 
OnNotificationEvent(tCONN_ID conn_id,uint16_t handle,uint16_t len,uint8_t * value)885   void OnNotificationEvent(tCONN_ID conn_id, uint16_t handle, uint16_t len, uint8_t* value) {
886     HearingDevice* device = hearingDevices.FindByConnId(conn_id);
887     if (!device) {
888       log::error("unknown device: conn_id=0x{:x}", conn_id);
889       return;
890     }
891 
892     if (device->audio_status_handle != handle) {
893       log::warn("unexpected handle: bd_addr={} audio_status_handle=0x{:x} handle=0x{:x}",
894                 device->address, device->audio_status_handle, handle);
895       return;
896     }
897 
898     if (len < 1) {
899       log::warn("invalid data length (expected 1+ bytes): bd_addr={} len={}", device->address, len);
900       return;
901     }
902 
903     if (value[0] != 0) {
904       log::warn("received error status: bd_addr={} status=0x{:x}", device->address, value[0]);
905       return;
906     }
907 
908     log::info("received success notification: bd_addr={} command_acked={}", device->address,
909               device->command_acked);
910     device->command_acked = true;
911   }
912 
OnReadOnlyPropertiesRead(tCONN_ID conn_id,tGATT_STATUS,uint16_t,uint16_t len,uint8_t * value,void *)913   void OnReadOnlyPropertiesRead(tCONN_ID conn_id, tGATT_STATUS /*status*/, uint16_t /*handle*/,
914                                 uint16_t len, uint8_t* value, void* /*data*/) {
915     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
916     if (!hearingDevice) {
917       log::error("unknown device: conn_id=0x{:x}", conn_id);
918       return;
919     }
920 
921     uint8_t* p = value;
922 
923     uint8_t version;
924     STREAM_TO_UINT8(version, p);
925 
926     if (version != 0x01) {
927       log::warn("unsupported version: bd_addr={} version=0x{:x}", hearingDevice->address, version);
928       return;
929     }
930 
931     // version 0x01 of read only properties:
932     if (len < 17) {
933       log::warn("invalid data length (expected 17+ bytes): bd_addr={} len={}",
934                 hearingDevice->address, len);
935       return;
936     }
937 
938     uint8_t capabilities;
939     STREAM_TO_UINT8(capabilities, p);
940     STREAM_TO_UINT64(hearingDevice->hi_sync_id, p);
941     uint8_t feature_map;
942     STREAM_TO_UINT8(feature_map, p);
943     STREAM_TO_UINT16(hearingDevice->render_delay, p);
944     STREAM_TO_UINT16(hearingDevice->preparation_delay, p);
945     uint16_t codecs;
946     STREAM_TO_UINT16(codecs, p);
947 
948     hearingDevice->capabilities = capabilities;
949     hearingDevice->codecs = codecs;
950 
951     bool side = capabilities & CAPABILITY_SIDE;
952     bool binaural = capabilities & CAPABILITY_BINAURAL;
953     bool csis_capable = capabilities & CAPABILITY_CSIS;
954 
955     if (capabilities & CAPABILITY_RESERVED) {
956       log::warn("reserved capabilities bits are set: bd_addr={} capabilities=0x{:x}",
957                 hearingDevice->address, capabilities);
958     }
959 
960     bool g722_16khz_supported = codecs & (1 << CODEC_G722_16KHZ);
961     bool g722_24khz_supported = codecs & (1 << CODEC_G722_24KHZ);
962 
963     if (!g722_16khz_supported) {
964       log::warn("mandatory codec G722@16kHz not supported: bd_addr={}", hearingDevice->address);
965     }
966 
967     log::info(
968             "device capabilities: bd_addr={} side={} binaural={}"
969             " CSIS_supported={} hi_sync_id=0x{:x} render_delay={}"
970             " preparation_delay={} G722@16kHz_supported={} G722@24kHz_supported={}",
971             hearingDevice->address, side ? "right" : "left", binaural, csis_capable,
972             hearingDevice->hi_sync_id, hearingDevice->render_delay,
973             hearingDevice->preparation_delay, g722_16khz_supported, g722_24khz_supported);
974   }
975 
CalcCompressedAudioPacketSize(uint16_t codec_type,int connection_interval)976   uint16_t CalcCompressedAudioPacketSize(uint16_t codec_type, int connection_interval) {
977     int sample_rate;
978 
979     const int sample_bit_rate = 16;  /* 16 bits per sample */
980     const int compression_ratio = 4; /* G.722 has a 4:1 compression ratio */
981     if (codec_type == CODEC_G722_24KHZ) {
982       sample_rate = 24000;
983     } else {
984       sample_rate = 16000;
985     }
986 
987     // compressed_data_packet_size is the size in bytes of the compressed audio
988     // data buffer that is generated for each connection interval.
989     uint32_t compressed_data_packet_size =
990             (sample_rate * connection_interval * (sample_bit_rate / 8) / compression_ratio) / 1000;
991     return (uint16_t)compressed_data_packet_size;
992   }
993 
ChooseCodec(const HearingDevice & hearingDevice)994   void ChooseCodec(const HearingDevice& hearingDevice) {
995     if (codec_in_use) {
996       return;
997     }
998 
999     // use the best codec available for this pair of devices.
1000     uint16_t codecs = hearingDevice.codecs;
1001     if (hearingDevice.hi_sync_id != 0) {
1002       for (const auto& device : hearingDevices.devices) {
1003         if (device.hi_sync_id != hearingDevice.hi_sync_id) {
1004           continue;
1005         }
1006 
1007         codecs &= device.codecs;
1008       }
1009     }
1010 
1011     if ((codecs & (1 << CODEC_G722_24KHZ)) &&
1012         bluetooth::shim::GetController()->SupportsBle2mPhy() &&
1013         default_data_interval_ms == HA_INTERVAL_10_MS) {
1014       codec_in_use = CODEC_G722_24KHZ;
1015     } else if (codecs & (1 << CODEC_G722_16KHZ)) {
1016       codec_in_use = CODEC_G722_16KHZ;
1017     }
1018   }
1019 
OnAudioStatus(tCONN_ID,tGATT_STATUS,uint16_t,uint16_t len,uint8_t * value,void *)1020   void OnAudioStatus(tCONN_ID /*conn_id*/, tGATT_STATUS /*status*/, uint16_t /*handle*/,
1021                      uint16_t len, uint8_t* value, void* /*data*/) {
1022     log::info("{}", base::HexEncode(value, len));
1023   }
1024 
OnPsmRead(tCONN_ID conn_id,tGATT_STATUS status,uint16_t,uint16_t len,uint8_t * value,void *)1025   void OnPsmRead(tCONN_ID conn_id, tGATT_STATUS status, uint16_t /*handle*/, uint16_t len,
1026                  uint8_t* value, void* /*data*/) {
1027     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1028     if (!hearingDevice) {
1029       log::error("unknown device: conn_id=0x{:x}", conn_id);
1030       return;
1031     }
1032 
1033     if (status != GATT_SUCCESS) {
1034       log::error("error reading PSM: bd_addr={} status={}", hearingDevice->address, status);
1035       return;
1036     }
1037 
1038     if (len < 2) {
1039       log::error("invalid PSM length: bd_addr={} len={}", hearingDevice->address, len);
1040       return;
1041     }
1042 
1043     uint16_t psm = 0;
1044     STREAM_TO_UINT16(psm, value);
1045 
1046     log::info("read PSM: bd_addr={} psm=0x{:x}", hearingDevice->address, psm);
1047 
1048     if (hearingDevice->gap_handle == GAP_INVALID_HANDLE &&
1049         BTM_IsEncrypted(hearingDevice->address, BT_TRANSPORT_LE)) {
1050       ConnectSocket(hearingDevice, psm);
1051     }
1052   }
1053 
ConnectSocket(HearingDevice * hearingDevice,uint16_t psm)1054   void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) {
1055     tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512};
1056 
1057     log::info("bd_addr={} psm=0x{:x}", hearingDevice->address, psm);
1058 
1059     SendEnableServiceChangedInd(hearingDevice);
1060 
1061     uint8_t service_id = hearingDevice->isLeft() ? BTM_SEC_SERVICE_HEARING_AID_LEFT
1062                                                  : BTM_SEC_SERVICE_HEARING_AID_RIGHT;
1063     uint16_t gap_handle = GAP_ConnOpen(
1064             "", service_id, false, &hearingDevice->address, psm, 514 /* MPS */, &cfg_info, nullptr,
1065             /// b/309483354:
1066             /// Encryption needs to be explicitly requested at channel
1067             /// establishment even though validation is performed in this module
1068             /// because of re-connection logic present in the L2CAP module.
1069             /// The L2CAP will automatically reconnect the LE-ACL link on
1070             /// disconnection when there is a pending channel request,
1071             /// which invalidates all encryption checks performed here.
1072             BTM_SEC_IN_ENCRYPT | BTM_SEC_OUT_ENCRYPT,
1073             HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE);
1074 
1075     if (gap_handle == GAP_INVALID_HANDLE) {
1076       log::error("failed to open socket: bd_addr={}", hearingDevice->address);
1077     } else {
1078       hearingDevice->gap_handle = gap_handle;
1079       log::info("sent GAP connect request: bd_addr={}, gap_handle={}", hearingDevice->address,
1080                 gap_handle);
1081     }
1082   }
1083 
OnReadOnlyPropertiesReadStatic(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1084   static void OnReadOnlyPropertiesReadStatic(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle,
1085                                              uint16_t len, uint8_t* value, void* data) {
1086     if (instance) {
1087       instance->OnReadOnlyPropertiesRead(conn_id, status, handle, len, value, data);
1088     }
1089   }
1090 
OnAudioStatusStatic(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1091   static void OnAudioStatusStatic(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle,
1092                                   uint16_t len, uint8_t* value, void* data) {
1093     if (instance) {
1094       instance->OnAudioStatus(conn_id, status, handle, len, value, data);
1095     }
1096   }
1097 
OnPsmReadStatic(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)1098   static void OnPsmReadStatic(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1099                               uint8_t* value, void* data) {
1100     if (instance) {
1101       instance->OnPsmRead(conn_id, status, handle, len, value, data);
1102     }
1103   }
1104 
1105   /* CoC Socket, BLE connection parameter are ready */
OnDeviceReady(const RawAddress & address)1106   void OnDeviceReady(const RawAddress& address) {
1107     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
1108     if (!hearingDevice) {
1109       log::error("unknown device: bd_addr={}", address);
1110       return;
1111     }
1112 
1113     log::info("bd_addr={}", address);
1114 
1115     if (hearingDevice->first_connection) {
1116       btif_storage_add_hearing_aid(*hearingDevice);
1117 
1118       hearingDevice->first_connection = false;
1119     }
1120 
1121     /* Register and enable the Audio Status Notification */
1122     tGATT_STATUS register_status = BTA_GATTC_RegisterForNotifications(
1123             gatt_if, address, hearingDevice->audio_status_handle);
1124 
1125     if (register_status != GATT_SUCCESS) {
1126       log::error("failed to register for notifications: bd_addr={} status={} handle=0x{:x}",
1127                  address, register_status, hearingDevice->audio_status_handle);
1128       return;
1129     }
1130 
1131     std::vector<uint8_t> value(2);
1132     uint8_t* ptr = value.data();
1133     UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
1134 
1135     BtaGattQueue::WriteDescriptor(hearingDevice->conn_id, hearingDevice->audio_status_ccc_handle,
1136                                   std::move(value), GATT_WRITE, write_rpt_ctl_cfg_cb, nullptr);
1137 
1138     ChooseCodec(*hearingDevice);
1139     SendStart(hearingDevice);
1140 
1141     if (audio_running) {
1142       // Inform the other side (if any) of this connection
1143       std::vector<uint8_t> inform_conn_state(
1144               {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_CONNECTED});
1145       send_state_change_to_other_side(hearingDevice, inform_conn_state);
1146     }
1147 
1148     hearingDevice->connecting_actively = false;
1149     hearingDevice->accepting_audio = true;
1150 
1151     StartSendingAudio(*hearingDevice);
1152     callbacks->OnDeviceAvailable(hearingDevice->capabilities, hearingDevice->hi_sync_id, address);
1153     callbacks->OnConnectionState(ConnectionState::CONNECTED, address);
1154   }
1155 
StartSendingAudio(const HearingDevice & hearingDevice)1156   void StartSendingAudio(const HearingDevice& hearingDevice) {
1157     log::info("bd_addr={}", hearingDevice.address);
1158 
1159     if (encoder_state_left == nullptr) {
1160       encoder_state_init();
1161       seq_counter = 0;
1162 
1163       CodecConfiguration codec;
1164       if (codec_in_use == CODEC_G722_24KHZ) {
1165         codec.sample_rate = 24000;
1166       } else {
1167         codec.sample_rate = 16000;
1168       }
1169       codec.bit_rate = 16;
1170       codec.data_interval_ms = default_data_interval_ms;
1171 
1172       uint16_t delay_report_ms = 0;
1173       if (hearingDevice.render_delay != 0) {
1174         delay_report_ms = hearingDevice.render_delay +
1175                           (ADD_RENDER_DELAY_INTERVALS * default_data_interval_ms);
1176       }
1177 
1178       HearingAidAudioSource::Start(codec, audioReceiver, delay_report_ms);
1179     }
1180   }
1181 
OnAudioSuspend(const std::function<void ()> & stop_audio_ticks)1182   void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) {
1183     log::assert_that((bool)stop_audio_ticks, "stop_audio_ticks is empty");
1184 
1185     if (!audio_running) {
1186       log::warn("Unexpected audio suspend");
1187     } else {
1188       log::info("audio_running={}", audio_running);
1189     }
1190 
1191     // Close the ASRC context.
1192     ResetAsrc();
1193 
1194     audio_running = false;
1195     stop_audio_ticks();
1196 
1197     std::vector<uint8_t> stop({CONTROL_POINT_OP_STOP});
1198     for (auto& device : hearingDevices.devices) {
1199       if (!device.accepting_audio) {
1200         continue;
1201       }
1202 
1203       if (!device.playback_started) {
1204         log::warn("Playback not started, skip send Stop cmd, bd_addr={}", device.address);
1205       } else {
1206         log::info("send Stop cmd, bd_addr={}", device.address);
1207         device.playback_started = false;
1208         device.command_acked = false;
1209         BtaGattQueue::WriteCharacteristic(device.conn_id, device.audio_control_point_handle, stop,
1210                                           GATT_WRITE, nullptr, nullptr);
1211       }
1212     }
1213   }
1214 
OnAudioResume(const std::function<void ()> & start_audio_ticks)1215   void OnAudioResume(const std::function<void()>& start_audio_ticks) {
1216     log::assert_that((bool)start_audio_ticks, "start_audio_ticks is empty");
1217 
1218     if (audio_running) {
1219       log::error("Unexpected Audio Resume");
1220     } else {
1221       log::info("audio_running={}", audio_running);
1222     }
1223 
1224     for (auto& device : hearingDevices.devices) {
1225       if (!device.accepting_audio) {
1226         continue;
1227       }
1228       audio_running = true;
1229       SendStart(&device);
1230     }
1231 
1232     if (!audio_running) {
1233       log::info("No device (0/{}) ready to start", GetDeviceCount());
1234       return;
1235     }
1236 
1237     // Open the ASRC context.
1238     ConfigureAsrc();
1239 
1240     // TODO: shall we also reset the encoder ?
1241     encoder_state_release();
1242     encoder_state_init();
1243     seq_counter = 0;
1244 
1245     start_audio_ticks();
1246   }
1247 
GetOtherSideStreamStatus(HearingDevice * this_side_device)1248   uint8_t GetOtherSideStreamStatus(HearingDevice* this_side_device) {
1249     for (auto& device : hearingDevices.devices) {
1250       if ((device.address == this_side_device->address) ||
1251           (device.hi_sync_id != this_side_device->hi_sync_id)) {
1252         continue;
1253       }
1254       if (audio_running && (device.conn_id != INVALID_CONN_ID)) {
1255         return OTHER_SIDE_IS_STREAMING;
1256       } else {
1257         return OTHER_SIDE_NOT_STREAMING;
1258       }
1259     }
1260     return OTHER_SIDE_NOT_STREAMING;
1261   }
1262 
SendEnableServiceChangedInd(HearingDevice * device)1263   void SendEnableServiceChangedInd(HearingDevice* device) {
1264     log::info("bd_addr={}", device->address);
1265 
1266     std::vector<uint8_t> value(2);
1267     uint8_t* ptr = value.data();
1268     UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION);
1269 
1270     BtaGattQueue::WriteDescriptor(device->conn_id, device->service_changed_ccc_handle,
1271                                   std::move(value), GATT_WRITE, nullptr, nullptr);
1272   }
1273 
SendStart(HearingDevice * device)1274   void SendStart(HearingDevice* device) {
1275     std::vector<uint8_t> start({CONTROL_POINT_OP_START, codec_in_use, AUDIOTYPE_UNKNOWN,
1276                                 (uint8_t)current_volume, OTHER_SIDE_NOT_STREAMING});
1277 
1278     if (!audio_running) {
1279       if (!device->playback_started) {
1280         log::info("Skip Send Start since audio is not running, bd_addr={}", device->address);
1281       } else {
1282         log::error("Audio not running but Playback has started, bd_addr={}", device->address);
1283       }
1284       return;
1285     }
1286 
1287     if (current_volume == VOLUME_UNKNOWN) {
1288       start[3] = (uint8_t)VOLUME_MIN;
1289     }
1290 
1291     if (device->playback_started) {
1292       log::error("Playback already started, skip send Start cmd, bd_addr={}", device->address);
1293     } else {
1294       start[4] = GetOtherSideStreamStatus(device);
1295       log::info(
1296               "send Start cmd, volume=0x{:x}, audio type=0x{:x}, bd_addr={}, other "
1297               "side streaming=0x{:x}",
1298               start[3], start[2], device->address, start[4]);
1299       device->command_acked = false;
1300       BtaGattQueue::WriteCharacteristic(device->conn_id, device->audio_control_point_handle, start,
1301                                         GATT_WRITE, HearingAidImpl::StartAudioCtrlCallbackStatic,
1302                                         nullptr);
1303     }
1304   }
1305 
StartAudioCtrlCallbackStatic(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t,const uint8_t *,void *)1306   static void StartAudioCtrlCallbackStatic(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle,
1307                                            uint16_t /*len*/, const uint8_t* /*value*/,
1308                                            void* /*data*/) {
1309     if (status != GATT_SUCCESS) {
1310       log::error("handle={}, conn_id={}, status=0x{:x}", handle, conn_id,
1311                  static_cast<uint8_t>(status));
1312       return;
1313     }
1314     if (!instance) {
1315       log::error("instance is null");
1316       return;
1317     }
1318     instance->StartAudioCtrlCallback(conn_id);
1319   }
1320 
StartAudioCtrlCallback(tCONN_ID conn_id)1321   void StartAudioCtrlCallback(tCONN_ID conn_id) {
1322     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1323     if (!hearingDevice) {
1324       log::error("Skipping unknown device, conn_id=0x{:x}", conn_id);
1325       return;
1326     }
1327     log::info("device: {}", hearingDevice->address);
1328     hearingDevice->playback_started = true;
1329   }
1330 
1331   /* Compare the two sides LE CoC credit and return true to drop two sides
1332    * packet on these situations.
1333    * 1) The credit is close
1334    * 2) Other side is disconnected
1335    * 3) Get one side current credit value failure.
1336    *
1337    * Otherwise, just flush audio packet one side.
1338    */
NeedToDropPacket(HearingDevice * target_side,HearingDevice * other_side)1339   bool NeedToDropPacket(HearingDevice* target_side, HearingDevice* other_side) {
1340     // Just drop packet if the other side does not exist.
1341     if (!other_side) {
1342       log::debug("other side not connected to profile");
1343       return true;
1344     }
1345 
1346     uint16_t diff_credit = 0;
1347 
1348     uint16_t target_current_credit = stack::l2cap::get_interface().L2CA_GetPeerLECocCredit(
1349             target_side->address, GAP_ConnGetL2CAPCid(target_side->gap_handle));
1350     if (target_current_credit == L2CAP_LE_CREDIT_MAX) {
1351       log::error("Get target side credit value fail.");
1352       return true;
1353     }
1354 
1355     uint16_t other_current_credit = stack::l2cap::get_interface().L2CA_GetPeerLECocCredit(
1356             other_side->address, GAP_ConnGetL2CAPCid(other_side->gap_handle));
1357     if (other_current_credit == L2CAP_LE_CREDIT_MAX) {
1358       log::error("Get other side credit value fail.");
1359       return true;
1360     }
1361 
1362     if (target_current_credit > other_current_credit) {
1363       diff_credit = target_current_credit - other_current_credit;
1364     } else {
1365       diff_credit = other_current_credit - target_current_credit;
1366     }
1367     log::debug("Target({}) Credit: {}, Other({}) Credit: {}, Init Credit: {}", target_side->address,
1368                target_current_credit, other_side->address, other_current_credit, init_credit);
1369     return diff_credit < (init_credit / 2 - 1);
1370   }
1371 
OnAudioDataReadyResample(const std::vector<uint8_t> & data)1372   void OnAudioDataReadyResample(const std::vector<uint8_t>& data) {
1373     if (asrc == nullptr) {
1374       return OnAudioDataReady(data);
1375     }
1376 
1377     for (auto const resampled_data : asrc->Run(data)) {
1378       OnAudioDataReady(*resampled_data);
1379     }
1380   }
1381 
OnAudioDataReady(const std::vector<uint8_t> & data)1382   void OnAudioDataReady(const std::vector<uint8_t>& data) {
1383     /* For now we assume data comes in as 16bit per sample 16kHz PCM stereo */
1384     bool need_drop = false;
1385     int num_samples = data.size() / (2 /*bytes_per_sample*/ * 2 /*number of channels*/);
1386 
1387     // The G.722 codec accept only even number of samples for encoding
1388     if (num_samples % 2 != 0) {
1389       log::fatal("num_samples is not even: {}", num_samples);
1390     }
1391 
1392     // TODO: we should cache left/right and current state, instead of recomputing
1393     // it for each packet, 100 times a second.
1394     HearingDevice* left = nullptr;
1395     HearingDevice* right = nullptr;
1396     for (auto& device : hearingDevices.devices) {
1397       if (!device.accepting_audio) {
1398         continue;
1399       }
1400 
1401       if (device.isLeft()) {
1402         left = &device;
1403       } else {
1404         right = &device;
1405       }
1406     }
1407 
1408     if (left == nullptr && right == nullptr) {
1409       log::warn("No more (0/{}) devices ready", GetDeviceCount());
1410       DoDisconnectAudioStop();
1411       return;
1412     }
1413 
1414     std::vector<uint16_t> chan_left;
1415     std::vector<uint16_t> chan_right;
1416     if (left == nullptr || right == nullptr) {
1417       for (int i = 0; i < num_samples; i++) {
1418         const uint8_t* sample = data.data() + i * 4;
1419 
1420         int16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1421 
1422         sample += 2;
1423         int16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1424 
1425         uint16_t mono_data = (int16_t)(((uint32_t)left + (uint32_t)right) >> 1);
1426         chan_left.push_back(mono_data);
1427         chan_right.push_back(mono_data);
1428       }
1429     } else {
1430       for (int i = 0; i < num_samples; i++) {
1431         const uint8_t* sample = data.data() + i * 4;
1432 
1433         uint16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1434         chan_left.push_back(left);
1435 
1436         sample += 2;
1437         uint16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1438         chan_right.push_back(right);
1439       }
1440     }
1441 
1442     // Skipping packets completely messes up the resampler context.
1443     // The flush threshold is set to the number of credits specified for the
1444     // ASHA l2cap streaming channel. This will ensure it is only triggered in
1445     // case of critical failure.
1446     uint16_t l2cap_flush_threshold = 8;
1447 
1448     // TODO: monural, binarual check
1449 
1450     // divide encoded data into packets, add header, send.
1451 
1452     // TODO: make those buffers static and global to prevent constant
1453     // reallocations
1454     // TODO: this should basically fit the encoded data, tune the size later
1455     std::vector<uint8_t> encoded_data_left;
1456     auto time_point = std::chrono::steady_clock::now();
1457     if (left) {
1458       // TODO: instead of a magic number, we need to figure out the correct
1459       // buffer size
1460       encoded_data_left.resize(4000);
1461       int encoded_size = g722_encode(encoder_state_left, encoded_data_left.data(),
1462                                      (const int16_t*)chan_left.data(), chan_left.size());
1463       encoded_data_left.resize(encoded_size);
1464 
1465       uint16_t cid = GAP_ConnGetL2CAPCid(left->gap_handle);
1466       uint16_t packets_in_chans =
1467               stack::l2cap::get_interface().L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
1468       if (packets_in_chans > l2cap_flush_threshold) {
1469         // Compare the two sides LE CoC credit value to confirm need to drop or
1470         // skip audio packet.
1471         if (NeedToDropPacket(left, right) && IsBelowDropFrequency(time_point)) {
1472           log::info("{} triggers dropping, {} packets in channel", left->address, packets_in_chans);
1473           need_drop = true;
1474           left->audio_stats.trigger_drop_count++;
1475         } else {
1476           log::info("{} skipping {} packets", left->address, packets_in_chans);
1477           left->audio_stats.packet_flush_count += packets_in_chans;
1478           left->audio_stats.frame_flush_count++;
1479           const uint16_t buffers_left =
1480                   stack::l2cap::get_interface().L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_ALL);
1481           if (buffers_left) {
1482             log::warn("Unable to flush L2CAP ALL (left HA) channel peer:{} cid:{} buffers_left:{}",
1483                       left->address, cid, buffers_left);
1484           }
1485         }
1486         hearingDevices.StartRssiLog();
1487       }
1488       check_and_do_rssi_read(left);
1489     }
1490 
1491     std::vector<uint8_t> encoded_data_right;
1492     if (right) {
1493       // TODO: instead of a magic number, we need to figure out the correct
1494       // buffer size
1495       encoded_data_right.resize(4000);
1496       int encoded_size = g722_encode(encoder_state_right, encoded_data_right.data(),
1497                                      (const int16_t*)chan_right.data(), chan_right.size());
1498       encoded_data_right.resize(encoded_size);
1499 
1500       uint16_t cid = GAP_ConnGetL2CAPCid(right->gap_handle);
1501       uint16_t packets_in_chans =
1502               stack::l2cap::get_interface().L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
1503       if (packets_in_chans > l2cap_flush_threshold) {
1504         // Compare the two sides LE CoC credit value to confirm need to drop or
1505         // skip audio packet.
1506         if (NeedToDropPacket(right, left) && IsBelowDropFrequency(time_point)) {
1507           log::info("{} triggers dropping, {} packets in channel", right->address,
1508                     packets_in_chans);
1509           need_drop = true;
1510           right->audio_stats.trigger_drop_count++;
1511         } else {
1512           log::info("{} skipping {} packets", right->address, packets_in_chans);
1513           right->audio_stats.packet_flush_count += packets_in_chans;
1514           right->audio_stats.frame_flush_count++;
1515           const uint16_t buffers_left =
1516                   stack::l2cap::get_interface().L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_ALL);
1517           if (buffers_left) {
1518             log::warn("Unable to flush L2CAP ALL (right HA) channel peer:{} cid:{} buffers_left:{}",
1519                       right->address, cid, buffers_left);
1520           }
1521         }
1522         hearingDevices.StartRssiLog();
1523       }
1524       check_and_do_rssi_read(right);
1525     }
1526 
1527     size_t encoded_data_size = std::max(encoded_data_left.size(), encoded_data_right.size());
1528 
1529     uint16_t packet_size = CalcCompressedAudioPacketSize(codec_in_use, default_data_interval_ms);
1530 
1531     if (need_drop) {
1532       last_drop_time_point = time_point;
1533       if (left) {
1534         left->audio_stats.packet_drop_count++;
1535       }
1536       if (right) {
1537         right->audio_stats.packet_drop_count++;
1538       }
1539       return;
1540     }
1541 
1542     for (size_t i = 0; i < encoded_data_size; i += packet_size) {
1543       if (left) {
1544         left->audio_stats.packet_send_count++;
1545         SendAudio(encoded_data_left.data() + i, packet_size, left);
1546       }
1547       if (right) {
1548         right->audio_stats.packet_send_count++;
1549         SendAudio(encoded_data_right.data() + i, packet_size, right);
1550       }
1551       seq_counter++;
1552     }
1553     if (left) {
1554       left->audio_stats.frame_send_count++;
1555     }
1556     if (right) {
1557       right->audio_stats.frame_send_count++;
1558     }
1559   }
1560 
SendAudio(uint8_t * encoded_data,uint16_t packet_size,HearingDevice * hearingAid)1561   void SendAudio(uint8_t* encoded_data, uint16_t packet_size, HearingDevice* hearingAid) {
1562     if (!hearingAid->playback_started || !hearingAid->command_acked) {
1563       log::warn("Playback stalled: bd_addr={} cmd send={} cmd acked={}", hearingAid->address,
1564                 hearingAid->playback_started, hearingAid->command_acked);
1565       return;
1566     }
1567 
1568     BT_HDR* audio_packet = malloc_l2cap_buf(packet_size + 1);
1569     uint8_t* p = get_l2cap_sdu_start_ptr(audio_packet);
1570     *p = seq_counter;
1571     p++;
1572     memcpy(p, encoded_data, packet_size);
1573 
1574     log::verbose("bd_addr={} packet_size={}", hearingAid->address, packet_size);
1575 
1576     uint16_t result = GAP_ConnWriteData(hearingAid->gap_handle, audio_packet);
1577 
1578     if (result != BT_PASS) {
1579       log::error("Error sending data: 0x{:x}", result);
1580     }
1581   }
1582 
GapCallback(uint16_t gap_handle,uint16_t event,tGAP_CB_DATA *)1583   void GapCallback(uint16_t gap_handle, uint16_t event, tGAP_CB_DATA* /*data*/) {
1584     HearingDevice* hearingDevice = hearingDevices.FindByGapHandle(gap_handle);
1585     if (!hearingDevice) {
1586       log::error("unknown device: gap_handle={} event=0x{:x}", gap_handle, event);
1587       return;
1588     }
1589 
1590     switch (event) {
1591       case GAP_EVT_CONN_OPENED: {
1592         RawAddress address = *GAP_ConnGetRemoteAddr(gap_handle);
1593         uint16_t tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
1594 
1595         init_credit = stack::l2cap::get_interface().L2CA_GetPeerLECocCredit(
1596                 address, GAP_ConnGetL2CAPCid(gap_handle));
1597 
1598         log::info("GAP_EVT_CONN_OPENED: bd_addr={} tx_mtu={} init_credit={}", address, tx_mtu,
1599                   init_credit);
1600 
1601         HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
1602         if (!hearingDevice) {
1603           log::error("unknown device: bd_addr={}", address);
1604           return;
1605         }
1606         hearingDevice->gap_opened = true;
1607         if (hearingDevice->connection_update_status == COMPLETED) {
1608           OnDeviceReady(address);
1609         }
1610         break;
1611       }
1612 
1613       case GAP_EVT_CONN_CLOSED:
1614         log::info("GAP_EVT_CONN_CLOSED: bd_addr={} accepting_audio={}", hearingDevice->address,
1615                   hearingDevice->accepting_audio);
1616 
1617         if (!hearingDevice->accepting_audio) {
1618           /* Disconnect connection when data channel is not available */
1619           BTA_GATTC_Close(hearingDevice->conn_id);
1620         } else {
1621           /* Just clean data channel related parameter when data channel is
1622            * available */
1623           hearingDevice->gap_handle = GAP_INVALID_HANDLE;
1624           hearingDevice->accepting_audio = false;
1625           hearingDevice->playback_started = false;
1626           hearingDevice->command_acked = false;
1627           hearingDevice->gap_opened = false;
1628         }
1629         break;
1630 
1631       case GAP_EVT_CONN_DATA_AVAIL: {
1632         log::verbose("GAP_EVT_CONN_DATA_AVAIL: bd_addr={}", hearingDevice->address);
1633 
1634         // only data we receive back from hearing aids are some stats, not
1635         // really important, but useful now for debugging.
1636         uint32_t bytes_to_read = 0;
1637         GAP_GetRxQueueCnt(gap_handle, &bytes_to_read);
1638         std::vector<uint8_t> buffer(bytes_to_read);
1639 
1640         uint16_t bytes_read = 0;
1641         // TODO:GAP_ConnReadData should accept uint32_t for length!
1642         GAP_ConnReadData(gap_handle, buffer.data(), buffer.size(), &bytes_read);
1643 
1644         if (bytes_read < 4) {
1645           log::warn("Wrong data length");
1646           return;
1647         }
1648 
1649         uint8_t* p = buffer.data();
1650 
1651         log::verbose("stats from the hearing aid:");
1652         for (size_t i = 0; i + 4 <= buffer.size(); i += 4) {
1653           uint16_t event_counter, frame_index;
1654           STREAM_TO_UINT16(event_counter, p);
1655           STREAM_TO_UINT16(frame_index, p);
1656           log::verbose("event_counter={} frame_index: {}", event_counter, frame_index);
1657         }
1658         break;
1659       }
1660 
1661       case GAP_EVT_TX_EMPTY:
1662         log::info("GAP_EVT_TX_EMPTY: bd_addr={}", hearingDevice->address);
1663         break;
1664 
1665       case GAP_EVT_CONN_CONGESTED:
1666         log::info("GAP_EVT_CONN_CONGESTED: bd_addr={}", hearingDevice->address);
1667 
1668         // TODO: make it into function
1669         HearingAidAudioSource::Stop();
1670         // TODO: kill the encoder only if all hearing aids are down.
1671         // g722_encode_release(encoder_state);
1672         // encoder_state_left = nulllptr;
1673         // encoder_state_right = nulllptr;
1674         break;
1675 
1676       case GAP_EVT_CONN_UNCONGESTED:
1677         log::info("GAP_EVT_CONN_UNCONGESTED: bd_addr={}", hearingDevice->address);
1678         break;
1679     }
1680   }
1681 
GapCallbackStatic(uint16_t gap_handle,uint16_t event,tGAP_CB_DATA * data)1682   static void GapCallbackStatic(uint16_t gap_handle, uint16_t event, tGAP_CB_DATA* data) {
1683     if (instance) {
1684       instance->GapCallback(gap_handle, event, data);
1685     }
1686   }
1687 
DumpRssi(int fd,const HearingDevice & device)1688   void DumpRssi(int fd, const HearingDevice& device) {
1689     const struct AudioStats* stats = &device.audio_stats;
1690 
1691     if (stats->rssi_history.size() <= 0) {
1692       dprintf(fd, "  No RSSI history for %s:\n",
1693               device.address.ToRedactedStringForLogging().c_str());
1694       return;
1695     }
1696     dprintf(fd, "  RSSI history for %s:\n", device.address.ToRedactedStringForLogging().c_str());
1697 
1698     dprintf(fd, "    Time of RSSI    0.0  0.1  0.2  0.3  0.4  0.5  0.6  0.7  0.8  0.9\n");
1699     for (auto& rssi_logs : stats->rssi_history) {
1700       if (rssi_logs.rssi.size() <= 0) {
1701         break;
1702       }
1703 
1704       char eventtime[20];
1705       char temptime[20];
1706       struct tm* tstamp = localtime(&rssi_logs.timestamp.tv_sec);
1707       if (!strftime(temptime, sizeof(temptime), "%H:%M:%S", tstamp)) {
1708         log::error("strftime fails. tm_sec={}, tm_min={}, tm_hour={}", tstamp->tm_sec,
1709                    tstamp->tm_min, tstamp->tm_hour);
1710         osi_strlcpy(temptime, "UNKNOWN TIME", sizeof(temptime));
1711       }
1712       snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime,
1713                rssi_logs.timestamp.tv_nsec / 1000000);
1714 
1715       dprintf(fd, "    %s: ", eventtime);
1716 
1717       for (auto rssi_value : rssi_logs.rssi) {
1718         dprintf(fd, " %04d", rssi_value);
1719       }
1720       dprintf(fd, "\n");
1721     }
1722   }
1723 
Dump(int fd)1724   void Dump(int fd) {
1725     std::stringstream stream;
1726     for (const auto& device : hearingDevices.devices) {
1727       bool side = device.capabilities & CAPABILITY_SIDE;
1728       bool standalone = device.capabilities & CAPABILITY_BINAURAL;
1729       stream << "  " << device.address.ToString() << " " << (device.accepting_audio ? "" : "not ")
1730              << "connected" << "\n    " << (standalone ? "binaural" : "monaural") << " "
1731              << (side ? "right" : "left") << " " << loghex(device.hi_sync_id) << std::endl;
1732       stream << "    Trigger dropped counts                                 : "
1733              << device.audio_stats.trigger_drop_count
1734              << "\n    Packet dropped counts                                  : "
1735              << device.audio_stats.packet_drop_count
1736              << "\n    Packet counts (send/flush)                             : "
1737              << device.audio_stats.packet_send_count << " / "
1738              << device.audio_stats.packet_flush_count
1739              << "\n    Frame counts (sent/flush)                              : "
1740              << device.audio_stats.frame_send_count << " / " << device.audio_stats.frame_flush_count
1741              << std::endl;
1742 
1743       DumpRssi(fd, device);
1744     }
1745     dprintf(fd, "%s", stream.str().c_str());
1746   }
1747 
Disconnect(const RawAddress & address)1748   void Disconnect(const RawAddress& address) {
1749     HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
1750     if (!hearingDevice) {
1751       log::error("unknown device: bd_addr={}", address);
1752       return;
1753     }
1754 
1755     bool connected = hearingDevice->accepting_audio;
1756     bool connecting_by_user = hearingDevice->connecting_actively;
1757 
1758     log::info("bd_addr={} playback_started={} accepting_audio={}", hearingDevice->address,
1759               hearingDevice->playback_started, hearingDevice->accepting_audio);
1760 
1761     if (hearingDevice->connecting_actively) {
1762       // cancel pending direct connect
1763       BTA_GATTC_CancelOpen(gatt_if, address, true);
1764     }
1765 
1766     // Removes all registrations for connection.
1767     BTA_GATTC_CancelOpen(0, address, false);
1768 
1769     // Inform the other side (if any) of this disconnection
1770     std::vector<uint8_t> inform_disconn_state(
1771             {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
1772     send_state_change_to_other_side(hearingDevice, inform_disconn_state);
1773 
1774     DoDisconnectCleanUp(hearingDevice);
1775 
1776     if (!connected) {
1777       /* In case user wanted to connect, sent DISCONNECTED state */
1778       if (connecting_by_user) {
1779         callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
1780       }
1781       /* Do remove device when the address is useless. */
1782       hearingDevices.Remove(address);
1783       return;
1784     }
1785 
1786     callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
1787     /* Do remove device when the address is useless. */
1788     hearingDevices.Remove(address);
1789     for (const auto& device : hearingDevices.devices) {
1790       if (device.accepting_audio) {
1791         return;
1792       }
1793     }
1794 
1795     log::info("No more (0/{}) devices ready", GetDeviceCount());
1796     DoDisconnectAudioStop();
1797   }
1798 
OnGattDisconnected(tCONN_ID conn_id,tGATT_IF,RawAddress remote_bda)1799   void OnGattDisconnected(tCONN_ID conn_id, tGATT_IF /*client_if*/, RawAddress remote_bda) {
1800     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1801     if (!hearingDevice) {
1802       log::error("unknown device: conn_id=0x{:x} bd_addr={}", conn_id, remote_bda);
1803       return;
1804     }
1805 
1806     log::info("conn_id=0x{:x} bd_addr={}", conn_id, remote_bda);
1807 
1808     // Inform the other side (if any) of this disconnection
1809     std::vector<uint8_t> inform_disconn_state(
1810             {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
1811     send_state_change_to_other_side(hearingDevice, inform_disconn_state);
1812 
1813     DoDisconnectCleanUp(hearingDevice);
1814 
1815     HearingDevice* other_connected_device_from_set =
1816             hearingDevices.FindOtherConnectedDeviceFromSet(*hearingDevice);
1817 
1818     if (other_connected_device_from_set != nullptr) {
1819       log::info(
1820               "Another device from the set is still connected, issuing a direct "
1821               "connection, other_device_bda={}",
1822               other_connected_device_from_set->address);
1823     }
1824 
1825     // If another device from the pair is still connected, do a direct
1826     // connection to scan more aggressively and connect as fast as possible
1827     hearingDevice->connecting_actively = other_connected_device_from_set != nullptr;
1828 
1829     auto connection_type = hearingDevice->connecting_actively ? BTM_BLE_DIRECT_CONNECTION
1830                                                               : BTM_BLE_BKG_CONNECT_ALLOW_LIST;
1831 
1832     hearingDevice->switch_to_background_connection_after_failure =
1833             connection_type == BTM_BLE_DIRECT_CONNECTION;
1834 
1835     // This is needed just for the first connection. After stack is restarted,
1836     // code that loads device will add them to acceptlist.
1837     BTA_GATTC_Open(gatt_if, hearingDevice->address, connection_type, false);
1838 
1839     callbacks->OnConnectionState(ConnectionState::DISCONNECTED, remote_bda);
1840 
1841     for (const auto& device : hearingDevices.devices) {
1842       if (device.accepting_audio) {
1843         return;
1844       }
1845     }
1846 
1847     log::info("No more (0/{}) devices ready", GetDeviceCount());
1848     DoDisconnectAudioStop();
1849   }
1850 
DoDisconnectCleanUp(HearingDevice * hearingDevice)1851   void DoDisconnectCleanUp(HearingDevice* hearingDevice) {
1852     if (hearingDevice->connection_update_status != COMPLETED) {
1853       log::info("connection update not completed: status={}, bd_addr={}",
1854                 hearingDevice->connection_update_status, hearingDevice->address);
1855 
1856       if (hearingDevice->connection_update_status == STARTED) {
1857         OnConnectionUpdateComplete(hearingDevice->conn_id, NULL);
1858       }
1859     }
1860     hearingDevice->connection_update_status = NONE;
1861     hearingDevice->gap_opened = false;
1862 
1863     if (hearingDevice->conn_id != INVALID_CONN_ID) {
1864       BtaGattQueue::Clean(hearingDevice->conn_id);
1865       BTA_GATTC_Close(hearingDevice->conn_id);
1866       hearingDevice->conn_id = INVALID_CONN_ID;
1867     }
1868 
1869     if (hearingDevice->gap_handle != GAP_INVALID_HANDLE) {
1870       GAP_ConnClose(hearingDevice->gap_handle);
1871       hearingDevice->gap_handle = GAP_INVALID_HANDLE;
1872     }
1873 
1874     hearingDevice->accepting_audio = false;
1875     log::info("bd_addr={} playback_started={}", hearingDevice->address,
1876               hearingDevice->playback_started);
1877     hearingDevice->playback_started = false;
1878     hearingDevice->command_acked = false;
1879   }
1880 
DoDisconnectAudioStop()1881   void DoDisconnectAudioStop() {
1882     HearingAidAudioSource::Stop();
1883     audio_running = false;
1884     encoder_state_release();
1885     current_volume = VOLUME_UNKNOWN;
1886     ResetAsrc();
1887   }
1888 
SetVolume(int8_t volume)1889   void SetVolume(int8_t volume) {
1890     log::debug("{}", volume);
1891     current_volume = volume;
1892     for (HearingDevice& device : hearingDevices.devices) {
1893       if (!device.accepting_audio) {
1894         continue;
1895       }
1896 
1897       std::vector<uint8_t> volume_value({static_cast<unsigned char>(volume)});
1898       BtaGattQueue::WriteCharacteristic(device.conn_id, device.volume_handle, volume_value,
1899                                         GATT_WRITE_NO_RSP, nullptr, nullptr);
1900     }
1901   }
1902 
CleanUp()1903   void CleanUp() {
1904     BTA_GATTC_AppDeregister(gatt_if);
1905     for (HearingDevice& device : hearingDevices.devices) {
1906       DoDisconnectCleanUp(&device);
1907     }
1908 
1909     hearingDevices.devices.clear();
1910 
1911     encoder_state_release();
1912   }
1913 
1914 private:
1915   uint8_t gatt_if;
1916   uint8_t seq_counter;
1917   /* current volume gain for the hearing aids*/
1918   int8_t current_volume;
1919   bluetooth::hearing_aid::HearingAidCallbacks* callbacks;
1920 
1921   /* currently used codec */
1922   uint8_t codec_in_use;
1923 
1924   uint16_t default_data_interval_ms;
1925 
1926   uint16_t init_credit;
1927 
1928   HearingDevices hearingDevices;
1929 
find_server_changed_ccc_handle(tCONN_ID conn_id,const gatt::Service * service)1930   void find_server_changed_ccc_handle(tCONN_ID conn_id, const gatt::Service* service) {
1931     HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1932     if (!hearingDevice) {
1933       log::error("unknown device: conn_id=0x{:x}", conn_id);
1934       return;
1935     }
1936 
1937     for (const gatt::Characteristic& charac : service->characteristics) {
1938       if (charac.uuid == Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD)) {
1939         hearingDevice->service_changed_ccc_handle = find_ccc_handle(conn_id, charac.value_handle);
1940         if (!hearingDevice->service_changed_ccc_handle) {
1941           log::error("failed to find service changed CCC descriptor: bd_addr={}",
1942                      hearingDevice->address);
1943           continue;
1944         }
1945         log::info("bd_addr={} service_changed_ccc=0x{:x}", hearingDevice->address,
1946                   hearingDevice->service_changed_ccc_handle);
1947         break;
1948       }
1949     }
1950   }
1951 
1952   // Find the handle for the client characteristics configuration of a given
1953   // characteristics
find_ccc_handle(tCONN_ID conn_id,uint16_t char_handle)1954   uint16_t find_ccc_handle(tCONN_ID conn_id, uint16_t char_handle) {
1955     const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, char_handle);
1956 
1957     if (!p_char) {
1958       log::warn("No such characteristic: {}", char_handle);
1959       return 0;
1960     }
1961 
1962     for (const gatt::Descriptor& desc : p_char->descriptors) {
1963       if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG)) {
1964         return desc.handle;
1965       }
1966     }
1967 
1968     return 0;
1969   }
1970 
send_state_change(HearingDevice * device,std::vector<uint8_t> payload)1971   void send_state_change(HearingDevice* device, std::vector<uint8_t> payload) {
1972     if (device->conn_id != INVALID_CONN_ID) {
1973       if (device->service_changed_rcvd) {
1974         log::info("service discover is in progress, skip send State Change cmd.");
1975         return;
1976       }
1977       // Send the data packet
1978       log::info("Send State Change: bd_addr={} status=0x{:x}", device->address, payload[1]);
1979       BtaGattQueue::WriteCharacteristic(device->conn_id, device->audio_control_point_handle,
1980                                         payload, GATT_WRITE_NO_RSP, nullptr, nullptr);
1981     }
1982   }
1983 
send_state_change_to_other_side(HearingDevice * this_side_device,std::vector<uint8_t> payload)1984   void send_state_change_to_other_side(HearingDevice* this_side_device,
1985                                        std::vector<uint8_t> payload) {
1986     for (auto& device : hearingDevices.devices) {
1987       if ((device.address == this_side_device->address) ||
1988           (device.hi_sync_id != this_side_device->hi_sync_id)) {
1989         continue;
1990       }
1991       send_state_change(&device, payload);
1992     }
1993   }
1994 
check_and_do_rssi_read(HearingDevice * device)1995   void check_and_do_rssi_read(HearingDevice* device) {
1996     if (device->read_rssi_count > 0) {
1997       device->num_intervals_since_last_rssi_read++;
1998       if (device->num_intervals_since_last_rssi_read >= PERIOD_TO_READ_RSSI_IN_INTERVALS) {
1999         device->num_intervals_since_last_rssi_read = 0;
2000         log::debug("bd_addr={}", device->address);
2001         if (get_btm_client_interface().link_controller.BTM_ReadRSSI(
2002                     device->address, read_rssi_callback) != tBTM_STATUS::BTM_CMD_STARTED) {
2003           log::warn("Unable to read RSSI peer:{}", device->address);
2004         }
2005       }
2006     }
2007   }
2008 };
2009 
read_rssi_callback(void * p_void)2010 static void read_rssi_callback(void* p_void) {
2011   tBTM_RSSI_RESULT* p_result = (tBTM_RSSI_RESULT*)p_void;
2012 
2013   if (!p_result) {
2014     return;
2015   }
2016 
2017   if ((instance) && (p_result->status == tBTM_STATUS::BTM_SUCCESS)) {
2018     instance->OnReadRssiComplete(p_result->rem_bda, p_result->rssi);
2019   }
2020 }
2021 
hearingaid_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)2022 static void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
2023   if (p_data == nullptr) {
2024     return;
2025   }
2026 
2027   switch (event) {
2028     case BTA_GATTC_DEREG_EVT:
2029       log::info("");
2030       break;
2031 
2032     case BTA_GATTC_OPEN_EVT: {
2033       if (!instance) {
2034         return;
2035       }
2036       tBTA_GATTC_OPEN& o = p_data->open;
2037       instance->OnGattConnected(o.status, o.conn_id, o.client_if, o.remote_bda, o.transport, o.mtu);
2038       break;
2039     }
2040 
2041     case BTA_GATTC_CLOSE_EVT: {
2042       if (!instance) {
2043         return;
2044       }
2045       tBTA_GATTC_CLOSE& c = p_data->close;
2046       instance->OnGattDisconnected(c.conn_id, c.client_if, c.remote_bda);
2047     } break;
2048 
2049     case BTA_GATTC_SEARCH_CMPL_EVT:
2050       if (!instance) {
2051         return;
2052       }
2053       instance->OnServiceSearchComplete(p_data->search_cmpl.conn_id, p_data->search_cmpl.status);
2054       break;
2055 
2056     case BTA_GATTC_NOTIF_EVT:
2057       if (!instance) {
2058         return;
2059       }
2060       if (!p_data->notify.is_notify || p_data->notify.len > GATT_MAX_ATTR_LEN) {
2061         log::error("rejected BTA_GATTC_NOTIF_EVT. is_notify={}, len={}", p_data->notify.is_notify,
2062                    p_data->notify.len);
2063         break;
2064       }
2065       instance->OnNotificationEvent(p_data->notify.conn_id, p_data->notify.handle,
2066                                     p_data->notify.len, p_data->notify.value);
2067       break;
2068 
2069     case BTA_GATTC_ENC_CMPL_CB_EVT:
2070       if (!instance) {
2071         return;
2072       }
2073       instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda,
2074                                      BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE));
2075       break;
2076 
2077     case BTA_GATTC_CONN_UPDATE_EVT:
2078       if (!instance) {
2079         return;
2080       }
2081       instance->OnConnectionUpdateComplete(p_data->conn_update.conn_id, p_data);
2082       break;
2083 
2084     case BTA_GATTC_SRVC_CHG_EVT:
2085       if (!instance) {
2086         return;
2087       }
2088       instance->OnServiceChangeEvent(p_data->service_changed.remote_bda);
2089       break;
2090 
2091     case BTA_GATTC_SRVC_DISC_DONE_EVT:
2092       if (!instance) {
2093         return;
2094       }
2095       instance->OnServiceDiscDoneEvent(p_data->service_discovery_done.remote_bda);
2096       break;
2097     case BTA_GATTC_PHY_UPDATE_EVT: {
2098       if (!instance) {
2099         return;
2100       }
2101       tBTA_GATTC_PHY_UPDATE& p = p_data->phy_update;
2102       instance->OnPhyUpdateEvent(p.conn_id, p.tx_phy, p.rx_phy, p.status);
2103       break;
2104     }
2105 
2106     default:
2107       break;
2108   }
2109 }
2110 
encryption_callback(RawAddress address,tBT_TRANSPORT,void *,tBTM_STATUS status)2111 static void encryption_callback(RawAddress address, tBT_TRANSPORT, void*, tBTM_STATUS status) {
2112   if (instance) {
2113     instance->OnEncryptionComplete(address, status == tBTM_STATUS::BTM_SUCCESS ? true : false);
2114   }
2115 }
2116 
2117 class HearingAidAudioReceiverImpl : public HearingAidAudioReceiver {
2118 public:
OnAudioDataReady(const std::vector<uint8_t> & data)2119   void OnAudioDataReady(const std::vector<uint8_t>& data) override {
2120     if (instance) {
2121       instance->OnAudioDataReadyResample(data);
2122     }
2123   }
OnAudioSuspend(const std::function<void ()> & stop_audio_ticks)2124   void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) override {
2125     if (instance) {
2126       instance->OnAudioSuspend(stop_audio_ticks);
2127     }
2128   }
OnAudioResume(const std::function<void ()> & start_audio_ticks)2129   void OnAudioResume(const std::function<void()>& start_audio_ticks) override {
2130     if (instance) {
2131       instance->OnAudioResume(start_audio_ticks);
2132     }
2133   }
2134 };
2135 
2136 HearingAidAudioReceiverImpl audioReceiverImpl;
2137 
2138 }  // namespace
2139 
Initialize(bluetooth::hearing_aid::HearingAidCallbacks * callbacks,Closure initCb)2140 void HearingAid::Initialize(bluetooth::hearing_aid::HearingAidCallbacks* callbacks,
2141                             Closure initCb) {
2142   std::scoped_lock<std::mutex> lock(instance_mutex);
2143   if (instance) {
2144     log::error("Already initialized!");
2145     return;
2146   }
2147 
2148   audioReceiver = &audioReceiverImpl;
2149   instance = new HearingAidImpl(callbacks, initCb);
2150   HearingAidAudioSource::Initialize();
2151 }
2152 
IsHearingAidRunning()2153 bool HearingAid::IsHearingAidRunning() { return instance; }
2154 
Connect(const RawAddress & address)2155 void HearingAid::Connect(const RawAddress& address) {
2156   if (!instance) {
2157     log::error("Hearing Aid instance is not available");
2158     return;
2159   }
2160   instance->Connect(address);
2161 }
2162 
Disconnect(const RawAddress & address)2163 void HearingAid::Disconnect(const RawAddress& address) {
2164   if (!instance) {
2165     log::error("Hearing Aid instance is not available");
2166     return;
2167   }
2168   instance->Disconnect(address);
2169 }
2170 
AddToAcceptlist(const RawAddress & address)2171 void HearingAid::AddToAcceptlist(const RawAddress& address) {
2172   if (!instance) {
2173     log::error("Hearing Aid instance is not available");
2174     return;
2175   }
2176   instance->AddToAcceptlist(address);
2177 }
2178 
SetVolume(int8_t volume)2179 void HearingAid::SetVolume(int8_t volume) {
2180   if (!instance) {
2181     log::error("Hearing Aid instance is not available");
2182     return;
2183   }
2184   instance->SetVolume(volume);
2185 }
2186 
AddFromStorage(const HearingDevice & dev_info,bool is_acceptlisted)2187 void HearingAid::AddFromStorage(const HearingDevice& dev_info, bool is_acceptlisted) {
2188   if (!instance) {
2189     log::error("Not initialized yet");
2190   }
2191 
2192   instance->AddFromStorage(dev_info, is_acceptlisted);
2193 }
2194 
GetDeviceCount()2195 int HearingAid::GetDeviceCount() {
2196   if (!instance) {
2197     log::info("Not initialized yet");
2198     return 0;
2199   }
2200 
2201   return instance->GetDeviceCount();
2202 }
2203 
CleanUp()2204 void HearingAid::CleanUp() {
2205   std::scoped_lock<std::mutex> lock(instance_mutex);
2206   // Must stop audio source to make sure it doesn't call any of callbacks on our
2207   // soon to be  null instance
2208   HearingAidAudioSource::Stop();
2209 
2210   HearingAidImpl* ptr = instance;
2211   instance = nullptr;
2212   HearingAidAudioSource::CleanUp();
2213 
2214   ptr->CleanUp();
2215 
2216   delete ptr;
2217 }
2218 
DebugDump(int fd)2219 void HearingAid::DebugDump(int fd) {
2220   std::scoped_lock<std::mutex> lock(instance_mutex);
2221   dprintf(fd, "Hearing Aid Manager:\n");
2222   if (instance) {
2223     instance->Dump(fd);
2224   }
2225   HearingAidAudioSource::DebugDump(fd);
2226   dprintf(fd, "\n");
2227 }
2228