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