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