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