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 virtual ~HearingAidImpl() = 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 // Set data length
394 // TODO(jpawlowski: for 16khz only 87 is required, optimize
395 BTM_SetBleDataLength(address, 167);
396
397 tBTM_SEC_DEV_REC* p_dev_rec = btm_find_dev(address);
398 if (p_dev_rec) {
399 if (p_dev_rec->sec_state == BTM_SEC_STATE_ENCRYPTING ||
400 p_dev_rec->sec_state == BTM_SEC_STATE_AUTHENTICATING) {
401 /* if security collision happened, wait for encryption done
402 * (BTA_GATTC_ENC_CMPL_CB_EVT) */
403 return;
404 }
405 }
406
407 /* verify bond */
408 uint8_t sec_flag = 0;
409 BTM_GetSecurityFlagsByTransport(address, &sec_flag, BT_TRANSPORT_LE);
410
411 if (sec_flag & BTM_SEC_FLAG_ENCRYPTED) {
412 /* if link has been encrypted */
413 OnEncryptionComplete(address, true);
414 return;
415 }
416
417 if (sec_flag & BTM_SEC_FLAG_LKEY_KNOWN) {
418 /* if bonded and link not encrypted */
419 sec_flag = BTM_BLE_SEC_ENCRYPT;
420 BTM_SetEncryption(address, BTA_TRANSPORT_LE, encryption_callback, nullptr,
421 sec_flag);
422 return;
423 }
424
425 /* otherwise let it go through */
426 OnEncryptionComplete(address, true);
427 }
428
OnConnectionUpdateComplete(uint16_t conn_id,tBTA_GATTC * p_data)429 void OnConnectionUpdateComplete(uint16_t conn_id, tBTA_GATTC* p_data) {
430 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
431 if (!hearingDevice) {
432 DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
433 return;
434 }
435
436 if (p_data) {
437 if (p_data->conn_update.status == 0) {
438 bool same_conn_interval =
439 (hearingDevice->requested_connection_interval ==
440 p_data->conn_update.interval);
441
442 switch (hearingDevice->connection_update_status) {
443 case COMPLETED:
444 if (!same_conn_interval) {
445 LOG(WARNING) << __func__
446 << ": Unexpected change. Redo. connection interval="
447 << p_data->conn_update.interval << ", expected="
448 << hearingDevice->requested_connection_interval
449 << ", conn_id=" << conn_id
450 << ", connection_update_status="
451 << hearingDevice->connection_update_status;
452 // Redo this connection interval change.
453 hearingDevice->connection_update_status = AWAITING;
454 }
455 break;
456 case STARTED:
457 if (same_conn_interval) {
458 LOG(INFO) << __func__
459 << ": Connection update completed. conn_id=" << conn_id
460 << ", device=" << hearingDevice->address;
461 hearingDevice->connection_update_status = COMPLETED;
462 } else {
463 LOG(WARNING) << __func__
464 << ": Ignored. Different connection interval="
465 << p_data->conn_update.interval << ", expected="
466 << hearingDevice->requested_connection_interval
467 << ", conn_id=" << conn_id
468 << ", connection_update_status="
469 << hearingDevice->connection_update_status;
470 // Wait for the right Connection Update Completion.
471 return;
472 }
473 break;
474 case AWAITING:
475 case NONE:
476 break;
477 }
478
479 // Inform this side and other side device (if any) of Connection
480 // Updates.
481 std::vector<uint8_t> conn_update(
482 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_CONN_UPDATE,
483 (uint8_t)p_data->conn_update.interval});
484 send_state_change_to_other_side(hearingDevice, conn_update);
485 send_state_change(hearingDevice, conn_update);
486 } else {
487 LOG(INFO) << __func__
488 << ": error status=" << loghex(p_data->conn_update.status)
489 << ", conn_id=" << conn_id
490 << ", device=" << hearingDevice->address
491 << ", connection_update_status="
492 << hearingDevice->connection_update_status;
493
494 if (hearingDevice->connection_update_status == STARTED) {
495 // Redo this connection interval change.
496 LOG(ERROR) << __func__ << ": Redo Connection Interval change";
497 hearingDevice->connection_update_status = AWAITING;
498 }
499 }
500 } else {
501 hearingDevice->connection_update_status = NONE;
502 }
503
504 for (auto& device : hearingDevices.devices) {
505 if (device.conn_id && (device.connection_update_status == AWAITING)) {
506 device.connection_update_status = STARTED;
507 device.requested_connection_interval =
508 UpdateBleConnParams(device.address);
509 return;
510 }
511 }
512 }
513
514 // Completion Callback for the RSSI read operation.
OnReadRssiComplete(const RawAddress & address,int8_t rssi_value)515 void OnReadRssiComplete(const RawAddress& address, int8_t rssi_value) {
516 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
517 if (!hearingDevice) {
518 LOG(INFO) << "Skipping unknown device" << address;
519 return;
520 }
521
522 VLOG(1) << __func__ << ": device=" << address << ", rssi=" << (int)rssi_value;
523
524 if (hearingDevice->read_rssi_count <= 0) {
525 LOG(ERROR) << __func__ << ": device=" << address
526 << ", invalid read_rssi_count=" << hearingDevice->read_rssi_count;
527 return;
528 }
529
530 rssi_log& last_log_set = hearingDevice->audio_stats.rssi_history.back();
531
532 if (hearingDevice->read_rssi_count == READ_RSSI_NUM_TRIES) {
533 // Store the timestamp only for the first one after packet flush
534 clock_gettime(CLOCK_REALTIME, &last_log_set.timestamp);
535 LOG(INFO) << __func__ << ": store time. device=" << address << ", rssi=" << (int)rssi_value;
536 }
537
538 last_log_set.rssi.emplace_back(rssi_value);
539 hearingDevice->read_rssi_count--;
540 }
541
OnEncryptionComplete(const RawAddress & address,bool success)542 void OnEncryptionComplete(const RawAddress& address, bool success) {
543 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
544 if (!hearingDevice) {
545 DVLOG(2) << "Skipping unknown device" << address;
546 return;
547 }
548
549 if (!success) {
550 LOG(ERROR) << "encryption failed";
551 BTA_GATTC_Close(hearingDevice->conn_id);
552 if (hearingDevice->first_connection) {
553 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
554 }
555 return;
556 }
557
558 DVLOG(2) << __func__ << " " << address;
559
560 if (hearingDevice->audio_control_point_handle &&
561 hearingDevice->audio_status_handle &&
562 hearingDevice->audio_status_ccc_handle &&
563 hearingDevice->volume_handle && hearingDevice->read_psm_handle) {
564 // Use cached data, jump to read PSM
565 ReadPSM(hearingDevice);
566 } else {
567 hearingDevice->first_connection = true;
568 BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID);
569 }
570 }
571
OnServiceChangeEvent(const RawAddress & address)572 void OnServiceChangeEvent(const RawAddress& address) {
573 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
574 if (!hearingDevice) {
575 VLOG(2) << "Skipping unknown device" << address;
576 return;
577 }
578 LOG(INFO) << __func__ << ": address=" << address;
579 hearingDevice->first_connection = true;
580 hearingDevice->service_changed_rcvd = true;
581 BtaGattQueue::Clean(hearingDevice->conn_id);
582 if (hearingDevice->gap_handle) {
583 GAP_ConnClose(hearingDevice->gap_handle);
584 hearingDevice->gap_handle = 0;
585 }
586 }
587
OnServiceDiscDoneEvent(const RawAddress & address)588 void OnServiceDiscDoneEvent(const RawAddress& address) {
589 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
590 if (!hearingDevice) {
591 VLOG(2) << "Skipping unknown device" << address;
592 return;
593 }
594 if (hearingDevice->service_changed_rcvd) {
595 BTA_GATTC_ServiceSearchRequest(hearingDevice->conn_id, &HEARING_AID_UUID);
596 }
597 }
598
OnServiceSearchComplete(uint16_t conn_id,tGATT_STATUS status)599 void OnServiceSearchComplete(uint16_t conn_id, tGATT_STATUS status) {
600 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
601 if (!hearingDevice) {
602 DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
603 return;
604 }
605
606 // Known device, nothing to do.
607 if (!hearingDevice->first_connection) return;
608
609 if (status != GATT_SUCCESS) {
610 /* close connection and report service discovery complete with error */
611 LOG(ERROR) << "Service discovery failed";
612 if (hearingDevice->first_connection) {
613 callbacks->OnConnectionState(ConnectionState::DISCONNECTED,
614 hearingDevice->address);
615 }
616 return;
617 }
618
619 const std::list<gatt::Service>* services = BTA_GATTC_GetServices(conn_id);
620
621 const gatt::Service* service = nullptr;
622 for (const gatt::Service& tmp : *services) {
623 if (tmp.uuid == Uuid::From16Bit(UUID_SERVCLASS_GATT_SERVER)) {
624 LOG(INFO) << "Found UUID_SERVCLASS_GATT_SERVER, handle="
625 << loghex(tmp.handle);
626 const gatt::Service* service_changed_service = &tmp;
627 find_server_changed_ccc_handle(conn_id, service_changed_service);
628 } else if (tmp.uuid == HEARING_AID_UUID) {
629 LOG(INFO) << "Found Hearing Aid service, handle=" << loghex(tmp.handle);
630 service = &tmp;
631 }
632 }
633
634 if (!service) {
635 LOG(ERROR) << "No Hearing Aid service found";
636 callbacks->OnConnectionState(ConnectionState::DISCONNECTED,
637 hearingDevice->address);
638 return;
639 }
640
641 for (const gatt::Characteristic& charac : service->characteristics) {
642 if (charac.uuid == READ_ONLY_PROPERTIES_UUID) {
643 if (!btif_storage_get_hearing_aid_prop(
644 hearingDevice->address, &hearingDevice->capabilities,
645 &hearingDevice->hi_sync_id, &hearingDevice->render_delay,
646 &hearingDevice->preparation_delay, &hearingDevice->codecs)) {
647 VLOG(2) << "Reading read only properties "
648 << loghex(charac.value_handle);
649 BtaGattQueue::ReadCharacteristic(
650 conn_id, charac.value_handle,
651 HearingAidImpl::OnReadOnlyPropertiesReadStatic, nullptr);
652 }
653 } else if (charac.uuid == AUDIO_CONTROL_POINT_UUID) {
654 hearingDevice->audio_control_point_handle = charac.value_handle;
655 // store audio control point!
656 } else if (charac.uuid == AUDIO_STATUS_UUID) {
657 hearingDevice->audio_status_handle = charac.value_handle;
658
659 hearingDevice->audio_status_ccc_handle =
660 find_ccc_handle(conn_id, charac.value_handle);
661 if (!hearingDevice->audio_status_ccc_handle) {
662 LOG(ERROR) << __func__ << ": cannot find Audio Status CCC descriptor";
663 continue;
664 }
665
666 LOG(INFO) << __func__
667 << ": audio_status_handle=" << loghex(charac.value_handle)
668 << ", ccc=" << loghex(hearingDevice->audio_status_ccc_handle);
669 } else if (charac.uuid == VOLUME_UUID) {
670 hearingDevice->volume_handle = charac.value_handle;
671 } else if (charac.uuid == LE_PSM_UUID) {
672 hearingDevice->read_psm_handle = charac.value_handle;
673 } else {
674 LOG(WARNING) << "Unknown characteristic found:" << charac.uuid;
675 }
676 }
677
678 if (hearingDevice->service_changed_rcvd) {
679 hearingDevice->service_changed_rcvd = false;
680 }
681
682 ReadPSM(hearingDevice);
683 }
684
ReadPSM(HearingDevice * hearingDevice)685 void ReadPSM(HearingDevice* hearingDevice) {
686 if (hearingDevice->read_psm_handle) {
687 LOG(INFO) << "Reading PSM " << loghex(hearingDevice->read_psm_handle)
688 << ", device=" << hearingDevice->address;
689 BtaGattQueue::ReadCharacteristic(
690 hearingDevice->conn_id, hearingDevice->read_psm_handle,
691 HearingAidImpl::OnPsmReadStatic, nullptr);
692 }
693 }
694
OnNotificationEvent(uint16_t conn_id,uint16_t handle,uint16_t len,uint8_t * value)695 void OnNotificationEvent(uint16_t conn_id, uint16_t handle, uint16_t len,
696 uint8_t* value) {
697 HearingDevice* device = hearingDevices.FindByConnId(conn_id);
698 if (!device) {
699 LOG(INFO) << __func__
700 << ": Skipping unknown device, conn_id=" << loghex(conn_id);
701 return;
702 }
703
704 if (device->audio_status_handle != handle) {
705 LOG(INFO) << __func__ << ": Mismatched handle, "
706 << loghex(device->audio_status_handle)
707 << "!=" << loghex(handle);
708 return;
709 }
710
711 if (len < 1) {
712 LOG(ERROR) << __func__ << ": Data Length too small, len=" << len
713 << ", expecting at least 1";
714 return;
715 }
716
717 if (value[0] != 0) {
718 LOG(INFO) << __func__
719 << ": Invalid returned status. data=" << loghex(value[0]);
720 return;
721 }
722
723 LOG(INFO) << __func__
724 << ": audio status success notification. command_acked="
725 << device->command_acked;
726 device->command_acked = true;
727 }
728
OnReadOnlyPropertiesRead(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)729 void OnReadOnlyPropertiesRead(uint16_t conn_id, tGATT_STATUS status,
730 uint16_t handle, uint16_t len, uint8_t* value,
731 void* data) {
732 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
733 if (!hearingDevice) {
734 DVLOG(2) << __func__ << "unknown conn_id=" << loghex(conn_id);
735 return;
736 }
737
738 VLOG(2) << __func__ << " " << base::HexEncode(value, len);
739
740 uint8_t* p = value;
741
742 uint8_t version;
743 STREAM_TO_UINT8(version, p);
744
745 if (version != 0x01) {
746 LOG(WARNING) << "Unknown version: " << loghex(version);
747 return;
748 }
749
750 // version 0x01 of read only properties:
751 if (len < 17) {
752 LOG(WARNING) << "Read only properties too short: " << loghex(len);
753 return;
754 }
755 uint8_t capabilities;
756 STREAM_TO_UINT8(capabilities, p);
757 hearingDevice->capabilities = capabilities;
758 bool side = capabilities & CAPABILITY_SIDE;
759 bool standalone = capabilities & CAPABILITY_BINAURAL;
760 VLOG(2) << __func__ << " capabilities: " << (side ? "right" : "left")
761 << ", " << (standalone ? "binaural" : "monaural");
762
763 if (capabilities & CAPABILITY_RESERVED) {
764 LOG(WARNING) << __func__ << " reserved capabilities are set";
765 }
766
767 STREAM_TO_UINT64(hearingDevice->hi_sync_id, p);
768 VLOG(2) << __func__ << " hiSyncId: " << loghex(hearingDevice->hi_sync_id);
769 uint8_t feature_map;
770 STREAM_TO_UINT8(feature_map, p);
771
772 STREAM_TO_UINT16(hearingDevice->render_delay, p);
773 VLOG(2) << __func__
774 << " render delay: " << loghex(hearingDevice->render_delay);
775
776 STREAM_TO_UINT16(hearingDevice->preparation_delay, p);
777 VLOG(2) << __func__ << " preparation delay: "
778 << loghex(hearingDevice->preparation_delay);
779
780 uint16_t codecs;
781 STREAM_TO_UINT16(codecs, p);
782 hearingDevice->codecs = codecs;
783 VLOG(2) << __func__ << " supported codecs: " << loghex(codecs);
784 if (codecs & (1 << CODEC_G722_16KHZ)) VLOG(2) << "\tG722@16kHz";
785 if (codecs & (1 << CODEC_G722_24KHZ)) VLOG(2) << "\tG722@24kHz";
786
787 if (!(codecs & (1 << CODEC_G722_16KHZ))) {
788 LOG(WARNING) << __func__ << " Mandatory codec, G722@16kHz not supported";
789 }
790 }
791
CalcCompressedAudioPacketSize(uint16_t codec_type,int connection_interval)792 uint16_t CalcCompressedAudioPacketSize(uint16_t codec_type,
793 int connection_interval) {
794 int sample_rate;
795
796 const int sample_bit_rate = 16; /* 16 bits per sample */
797 const int compression_ratio = 4; /* G.722 has a 4:1 compression ratio */
798 if (codec_type == CODEC_G722_24KHZ) {
799 sample_rate = 24000;
800 } else {
801 sample_rate = 16000;
802 }
803
804 // compressed_data_packet_size is the size in bytes of the compressed audio
805 // data buffer that is generated for each connection interval.
806 uint32_t compressed_data_packet_size =
807 (sample_rate * connection_interval * (sample_bit_rate / 8) /
808 compression_ratio) /
809 1000;
810 return ((uint16_t)compressed_data_packet_size);
811 }
812
ChooseCodec(const HearingDevice & hearingDevice)813 void ChooseCodec(const HearingDevice& hearingDevice) {
814 if (codec_in_use) return;
815
816 // use the best codec available for this pair of devices.
817 uint16_t codecs = hearingDevice.codecs;
818 if (hearingDevice.hi_sync_id != 0) {
819 for (const auto& device : hearingDevices.devices) {
820 if (device.hi_sync_id != hearingDevice.hi_sync_id) continue;
821
822 codecs &= device.codecs;
823 }
824 }
825
826 if ((codecs & (1 << CODEC_G722_24KHZ)) &&
827 controller_get_interface()->supports_ble_2m_phy() &&
828 default_data_interval_ms == HA_INTERVAL_10_MS) {
829 codec_in_use = CODEC_G722_24KHZ;
830 } else if (codecs & (1 << CODEC_G722_16KHZ)) {
831 codec_in_use = CODEC_G722_16KHZ;
832 }
833 }
834
OnAudioStatus(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)835 void OnAudioStatus(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
836 uint16_t len, uint8_t* value, void* data) {
837 LOG(INFO) << __func__ << " " << base::HexEncode(value, len);
838 }
839
OnPsmRead(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)840 void OnPsmRead(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
841 uint16_t len, uint8_t* value, void* data) {
842 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
843 if (!hearingDevice) {
844 DVLOG(2) << "Skipping unknown read event, conn_id=" << loghex(conn_id);
845 return;
846 }
847
848 if (status != GATT_SUCCESS) {
849 LOG(ERROR) << "Error reading PSM for device" << hearingDevice->address;
850 return;
851 }
852
853 if (len > 2) {
854 LOG(ERROR) << "Bad PSM length";
855 return;
856 }
857
858 uint16_t psm = *((uint16_t*)value);
859 VLOG(2) << "read psm:" << loghex(psm);
860
861 ConnectSocket(hearingDevice, psm);
862 }
863
ConnectSocket(HearingDevice * hearingDevice,uint16_t psm)864 void ConnectSocket(HearingDevice* hearingDevice, uint16_t psm) {
865 tL2CAP_CFG_INFO cfg_info = tL2CAP_CFG_INFO{.mtu = 512};
866
867 SendEnableServiceChangedInd(hearingDevice);
868
869 uint8_t service_id = hearingDevice->isLeft()
870 ? BTM_SEC_SERVICE_HEARING_AID_LEFT
871 : BTM_SEC_SERVICE_HEARING_AID_RIGHT;
872 uint16_t gap_handle = GAP_ConnOpen(
873 "", service_id, false, &hearingDevice->address, psm, 514 /* MPS */,
874 &cfg_info, nullptr, BTM_SEC_NONE /* TODO: request security ? */,
875 L2CAP_FCR_LE_COC_MODE, HearingAidImpl::GapCallbackStatic,
876 BT_TRANSPORT_LE);
877 if (gap_handle == GAP_INVALID_HANDLE) {
878 LOG(ERROR) << "UNABLE TO GET gap_handle";
879 return;
880 }
881
882 hearingDevice->gap_handle = gap_handle;
883 LOG(INFO) << "Successfully sent GAP connect request";
884 }
885
OnReadOnlyPropertiesReadStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)886 static void OnReadOnlyPropertiesReadStatic(uint16_t conn_id,
887 tGATT_STATUS status,
888 uint16_t handle, uint16_t len,
889 uint8_t* value, void* data) {
890 if (instance)
891 instance->OnReadOnlyPropertiesRead(conn_id, status, handle, len, value,
892 data);
893 }
OnAudioStatusStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)894 static void OnAudioStatusStatic(uint16_t conn_id, tGATT_STATUS status,
895 uint16_t handle, uint16_t len, uint8_t* value,
896 void* data) {
897 if (instance)
898 instance->OnAudioStatus(conn_id, status, handle, len, value, data);
899 }
900
OnPsmReadStatic(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)901 static void OnPsmReadStatic(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->OnPsmRead(conn_id, status, handle, len, value, data);
906 }
907
908 /* CoC Socket is ready */
OnGapConnection(const RawAddress & address)909 void OnGapConnection(const RawAddress& address) {
910 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
911 if (!hearingDevice) {
912 LOG(INFO) << "Device not connected to profile" << address;
913 return;
914 }
915
916 if (hearingDevice->first_connection) {
917 /* add device into BG connection to accept remote initiated connection */
918 BTA_GATTC_Open(gatt_if, address, false, GATT_TRANSPORT_LE, false);
919
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(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()1008 void OnAudioSuspend() {
1009 if (!audio_running) {
1010 LOG(WARNING) << __func__ << ": Unexpected audio suspend";
1011 } else {
1012 LOG(INFO) << __func__ << ": audio_running=" << audio_running;
1013 }
1014 audio_running = false;
1015
1016 std::vector<uint8_t> stop({CONTROL_POINT_OP_STOP});
1017 for (auto& device : hearingDevices.devices) {
1018 if (!device.accepting_audio) continue;
1019
1020 if (!device.playback_started) {
1021 LOG(WARNING) << __func__
1022 << ": Playback not started, skip send Stop cmd, device="
1023 << device.address;
1024 } else {
1025 LOG(INFO) << __func__ << ": send Stop cmd, device=" << device.address;
1026 device.playback_started = false;
1027 device.command_acked = false;
1028 BtaGattQueue::WriteCharacteristic(device.conn_id,
1029 device.audio_control_point_handle,
1030 stop, GATT_WRITE, nullptr, nullptr);
1031 }
1032 }
1033 }
1034
OnAudioResume()1035 void OnAudioResume() {
1036 if (audio_running) {
1037 LOG(ERROR) << __func__ << ": Unexpected Audio Resume";
1038 } else {
1039 LOG(INFO) << __func__ << ": audio_running=" << audio_running;
1040 }
1041 audio_running = true;
1042
1043 // TODO: shall we also reset the encoder ?
1044 encoder_state_release();
1045 encoder_state_init();
1046 seq_counter = 0;
1047
1048 for (auto& device : hearingDevices.devices) {
1049 if (!device.accepting_audio) continue;
1050 SendStart(&device);
1051 }
1052 }
1053
GetOtherSideStreamStatus(HearingDevice * this_side_device)1054 uint8_t GetOtherSideStreamStatus(HearingDevice* this_side_device) {
1055 for (auto& device : hearingDevices.devices) {
1056 if ((device.address == this_side_device->address) ||
1057 (device.hi_sync_id != this_side_device->hi_sync_id)) {
1058 continue;
1059 }
1060 if (audio_running && (device.conn_id != 0)) {
1061 return (OTHER_SIDE_IS_STREAMING);
1062 } else {
1063 return (OTHER_SIDE_NOT_STREAMING);
1064 }
1065 }
1066 return (OTHER_SIDE_NOT_STREAMING);
1067 }
1068
SendEnableServiceChangedInd(HearingDevice * device)1069 void SendEnableServiceChangedInd(HearingDevice* device) {
1070 VLOG(2) << __func__ << " Enable " << device->address
1071 << "service changed ind.";
1072 std::vector<uint8_t> value(2);
1073 uint8_t* ptr = value.data();
1074 UINT16_TO_STREAM(ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION);
1075 BtaGattQueue::WriteDescriptor(
1076 device->conn_id, device->service_changed_ccc_handle, std::move(value),
1077 GATT_WRITE, nullptr, nullptr);
1078 }
1079
SendStart(HearingDevice * device)1080 void SendStart(HearingDevice* device) {
1081 std::vector<uint8_t> start({CONTROL_POINT_OP_START, codec_in_use,
1082 AUDIOTYPE_UNKNOWN, (uint8_t)current_volume,
1083 OTHER_SIDE_NOT_STREAMING});
1084
1085 if (!audio_running) {
1086 if (!device->playback_started) {
1087 LOG(INFO) << __func__
1088 << ": Skip Send Start since audio is not running, device="
1089 << device->address;
1090 } else {
1091 LOG(ERROR) << __func__
1092 << ": Audio not running but Playback has started, device="
1093 << device->address;
1094 }
1095 return;
1096 }
1097
1098 if (current_volume == VOLUME_UNKNOWN) start[3] = (uint8_t)VOLUME_MIN;
1099
1100 if (device->playback_started) {
1101 LOG(ERROR) << __func__
1102 << ": Playback already started, skip send Start cmd, device="
1103 << device->address;
1104 } else {
1105 start[4] = GetOtherSideStreamStatus(device);
1106 LOG(INFO) << __func__ << ": send Start cmd, volume=" << loghex(start[3])
1107 << ", audio type=" << loghex(start[2])
1108 << ", device=" << device->address
1109 << ", other side streaming=" << loghex(start[4]);
1110 device->playback_started = true;
1111 device->command_acked = false;
1112 BtaGattQueue::WriteCharacteristic(device->conn_id,
1113 device->audio_control_point_handle,
1114 start, GATT_WRITE, nullptr, nullptr);
1115 }
1116 }
1117
OnAudioDataReady(const std::vector<uint8_t> & data)1118 void OnAudioDataReady(const std::vector<uint8_t>& data) {
1119 /* For now we assume data comes in as 16bit per sample 16kHz PCM stereo */
1120 DVLOG(2) << __func__;
1121
1122 int num_samples =
1123 data.size() / (2 /*bytes_per_sample*/ * 2 /*number of channels*/);
1124
1125 // The G.722 codec accept only even number of samples for encoding
1126 if (num_samples % 2 != 0)
1127 LOG(FATAL) << "num_samples is not even: " << num_samples;
1128
1129 // TODO: we should cache left/right and current state, instad of recomputing
1130 // it for each packet, 100 times a second.
1131 HearingDevice* left = nullptr;
1132 HearingDevice* right = nullptr;
1133 for (auto& device : hearingDevices.devices) {
1134 if (!device.accepting_audio) continue;
1135
1136 if (device.isLeft())
1137 left = &device;
1138 else
1139 right = &device;
1140 }
1141
1142 if (left == nullptr && right == nullptr) {
1143 HearingAidAudioSource::Stop();
1144 audio_running = false;
1145 encoder_state_release();
1146 current_volume = VOLUME_UNKNOWN;
1147 return;
1148 }
1149
1150 std::vector<uint16_t> chan_left;
1151 std::vector<uint16_t> chan_right;
1152 if (left == nullptr || right == nullptr) {
1153 for (int i = 0; i < num_samples; i++) {
1154 const uint8_t* sample = data.data() + i * 4;
1155
1156 int16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1157
1158 sample += 2;
1159 int16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1160
1161 uint16_t mono_data = (int16_t)(((uint32_t)left + (uint32_t)right) >> 1);
1162 chan_left.push_back(mono_data);
1163 chan_right.push_back(mono_data);
1164 }
1165 } else {
1166 for (int i = 0; i < num_samples; i++) {
1167 const uint8_t* sample = data.data() + i * 4;
1168
1169 uint16_t left = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1170 chan_left.push_back(left);
1171
1172 sample += 2;
1173 uint16_t right = (int16_t)((*(sample + 1) << 8) + *sample) >> 1;
1174 chan_right.push_back(right);
1175 }
1176 }
1177
1178 // TODO: monural, binarual check
1179
1180 // divide encoded data into packets, add header, send.
1181
1182 // TODO: make those buffers static and global to prevent constant
1183 // reallocations
1184 // TODO: this should basically fit the encoded data, tune the size later
1185 std::vector<uint8_t> encoded_data_left;
1186 if (left) {
1187 // TODO: instead of a magic number, we need to figure out the correct
1188 // buffer size
1189 encoded_data_left.resize(4000);
1190 int encoded_size =
1191 g722_encode(encoder_state_left, encoded_data_left.data(),
1192 (const int16_t*)chan_left.data(), chan_left.size());
1193 encoded_data_left.resize(encoded_size);
1194
1195 uint16_t cid = GAP_ConnGetL2CAPCid(left->gap_handle);
1196 uint16_t packets_to_flush = L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
1197 if (packets_to_flush) {
1198 VLOG(2) << left->address << " skipping " << packets_to_flush
1199 << " packets";
1200 left->audio_stats.packet_flush_count += packets_to_flush;
1201 left->audio_stats.frame_flush_count++;
1202 hearingDevices.StartRssiLog();
1203 }
1204 // flush all packets stuck in queue
1205 L2CA_FlushChannel(cid, 0xffff);
1206 check_and_do_rssi_read(left);
1207 }
1208
1209 std::vector<uint8_t> encoded_data_right;
1210 if (right) {
1211 // TODO: instead of a magic number, we need to figure out the correct
1212 // buffer size
1213 encoded_data_right.resize(4000);
1214 int encoded_size =
1215 g722_encode(encoder_state_right, encoded_data_right.data(),
1216 (const int16_t*)chan_right.data(), chan_right.size());
1217 encoded_data_right.resize(encoded_size);
1218
1219 uint16_t cid = GAP_ConnGetL2CAPCid(right->gap_handle);
1220 uint16_t packets_to_flush = L2CA_FlushChannel(cid, L2CAP_FLUSH_CHANS_GET);
1221 if (packets_to_flush) {
1222 VLOG(2) << right->address << " skipping " << packets_to_flush
1223 << " packets";
1224 right->audio_stats.packet_flush_count += packets_to_flush;
1225 right->audio_stats.frame_flush_count++;
1226 hearingDevices.StartRssiLog();
1227 }
1228 // flush all packets stuck in queue
1229 L2CA_FlushChannel(cid, 0xffff);
1230 check_and_do_rssi_read(right);
1231 }
1232
1233 size_t encoded_data_size =
1234 std::max(encoded_data_left.size(), encoded_data_right.size());
1235
1236 uint16_t packet_size =
1237 CalcCompressedAudioPacketSize(codec_in_use, default_data_interval_ms);
1238
1239 for (size_t i = 0; i < encoded_data_size; i += packet_size) {
1240 if (left) {
1241 left->audio_stats.packet_send_count++;
1242 SendAudio(encoded_data_left.data() + i, packet_size, left);
1243 }
1244 if (right) {
1245 right->audio_stats.packet_send_count++;
1246 SendAudio(encoded_data_right.data() + i, packet_size, right);
1247 }
1248 seq_counter++;
1249 }
1250 if (left) left->audio_stats.frame_send_count++;
1251 if (right) right->audio_stats.frame_send_count++;
1252 }
1253
SendAudio(uint8_t * encoded_data,uint16_t packet_size,HearingDevice * hearingAid)1254 void SendAudio(uint8_t* encoded_data, uint16_t packet_size,
1255 HearingDevice* hearingAid) {
1256 if (!hearingAid->playback_started || !hearingAid->command_acked) {
1257 VLOG(2) << __func__
1258 << ": Playback stalled, device=" << hearingAid->address
1259 << ", cmd send=" << hearingAid->playback_started
1260 << ", cmd acked=" << hearingAid->command_acked;
1261 return;
1262 }
1263
1264 BT_HDR* audio_packet = malloc_l2cap_buf(packet_size + 1);
1265 uint8_t* p = get_l2cap_sdu_start_ptr(audio_packet);
1266 *p = seq_counter;
1267 p++;
1268 memcpy(p, encoded_data, packet_size);
1269
1270 DVLOG(2) << hearingAid->address << " : " << base::HexEncode(p, packet_size);
1271
1272 uint16_t result = GAP_ConnWriteData(hearingAid->gap_handle, audio_packet);
1273
1274 if (result != BT_PASS) {
1275 LOG(ERROR) << " Error sending data: " << loghex(result);
1276 }
1277 }
1278
GapCallback(uint16_t gap_handle,uint16_t event,tGAP_CB_DATA * data)1279 void GapCallback(uint16_t gap_handle, uint16_t event, tGAP_CB_DATA* data) {
1280 HearingDevice* hearingDevice = hearingDevices.FindByGapHandle(gap_handle);
1281 if (!hearingDevice) {
1282 LOG(INFO) << "Skipping unknown device, gap_handle=" << gap_handle;
1283 return;
1284 }
1285
1286 switch (event) {
1287 case GAP_EVT_CONN_OPENED: {
1288 RawAddress address = *GAP_ConnGetRemoteAddr(gap_handle);
1289 uint16_t tx_mtu = GAP_ConnGetRemMtuSize(gap_handle);
1290
1291 LOG(INFO) << "GAP_EVT_CONN_OPENED " << address << ", tx_mtu=" << tx_mtu;
1292 OnGapConnection(address);
1293 break;
1294 }
1295
1296 // TODO: handle properly!
1297 case GAP_EVT_CONN_CLOSED:
1298 LOG(INFO) << __func__
1299 << ": GAP_EVT_CONN_CLOSED: " << hearingDevice->address
1300 << ", playback_started=" << hearingDevice->playback_started;
1301 hearingDevice->accepting_audio = false;
1302 hearingDevice->gap_handle = 0;
1303 hearingDevice->playback_started = false;
1304 hearingDevice->command_acked = false;
1305 break;
1306 case GAP_EVT_CONN_DATA_AVAIL: {
1307 DVLOG(2) << "GAP_EVT_CONN_DATA_AVAIL";
1308
1309 // only data we receive back from hearing aids are some stats, not
1310 // really important, but useful now for debugging.
1311 uint32_t bytes_to_read = 0;
1312 GAP_GetRxQueueCnt(gap_handle, &bytes_to_read);
1313 std::vector<uint8_t> buffer(bytes_to_read);
1314
1315 uint16_t bytes_read = 0;
1316 // TODO:GAP_ConnReadData should accpet uint32_t for length!
1317 GAP_ConnReadData(gap_handle, buffer.data(), buffer.size(), &bytes_read);
1318
1319 if (bytes_read < 4) {
1320 LOG(WARNING) << " Wrong data length";
1321 return;
1322 }
1323
1324 uint8_t* p = buffer.data();
1325
1326 DVLOG(1) << "stats from the hearing aid:";
1327 for (size_t i = 0; i + 4 <= buffer.size(); i += 4) {
1328 uint16_t event_counter, frame_index;
1329 STREAM_TO_UINT16(event_counter, p);
1330 STREAM_TO_UINT16(frame_index, p);
1331 DVLOG(1) << "event_counter=" << event_counter
1332 << " frame_index: " << frame_index;
1333 }
1334 break;
1335 }
1336
1337 case GAP_EVT_TX_EMPTY:
1338 DVLOG(2) << "GAP_EVT_TX_EMPTY";
1339 break;
1340 case GAP_EVT_CONN_CONGESTED:
1341 DVLOG(2) << "GAP_EVT_CONN_CONGESTED";
1342
1343 // TODO: make it into function
1344 HearingAidAudioSource::Stop();
1345 // TODO: kill the encoder only if all hearing aids are down.
1346 // g722_encode_release(encoder_state);
1347 // encoder_state_left = nulllptr;
1348 // encoder_state_right = nulllptr;
1349 break;
1350 case GAP_EVT_CONN_UNCONGESTED:
1351 DVLOG(2) << "GAP_EVT_CONN_UNCONGESTED";
1352 break;
1353
1354 case GAP_EVT_LE_COC_CREDITS: {
1355 auto& tmp = data->coc_credits;
1356 DVLOG(2) << "GAP_EVT_LE_COC_CREDITS, for device: "
1357 << hearingDevice->address << " added" << tmp.credits_received
1358 << " credit_count: " << tmp.credit_count;
1359 break;
1360 }
1361 }
1362 }
1363
GapCallbackStatic(uint16_t gap_handle,uint16_t event,tGAP_CB_DATA * data)1364 static void GapCallbackStatic(uint16_t gap_handle, uint16_t event,
1365 tGAP_CB_DATA* data) {
1366 if (instance) instance->GapCallback(gap_handle, event, data);
1367 }
1368
DumpRssi(int fd,const HearingDevice & device)1369 void DumpRssi(int fd, const HearingDevice& device) {
1370 const struct AudioStats* stats = &device.audio_stats;
1371
1372 if (stats->rssi_history.size() <= 0) {
1373 dprintf(fd, " No RSSI history for %s:\n", device.address.ToString().c_str());
1374 return;
1375 }
1376 dprintf(fd, " RSSI history for %s:\n", device.address.ToString().c_str());
1377
1378 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");
1379 for (auto& rssi_logs : stats->rssi_history) {
1380 if (rssi_logs.rssi.size() <= 0) {
1381 break;
1382 }
1383
1384 char eventtime[20];
1385 char temptime[20];
1386 struct tm* tstamp = localtime(&rssi_logs.timestamp.tv_sec);
1387 if (!strftime(temptime, sizeof(temptime), "%H:%M:%S", tstamp)) {
1388 LOG(ERROR) << __func__ << ": strftime fails. tm_sec=" << tstamp->tm_sec << ", tm_min=" << tstamp->tm_min
1389 << ", tm_hour=" << tstamp->tm_hour;
1390 strlcpy(temptime, "UNKNOWN TIME", sizeof(temptime));
1391 }
1392 snprintf(eventtime, sizeof(eventtime), "%s.%03ld", temptime, rssi_logs.timestamp.tv_nsec / 1000000);
1393
1394 dprintf(fd, " %s: ", eventtime);
1395
1396 for (auto rssi_value : rssi_logs.rssi) {
1397 dprintf(fd, " %04d", rssi_value);
1398 }
1399 dprintf(fd, "\n");
1400 }
1401 }
1402
Dump(int fd)1403 void Dump(int fd) {
1404 std::stringstream stream;
1405 for (const auto& device : hearingDevices.devices) {
1406 bool side = device.capabilities & CAPABILITY_SIDE;
1407 bool standalone = device.capabilities & CAPABILITY_BINAURAL;
1408 stream << " " << device.address.ToString() << " "
1409 << (device.accepting_audio ? "" : "not ") << "connected"
1410 << "\n " << (standalone ? "binaural" : "monaural") << " "
1411 << (side ? "right" : "left") << " " << loghex(device.hi_sync_id)
1412 << std::endl;
1413 stream
1414 << " Packet counts (enqueued/flushed) : "
1415 << device.audio_stats.packet_send_count << " / "
1416 << device.audio_stats.packet_flush_count
1417 << "\n Frame counts (enqueued/flushed) : "
1418 << device.audio_stats.frame_send_count << " / "
1419 << device.audio_stats.frame_flush_count << std::endl;
1420
1421 DumpRssi(fd, device);
1422 }
1423 dprintf(fd, "%s", stream.str().c_str());
1424 }
1425
Disconnect(const RawAddress & address)1426 void Disconnect(const RawAddress& address) override {
1427 DVLOG(2) << __func__;
1428 HearingDevice* hearingDevice = hearingDevices.FindByAddress(address);
1429 if (!hearingDevice) {
1430 LOG(INFO) << "Device not connected to profile" << address;
1431 return;
1432 }
1433
1434 VLOG(2) << __func__ << ": " << address;
1435
1436 bool connected = hearingDevice->accepting_audio;
1437
1438 LOG(INFO) << "GAP_EVT_CONN_CLOSED: " << hearingDevice->address
1439 << ", playback_started=" << hearingDevice->playback_started
1440 << ", accepting_audio=" << hearingDevice->accepting_audio;
1441
1442 if (hearingDevice->connecting_actively) {
1443 // cancel pending direct connect
1444 BTA_GATTC_CancelOpen(gatt_if, address, true);
1445 }
1446
1447 // Removes all registrations for connection.
1448 BTA_GATTC_CancelOpen(0, address, false);
1449
1450 // Inform the other side (if any) of this disconnection
1451 std::vector<uint8_t> inform_disconn_state(
1452 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
1453 send_state_change_to_other_side(hearingDevice, inform_disconn_state);
1454
1455 DoDisconnectCleanUp(hearingDevice);
1456
1457 hearingDevices.Remove(address);
1458
1459 if (connected)
1460 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, address);
1461 }
1462
OnGattDisconnected(tGATT_STATUS status,uint16_t conn_id,tGATT_IF client_if,RawAddress remote_bda,tBTA_GATT_REASON reason)1463 void OnGattDisconnected(tGATT_STATUS status, uint16_t conn_id,
1464 tGATT_IF client_if, RawAddress remote_bda,
1465 tBTA_GATT_REASON reason) {
1466 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1467 if (!hearingDevice) {
1468 VLOG(2) << "Skipping unknown device disconnect, conn_id="
1469 << loghex(conn_id);
1470 return;
1471 }
1472 VLOG(2) << __func__ << ": conn_id=" << loghex(conn_id)
1473 << ", reason=" << loghex(reason) << ", remote_bda=" << remote_bda;
1474
1475 // Inform the other side (if any) of this disconnection
1476 std::vector<uint8_t> inform_disconn_state(
1477 {CONTROL_POINT_OP_STATE_CHANGE, STATE_CHANGE_OTHER_SIDE_DISCONNECTED});
1478 send_state_change_to_other_side(hearingDevice, inform_disconn_state);
1479
1480 DoDisconnectCleanUp(hearingDevice);
1481
1482 callbacks->OnConnectionState(ConnectionState::DISCONNECTED, remote_bda);
1483 }
1484
DoDisconnectCleanUp(HearingDevice * hearingDevice)1485 void DoDisconnectCleanUp(HearingDevice* hearingDevice) {
1486 if (hearingDevice->connection_update_status != COMPLETED) {
1487 LOG(INFO) << __func__ << ": connection update not completed. Current="
1488 << hearingDevice->connection_update_status
1489 << ", device=" << hearingDevice->address;
1490
1491 if (hearingDevice->connection_update_status == STARTED) {
1492 OnConnectionUpdateComplete(hearingDevice->conn_id, NULL);
1493 }
1494 }
1495 hearingDevice->connection_update_status = NONE;
1496
1497 if (hearingDevice->conn_id) {
1498 BtaGattQueue::Clean(hearingDevice->conn_id);
1499 BTA_GATTC_Close(hearingDevice->conn_id);
1500 hearingDevice->conn_id = 0;
1501 }
1502
1503 if (hearingDevice->gap_handle) {
1504 GAP_ConnClose(hearingDevice->gap_handle);
1505 hearingDevice->gap_handle = 0;
1506 }
1507
1508 hearingDevice->accepting_audio = false;
1509 LOG(INFO) << __func__ << ": device=" << hearingDevice->address
1510 << ", playback_started=" << hearingDevice->playback_started;
1511 hearingDevice->playback_started = false;
1512 hearingDevice->command_acked = false;
1513 }
1514
SetVolume(int8_t volume)1515 void SetVolume(int8_t volume) override {
1516 VLOG(2) << __func__ << ": " << +volume;
1517 current_volume = volume;
1518 for (HearingDevice& device : hearingDevices.devices) {
1519 if (!device.accepting_audio) continue;
1520
1521 std::vector<uint8_t> volume_value({static_cast<unsigned char>(volume)});
1522 BtaGattQueue::WriteCharacteristic(device.conn_id, device.volume_handle,
1523 volume_value, GATT_WRITE_NO_RSP,
1524 nullptr, nullptr);
1525 }
1526 }
1527
CleanUp()1528 void CleanUp() {
1529 BTA_GATTC_AppDeregister(gatt_if);
1530 for (HearingDevice& device : hearingDevices.devices) {
1531 DoDisconnectCleanUp(&device);
1532 }
1533
1534 hearingDevices.devices.clear();
1535
1536 encoder_state_release();
1537 }
1538
1539 private:
1540 uint8_t gatt_if;
1541 uint8_t seq_counter;
1542 /* current volume gain for the hearing aids*/
1543 int8_t current_volume;
1544 bluetooth::hearing_aid::HearingAidCallbacks* callbacks;
1545
1546 /* currently used codec */
1547 uint8_t codec_in_use;
1548
1549 uint16_t default_data_interval_ms;
1550
1551 HearingDevices hearingDevices;
1552
find_server_changed_ccc_handle(uint16_t conn_id,const gatt::Service * service)1553 void find_server_changed_ccc_handle(uint16_t conn_id,
1554 const gatt::Service* service) {
1555 HearingDevice* hearingDevice = hearingDevices.FindByConnId(conn_id);
1556 if (!hearingDevice) {
1557 DVLOG(2) << "Skipping unknown device, conn_id=" << loghex(conn_id);
1558 return;
1559 }
1560 for (const gatt::Characteristic& charac : service->characteristics) {
1561 if (charac.uuid == Uuid::From16Bit(GATT_UUID_GATT_SRV_CHGD)) {
1562 hearingDevice->service_changed_ccc_handle =
1563 find_ccc_handle(conn_id, charac.value_handle);
1564 if (!hearingDevice->service_changed_ccc_handle) {
1565 LOG(ERROR) << __func__
1566 << ": cannot find service changed CCC descriptor";
1567 continue;
1568 }
1569 LOG(INFO) << __func__ << " service_changed_ccc="
1570 << loghex(hearingDevice->service_changed_ccc_handle);
1571 break;
1572 }
1573 }
1574 }
1575
1576 // Find the handle for the client characteristics configuration of a given
1577 // characteristics
find_ccc_handle(uint16_t conn_id,uint16_t char_handle)1578 uint16_t find_ccc_handle(uint16_t conn_id, uint16_t char_handle) {
1579 const gatt::Characteristic* p_char =
1580 BTA_GATTC_GetCharacteristic(conn_id, char_handle);
1581
1582 if (!p_char) {
1583 LOG(WARNING) << __func__ << ": No such characteristic: " << char_handle;
1584 return 0;
1585 }
1586
1587 for (const gatt::Descriptor& desc : p_char->descriptors) {
1588 if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG))
1589 return desc.handle;
1590 }
1591
1592 return 0;
1593 }
1594
send_state_change(HearingDevice * device,std::vector<uint8_t> payload)1595 void send_state_change(HearingDevice* device, std::vector<uint8_t> payload) {
1596 if (device->conn_id != 0) {
1597 if (device->service_changed_rcvd) {
1598 LOG(INFO)
1599 << __func__
1600 << ": service discover is in progress, skip send State Change cmd.";
1601 return;
1602 }
1603 // Send the data packet
1604 LOG(INFO) << __func__ << ": Send State Change. device=" << device->address
1605 << ", status=" << loghex(payload[1]);
1606 BtaGattQueue::WriteCharacteristic(
1607 device->conn_id, device->audio_control_point_handle, payload,
1608 GATT_WRITE_NO_RSP, nullptr, nullptr);
1609 }
1610 }
1611
send_state_change_to_other_side(HearingDevice * this_side_device,std::vector<uint8_t> payload)1612 void send_state_change_to_other_side(HearingDevice* this_side_device,
1613 std::vector<uint8_t> payload) {
1614 for (auto& device : hearingDevices.devices) {
1615 if ((device.address == this_side_device->address) ||
1616 (device.hi_sync_id != this_side_device->hi_sync_id)) {
1617 continue;
1618 }
1619 send_state_change(&device, payload);
1620 }
1621 }
1622
check_and_do_rssi_read(HearingDevice * device)1623 void check_and_do_rssi_read(HearingDevice* device) {
1624 if (device->read_rssi_count > 0) {
1625 device->num_intervals_since_last_rssi_read++;
1626 if (device->num_intervals_since_last_rssi_read >= PERIOD_TO_READ_RSSI_IN_INTERVALS) {
1627 device->num_intervals_since_last_rssi_read = 0;
1628 VLOG(1) << __func__ << ": device=" << device->address;
1629 BTM_ReadRSSI(device->address, read_rssi_cb);
1630 }
1631 }
1632 }
1633 };
1634
read_rssi_cb(void * p_void)1635 void read_rssi_cb(void* p_void) {
1636 tBTM_RSSI_RESULT* p_result = (tBTM_RSSI_RESULT*)p_void;
1637
1638 if (!p_result) return;
1639
1640 if ((instance) && (p_result->status == BTM_SUCCESS)) {
1641 instance->OnReadRssiComplete(p_result->rem_bda, p_result->rssi);
1642 }
1643 }
1644
hearingaid_gattc_callback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)1645 void hearingaid_gattc_callback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
1646 VLOG(2) << __func__ << " event = " << +event;
1647
1648 if (p_data == nullptr) return;
1649
1650 switch (event) {
1651 case BTA_GATTC_DEREG_EVT:
1652 break;
1653
1654 case BTA_GATTC_OPEN_EVT: {
1655 if (!instance) return;
1656 tBTA_GATTC_OPEN& o = p_data->open;
1657 instance->OnGattConnected(o.status, o.conn_id, o.client_if, o.remote_bda,
1658 o.transport, o.mtu);
1659 break;
1660 }
1661
1662 case BTA_GATTC_CLOSE_EVT: {
1663 if (!instance) return;
1664 tBTA_GATTC_CLOSE& c = p_data->close;
1665 instance->OnGattDisconnected(c.status, c.conn_id, c.client_if,
1666 c.remote_bda, c.reason);
1667 } break;
1668
1669 case BTA_GATTC_SEARCH_CMPL_EVT:
1670 if (!instance) return;
1671 instance->OnServiceSearchComplete(p_data->search_cmpl.conn_id,
1672 p_data->search_cmpl.status);
1673 break;
1674
1675 case BTA_GATTC_NOTIF_EVT:
1676 if (!instance) return;
1677 if (!p_data->notify.is_notify || p_data->notify.len > GATT_MAX_ATTR_LEN) {
1678 LOG(ERROR) << __func__ << ": rejected BTA_GATTC_NOTIF_EVT. is_notify="
1679 << p_data->notify.is_notify
1680 << ", len=" << p_data->notify.len;
1681 break;
1682 }
1683 instance->OnNotificationEvent(p_data->notify.conn_id,
1684 p_data->notify.handle, p_data->notify.len,
1685 p_data->notify.value);
1686 break;
1687
1688 case BTA_GATTC_ENC_CMPL_CB_EVT:
1689 if (!instance) return;
1690 instance->OnEncryptionComplete(p_data->enc_cmpl.remote_bda, true);
1691 break;
1692
1693 case BTA_GATTC_CONN_UPDATE_EVT:
1694 if (!instance) return;
1695 instance->OnConnectionUpdateComplete(p_data->conn_update.conn_id, p_data);
1696 break;
1697
1698 case BTA_GATTC_SRVC_CHG_EVT:
1699 if (!instance) return;
1700 instance->OnServiceChangeEvent(p_data->remote_bda);
1701 break;
1702
1703 case BTA_GATTC_SRVC_DISC_DONE_EVT:
1704 if (!instance) return;
1705 instance->OnServiceDiscDoneEvent(p_data->remote_bda);
1706 break;
1707
1708 default:
1709 break;
1710 }
1711 }
1712
encryption_callback(const RawAddress * address,tGATT_TRANSPORT,void *,tBTM_STATUS status)1713 void encryption_callback(const RawAddress* address, tGATT_TRANSPORT, void*,
1714 tBTM_STATUS status) {
1715 if (instance) {
1716 instance->OnEncryptionComplete(*address,
1717 status == BTM_SUCCESS ? true : false);
1718 }
1719 }
1720
1721 class HearingAidAudioReceiverImpl : public HearingAidAudioReceiver {
1722 public:
OnAudioDataReady(const std::vector<uint8_t> & data)1723 void OnAudioDataReady(const std::vector<uint8_t>& data) override {
1724 if (instance) instance->OnAudioDataReady(data);
1725 }
OnAudioSuspend(std::promise<void> do_suspend_promise)1726 void OnAudioSuspend(std::promise<void> do_suspend_promise) override {
1727 if (instance) instance->OnAudioSuspend();
1728 do_suspend_promise.set_value();
1729 }
1730
OnAudioResume(std::promise<void> do_resume_promise)1731 void OnAudioResume(std::promise<void> do_resume_promise) override {
1732 if (instance) instance->OnAudioResume();
1733 do_resume_promise.set_value();
1734 }
1735 };
1736
1737 HearingAidAudioReceiverImpl audioReceiverImpl;
1738
1739 } // namespace
1740
Initialize(bluetooth::hearing_aid::HearingAidCallbacks * callbacks,Closure initCb)1741 void HearingAid::Initialize(
1742 bluetooth::hearing_aid::HearingAidCallbacks* callbacks, Closure initCb) {
1743 if (instance) {
1744 LOG(ERROR) << "Already initialized!";
1745 }
1746
1747 audioReceiver = &audioReceiverImpl;
1748 instance = new HearingAidImpl(callbacks, initCb);
1749 HearingAidAudioSource::Initialize();
1750 }
1751
IsHearingAidRunning()1752 bool HearingAid::IsHearingAidRunning() { return instance; }
1753
Get()1754 HearingAid* HearingAid::Get() {
1755 CHECK(instance);
1756 return instance;
1757 };
1758
AddFromStorage(const HearingDevice & dev_info,uint16_t is_white_listed)1759 void HearingAid::AddFromStorage(const HearingDevice& dev_info,
1760 uint16_t is_white_listed) {
1761 if (!instance) {
1762 LOG(ERROR) << "Not initialized yet";
1763 }
1764
1765 instance->AddFromStorage(dev_info, is_white_listed);
1766 };
1767
GetDeviceCount()1768 int HearingAid::GetDeviceCount() {
1769 if (!instance) {
1770 LOG(INFO) << __func__ << ": Not initialized yet";
1771 return 0;
1772 }
1773
1774 return (instance->GetDeviceCount());
1775 }
1776
CleanUp()1777 void HearingAid::CleanUp() {
1778 // Must stop audio source to make sure it doesn't call any of callbacks on our
1779 // soon to be null instance
1780 HearingAidAudioSource::Stop();
1781
1782 HearingAidImpl* ptr = instance;
1783 instance = nullptr;
1784 HearingAidAudioSource::CleanUp();
1785
1786 ptr->CleanUp();
1787
1788 delete ptr;
1789 };
1790
DebugDump(int fd)1791 void HearingAid::DebugDump(int fd) {
1792 dprintf(fd, "Hearing Aid Manager:\n");
1793 if (instance) instance->Dump(fd);
1794 HearingAidAudioSource::DebugDump(fd);
1795 dprintf(fd, "\n");
1796 }
1797