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