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 #include "bta_hearing_aid_api.h"
20
21 #define LOG_TAG "bluetooth"
22
23 #include <base/bind.h>
24 #include <base/callback.h>
25 #include <base/strings/string_number_conversions.h> // HexEncode
26 #include <cstdint>
27 #include <vector>
28
29 #include "bta/include/bta_gatt_api.h"
30 #include "bta/include/bta_gatt_queue.h"
31 #include "bta/include/bta_hearing_aid_api.h"
32 #include "device/include/controller.h"
33 #include "embdrv/g722/g722_enc_dec.h"
34 #include "osi/include/log.h"
35 #include "osi/include/properties.h"
36 #include "stack/btm/btm_sec.h"
37 #include "stack/include/acl_api.h" // BTM_ReadRSSI
38 #include "stack/include/acl_api_types.h" // tBTM_RSSI_RESULT
39 #include "stack/include/gap_api.h"
40 #include "stack/include/l2c_api.h" // L2CAP_MIN_OFFSET
41 #include "types/bluetooth/uuid.h"
42 #include "types/bt_transport.h"
43 #include "types/raw_address.h"
44
45 using base::Closure;
46 using bluetooth::Uuid;
47 using bluetooth::hearing_aid::ConnectionState;
48
49 // The MIN_CE_LEN parameter for Connection Parameters based on the current
50 // Connection Interval
51 constexpr uint16_t MIN_CE_LEN_10MS_CI = 0x0006;
52 constexpr uint16_t MIN_CE_LEN_20MS_CI = 0x000C;
53 constexpr uint16_t CONNECTION_INTERVAL_10MS_PARAM = 0x0008;
54 constexpr uint16_t CONNECTION_INTERVAL_20MS_PARAM = 0x0010;
55
56 void btif_storage_add_hearing_aid(const HearingDevice& dev_info);
57 bool btif_storage_get_hearing_aid_prop(
58 const RawAddress& address, uint8_t* capabilities, uint64_t* hi_sync_id,
59 uint16_t* render_delay, uint16_t* preparation_delay, uint16_t* codecs);
60
61 constexpr uint8_t CODEC_G722_16KHZ = 0x01;
62 constexpr uint8_t CODEC_G722_24KHZ = 0x02;
63
64 // audio control point opcodes
65 constexpr uint8_t CONTROL_POINT_OP_START = 0x01;
66 constexpr uint8_t CONTROL_POINT_OP_STOP = 0x02;
67 constexpr uint8_t CONTROL_POINT_OP_STATE_CHANGE = 0x03;
68
69 constexpr uint8_t STATE_CHANGE_OTHER_SIDE_DISCONNECTED = 0x00;
70 constexpr uint8_t STATE_CHANGE_OTHER_SIDE_CONNECTED = 0x01;
71 constexpr uint8_t STATE_CHANGE_CONN_UPDATE = 0x02;
72
73 // used to mark current_volume as not yet known, or possibly old
74 constexpr int8_t VOLUME_UNKNOWN = 127;
75 constexpr int8_t VOLUME_MIN = -127;
76
77 // audio type
78 constexpr uint8_t AUDIOTYPE_UNKNOWN = 0x00;
79
80 // Status of the other side Hearing Aids device
81 constexpr uint8_t OTHER_SIDE_NOT_STREAMING = 0x00;
82 constexpr uint8_t OTHER_SIDE_IS_STREAMING = 0x01;
83
84 // This ADD_RENDER_DELAY_INTERVALS is the number of connection intervals when
85 // the audio data packet is send by Audio Engine to when the Hearing Aids device
86 // received it from the air. We assumed that there is 2 data buffer queued from
87 // audio subsystem to bluetooth chip. Then the estimated OTA delay is two
88 // connnection intervals.
89 constexpr uint16_t ADD_RENDER_DELAY_INTERVALS = 4;
90
91 namespace {
92
93 // clang-format off
94 Uuid HEARING_AID_UUID = Uuid::FromString("FDF0");
95 Uuid READ_ONLY_PROPERTIES_UUID = Uuid::FromString("6333651e-c481-4a3e-9169-7c902aad37bb");
96 Uuid AUDIO_CONTROL_POINT_UUID = Uuid::FromString("f0d4de7e-4a88-476c-9d9f-1937b0996cc0");
97 Uuid AUDIO_STATUS_UUID = Uuid::FromString("38663f1a-e711-4cac-b641-326b56404837");
98 Uuid VOLUME_UUID = Uuid::FromString("00e4ca9e-ab14-41e4-8823-f9e70c7e91df");
99 Uuid LE_PSM_UUID = Uuid::FromString("2d410339-82b6-42aa-b34e-e2e01df8cc1a");
100 // clang-format on
101
102 void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data);
103 void encryption_callback(const RawAddress*, tBT_TRANSPORT, void*, tBTM_STATUS);
104 void read_rssi_cb(void* p_void);
105
malloc_l2cap_buf(uint16_t len)106 inline BT_HDR* malloc_l2cap_buf(uint16_t len) {
107 BT_HDR* msg = (BT_HDR*)osi_malloc(BT_HDR_SIZE + L2CAP_MIN_OFFSET +
108 len /* LE-only, no need for FCS here */);
109 msg->offset = L2CAP_MIN_OFFSET;
110 msg->len = len;
111 return msg;
112 }
113
get_l2cap_sdu_start_ptr(BT_HDR * msg)114 inline uint8_t* get_l2cap_sdu_start_ptr(BT_HDR* msg) {
115 return (uint8_t*)(msg) + BT_HDR_SIZE + L2CAP_MIN_OFFSET;
116 }
117
118 class HearingAidImpl;
119 HearingAidImpl* instance;
120 HearingAidAudioReceiver* audioReceiver;
121
122 class HearingDevices {
123 public:
Add(HearingDevice device)124 void Add(HearingDevice device) {
125 if (FindByAddress(device.address) != nullptr) return;
126
127 devices.push_back(device);
128 }
129
Remove(const RawAddress & address)130 void Remove(const RawAddress& address) {
131 for (auto it = devices.begin(); it != devices.end();) {
132 if (it->address != address) {
133 ++it;
134 continue;
135 }
136
137 it = devices.erase(it);
138 return;
139 }
140 }
141
FindByAddress(const RawAddress & address)142 HearingDevice* FindByAddress(const RawAddress& address) {
143 auto iter = std::find_if(devices.begin(), devices.end(),
144 [&address](const HearingDevice& device) {
145 return device.address == address;
146 });
147
148 return (iter == devices.end()) ? nullptr : &(*iter);
149 }
150
FindByConnId(uint16_t conn_id)151 HearingDevice* FindByConnId(uint16_t conn_id) {
152 auto iter = std::find_if(devices.begin(), devices.end(),
153 [&conn_id](const HearingDevice& device) {
154 return device.conn_id == conn_id;
155 });
156
157 return (iter == devices.end()) ? nullptr : &(*iter);
158 }
159
FindByGapHandle(uint16_t gap_handle)160 HearingDevice* FindByGapHandle(uint16_t gap_handle) {
161 auto iter = std::find_if(devices.begin(), devices.end(),
162 [&gap_handle](const HearingDevice& device) {
163 return device.gap_handle == gap_handle;
164 });
165
166 return (iter == devices.end()) ? nullptr : &(*iter);
167 }
168
IsAnyConnectionUpdateStarted()169 bool IsAnyConnectionUpdateStarted() {
170 for (const auto& d : devices) {
171 if (d.connection_update_status == STARTED) return true;
172 }
173
174 return false;
175 }
176
StartRssiLog()177 void StartRssiLog() {
178 int read_rssi_start_interval_count = 0;
179
180 for (auto& d : devices) {
181 VLOG(1) << __func__ << ": device=" << d.address << ", read_rssi_count=" << d.read_rssi_count;
182
183 // Reset the count
184 if (d.read_rssi_count <= 0) {
185 d.read_rssi_count = READ_RSSI_NUM_TRIES;
186 d.num_intervals_since_last_rssi_read = read_rssi_start_interval_count;
187
188 // Spaced apart the Read RSSI commands to the BT controller.
189 read_rssi_start_interval_count += PERIOD_TO_READ_RSSI_IN_INTERVALS / 2;
190 read_rssi_start_interval_count %= PERIOD_TO_READ_RSSI_IN_INTERVALS;
191
192 std::deque<rssi_log>& rssi_logs = d.audio_stats.rssi_history;
193 if (rssi_logs.size() >= MAX_RSSI_HISTORY) {
194 rssi_logs.pop_front();
195 }
196 rssi_logs.emplace_back();
197 }
198 }
199 }
200
size()201 size_t size() { return (devices.size()); }
202
203 std::vector<HearingDevice> devices;
204 };
205
write_rpt_ctl_cfg_cb(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,void * data)206 static void write_rpt_ctl_cfg_cb(uint16_t conn_id, tGATT_STATUS status,
207 uint16_t handle, void* data) {
208 if (status != GATT_SUCCESS) {
209 LOG(ERROR) << __func__ << ": handle=" << handle << ", conn_id=" << conn_id
210 << ", status=" << loghex(static_cast<uint8_t>(status));
211 }
212 }
213
214 g722_encode_state_t* encoder_state_left = nullptr;
215 g722_encode_state_t* encoder_state_right = nullptr;
216
encoder_state_init()217 inline void encoder_state_init() {
218 if (encoder_state_left != nullptr) {
219 LOG(WARNING) << __func__ << ": encoder already initialized";
220 return;
221 }
222 encoder_state_left = g722_encode_init(nullptr, 64000, G722_PACKED);
223 encoder_state_right = g722_encode_init(nullptr, 64000, G722_PACKED);
224 }
225
encoder_state_release()226 inline void encoder_state_release() {
227 if (encoder_state_left != nullptr) {
228 g722_encode_release(encoder_state_left);
229 encoder_state_left = nullptr;
230 g722_encode_release(encoder_state_right);
231 encoder_state_right = nullptr;
232 }
233 }
234
235 class HearingAidImpl : public HearingAid {
236 private:
237 // Keep track of whether the Audio Service has resumed audio playback
238 bool audio_running;
239 // For Testing: overwrite the MIN_CE_LEN during connection parameter updates
240 uint16_t overwrite_min_ce_len;
241
242 public:
243 ~HearingAidImpl() override = default;
244
HearingAidImpl(bluetooth::hearing_aid::HearingAidCallbacks * callbacks,Closure initCb)245 HearingAidImpl(bluetooth::hearing_aid::HearingAidCallbacks* callbacks,
246 Closure initCb)
247 : audio_running(false),
248 overwrite_min_ce_len(0),
249 gatt_if(0),
250 seq_counter(0),
251 current_volume(VOLUME_UNKNOWN),
252 callbacks(callbacks),
253 codec_in_use(0) {
254 default_data_interval_ms = (uint16_t)osi_property_get_int32(
255 "persist.bluetooth.hearingaid.interval", (int32_t)HA_INTERVAL_20_MS);
256 if ((default_data_interval_ms != HA_INTERVAL_10_MS) &&
257 (default_data_interval_ms != HA_INTERVAL_20_MS)) {
258 LOG(ERROR) << __func__
259 << ": invalid interval=" << default_data_interval_ms
260 << "ms. Overwriting back to default";
261 default_data_interval_ms = HA_INTERVAL_20_MS;
262 }
263 VLOG(2) << __func__
264 << ", default_data_interval_ms=" << default_data_interval_ms;
265
266 overwrite_min_ce_len = (uint16_t)osi_property_get_int32(
267 "persist.bluetooth.hearingaidmincelen", 0);
268 if (overwrite_min_ce_len) {
269 LOG(INFO) << __func__
270 << ": Overwrites MIN_CE_LEN=" << overwrite_min_ce_len;
271 }
272
273 BTA_GATTC_AppRegister(
274 hearingaid_gattc_callback,
275 base::Bind(
276 [](Closure initCb, uint8_t client_id, uint8_t status) {
277 if (status != GATT_SUCCESS) {
278 LOG(ERROR) << "Can't start Hearing Aid profile - no gatt "
279 "clients left!";
280 return;
281 }
282 instance->gatt_if = client_id;
283 initCb.Run();
284 },
285 initCb), false);
286 }
287
UpdateBleConnParams(const RawAddress & address)288 uint16_t UpdateBleConnParams(const RawAddress& address) {
289 /* List of parameters that depends on the chosen Connection Interval */
290 uint16_t min_ce_len;
291 uint16_t connection_interval;
292
293 switch (default_data_interval_ms) {
294 case HA_INTERVAL_10_MS:
295 min_ce_len = MIN_CE_LEN_10MS_CI;
296 connection_interval = CONNECTION_INTERVAL_10MS_PARAM;
297 break;
298 case HA_INTERVAL_20_MS:
299 min_ce_len = MIN_CE_LEN_20MS_CI;
300 connection_interval = CONNECTION_INTERVAL_20MS_PARAM;
301 break;
302 default:
303 LOG(ERROR) << __func__ << ":Error: invalid default_data_interval_ms="
304 << default_data_interval_ms;
305 min_ce_len = MIN_CE_LEN_10MS_CI;
306 connection_interval = CONNECTION_INTERVAL_10MS_PARAM;
307 }
308
309 if (overwrite_min_ce_len != 0) {
310 VLOG(2) << __func__ << ": min_ce_len=" << min_ce_len
311 << " is overwritten to " << overwrite_min_ce_len;
312 min_ce_len = overwrite_min_ce_len;
313 }
314
315 L2CA_UpdateBleConnParams(address, connection_interval, connection_interval,
316 0x000A, 0x0064 /*1s*/, min_ce_len, min_ce_len);
317 return connection_interval;
318 }
319
Connect(const RawAddress & address)320 void Connect(const RawAddress& address) override {
321 DVLOG(2) << __func__ << " " << address;
322 hearingDevices.Add(HearingDevice(address, true));
323 BTA_GATTC_Open(gatt_if, address, true, false);
324 }
325
AddToAcceptlist(const RawAddress & address)326 void AddToAcceptlist(const RawAddress& address) override {
327 VLOG(2) << __func__ << " address: " << address;
328 hearingDevices.Add(HearingDevice(address, true));
329 BTA_GATTC_Open(gatt_if, address, false, false);
330 }
331
AddFromStorage(const HearingDevice & dev_info,uint16_t is_acceptlisted)332 void AddFromStorage(const HearingDevice& dev_info, uint16_t is_acceptlisted) {
333 DVLOG(2) << __func__ << " " << dev_info.address
334 << ", hiSyncId=" << loghex(dev_info.hi_sync_id)
335 << ", isAcceptlisted=" << is_acceptlisted;
336 if (is_acceptlisted) {
337 hearingDevices.Add(dev_info);
338
339 // TODO: we should increase the scanning window for few seconds, to get
340 // faster initial connection, same after hearing aid disconnects, i.e.
341 // BTM_BleSetConnScanParams(2048, 1024);
342
343 /* add device into BG connection to accept remote initiated connection */
344 BTA_GATTC_Open(gatt_if, dev_info.address, false, false);
345 }
346
347 callbacks->OnDeviceAvailable(dev_info.capabilities, dev_info.hi_sync_id,
348 dev_info.address);
349 }
350
GetDeviceCount()351 int GetDeviceCount() { return (hearingDevices.size()); }
352
OnGattConnected(tGATT_STATUS status,uint16_t conn_id,tGATT_IF client_if,RawAddress address,tBT_TRANSPORT transport,uint16_t mtu)353 void OnGattConnected(tGATT_STATUS status, uint16_t conn_id,
354 tGATT_IF client_if, RawAddress address,
355 tBT_TRANSPORT transport, uint16_t mtu) {
356 VLOG(2) << __func__ << ": address=" << address << ", conn_id=" << conn_id;
357
358 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
359 if (!hearingDevice) {
360 /* When Hearing Aid is quickly disabled and enabled in settings, this case
361 * might happen */
362 LOG(WARNING) << "Closing connection to non hearing-aid device, address="
363 << address;
364 BTA_GATTC_Close(conn_id);
365 return;
366 }
367
368 if (status != GATT_SUCCESS) {
369 if (!hearingDevice->connecting_actively) {
370 // acceptlist connection failed, that's ok.
371 return;
372 }
373
374 LOG(INFO) << "Failed to connect to Hearing Aid device";
375 hearingDevices.Remove(address);
376 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
377 return;
378 }
379
380 hearingDevice->connecting_actively = false;
381 hearingDevice->conn_id = conn_id;
382
383 /* We must update connection parameters one at a time, otherwise anchor
384 * point (start of connection event) for two devices can be too close to
385 * each other. Here, by setting min_ce_len=max_ce_len=X, we force controller
386 * to move anchor point of both connections away from each other, to make
387 * sure we'll be able to fit all the data we want in one connection event.
388 */
389 bool any_update_pending = hearingDevices.IsAnyConnectionUpdateStarted();
390 // mark the device as pending connection update. If we don't start the
391 // update now, it'll be started once current device finishes.
392 if (!any_update_pending) {
393 hearingDevice->connection_update_status = STARTED;
394 hearingDevice->requested_connection_interval =
395 UpdateBleConnParams(address);
396 } else {
397 hearingDevice->connection_update_status = AWAITING;
398 }
399
400 if (controller_get_interface()->supports_ble_2m_phy()) {
401 LOG(INFO) << address << " set preferred PHY to 2M";
402 BTM_BleSetPhy(address, PHY_LE_2M, PHY_LE_2M, 0);
403 }
404
405 // Set data length
406 // TODO(jpawlowski: for 16khz only 87 is required, optimize
407 BTM_SetBleDataLength(address, 167);
408
409 if (BTM_SecIsSecurityPending(address)) {
410 /* if security collision happened, wait for encryption done
411 * (BTA_GATTC_ENC_CMPL_CB_EVT) */
412 return;
413 }
414
415 /* verify bond */
416 if (BTM_IsEncrypted(address, BT_TRANSPORT_LE)) {
417 /* if link has been encrypted */
418 OnEncryptionComplete(address, true);
419 return;
420 }
421
422 if (BTM_IsLinkKeyKnown(address, BT_TRANSPORT_LE)) {
423 /* if bonded and link not encrypted */
424 BTM_SetEncryption(address, BT_TRANSPORT_LE, encryption_callback, nullptr,
425 BTM_BLE_SEC_ENCRYPT);
426 return;
427 }
428
429 /* otherwise let it go through */
430 OnEncryptionComplete(address, true);
431 }
432
OnConnectionUpdateComplete(uint16_t conn_id,tBTA_GATTC * p_data)433 void OnConnectionUpdateComplete(uint16_t conn_id, tBTA_GATTC* p_data) {
434 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
435 if (!hearingDevice) {
436 DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
437 return;
438 }
439
440 if (p_data) {
441 if (p_data->conn_update.status == 0) {
442 bool same_conn_interval =
443 (hearingDevice->requested_connection_interval ==
444 p_data->conn_update.interval);
445
446 switch (hearingDevice->connection_update_status) {
447 case COMPLETED:
448 if (!same_conn_interval) {
449 LOG(WARNING) << __func__
450 << ": Unexpected change. Redo. connection interval="
451 << p_data->conn_update.interval << ", expected="
452 << hearingDevice->requested_connection_interval
453 << ", conn_id=" << conn_id
454 << ", connection_update_status="
455 << hearingDevice->connection_update_status;
456 // Redo this connection interval change.
457 hearingDevice->connection_update_status = AWAITING;
458 }
459 break;
460 case STARTED:
461 if (same_conn_interval) {
462 LOG(INFO) << __func__
463 << ": Connection update completed. conn_id=" << conn_id
464 << ", device=" << hearingDevice->address;
465 hearingDevice->connection_update_status = COMPLETED;
466 } else {
467 LOG(WARNING) << __func__
468 << ": Ignored. Different connection interval="
469 << p_data->conn_update.interval << ", expected="
470 << hearingDevice->requested_connection_interval
471 << ", conn_id=" << conn_id
472 << ", connection_update_status="
473 << hearingDevice->connection_update_status;
474 // Wait for the right Connection Update Completion.
475 return;
476 }
477 break;
478 case AWAITING:
479 case NONE:
480 break;
481 }
482
483 // Inform this side and other side device (if any) of Connection
484 // Updates.
485 std::vector<uint8_t> conn_update(
486 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_CONN_UPDATE,
487 (uint8_t)p_data->conn_update.interval});
488 send_state_change_to_other_side(hearingDevice, conn_update);
489 send_state_change(hearingDevice, conn_update);
490 } else {
491 LOG(INFO) << __func__ << ": error status="
492 << loghex(static_cast<uint8_t>(p_data->conn_update.status))
493 << ", conn_id=" << conn_id
494 << ", device=" << hearingDevice->address
495 << ", connection_update_status="
496 << hearingDevice->connection_update_status;
497
498 if (hearingDevice->connection_update_status == STARTED) {
499 // Redo this connection interval change.
500 LOG(ERROR) << __func__ << ": Redo Connection Interval change";
501 hearingDevice->connection_update_status = AWAITING;
502 }
503 }
504 } else {
505 hearingDevice->connection_update_status = NONE;
506 }
507
508 for (auto& device : hearingDevices.devices) {
509 if (device.conn_id && (device.connection_update_status == AWAITING)) {
510 device.connection_update_status = STARTED;
511 device.requested_connection_interval =
512 UpdateBleConnParams(device.address);
513 return;
514 }
515 }
516 }
517
518 // Completion Callback for the RSSI read operation.
OnReadRssiComplete(const RawAddress & address,int8_t rssi_value)519 void OnReadRssiComplete(const RawAddress& address, int8_t rssi_value) {
520 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
521 if (!hearingDevice) {
522 LOG(INFO) << "Skipping unknown device" << address;
523 return;
524 }
525
526 VLOG(1) << __func__ << ": device=" << address << ", rssi=" << (int)rssi_value;
527
528 if (hearingDevice->read_rssi_count <= 0) {
529 LOG(ERROR) << __func__ << ": device=" << address
530 << ", invalid read_rssi_count=" << hearingDevice->read_rssi_count;
531 return;
532 }
533
534 rssi_log& last_log_set = hearingDevice->audio_stats.rssi_history.back();
535
536 if (hearingDevice->read_rssi_count == READ_RSSI_NUM_TRIES) {
537 // Store the timestamp only for the first one after packet flush
538 clock_gettime(CLOCK_REALTIME, &last_log_set.timestamp);
539 LOG(INFO) << __func__ << ": store time. device=" << address << ", rssi=" << (int)rssi_value;
540 }
541
542 last_log_set.rssi.emplace_back(rssi_value);
543 hearingDevice->read_rssi_count--;
544 }
545
OnEncryptionComplete(const RawAddress & address,bool success)546 void OnEncryptionComplete(const RawAddress& address, bool success) {
547 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
548 if (!hearingDevice) {
549 DVLOG(2) << "Skipping unknown device" << address;
550 return;
551 }
552
553 if (!success) {
554 LOG(ERROR) << "encryption failed";
555 BTA_GATTC_Close(hearingDevice->conn_id);
556 if (hearingDevice->first_connection) {
557 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
558 }
559 return;
560 }
561
562 DVLOG(2) << __func__ << " " << address;
563
564 if (hearingDevice->audio_control_point_handle &&
565 hearingDevice->audio_status_handle &&
566 hearingDevice->audio_status_ccc_handle &&
567 hearingDevice->volume_handle && hearingDevice->read_psm_handle) {
568 // Use cached data, jump to read PSM
569 ReadPSM(hearingDevice);
570 } else {
571 hearingDevice->first_connection = true;
572 BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID);
573 }
574 }
575
OnServiceChangeEvent(const RawAddress & address)576 void OnServiceChangeEvent(const RawAddress& address) {
577 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
578 if (!hearingDevice) {
579 VLOG(2) << "Skipping unknown device" << address;
580 return;
581 }
582 LOG(INFO) << __func__ << ": address=" << address;
583 hearingDevice->first_connection = true;
584 hearingDevice->service_changed_rcvd = true;
585 BtaGattQueue::Clean(hearingDevice->conn_id);
586 if (hearingDevice->gap_handle) {
587 GAP_ConnClose(hearingDevice->gap_handle);
588 hearingDevice->gap_handle = 0;
589 }
590 }
591
OnServiceDiscDoneEvent(const RawAddress & address)592 void OnServiceDiscDoneEvent(const RawAddress& address) {
593 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
594 if (!hearingDevice) {
595 VLOG(2) << "Skipping unknown device" << address;
596 return;
597 }
598 if (hearingDevice->service_changed_rcvd) {
599 BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID);
600 }
601 }
602
OnServiceSearchComplete(uint16_t conn_id,tGATT_STATUS status)603 void OnServiceSearchComplete(uint16_t conn_id, tGATT_STATUS status) {
604 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
605 if (!hearingDevice) {
606 DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
607 return;
608 }
609
610 // Known device, nothing to do.
611 if (!hearingDevice->first_connection) return;
612
613 if (status != GATT_SUCCESS) {
614 /* close connection and report service discovery complete with error */
615 LOG(ERROR) << "Service discovery failed";
616 if (hearingDevice->first_connection) {
617 callbacks->OnConnectionState(ConnectionState::DISCONNECTED,
618 hearingDevice->address);
619 }
620 return;
621 }
622
623 const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
624
625 const gatt::Service* service = nullptr;
626 for (const gatt::Service& tmp : *services) {
627 if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) {
628 LOG(INFO) << "Found UUID_SERVCLASS_GATT_SERVER, handle="
629 << loghex(tmp.handle);
630 const gatt::Service* service_changed_service = &tmp;
631 find_server_changed_ccc_handle(conn_id, service_changed_service);
632 } else if (tmp.uuid == HEARING_AID_UUID) {
633 LOG(INFO) << "Found Hearing Aid service, handle=" << loghex(tmp.handle);
634 service = &tmp;
635 }
636 }
637
638 if (!service) {
639 LOG(ERROR) << "No Hearing Aid service found";
640 callbacks->OnConnectionState(ConnectionState::DISCONNECTED,
641 hearingDevice->address);
642 return;
643 }
644
645 for (const gatt::Characteristic& charac : service->characteristics) {
646 if (charac.uuid == READ_ONLY_PROPERTIES_UUID) {
647 if (!btif_storage_get_hearing_aid_prop(
648 hearingDevice->address, &hearingDevice->capabilities,
649 &hearingDevice->hi_sync_id, &hearingDevice->render_delay,
650 &hearingDevice->preparation_delay, &hearingDevice->codecs)) {
651 VLOG(2) << "Reading read only properties "
652 << loghex(charac.value_handle);
653 BtaGattQueue::ReadCharacteristic(
654 conn_id, charac.value_handle,
655 HearingAidImpl::OnReadOnlyPropertiesReadStatic, nullptr);
656 }
657 } else if (charac.uuid == AUDIO_CONTROL_POINT_UUID) {
658 hearingDevice->audio_control_point_handle = charac.value_handle;
659 // store audio control point!
660 } else if (charac.uuid == AUDIO_STATUS_UUID) {
661 hearingDevice->audio_status_handle = charac.value_handle;
662
663 hearingDevice->audio_status_ccc_handle =
664 find_ccc_handle(conn_id, charac.value_handle);
665 if (!hearingDevice->audio_status_ccc_handle) {
666 LOG(ERROR) << __func__ << ": cannot find Audio Status CCC descriptor";
667 continue;
668 }
669
670 LOG(INFO) << __func__
671 << ": audio_status_handle=" << loghex(charac.value_handle)
672 << ", ccc=" << loghex(hearingDevice->audio_status_ccc_handle);
673 } else if (charac.uuid == VOLUME_UUID) {
674 hearingDevice->volume_handle = charac.value_handle;
675 } else if (charac.uuid == LE_PSM_UUID) {
676 hearingDevice->read_psm_handle = charac.value_handle;
677 } else {
678 LOG(WARNING) << "Unknown characteristic found:" << charac.uuid;
679 }
680 }
681
682 if (hearingDevice->service_changed_rcvd) {
683 hearingDevice->service_changed_rcvd = false;
684 }
685
686 ReadPSM(hearingDevice);
687 }
688
ReadPSM(HearingDevice * hearingDevice)689 void ReadPSM(HearingDevice* hearingDevice) {
690 if (hearingDevice->read_psm_handle) {
691 LOG(INFO) << "Reading PSM " << loghex(hearingDevice->read_psm_handle)
692 << ", device=" << hearingDevice->address;
693 BtaGattQueue::ReadCharacteristic(
694 hearingDevice->conn_id, hearingDevice->read_psm_handle,
695 HearingAidImpl::OnPsmReadStatic, nullptr);
696 }
697 }
698
OnNotificationEvent(uint16_t conn_id,uint16_t handle,uint16_t len,uint8_t * value)699 void OnNotificationEvent(uint16_t conn_id, uint16_t handle, uint16_t len,
700 uint8_t* value) {
701 HearingDevice* device = hearingDevices.FindByConnId(conn_id);
702 if (!device) {
703 LOG(INFO) << __func__
704 << ": Skipping unknown device, conn_id=" << loghex(conn_id);
705 return;
706 }
707
708 if (device->audio_status_handle != handle) {
709 LOG(INFO) << __func__ << ": Mismatched handle, "
710 << loghex(device->audio_status_handle)
711 << "!=" << loghex(handle);
712 return;
713 }
714
715 if (len < 1) {
716 LOG(ERROR) << __func__ << ": Data Length too small, len=" << len
717 << ", expecting at least 1";
718 return;
719 }
720
721 if (value[0] != 0) {
722 LOG(INFO) << __func__
723 << ": Invalid returned status. data=" << loghex(value[0]);
724 return;
725 }
726
727 LOG(INFO) << __func__
728 << ": audio status success notification. command_acked="
729 << device->command_acked;
730 device->command_acked = true;
731 }
732
OnReadOnlyPropertiesRead(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)733 void OnReadOnlyPropertiesRead(uint16_t conn_id, tGATT_STATUS status,
734 uint16_t handle, uint16_t len, uint8_t* value,
735 void* data) {
736 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
737 if (!hearingDevice) {
738 DVLOG(2) << __func__ << "unknown conn_id=" << loghex(conn_id);
739 return;
740 }
741
742 VLOG(2) << __func__ << " " << base::HexEncode(value, len);
743
744 uint8_t* p = value;
745
746 uint8_t version;
747 STREAM_TO_UINT8(version, p);
748
749 if (version != 0x01) {
750 LOG(WARNING) << "Unknown version: " << loghex(version);
751 return;
752 }
753
754 // version 0x01 of read only properties:
755 if (len < 17) {
756 LOG(WARNING) << "Read only properties too short: " << loghex(len);
757 return;
758 }
759 uint8_t capabilities;
760 STREAM_TO_UINT8(capabilities, p);
761 hearingDevice->capabilities = capabilities;
762 bool side = capabilities & CAPABILITY_SIDE;
763 bool standalone = capabilities & CAPABILITY_BINAURAL;
764 VLOG(2) << __func__ << " capabilities: " << (side ? "right" : "left")
765 << ", " << (standalone ? "binaural" : "monaural");
766
767 if (capabilities & CAPABILITY_RESERVED) {
768 LOG(WARNING) << __func__ << " reserved capabilities are set";
769 }
770
771 STREAM_TO_UINT64(hearingDevice->hi_sync_id, p);
772 VLOG(2) << __func__ << " hiSyncId: " << loghex(hearingDevice->hi_sync_id);
773 uint8_t feature_map;
774 STREAM_TO_UINT8(feature_map, p);
775
776 STREAM_TO_UINT16(hearingDevice->render_delay, p);
777 VLOG(2) << __func__
778 << " render delay: " << loghex(hearingDevice->render_delay);
779
780 STREAM_TO_UINT16(hearingDevice->preparation_delay, p);
781 VLOG(2) << __func__ << " preparation delay: "
782 << loghex(hearingDevice->preparation_delay);
783
784 uint16_t codecs;
785 STREAM_TO_UINT16(codecs, p);
786 hearingDevice->codecs = codecs;
787 VLOG(2) << __func__ << " supported codecs: " << loghex(codecs);
788 if (codecs & (1 << CODEC_G722_16KHZ)) VLOG(2) << "\tG722@16kHz";
789 if (codecs & (1 << CODEC_G722_24KHZ)) VLOG(2) << "\tG722@24kHz";
790
791 if (!(codecs & (1 << CODEC_G722_16KHZ))) {
792 LOG(WARNING) << __func__ << " Mandatory codec, G722@16kHz not supported";
793 }
794 }
795
CalcCompressedAudioPacketSize(uint16_t codec_type,int connection_interval)796 uint16_t CalcCompressedAudioPacketSize(uint16_t codec_type,
797 int connection_interval) {
798 int sample_rate;
799
800 const int sample_bit_rate = 16; /* 16 bits per sample */
801 const int compression_ratio = 4; /* G.722 has a 4:1 compression ratio */
802 if (codec_type == CODEC_G722_24KHZ) {
803 sample_rate = 24000;
804 } else {
805 sample_rate = 16000;
806 }
807
808 // compressed_data_packet_size is the size in bytes of the compressed audio
809 // data buffer that is generated for each connection interval.
810 uint32_t compressed_data_packet_size =
811 (sample_rate * connection_interval * (sample_bit_rate / 8) /
812 compression_ratio) /
813 1000;
814 return ((uint16_t)compressed_data_packet_size);
815 }
816
ChooseCodec(const HearingDevice & hearingDevice)817 void ChooseCodec(const HearingDevice& hearingDevice) {
818 if (codec_in_use) return;
819
820 // use the best codec available for this pair of devices.
821 uint16_t codecs = hearingDevice.codecs;
822 if (hearingDevice.hi_sync_id != 0) {
823 for (const auto& device : hearingDevices.devices) {
824 if (device.hi_sync_id != hearingDevice.hi_sync_id) continue;
825
826 codecs &= device.codecs;
827 }
828 }
829
830 if ((codecs & (1 << CODEC_G722_24KHZ)) &&
831 controller_get_interface()->supports_ble_2m_phy() &&
832 default_data_interval_ms == HA_INTERVAL_10_MS) {
833 codec_in_use = CODEC_G722_24KHZ;
834 } else if (codecs & (1 << CODEC_G722_16KHZ)) {
835 codec_in_use = CODEC_G722_16KHZ;
836 }
837 }
838
OnAudioStatus(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)839 void OnAudioStatus(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
840 uint16_t len, uint8_t* value, void* data) {
841 LOG(INFO) << __func__ << " " << base::HexEncode(value, len);
842 }
843
OnPsmRead(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)844 void OnPsmRead(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
845 uint16_t len, uint8_t* value, void* data) {
846 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
847 if (!hearingDevice) {
848 DVLOG(2) << "Skipping unknown read event, conn_id=" << loghex(conn_id);
849 return;
850 }
851
852 if (status != GATT_SUCCESS) {
853 LOG(ERROR) << "Error reading PSM for device" << hearingDevice->address;
854 return;
855 }
856
857 if (len > 2) {
858 LOG(ERROR) << "Bad PSM length";
859 return;
860 }
861
862 uint16_t psm = *((uint16_t*)value);
863 VLOG(2) << "read psm:" << loghex(psm);
864
865 ConnectSocket(hearingDevice, psm);
866 }
867
ConnectSocket(HearingDevice * hearingDevice,uint16_t psm)868 void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) {
869 tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512};
870
871 SendEnableServiceChangedInd(hearingDevice);
872
873 uint8_t service_id = hearingDevice->isLeft()
874 ? BTM_SEC_SERVICE_HEARING_AID_LEFT
875 : BTM_SEC_SERVICE_HEARING_AID_RIGHT;
876 uint16_t gap_handle = GAP_ConnOpen(
877 "", service_id, false, &hearingDevice->address, psm, 514 /* MPS */,
878 &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */,
879 HearingAidImpl::GapCallbackStatic, BT_TRANSPORT_LE);
880 if (gap_handle == GAP_INVALID_HANDLE) {
881 LOG(ERROR) << "UNABLE TO GET gap_handle";
882 return;
883 }
884
885 hearingDevice->gap_handle = gap_handle;
886 LOG(INFO) << "Successfully sent GAP connect request";
887 }
888
OnReadOnlyPropertiesReadStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)889 static void OnReadOnlyPropertiesReadStatic(uint16_t conn_id,
890 tGATT_STATUS status,
891 uint16_t handle, uint16_t len,
892 uint8_t* value, void* data) {
893 if (instance)
894 instance->OnReadOnlyPropertiesRead(conn_id, status, handle, len, value,
895 data);
896 }
OnAudioStatusStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)897 static void OnAudioStatusStatic(uint16_t conn_id, tGATT_STATUS status,
898 uint16_t handle, uint16_t len, uint8_t* value,
899 void* data) {
900 if (instance)
901 instance->OnAudioStatus(conn_id, status, handle, len, value, data);
902 }
903
OnPsmReadStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)904 static void OnPsmReadStatic(uint16_t conn_id, tGATT_STATUS status,
905 uint16_t handle, uint16_t len, uint8_t* value,
906 void* data) {
907 if (instance)
908 instance->OnPsmRead(conn_id, status, handle, len, value, data);
909 }
910
911 /* CoC Socket is ready */
OnGapConnection(const RawAddress & address)912 void OnGapConnection(const RawAddress& address) {
913 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
914 if (!hearingDevice) {
915 LOG(INFO) << "Device not connected to profile" << address;
916 return;
917 }
918
919 if (hearingDevice->first_connection) {
920 btif_storage_add_hearing_aid(*hearingDevice);
921
922 hearingDevice->first_connection = false;
923 }
924
925 LOG(INFO) << __func__ << ": audio_status_handle="
926 << loghex(hearingDevice->audio_status_handle)
927 << ", audio_status_ccc_handle="
928 << loghex(hearingDevice->audio_status_ccc_handle);
929
930 /* Register and enable the Audio Status Notification */
931 tGATT_STATUS register_status;
932 register_status = BTA_GATTC_RegisterForNotifications(
933 gatt_if, address, hearingDevice->audio_status_handle);
934 if (register_status != GATT_SUCCESS) {
935 LOG(ERROR) << __func__
936 << ": BTA_GATTC_RegisterForNotifications failed, status="
937 << loghex(static_cast<uint8_t>(register_status));
938 return;
939 }
940 std::vector<uint8_t> value(2);
941 uint8_t* ptr = value.data();
942 UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
943 BtaGattQueue::WriteDescriptor(
944 hearingDevice->conn_id, hearingDevice->audio_status_ccc_handle,
945 std::move(value), GATT_WRITE, write_rpt_ctl_cfg_cb, nullptr);
946
947 ChooseCodec(*hearingDevice);
948
949 SendStart(hearingDevice);
950
951 if (audio_running) {
952 // Inform the other side (if any) of this connection
953 std::vector<uint8_t> inform_conn_state(
954 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_CONNECTED});
955 send_state_change_to_other_side(hearingDevice, inform_conn_state);
956 }
957
958 hearingDevice->accepting_audio = true;
959 LOG(INFO) << __func__ << ": address=" << address
960 << ", hi_sync_id=" << loghex(hearingDevice->hi_sync_id)
961 << ", codec_in_use=" << loghex(codec_in_use)
962 << ", audio_running=" << audio_running;
963
964 StartSendingAudio(*hearingDevice);
965
966 callbacks->OnDeviceAvailable(hearingDevice->capabilities,
967 hearingDevice->hi_sync_id, address);
968 callbacks->OnConnectionState(ConnectionState::CONNECTED, address);
969 }
970
StartSendingAudio(const HearingDevice & hearingDevice)971 void StartSendingAudio(const HearingDevice& hearingDevice) {
972 VLOG(0) << __func__ << ": device=" << hearingDevice.address;
973
974 if (encoder_state_left == nullptr) {
975 encoder_state_init();
976 seq_counter = 0;
977
978 // use the best codec avaliable for this pair of devices.
979 uint16_t codecs = hearingDevice.codecs;
980 if (hearingDevice.hi_sync_id != 0) {
981 for (const auto& device : hearingDevices.devices) {
982 if (device.hi_sync_id != hearingDevice.hi_sync_id) continue;
983
984 codecs &= device.codecs;
985 }
986 }
987
988 CodecConfiguration codec;
989 if (codec_in_use == CODEC_G722_24KHZ) {
990 codec.sample_rate = 24000;
991 } else {
992 codec.sample_rate = 16000;
993 }
994 codec.bit_rate = 16;
995 codec.data_interval_ms = default_data_interval_ms;
996
997 uint16_t delay_report_ms = 0;
998 if (hearingDevice.render_delay != 0) {
999 delay_report_ms =
1000 hearingDevice.render_delay +
1001 (ADD_RENDER_DELAY_INTERVALS * default_data_interval_ms);
1002 }
1003
1004 HearingAidAudioSource::Start(codec, audioReceiver, delay_report_ms);
1005 }
1006 }
1007
OnAudioSuspend(const std::function<void ()> & stop_audio_ticks)1008 void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) {
1009 CHECK(stop_audio_ticks) << "stop_audio_ticks is empty";
1010
1011 if (!audio_running) {
1012 LOG(WARNING) << __func__ << ": Unexpected audio suspend";
1013 } else {
1014 LOG(INFO) << __func__ << ": audio_running=" << audio_running;
1015 }
1016 audio_running = false;
1017 stop_audio_ticks();
1018
1019 std::vector<uint8_t> stop({CONTROL_POINT_OP_STOP});
1020 for (auto& device : hearingDevices.devices) {
1021 if (!device.accepting_audio) continue;
1022
1023 if (!device.playback_started) {
1024 LOG(WARNING) << __func__
1025 << ": Playback not started, skip send Stop cmd, device="
1026 << device.address;
1027 } else {
1028 LOG(INFO) << __func__ << ": send Stop cmd, device=" << device.address;
1029 device.playback_started = false;
1030 device.command_acked = false;
1031 BtaGattQueue::WriteCharacteristic(device.conn_id,
1032 device.audio_control_point_handle,
1033 stop, GATT_WRITE, nullptr, nullptr);
1034 }
1035 }
1036 }
1037
OnAudioResume(const std::function<void ()> & start_audio_ticks)1038 void OnAudioResume(const std::function<void()>& start_audio_ticks) {
1039 CHECK(start_audio_ticks) << "start_audio_ticks is empty";
1040
1041 if (audio_running) {
1042 LOG(ERROR) << __func__ << ": Unexpected Audio Resume";
1043 } else {
1044 LOG(INFO) << __func__ << ": audio_running=" << audio_running;
1045 }
1046
1047 for (auto& device : hearingDevices.devices) {
1048 if (!device.accepting_audio) continue;
1049 audio_running = true;
1050 SendStart(&device);
1051 }
1052
1053 if (!audio_running) {
1054 LOG(INFO) << __func__ << ": No device (0/" << GetDeviceCount()
1055 << ") ready to start";
1056 return;
1057 }
1058
1059 // TODO: shall we also reset the encoder ?
1060 encoder_state_release();
1061 encoder_state_init();
1062 seq_counter = 0;
1063
1064 start_audio_ticks();
1065 }
1066
GetOtherSideStreamStatus(HearingDevice * this_side_device)1067 uint8_t GetOtherSideStreamStatus(HearingDevice* this_side_device) {
1068 for (auto& device : hearingDevices.devices) {
1069 if ((device.address == this_side_device->address) ||
1070 (device.hi_sync_id != this_side_device->hi_sync_id)) {
1071 continue;
1072 }
1073 if (audio_running && (device.conn_id != 0)) {
1074 return (OTHER_SIDE_IS_STREAMING);
1075 } else {
1076 return (OTHER_SIDE_NOT_STREAMING);
1077 }
1078 }
1079 return (OTHER_SIDE_NOT_STREAMING);
1080 }
1081
SendEnableServiceChangedInd(HearingDevice * device)1082 void SendEnableServiceChangedInd(HearingDevice* device) {
1083 VLOG(2) << __func__ << " Enable " << device->address
1084 << "service changed ind.";
1085 std::vector<uint8_t> value(2);
1086 uint8_t* ptr = value.data();
1087 UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION);
1088 BtaGattQueue::WriteDescriptor(
1089 device->conn_id, device->service_changed_ccc_handle, std::move(value),
1090 GATT_WRITE, nullptr, nullptr);
1091 }
1092
SendStart(HearingDevice * device)1093 void SendStart(HearingDevice* device) {
1094 std::vector<uint8_t> start({CONTROL_POINT_OP_START, codec_in_use,
1095 AUDIOTYPE_UNKNOWN, (uint8_t)current_volume,
1096 OTHER_SIDE_NOT_STREAMING});
1097
1098 if (!audio_running) {
1099 if (!device->playback_started) {
1100 LOG(INFO) << __func__
1101 << ": Skip Send Start since audio is not running, device="
1102 << device->address;
1103 } else {
1104 LOG(ERROR) << __func__
1105 << ": Audio not running but Playback has started, device="
1106 << device->address;
1107 }
1108 return;
1109 }
1110
1111 if (current_volume == VOLUME_UNKNOWN) start[3] = (uint8_t)VOLUME_MIN;
1112
1113 if (device->playback_started) {
1114 LOG(ERROR) << __func__
1115 << ": Playback already started, skip send Start cmd, device="
1116 << device->address;
1117 } else {
1118 start[4] = GetOtherSideStreamStatus(device);
1119 LOG(INFO) << __func__ << ": send Start cmd, volume=" << loghex(start[3])
1120 << ", audio type=" << loghex(start[2])
1121 << ", device=" << device->address
1122 << ", other side streaming=" << loghex(start[4]);
1123 device->command_acked = false;
1124 BtaGattQueue::WriteCharacteristic(
1125 device->conn_id, device->audio_control_point_handle, start,
1126 GATT_WRITE, HearingAidImpl::StartAudioCtrlCallbackStatic, nullptr);
1127 }
1128 }
1129
StartAudioCtrlCallbackStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,void * data)1130 static void StartAudioCtrlCallbackStatic(uint16_t conn_id,
1131 tGATT_STATUS status, uint16_t handle,
1132 void* data) {
1133 if (status != GATT_SUCCESS) {
1134 LOG(ERROR) << __func__ << ": handle=" << handle << ", conn_id=" << conn_id
1135 << ", status=" << loghex(static_cast<uint8_t>(status));
1136 return;
1137 }
1138 if (!instance) {
1139 LOG(ERROR) << __func__ << ": instance is null.";
1140 return;
1141 }
1142 instance->StartAudioCtrlCallback(conn_id);
1143 }
1144
StartAudioCtrlCallback(uint16_t conn_id)1145 void StartAudioCtrlCallback(uint16_t conn_id) {
1146 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1147 if (!hearingDevice) {
1148 LOG(ERROR) << "Skipping unknown device, conn_id=" << loghex(conn_id);
1149 return;
1150 }
1151 LOG(INFO) << __func__ << ": device: " << hearingDevice->address;
1152 hearingDevice->playback_started = true;
1153 }
1154
OnAudioDataReady(const std::vector<uint8_t> & data)1155 void OnAudioDataReady(const std::vector<uint8_t>& data) {
1156 /* For now we assume data comes in as 16bit per sample 16kHz PCM stereo */
1157 DVLOG(2) << __func__;
1158
1159 int num_samples =
1160 data.size() / (2 /*bytes_per_sample*/ * 2 /*number of channels*/);
1161
1162 // The G.722 codec accept only even number of samples for encoding
1163 if (num_samples % 2 != 0)
1164 LOG(FATAL) << "num_samples is not even: " << num_samples;
1165
1166 // TODO: we should cache left/right and current state, instad of recomputing
1167 // it for each packet, 100 times a second.
1168 HearingDevice* left = nullptr;
1169 HearingDevice* right = nullptr;
1170 for (auto& device : hearingDevices.devices) {
1171 if (!device.accepting_audio) continue;
1172
1173 if (device.isLeft())
1174 left = &device;
1175 else
1176 right = &device;
1177 }
1178
1179 if (left == nullptr && right == nullptr) {
1180 LOG(WARNING) << __func__ << ": No more (0/" << GetDeviceCount()
1181 << ") devices ready";
1182 DoDisconnectAudioStop();
1183 return;
1184 }
1185
1186 std::vector<uint16_t> chan_left;
1187 std::vector<uint16_t> chan_right;
1188 if (left == nullptr || right == nullptr) {
1189 for (int i = 0; i < num_samples; i++) {
1190 const uint8_t* sample = data.data() + i * 4;
1191
1192 int16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1193
1194 sample += 2;
1195 int16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1196
1197 uint16_t mono_data = (int16_t)(((uint32_t)left + (uint32_t)right) >> 1);
1198 chan_left.push_back(mono_data);
1199 chan_right.push_back(mono_data);
1200 }
1201 } else {
1202 for (int i = 0; i < num_samples; i++) {
1203 const uint8_t* sample = data.data() + i * 4;
1204
1205 uint16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1206 chan_left.push_back(left);
1207
1208 sample += 2;
1209 uint16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1210 chan_right.push_back(right);
1211 }
1212 }
1213
1214 // TODO: monural, binarual check
1215
1216 // divide encoded data into packets, add header, send.
1217
1218 // TODO: make those buffers static and global to prevent constant
1219 // reallocations
1220 // TODO: this should basically fit the encoded data, tune the size later
1221 std::vector<uint8_t> encoded_data_left;
1222 if (left) {
1223 // TODO: instead of a magic number, we need to figure out the correct
1224 // buffer size
1225 encoded_data_left.resize(4000);
1226 int encoded_size =
1227 g722_encode(encoder_state_left, encoded_data_left.data(),
1228 (const int16_t*)chan_left.data(), chan_left.size());
1229 encoded_data_left.resize(encoded_size);
1230
1231 uint16_t cid = GAP_ConnGetL2CAPCid(left->gap_handle);
1232 uint16_t packets_to_flush = L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
1233 if (packets_to_flush) {
1234 VLOG(2) << left->address << " skipping " << packets_to_flush
1235 << " packets";
1236 left->audio_stats.packet_flush_count += packets_to_flush;
1237 left->audio_stats.frame_flush_count++;
1238 hearingDevices.StartRssiLog();
1239 }
1240 // flush all packets stuck in queue
1241 L2CA_FlushChannel(cid, 0xffff);
1242 check_and_do_rssi_read(left);
1243 }
1244
1245 std::vector<uint8_t> encoded_data_right;
1246 if (right) {
1247 // TODO: instead of a magic number, we need to figure out the correct
1248 // buffer size
1249 encoded_data_right.resize(4000);
1250 int encoded_size =
1251 g722_encode(encoder_state_right, encoded_data_right.data(),
1252 (const int16_t*)chan_right.data(), chan_right.size());
1253 encoded_data_right.resize(encoded_size);
1254
1255 uint16_t cid = GAP_ConnGetL2CAPCid(right->gap_handle);
1256 uint16_t packets_to_flush = L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
1257 if (packets_to_flush) {
1258 VLOG(2) << right->address << " skipping " << packets_to_flush
1259 << " packets";
1260 right->audio_stats.packet_flush_count += packets_to_flush;
1261 right->audio_stats.frame_flush_count++;
1262 hearingDevices.StartRssiLog();
1263 }
1264 // flush all packets stuck in queue
1265 L2CA_FlushChannel(cid, 0xffff);
1266 check_and_do_rssi_read(right);
1267 }
1268
1269 size_t encoded_data_size =
1270 std::max(encoded_data_left.size(), encoded_data_right.size());
1271
1272 uint16_t packet_size =
1273 CalcCompressedAudioPacketSize(codec_in_use, default_data_interval_ms);
1274
1275 for (size_t i = 0; i < encoded_data_size; i += packet_size) {
1276 if (left) {
1277 left->audio_stats.packet_send_count++;
1278 SendAudio(encoded_data_left.data() + i, packet_size, left);
1279 }
1280 if (right) {
1281 right->audio_stats.packet_send_count++;
1282 SendAudio(encoded_data_right.data() + i, packet_size, right);
1283 }
1284 seq_counter++;
1285 }
1286 if (left) left->audio_stats.frame_send_count++;
1287 if (right) right->audio_stats.frame_send_count++;
1288 }
1289
SendAudio(uint8_t * encoded_data,uint16_t packet_size,HearingDevice * hearingAid)1290 void SendAudio(uint8_t* encoded_data, uint16_t packet_size,
1291 HearingDevice* hearingAid) {
1292 if (!hearingAid->playback_started || !hearingAid->command_acked) {
1293 VLOG(2) << __func__
1294 << ": Playback stalled, device=" << hearingAid->address
1295 << ", cmd send=" << hearingAid->playback_started
1296 << ", cmd acked=" << hearingAid->command_acked;
1297 return;
1298 }
1299
1300 BT_HDR* audio_packet = malloc_l2cap_buf(packet_size + 1);
1301 uint8_t* p = get_l2cap_sdu_start_ptr(audio_packet);
1302 *p = seq_counter;
1303 p++;
1304 memcpy(p, encoded_data, packet_size);
1305
1306 DVLOG(2) << hearingAid->address << " : " << base::HexEncode(p, packet_size);
1307
1308 uint16_t result = GAP_ConnWriteData(hearingAid->gap_handle, audio_packet);
1309
1310 if (result != BT_PASS) {
1311 LOG(ERROR) << " Error sending data: " << loghex(result);
1312 }
1313 }
1314
GapCallback(uint16_t gap_handle,uint16_t event,tGAP_CB_DATA * data)1315 void GapCallback(uint16_t gap_handle, uint16_t event, tGAP_CB_DATA* data) {
1316 HearingDevice* hearingDevice = hearingDevices.FindByGapHandle(gap_handle);
1317 if (!hearingDevice) {
1318 LOG(INFO) << "Skipping unknown device, gap_handle=" << gap_handle;
1319 return;
1320 }
1321
1322 switch (event) {
1323 case GAP_EVT_CONN_OPENED: {
1324 RawAddress address = *GAP_ConnGetRemoteAddr(gap_handle);
1325 uint16_t tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
1326
1327 LOG(INFO) << "GAP_EVT_CONN_OPENED " << address << ", tx_mtu=" << tx_mtu;
1328 OnGapConnection(address);
1329 break;
1330 }
1331
1332 // TODO: handle properly!
1333 case GAP_EVT_CONN_CLOSED:
1334 LOG(INFO) << __func__
1335 << ": GAP_EVT_CONN_CLOSED: " << hearingDevice->address
1336 << ", playback_started=" << hearingDevice->playback_started;
1337 hearingDevice->accepting_audio = false;
1338 hearingDevice->gap_handle = 0;
1339 hearingDevice->playback_started = false;
1340 hearingDevice->command_acked = false;
1341 break;
1342 case GAP_EVT_CONN_DATA_AVAIL: {
1343 DVLOG(2) << "GAP_EVT_CONN_DATA_AVAIL";
1344
1345 // only data we receive back from hearing aids are some stats, not
1346 // really important, but useful now for debugging.
1347 uint32_t bytes_to_read = 0;
1348 GAP_GetRxQueueCnt(gap_handle, &bytes_to_read);
1349 std::vector<uint8_t> buffer(bytes_to_read);
1350
1351 uint16_t bytes_read = 0;
1352 // TODO:GAP_ConnReadData should accpet uint32_t for length!
1353 GAP_ConnReadData(gap_handle, buffer.data(), buffer.size(), &bytes_read);
1354
1355 if (bytes_read < 4) {
1356 LOG(WARNING) << " Wrong data length";
1357 return;
1358 }
1359
1360 uint8_t* p = buffer.data();
1361
1362 DVLOG(1) << "stats from the hearing aid:";
1363 for (size_t i = 0; i + 4 <= buffer.size(); i += 4) {
1364 uint16_t event_counter, frame_index;
1365 STREAM_TO_UINT16(event_counter, p);
1366 STREAM_TO_UINT16(frame_index, p);
1367 DVLOG(1) << "event_counter=" << event_counter
1368 << " frame_index: " << frame_index;
1369 }
1370 break;
1371 }
1372
1373 case GAP_EVT_TX_EMPTY:
1374 DVLOG(2) << "GAP_EVT_TX_EMPTY";
1375 break;
1376 case GAP_EVT_CONN_CONGESTED:
1377 DVLOG(2) << "GAP_EVT_CONN_CONGESTED";
1378
1379 // TODO: make it into function
1380 HearingAidAudioSource::Stop();
1381 // TODO: kill the encoder only if all hearing aids are down.
1382 // g722_encode_release(encoder_state);
1383 // encoder_state_left = nulllptr;
1384 // encoder_state_right = nulllptr;
1385 break;
1386 case GAP_EVT_CONN_UNCONGESTED:
1387 DVLOG(2) << "GAP_EVT_CONN_UNCONGESTED";
1388 break;
1389 }
1390 }
1391
GapCallbackStatic(uint16_t gap_handle,uint16_t event,tGAP_CB_DATA * data)1392 static void GapCallbackStatic(uint16_t gap_handle, uint16_t event,
1393 tGAP_CB_DATA* data) {
1394 if (instance) instance->GapCallback(gap_handle, event, data);
1395 }
1396
DumpRssi(int fd,const HearingDevice & device)1397 void DumpRssi(int fd, const HearingDevice& device) {
1398 const struct AudioStats* stats = &device.audio_stats;
1399
1400 if (stats->rssi_history.size() <= 0) {
1401 dprintf(fd, " No RSSI history for %s:\n", device.address.ToString().c_str());
1402 return;
1403 }
1404 dprintf(fd, " RSSI history for %s:\n", device.address.ToString().c_str());
1405
1406 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");
1407 for (auto& rssi_logs : stats->rssi_history) {
1408 if (rssi_logs.rssi.size() <= 0) {
1409 break;
1410 }
1411
1412 char eventtime[20];
1413 char temptime[20];
1414 struct tm* tstamp = localtime(&rssi_logs.timestamp.tv_sec);
1415 if (!strftime(temptime, sizeof(temptime), "%H:%M:%S", tstamp)) {
1416 LOG(ERROR) << __func__ << ": strftime fails. tm_sec=" << tstamp->tm_sec << ", tm_min=" << tstamp->tm_min
1417 << ", tm_hour=" << tstamp->tm_hour;
1418 strlcpy(temptime, "UNKNOWN TIME", sizeof(temptime));
1419 }
1420 snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime, rssi_logs.timestamp.tv_nsec / 1000000);
1421
1422 dprintf(fd, " %s: ", eventtime);
1423
1424 for (auto rssi_value : rssi_logs.rssi) {
1425 dprintf(fd, " %04d", rssi_value);
1426 }
1427 dprintf(fd, "\n");
1428 }
1429 }
1430
Dump(int fd)1431 void Dump(int fd) {
1432 std::stringstream stream;
1433 for (const auto& device : hearingDevices.devices) {
1434 bool side = device.capabilities & CAPABILITY_SIDE;
1435 bool standalone = device.capabilities & CAPABILITY_BINAURAL;
1436 stream << " " << device.address.ToString() << " "
1437 << (device.accepting_audio ? "" : "not ") << "connected"
1438 << "\n " << (standalone ? "binaural" : "monaural") << " "
1439 << (side ? "right" : "left") << " " << loghex(device.hi_sync_id)
1440 << std::endl;
1441 stream
1442 << " Packet counts (enqueued/flushed) : "
1443 << device.audio_stats.packet_send_count << " / "
1444 << device.audio_stats.packet_flush_count
1445 << "\n Frame counts (enqueued/flushed) : "
1446 << device.audio_stats.frame_send_count << " / "
1447 << device.audio_stats.frame_flush_count << std::endl;
1448
1449 DumpRssi(fd, device);
1450 }
1451 dprintf(fd, "%s", stream.str().c_str());
1452 }
1453
Disconnect(const RawAddress & address)1454 void Disconnect(const RawAddress& address) override {
1455 DVLOG(2) << __func__;
1456 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
1457 if (!hearingDevice) {
1458 LOG(INFO) << "Device not connected to profile" << address;
1459 return;
1460 }
1461
1462 VLOG(2) << __func__ << ": " << address;
1463
1464 bool connected = hearingDevice->accepting_audio;
1465
1466 LOG(INFO) << "GAP_EVT_CONN_CLOSED: " << hearingDevice->address
1467 << ", playback_started=" << hearingDevice->playback_started
1468 << ", accepting_audio=" << hearingDevice->accepting_audio;
1469
1470 if (hearingDevice->connecting_actively) {
1471 // cancel pending direct connect
1472 BTA_GATTC_CancelOpen(gatt_if, address, true);
1473 }
1474
1475 // Removes all registrations for connection.
1476 BTA_GATTC_CancelOpen(0, address, false);
1477
1478 // Inform the other side (if any) of this disconnection
1479 std::vector<uint8_t> inform_disconn_state(
1480 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
1481 send_state_change_to_other_side(hearingDevice, inform_disconn_state);
1482
1483 DoDisconnectCleanUp(hearingDevice);
1484
1485 hearingDevices.Remove(address);
1486
1487 if (!connected) {
1488 return;
1489 }
1490
1491 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
1492 for (const auto& device : hearingDevices.devices) {
1493 if (device.accepting_audio) return;
1494 }
1495 LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount()
1496 << ") devices ready";
1497 DoDisconnectAudioStop();
1498 }
1499
OnGattDisconnected(uint16_t conn_id,tGATT_IF client_if,RawAddress remote_bda)1500 void OnGattDisconnected(uint16_t conn_id, tGATT_IF client_if,
1501 RawAddress remote_bda) {
1502 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1503 if (!hearingDevice) {
1504 VLOG(2) << "Skipping unknown device disconnect, conn_id="
1505 << loghex(conn_id);
1506 return;
1507 }
1508 VLOG(2) << __func__ << ": conn_id=" << loghex(conn_id)
1509 << ", remote_bda=" << remote_bda;
1510
1511 // Inform the other side (if any) of this disconnection
1512 std::vector<uint8_t> inform_disconn_state(
1513 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
1514 send_state_change_to_other_side(hearingDevice, inform_disconn_state);
1515
1516 DoDisconnectCleanUp(hearingDevice);
1517
1518 // This is needed just for the first connection. After stack is restarted,
1519 // code that loads device will add them to acceptlist.
1520 BTA_GATTC_Open(gatt_if, hearingDevice->address, false, false);
1521
1522 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, remote_bda);
1523
1524 for (const auto& device : hearingDevices.devices) {
1525 if (device.accepting_audio) return;
1526 }
1527 LOG(INFO) << __func__ << ": No more (0/" << GetDeviceCount()
1528 << ") devices ready";
1529 DoDisconnectAudioStop();
1530 }
1531
DoDisconnectCleanUp(HearingDevice * hearingDevice)1532 void DoDisconnectCleanUp(HearingDevice* hearingDevice) {
1533 if (hearingDevice->connection_update_status != COMPLETED) {
1534 LOG(INFO) << __func__ << ": connection update not completed. Current="
1535 << hearingDevice->connection_update_status
1536 << ", device=" << hearingDevice->address;
1537
1538 if (hearingDevice->connection_update_status == STARTED) {
1539 OnConnectionUpdateComplete(hearingDevice->conn_id, NULL);
1540 }
1541 }
1542 hearingDevice->connection_update_status = NONE;
1543
1544 if (hearingDevice->conn_id) {
1545 BtaGattQueue::Clean(hearingDevice->conn_id);
1546 BTA_GATTC_Close(hearingDevice->conn_id);
1547 hearingDevice->conn_id = 0;
1548 }
1549
1550 if (hearingDevice->gap_handle) {
1551 GAP_ConnClose(hearingDevice->gap_handle);
1552 hearingDevice->gap_handle = 0;
1553 }
1554
1555 hearingDevice->accepting_audio = false;
1556 LOG(INFO) << __func__ << ": device=" << hearingDevice->address
1557 << ", playback_started=" << hearingDevice->playback_started;
1558 hearingDevice->playback_started = false;
1559 hearingDevice->command_acked = false;
1560 }
1561
DoDisconnectAudioStop()1562 void DoDisconnectAudioStop() {
1563 HearingAidAudioSource::Stop();
1564 audio_running = false;
1565 encoder_state_release();
1566 current_volume = VOLUME_UNKNOWN;
1567 }
1568
SetVolume(int8_t volume)1569 void SetVolume(int8_t volume) override {
1570 VLOG(2) << __func__ << ": " << +volume;
1571 current_volume = volume;
1572 for (HearingDevice& device : hearingDevices.devices) {
1573 if (!device.accepting_audio) continue;
1574
1575 std::vector<uint8_t> volume_value({static_cast<unsigned char>(volume)});
1576 BtaGattQueue::WriteCharacteristic(device.conn_id, device.volume_handle,
1577 volume_value, GATT_WRITE_NO_RSP,
1578 nullptr, nullptr);
1579 }
1580 }
1581
CleanUp()1582 void CleanUp() {
1583 BTA_GATTC_AppDeregister(gatt_if);
1584 for (HearingDevice& device : hearingDevices.devices) {
1585 DoDisconnectCleanUp(&device);
1586 }
1587
1588 hearingDevices.devices.clear();
1589
1590 encoder_state_release();
1591 }
1592
1593 private:
1594 uint8_t gatt_if;
1595 uint8_t seq_counter;
1596 /* current volume gain for the hearing aids*/
1597 int8_t current_volume;
1598 bluetooth::hearing_aid::HearingAidCallbacks* callbacks;
1599
1600 /* currently used codec */
1601 uint8_t codec_in_use;
1602
1603 uint16_t default_data_interval_ms;
1604
1605 HearingDevices hearingDevices;
1606
find_server_changed_ccc_handle(uint16_t conn_id,const gatt::Service * service)1607 void find_server_changed_ccc_handle(uint16_t conn_id,
1608 const gatt::Service* service) {
1609 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1610 if (!hearingDevice) {
1611 DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
1612 return;
1613 }
1614 for (const gatt::Characteristic& charac : service->characteristics) {
1615 if (charac.uuid == Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD)) {
1616 hearingDevice->service_changed_ccc_handle =
1617 find_ccc_handle(conn_id, charac.value_handle);
1618 if (!hearingDevice->service_changed_ccc_handle) {
1619 LOG(ERROR) << __func__
1620 << ": cannot find service changed CCC descriptor";
1621 continue;
1622 }
1623 LOG(INFO) << __func__ << " service_changed_ccc="
1624 << loghex(hearingDevice->service_changed_ccc_handle);
1625 break;
1626 }
1627 }
1628 }
1629
1630 // Find the handle for the client characteristics configuration of a given
1631 // characteristics
find_ccc_handle(uint16_t conn_id,uint16_t char_handle)1632 uint16_t find_ccc_handle(uint16_t conn_id, uint16_t char_handle) {
1633 const gatt::Characteristic* p_char =
1634 BTA_GATTC_GetCharacteristic(conn_id, char_handle);
1635
1636 if (!p_char) {
1637 LOG(WARNING) << __func__ << ": No such characteristic: " << char_handle;
1638 return 0;
1639 }
1640
1641 for (const gatt::Descriptor& desc : p_char->descriptors) {
1642 if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG))
1643 return desc.handle;
1644 }
1645
1646 return 0;
1647 }
1648
send_state_change(HearingDevice * device,std::vector<uint8_t> payload)1649 void send_state_change(HearingDevice* device, std::vector<uint8_t> payload) {
1650 if (device->conn_id != 0) {
1651 if (device->service_changed_rcvd) {
1652 LOG(INFO)
1653 << __func__
1654 << ": service discover is in progress, skip send State Change cmd.";
1655 return;
1656 }
1657 // Send the data packet
1658 LOG(INFO) << __func__ << ": Send State Change. device=" << device->address
1659 << ", status=" << loghex(payload[1]);
1660 BtaGattQueue::WriteCharacteristic(
1661 device->conn_id, device->audio_control_point_handle, payload,
1662 GATT_WRITE_NO_RSP, nullptr, nullptr);
1663 }
1664 }
1665
send_state_change_to_other_side(HearingDevice * this_side_device,std::vector<uint8_t> payload)1666 void send_state_change_to_other_side(HearingDevice* this_side_device,
1667 std::vector<uint8_t> payload) {
1668 for (auto& device : hearingDevices.devices) {
1669 if ((device.address == this_side_device->address) ||
1670 (device.hi_sync_id != this_side_device->hi_sync_id)) {
1671 continue;
1672 }
1673 send_state_change(&device, payload);
1674 }
1675 }
1676
check_and_do_rssi_read(HearingDevice * device)1677 void check_and_do_rssi_read(HearingDevice* device) {
1678 if (device->read_rssi_count > 0) {
1679 device->num_intervals_since_last_rssi_read++;
1680 if (device->num_intervals_since_last_rssi_read >= PERIOD_TO_READ_RSSI_IN_INTERVALS) {
1681 device->num_intervals_since_last_rssi_read = 0;
1682 VLOG(1) << __func__ << ": device=" << device->address;
1683 BTM_ReadRSSI(device->address, read_rssi_cb);
1684 }
1685 }
1686 }
1687 };
1688
read_rssi_cb(void * p_void)1689 void read_rssi_cb(void* p_void) {
1690 tBTM_RSSI_RESULT* p_result = (tBTM_RSSI_RESULT*)p_void;
1691
1692 if (!p_result) return;
1693
1694 if ((instance) && (p_result->status == BTM_SUCCESS)) {
1695 instance->OnReadRssiComplete(p_result->rem_bda, p_result->rssi);
1696 }
1697 }
1698
hearingaid_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)1699 void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
1700 VLOG(2) << __func__ << " event = " << +event;
1701
1702 if (p_data == nullptr) return;
1703
1704 switch (event) {
1705 case BTA_GATTC_DEREG_EVT:
1706 break;
1707
1708 case BTA_GATTC_OPEN_EVT: {
1709 if (!instance) return;
1710 tBTA_GATTC_OPEN& o = p_data->open;
1711 instance->OnGattConnected(o.status, o.conn_id, o.client_if, o.remote_bda,
1712 o.transport, o.mtu);
1713 break;
1714 }
1715
1716 case BTA_GATTC_CLOSE_EVT: {
1717 if (!instance) return;
1718 tBTA_GATTC_CLOSE& c = p_data->close;
1719 instance->OnGattDisconnected(c.conn_id, c.client_if, c.remote_bda);
1720 } break;
1721
1722 case BTA_GATTC_SEARCH_CMPL_EVT:
1723 if (!instance) return;
1724 instance->OnServiceSearchComplete(p_data->search_cmpl.conn_id,
1725 p_data->search_cmpl.status);
1726 break;
1727
1728 case BTA_GATTC_NOTIF_EVT:
1729 if (!instance) return;
1730 if (!p_data->notify.is_notify || p_data->notify.len > GATT_MAX_ATTR_LEN) {
1731 LOG(ERROR) << __func__ << ": rejected BTA_GATTC_NOTIF_EVT. is_notify="
1732 << p_data->notify.is_notify
1733 << ", len=" << p_data->notify.len;
1734 break;
1735 }
1736 instance->OnNotificationEvent(p_data->notify.conn_id,
1737 p_data->notify.handle, p_data->notify.len,
1738 p_data->notify.value);
1739 break;
1740
1741 case BTA_GATTC_ENC_CMPL_CB_EVT:
1742 if (!instance) return;
1743 instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, true);
1744 break;
1745
1746 case BTA_GATTC_CONN_UPDATE_EVT:
1747 if (!instance) return;
1748 instance->OnConnectionUpdateComplete(p_data->conn_update.conn_id, p_data);
1749 break;
1750
1751 case BTA_GATTC_SRVC_CHG_EVT:
1752 if (!instance) return;
1753 instance->OnServiceChangeEvent(p_data->remote_bda);
1754 break;
1755
1756 case BTA_GATTC_SRVC_DISC_DONE_EVT:
1757 if (!instance) return;
1758 instance->OnServiceDiscDoneEvent(p_data->service_changed.remote_bda);
1759 break;
1760
1761 default:
1762 break;
1763 }
1764 }
1765
encryption_callback(const RawAddress * address,tBT_TRANSPORT,void *,tBTM_STATUS status)1766 void encryption_callback(const RawAddress* address, tBT_TRANSPORT, void*,
1767 tBTM_STATUS status) {
1768 if (instance) {
1769 instance->OnEncryptionComplete(*address,
1770 status == BTM_SUCCESS ? true : false);
1771 }
1772 }
1773
1774 class HearingAidAudioReceiverImpl : public HearingAidAudioReceiver {
1775 public:
OnAudioDataReady(const std::vector<uint8_t> & data)1776 void OnAudioDataReady(const std::vector<uint8_t>& data) override {
1777 if (instance) instance->OnAudioDataReady(data);
1778 }
OnAudioSuspend(const std::function<void ()> & stop_audio_ticks)1779 void OnAudioSuspend(const std::function<void()>& stop_audio_ticks) override {
1780 if (instance) instance->OnAudioSuspend(stop_audio_ticks);
1781 }
OnAudioResume(const std::function<void ()> & start_audio_ticks)1782 void OnAudioResume(const std::function<void()>& start_audio_ticks) override {
1783 if (instance) instance->OnAudioResume(start_audio_ticks);
1784 }
1785 };
1786
1787 HearingAidAudioReceiverImpl audioReceiverImpl;
1788
1789 } // namespace
1790
Initialize(bluetooth::hearing_aid::HearingAidCallbacks * callbacks,Closure initCb)1791 void HearingAid::Initialize(
1792 bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb) {
1793 if (instance) {
1794 LOG(ERROR) << "Already initialized!";
1795 }
1796
1797 audioReceiver = &audioReceiverImpl;
1798 instance = new HearingAidImpl(callbacks, initCb);
1799 HearingAidAudioSource::Initialize();
1800 }
1801
IsHearingAidRunning()1802 bool HearingAid::IsHearingAidRunning() { return instance; }
1803
Get()1804 HearingAid* HearingAid::Get() {
1805 CHECK(instance);
1806 return instance;
1807 };
1808
AddFromStorage(const HearingDevice & dev_info,uint16_t is_acceptlisted)1809 void HearingAid::AddFromStorage(const HearingDevice& dev_info,
1810 uint16_t is_acceptlisted) {
1811 if (!instance) {
1812 LOG(ERROR) << "Not initialized yet";
1813 }
1814
1815 instance->AddFromStorage(dev_info, is_acceptlisted);
1816 };
1817
GetDeviceCount()1818 int HearingAid::GetDeviceCount() {
1819 if (!instance) {
1820 LOG(INFO) << __func__ << ": Not initialized yet";
1821 return 0;
1822 }
1823
1824 return (instance->GetDeviceCount());
1825 }
1826
CleanUp()1827 void HearingAid::CleanUp() {
1828 // Must stop audio source to make sure it doesn't call any of callbacks on our
1829 // soon to be null instance
1830 HearingAidAudioSource::Stop();
1831
1832 HearingAidImpl* ptr = instance;
1833 instance = nullptr;
1834 HearingAidAudioSource::CleanUp();
1835
1836 ptr->CleanUp();
1837
1838 delete ptr;
1839 };
1840
DebugDump(int fd)1841 void HearingAid::DebugDump(int fd) {
1842 dprintf(fd, "Hearing Aid Manager:\n");
1843 if (instance) instance->Dump(fd);
1844 HearingAidAudioSource::DebugDump(fd);
1845 dprintf(fd, "\n");
1846 }
1847