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