• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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