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