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