1 /*
2  * Copyright 2021 HIMSA II K/S - www.himsa.com.
3  * Represented by EHIMA - www.ehima.com
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 #include <base/functional/bind.h>
19 #include <base/functional/callback.h>
20 #include <base/strings/string_number_conversions.h>
21 #include <bluetooth/log.h>
22 #include <com_android_bluetooth_flags.h>
23 #include <hardware/bt_csis.h>
24 #include <hardware/bt_gatt_types.h>
25 #include <stdio.h>
26 
27 #include <algorithm>
28 #include <cstddef>
29 #include <cstdint>
30 #include <cstring>
31 #include <limits>
32 #include <list>
33 #include <map>
34 #include <memory>
35 #include <mutex>
36 #include <sstream>
37 #include <string>
38 #include <type_traits>
39 #include <utility>
40 #include <vector>
41 
42 #include "advertise_data_parser.h"
43 #include "bta_api.h"
44 #include "bta_csis_api.h"
45 #include "bta_gatt_api.h"
46 #include "bta_gatt_queue.h"
47 #include "bta_groups.h"
48 #include "bta_sec_api.h"
49 #include "btif/include/btif_storage.h"
50 #include "btm_ble_api_types.h"
51 #include "btm_sec_api_types.h"
52 #include "crypto_toolbox/crypto_toolbox.h"
53 #include "csis_types.h"
54 #include "gap_api.h"
55 #include "gatt/database.h"
56 #include "gatt_api.h"
57 #include "gattdefs.h"
58 #include "internal_include/bt_target.h"
59 #include "internal_include/bt_trace.h"
60 #include "main/shim/le_scanning_manager.h"
61 #include "neighbor_inquiry.h"
62 #include "os/logging/log_adapter.h"
63 #include "osi/include/osi.h"
64 #include "osi/include/stack_power_telemetry.h"
65 #include "stack/btm/btm_sec.h"
66 #include "stack/gatt/gatt_int.h"
67 #include "stack/include/bt_types.h"
68 #include "stack/include/btm_ble_sec_api.h"
69 #include "stack/include/btm_client_interface.h"
70 #include "stack/include/btm_status.h"
71 #include "types/bluetooth/uuid.h"
72 #include "types/bt_transport.h"
73 #include "types/raw_address.h"
74 
75 using base::Closure;
76 using bluetooth::Uuid;
77 using bluetooth::csis::ConnectionState;
78 using bluetooth::csis::CsisClient;
79 using bluetooth::csis::CsisDevice;
80 using bluetooth::csis::CsisDiscoveryState;
81 using bluetooth::csis::CsisGroup;
82 using bluetooth::csis::CsisGroupLockStatus;
83 using bluetooth::csis::CsisInstance;
84 using bluetooth::csis::CsisLockCb;
85 using bluetooth::csis::CsisLockState;
86 using bluetooth::csis::kCsisLockUuid;
87 using bluetooth::csis::kCsisRankUuid;
88 using bluetooth::csis::kCsisServiceUuid;
89 using bluetooth::csis::kCsisSirkUuid;
90 using bluetooth::csis::kCsisSizeUuid;
91 
92 using bluetooth::groups::DeviceGroups;
93 using bluetooth::groups::DeviceGroupsCallbacks;
94 
95 using namespace bluetooth;
96 
97 namespace {
98 class CsisClientImpl;
99 CsisClientImpl* instance;
100 std::mutex instance_mutex;
101 DeviceGroupsCallbacks* device_group_callbacks;
102 
103 /**
104  * -----------------------------------------------------------------------------
105  * Coordinated Set Service - Client role
106  * -----------------------------------------------------------------------------
107  *
108  * CSIP allows to organize audio servers into sets e.g. Stereo Set, 5.1 Set
109  * and speed up connecting it.
110  *
111  * Since leaudio has already grouping API it was decided to integrate here CSIS
112  * and allow it to group devices semi-automatically.
113  *
114  * Flow:
115  * If connected device contains CSIS services, and it is included into CAP
116  * service or is not included at all, implementation reads all its
117  * characteristisc. The only mandatory characteristic is Set Identity Resolving
118  * Key (SIRK) and once this is read implementation assumes there is at least 2
119  * devices in the set and start to search for other members by looking for new
120  * Advertising Type (RSI Type) and Resolvable Set Identifier (RSI) in it.
121  * In the meantime other CSIS characteristics are read and Set Size might be
122  * updated. When new set member is found, there is callback called to upper
123  * layer with the address and group id for which member has been found. During
124  * this time Search is stopped. Upper layers bonds new devices and connect Le
125  * Audio profile. If there are other members to find, implementations repeats
126  * the procedure.
127  *
128  */
129 
130 class CsisClientImpl : public CsisClient {
131   static constexpr uint8_t CSIS_STORAGE_CURRENT_LAYOUT_MAGIC = 0x10;
132   static constexpr size_t CSIS_STORAGE_HEADER_SZ =
133           sizeof(CSIS_STORAGE_CURRENT_LAYOUT_MAGIC) + sizeof(uint8_t); /* num_of_sets */
134   static constexpr size_t CSIS_STORAGE_ENTRY_SZ = sizeof(uint8_t) /* set_id */ +
135                                                   sizeof(uint8_t) /* desired_size */ +
136                                                   sizeof(uint8_t) /* rank */ + Octet16().size();
137 
138 public:
CsisClientImpl(bluetooth::csis::CsisClientCallbacks * callbacks,Closure initCb)139   CsisClientImpl(bluetooth::csis::CsisClientCallbacks* callbacks, Closure initCb)
140       : gatt_if_(0), callbacks_(callbacks) {
141     BTA_GATTC_AppRegister(
142             [](tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
143               if (instance && p_data) {
144                 instance->GattcCallback(event, p_data);
145               }
146             },
147             base::Bind(
148                     [](Closure initCb, uint8_t client_id, uint8_t status) {
149                       if (status != GATT_SUCCESS) {
150                         log::error(
151                                 "Can't start Coordinated Set Service client profile - no "
152                                 "gatt clients left!");
153                         return;
154                       }
155                       instance->gatt_if_ = client_id;
156                       initCb.Run();
157 
158                       DeviceGroups::Initialize(device_group_callbacks);
159                       instance->dev_groups_ = DeviceGroups::Get();
160                     },
161                     initCb),
162             true);
163 
164     BTA_DmSirkSecCbRegister([](tBTA_DM_SEC_EVT event, tBTA_DM_SEC* p_data) {
165       if (event != BTA_DM_SIRK_VERIFICATION_REQ_EVT) {
166         log::error("Invalid event received by CSIP: {}", static_cast<int>(event));
167         return;
168       }
169 
170       instance->VerifySetMember(p_data->ble_req.bd_addr);
171     });
172 
173     log::debug("Background scan enabled");
174     CsisObserverSetBackground(true);
175   }
176 
177   ~CsisClientImpl() override = default;
178 
AssignCsisGroup(const RawAddress & address,int group_id,bool create_group_if_non_existing,const bluetooth::Uuid & uuid)179   std::shared_ptr<bluetooth::csis::CsisGroup> AssignCsisGroup(const RawAddress& address,
180                                                               int group_id,
181                                                               bool create_group_if_non_existing,
182                                                               const bluetooth::Uuid& uuid) {
183     log::debug("Device: {}, group_id: {}", address, group_id);
184     auto csis_group = FindCsisGroup(group_id);
185     if (!csis_group) {
186       if (create_group_if_non_existing) {
187         /* Let's create a group */
188         log::debug(": Create a new group {}", group_id);
189         auto g = std::make_shared<CsisGroup>(group_id, uuid);
190         csis_groups_.push_back(g);
191         csis_group = FindCsisGroup(group_id);
192       } else {
193         log::error(": Missing group - that shall not happen");
194         return nullptr;
195       }
196     }
197 
198     auto device = FindDeviceByAddress(address);
199     if (device == nullptr) {
200       auto dev = std::make_shared<CsisDevice>(address, false);
201       devices_.push_back(dev);
202       device = FindDeviceByAddress(address);
203     }
204 
205     if (!csis_group->IsDeviceInTheGroup(device)) {
206       csis_group->AddDevice(device);
207     }
208 
209     return csis_group;
210   }
211 
OnGroupAddedCb(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)212   void OnGroupAddedCb(const RawAddress& address, const bluetooth::Uuid& uuid, int group_id) {
213     log::debug("address: {}, uuid: {}, group_id: {}", address, uuid.ToString(), group_id);
214 
215     AssignCsisGroup(address, group_id, true, uuid);
216   }
217 
OnGroupMemberAddedCb(const RawAddress & address,int group_id)218   void OnGroupMemberAddedCb(const RawAddress& address, int group_id) {
219     log::debug("{}, group_id: {}", address, group_id);
220 
221     AssignCsisGroup(address, group_id, false, Uuid::kEmpty);
222   }
223 
OnGroupRemovedCb(const bluetooth::Uuid &,int group_id)224   void OnGroupRemovedCb(const bluetooth::Uuid& /*uuid*/, int group_id) {
225     RemoveCsisGroup(group_id);
226   }
227 
OnGroupMemberRemovedCb(const RawAddress & address,int group_id)228   void OnGroupMemberRemovedCb(const RawAddress& address, int group_id) {
229     log::debug("{}, group_id: {}", address, group_id);
230 
231     auto device = FindDeviceByAddress(address);
232     if (device) {
233       RemoveCsisDevice(device, group_id);
234     }
235   }
236 
OnGroupAddFromStorageCb(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)237   void OnGroupAddFromStorageCb(const RawAddress& address, const bluetooth::Uuid& uuid,
238                                int group_id) {
239     auto device = FindDeviceByAddress(address);
240     if (device == nullptr) {
241       return;
242     }
243 
244     auto csis_group = FindCsisGroup(group_id);
245     if (csis_group == nullptr) {
246       log::error("the csis group (id: {} ) does not exist", group_id);
247       return;
248     }
249 
250     if (!csis_group->IsDeviceInTheGroup(device)) {
251       log::error("the csis group (id: {} ) does contain the device: {}", group_id, address);
252       return;
253     }
254 
255     if (csis_group->GetUuid() == Uuid::kEmpty) {
256       csis_group->SetUuid(uuid);
257     }
258 
259     int rank = bluetooth::csis::CSIS_RANK_INVALID;
260     auto csis_instance = device->GetCsisInstanceByGroupId(group_id);
261     if (csis_instance) {
262       rank = csis_instance->GetRank();
263     }
264 
265     callbacks_->OnDeviceAvailable(device->addr, csis_group->GetGroupId(),
266                                   csis_group->GetDesiredSize(), rank, uuid);
267   }
268 
Connect(const RawAddress & address)269   void Connect(const RawAddress& address) override {
270     log::info("{}", address);
271 
272     auto device = FindDeviceByAddress(address);
273     if (device == nullptr) {
274       if (!BTM_IsLinkKeyKnown(address, BT_TRANSPORT_LE)) {
275         log::error("Connecting  {} when not bonded", address);
276         callbacks_->OnConnectionState(address, ConnectionState::DISCONNECTED);
277         return;
278       }
279       devices_.emplace_back(std::make_shared<CsisDevice>(address, true));
280     } else {
281       device->connecting_actively = true;
282     }
283 
284     BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, false);
285   }
286 
Disconnect(const RawAddress & addr)287   void Disconnect(const RawAddress& addr) override {
288     log::debug("{}", addr);
289 
290     auto device = FindDeviceByAddress(addr);
291     if (device == nullptr) {
292       log::warn("Device not connected to profile {}", addr);
293       callbacks_->OnConnectionState(addr, ConnectionState::DISCONNECTED);
294       return;
295     }
296 
297     /* Removes all active connections or registrations for connection */
298     if (device->IsConnected()) {
299       BTA_GATTC_Close(device->conn_id);
300     } else {
301       BTA_GATTC_CancelOpen(gatt_if_, addr, false);
302       DoDisconnectCleanUp(device);
303       callbacks_->OnConnectionState(addr, ConnectionState::DISCONNECTED);
304     }
305   }
306 
RemoveDevice(const RawAddress & addr)307   void RemoveDevice(const RawAddress& addr) override {
308     log::info("{}", addr);
309 
310     auto device = FindDeviceByAddress(addr);
311     if (device == nullptr) {
312       log::warn("{} not found", addr);
313       return;
314     }
315 
316     Disconnect(addr);
317 
318     if (device->GetNumberOfCsisInstances() == 0) {
319       RemoveCsisDevice(device);
320     }
321     dev_groups_->RemoveDevice(addr);
322   }
323 
GetGroupId(const RawAddress & addr,Uuid uuid)324   int GetGroupId(const RawAddress& addr, Uuid uuid) override {
325     auto device = FindDeviceByAddress(addr);
326     if (device == nullptr) {
327       return bluetooth::groups::kGroupUnknown;
328     }
329 
330     int group_id = dev_groups_->GetGroupId(addr, uuid);
331     auto csis_group = FindCsisGroup(group_id);
332     if (csis_group == nullptr) {
333       return bluetooth::groups::kGroupUnknown;
334     }
335 
336     return csis_group->GetGroupId();
337   }
338 
HandleCsisLockProcedureError(std::shared_ptr<CsisGroup> & csis_group,std::shared_ptr<CsisDevice> & csis_device,CsisGroupLockStatus status=CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER)339   void HandleCsisLockProcedureError(
340           std::shared_ptr<CsisGroup>& csis_group, std::shared_ptr<CsisDevice>& csis_device,
341           CsisGroupLockStatus status = CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER) {
342     /* Clear information about ongoing lock procedure */
343     CsisLockCb cb = csis_group->GetLockCb();
344     csis_group->SetTargetLockState(CsisLockState::CSIS_STATE_UNSET);
345 
346     int group_id = csis_group->GetGroupId();
347     /* Send unlock to previous devices. It shall be done in reverse order. */
348     auto prev_dev = csis_group->GetPrevDevice(csis_device);
349     while (prev_dev) {
350       if (prev_dev->IsConnected()) {
351         auto prev_csis_instance = prev_dev->GetCsisInstanceByGroupId(group_id);
352         log::assert_that(prev_csis_instance != nullptr, "prev_csis_instance does not exist!");
353         SetLock(prev_dev, prev_csis_instance, CsisLockState::CSIS_STATE_UNLOCKED);
354       }
355       prev_dev = csis_group->GetPrevDevice(prev_dev);
356     }
357     /* Call application callback */
358     NotifyGroupStatus(group_id, false, status, std::move(cb));
359   }
360 
OnGattCsisWriteLockRsp(tCONN_ID conn_id,tGATT_STATUS status,uint16_t,void * data)361   void OnGattCsisWriteLockRsp(tCONN_ID conn_id, tGATT_STATUS status, uint16_t /*handle*/,
362                               void* data) {
363     auto device = FindDeviceByConnId(conn_id);
364     if (device == nullptr) {
365       log::error("Device not there for conn_id: 0x{:04x}", conn_id);
366       return;
367     }
368 
369     int group_id = PTR_TO_UINT(data);
370     auto csis_group = FindCsisGroup(group_id);
371     if (csis_group == nullptr) {
372       log::error("There is no group: {}", group_id);
373       return;
374     }
375 
376     CsisLockState target_lock_state = csis_group->GetTargetLockState();
377 
378     log::debug("Device {}, target lock: {}, status: 0x{:02x}", device->addr, (int)target_lock_state,
379                (int)status);
380     if (target_lock_state == CsisLockState::CSIS_STATE_UNSET) {
381       return;
382     }
383 
384     if (status != GATT_SUCCESS && status != bluetooth::csis::kCsisErrorCodeLockAlreadyGranted) {
385       if (target_lock_state == CsisLockState::CSIS_STATE_UNLOCKED) {
386         /* When unlocking just drop the counter on error and that is it */
387         csis_group->UpdateLockTransitionCnt(-1);
388         return;
389       }
390 
391       /* In case of GATT ERROR */
392       log::error("Incorrect write status=0x{:02x}", (int)(status));
393 
394       /* Unlock previous devices */
395       HandleCsisLockProcedureError(csis_group, device);
396 
397       if (status == GATT_DATABASE_OUT_OF_SYNC) {
398         log::info("Database out of sync for {}", device->addr);
399         ClearDeviceInformationAndStartSearch(device);
400       }
401       return;
402     }
403 
404     /* All is good, continue. Try to send lock to other devices.*/
405     auto csis_instance = device->GetCsisInstanceByGroupId(group_id);
406     log::assert_that(csis_instance != nullptr, "csis_instance does not exist!");
407     csis_instance->SetLockState(target_lock_state);
408 
409     if (csis_group->GetLockTransitionCnt() == 0) {
410       log::error("Not expected lock state");
411       return;
412     }
413 
414     if (csis_group->UpdateLockTransitionCnt(-1) == 0) {
415       csis_group->SetCurrentLockState(csis_group->GetTargetLockState());
416       CsisLockCompleted(csis_group,
417                         csis_group->GetCurrentLockState() == CsisLockState::CSIS_STATE_LOCKED,
418                         CsisGroupLockStatus::SUCCESS);
419       return;
420     }
421 
422     if (target_lock_state == CsisLockState::CSIS_STATE_LOCKED) {
423       std::shared_ptr<CsisDevice> next_dev;
424 
425       do {
426         next_dev = csis_group->GetNextDevice(device);
427         if (!next_dev) {
428           break;
429         }
430       } while (!next_dev->IsConnected());
431 
432       if (next_dev) {
433         auto next_csis_inst = next_dev->GetCsisInstanceByGroupId(group_id);
434         log::assert_that(csis_instance != nullptr, "csis_instance does not exist!");
435 #if CSIP_UPPER_TESTER_FORCE_TO_SEND_LOCK == FALSE
436         if (next_csis_inst->GetLockState() == CsisLockState::CSIS_STATE_LOCKED) {
437           /* Somebody else managed to lock it.
438            * Unlock previous devices
439            */
440           HandleCsisLockProcedureError(csis_group, next_dev);
441           return;
442         }
443 #endif
444         SetLock(next_dev, next_csis_inst, CsisLockState::CSIS_STATE_LOCKED);
445       }
446     }
447   }
448 
SetLock(std::shared_ptr<CsisDevice> & device,std::shared_ptr<CsisInstance> & csis_instance,CsisLockState lock)449   void SetLock(std::shared_ptr<CsisDevice>& device, std::shared_ptr<CsisInstance>& csis_instance,
450                CsisLockState lock) {
451     std::vector<uint8_t> value = {(std::underlying_type<CsisLockState>::type)lock};
452 
453     log::info("{},  rank: {}, conn_id: 0x{:04x}, handle: 0x{:04x}", device->addr,
454               csis_instance->GetRank(), device->conn_id,
455               csis_instance->svc_data.lock_handle.val_hdl);
456 
457     BtaGattQueue::WriteCharacteristic(
458             device->conn_id, csis_instance->svc_data.lock_handle.val_hdl, value, GATT_WRITE,
459             [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t /*len*/,
460                const uint8_t* /*value*/, void* data) {
461               if (instance) {
462                 instance->OnGattCsisWriteLockRsp(conn_id, status, handle, data);
463               }
464             },
465             UINT_TO_PTR(csis_instance->GetGroupId()));
466   }
467 
NotifyGroupStatus(int group_id,bool lock,CsisGroupLockStatus status,CsisLockCb cb)468   void NotifyGroupStatus(int group_id, bool lock, CsisGroupLockStatus status, CsisLockCb cb) {
469     callbacks_->OnGroupLockChanged(group_id, lock, status);
470     if (cb) {
471       std::move(cb).Run(group_id, lock, status);
472     }
473   }
474 
GetDeviceList(int group_id)475   std::vector<RawAddress> GetDeviceList(int group_id) override {
476     std::vector<RawAddress> result;
477     auto csis_group = FindCsisGroup(group_id);
478 
479     if (!csis_group || csis_group->IsEmpty()) {
480       return result;
481     }
482 
483     auto csis_device = csis_group->GetFirstDevice();
484     while (csis_device) {
485       result.push_back(csis_device->addr);
486       csis_device = csis_group->GetNextDevice(csis_device);
487     }
488 
489     return result;
490   }
491 
LockGroup(int group_id,bool lock,CsisLockCb cb)492   void LockGroup(int group_id, bool lock, CsisLockCb cb) override {
493     if (lock) {
494       log::debug("Locking group: {}", group_id);
495     } else {
496       log::debug("Unlocking group: {}", group_id);
497     }
498 
499     /* For now we try to lock only connected devices in the group
500      * TODO: We can consider reconnected to not connected devices and then
501      * locked them
502      */
503     auto csis_group = FindCsisGroup(group_id);
504     if (csis_group == nullptr) {
505       log::error("Group not found: {}", group_id);
506       NotifyGroupStatus(group_id, false, CsisGroupLockStatus::FAILED_INVALID_GROUP, std::move(cb));
507       return;
508     }
509 
510     if (csis_group->IsEmpty()) {
511       NotifyGroupStatus(group_id, false, CsisGroupLockStatus::FAILED_GROUP_EMPTY, std::move(cb));
512       return;
513     }
514 
515     if (csis_group->GetTargetLockState() != CsisLockState::CSIS_STATE_UNSET) {
516       /* CSIS operation ongoing */
517 
518       log::debug("Lock operation ongoing: group id: {}, target state {}", group_id,
519                  (csis_group->GetTargetLockState() == CsisLockState::CSIS_STATE_LOCKED ? "lock"
520                                                                                        : "unlock"));
521       return;
522     }
523 
524     CsisLockState new_lock_state =
525             lock ? CsisLockState::CSIS_STATE_LOCKED : CsisLockState::CSIS_STATE_UNLOCKED;
526 
527     if (csis_group->GetCurrentLockState() == new_lock_state) {
528       log::debug("Nothing to do as requested lock is there");
529       NotifyGroupStatus(group_id, lock, CsisGroupLockStatus::SUCCESS, std::move(cb));
530       return;
531     }
532 
533 #if CSIP_UPPER_TESTER_FORCE_TO_SEND_LOCK == FALSE
534     if (lock && !csis_group->IsAvailableForCsisLockOperation()) {
535       log::debug("Group {} locked by other", group_id);
536       NotifyGroupStatus(group_id, false, CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER,
537                         std::move(cb));
538       return;
539     }
540 #endif
541 
542     csis_group->SetTargetLockState(new_lock_state, std::move(cb));
543 
544     if (lock) {
545       /* In locking case we need to make sure we lock all the device
546        * and that in case of error on the way to lock the group, we
547        * can revert lock previously locked devices as per specification.
548        */
549       auto csis_device = csis_group->GetFirstDevice();
550       while (!csis_device->IsConnected()) {
551         csis_device = csis_group->GetNextDevice(csis_device);
552       }
553 
554       auto csis_instance = csis_device->GetCsisInstanceByGroupId(group_id);
555       log::assert_that(csis_instance != nullptr, "csis_instance does not exist!");
556       SetLock(csis_device, csis_instance, new_lock_state);
557     } else {
558       /* For unlocking, we don't have to monitor status of unlocking device,
559        * therefore, we can just send unlock to all of them, in oposite rank
560        * order and check if we get new state notification.
561        */
562       auto csis_device = csis_group->GetLastDevice();
563       auto csis_instance = csis_device->GetCsisInstanceByGroupId(group_id);
564       log::assert_that(csis_instance != nullptr, "csis_instance does not exist!");
565       while (csis_device) {
566         if ((csis_device->IsConnected()) && (csis_instance->GetLockState() != new_lock_state)) {
567           csis_group->UpdateLockTransitionCnt(1);
568           SetLock(csis_device, csis_instance, new_lock_state);
569         }
570         csis_device = csis_group->GetPrevDevice(csis_device);
571       }
572     }
573   }
574 
GetDesiredSize(int group_id) const575   int GetDesiredSize(int group_id) const override {
576     auto csis_group = FindCsisGroup(group_id);
577     if (!csis_group) {
578       log::info("Unknown group {}", group_id);
579       return -1;
580     }
581 
582     return csis_group->GetDesiredSize();
583   }
584 
SerializeSets(const RawAddress & addr,std::vector<uint8_t> & out) const585   bool SerializeSets(const RawAddress& addr, std::vector<uint8_t>& out) const {
586     auto device = FindDeviceByAddress(addr);
587     if (device == nullptr) {
588       log::warn("Skipping unknown device addr= {}", addr);
589       return false;
590     }
591 
592     if (device->GetNumberOfCsisInstances() == 0) {
593       log::warn("No CSIS instances for addr= {}", addr);
594       return false;
595     }
596 
597     log::debug(": device= {}", device->addr);
598 
599     auto num_sets = device->GetNumberOfCsisInstances();
600     if ((num_sets == 0) || (num_sets > std::numeric_limits<uint8_t>::max())) {
601       return false;
602     }
603 
604     out.resize(CSIS_STORAGE_HEADER_SZ + (num_sets * CSIS_STORAGE_ENTRY_SZ));
605     auto* ptr = out.data();
606 
607     /* header */
608     UINT8_TO_STREAM(ptr, CSIS_STORAGE_CURRENT_LAYOUT_MAGIC);
609     UINT8_TO_STREAM(ptr, num_sets);
610 
611     /* set entries */
612     device->ForEachCsisInstance([&](const std::shared_ptr<CsisInstance>& csis_inst) {
613       auto gid = csis_inst->GetGroupId();
614       auto csis_group = FindCsisGroup(gid);
615       if (csis_group == nullptr) {
616         log::error("SerializeSets: No matching group found!");
617         return;
618       }
619 
620       UINT8_TO_STREAM(ptr, gid);
621       UINT8_TO_STREAM(ptr, csis_group->GetDesiredSize());
622       UINT8_TO_STREAM(ptr, csis_inst->GetRank());
623       Octet16 sirk = csis_group->GetSirk();
624       memcpy(ptr, sirk.data(), sirk.size());
625       ptr += sirk.size();
626     });
627 
628     return true;
629   }
630 
DeserializeSets(const RawAddress & addr,const std::vector<uint8_t> & in)631   std::map<uint8_t, uint8_t> DeserializeSets(const RawAddress& addr,
632                                              const std::vector<uint8_t>& in) {
633     std::map<uint8_t, uint8_t> group_rank_map;
634 
635     if (in.size() < CSIS_STORAGE_HEADER_SZ + CSIS_STORAGE_ENTRY_SZ) {
636       return group_rank_map;
637     }
638     auto* ptr = in.data();
639 
640     uint8_t magic;
641     STREAM_TO_UINT8(magic, ptr);
642 
643     if (magic == CSIS_STORAGE_CURRENT_LAYOUT_MAGIC) {
644       uint8_t num_sets;
645       STREAM_TO_UINT8(num_sets, ptr);
646 
647       if (in.size() < CSIS_STORAGE_HEADER_SZ + (num_sets * CSIS_STORAGE_ENTRY_SZ)) {
648         log::error("Invalid persistent storage data");
649         return group_rank_map;
650       }
651 
652       /* sets entries */
653       while (num_sets--) {
654         uint8_t gid;
655         Octet16 sirk;
656         uint8_t size;
657         uint8_t rank;
658 
659         STREAM_TO_UINT8(gid, ptr);
660         STREAM_TO_UINT8(size, ptr);
661         STREAM_TO_UINT8(rank, ptr);
662         STREAM_TO_ARRAY(sirk.data(), ptr, (int)sirk.size());
663 
664         // Set grouping and SIRK
665         auto csis_group = AssignCsisGroup(addr, gid, true, Uuid::kEmpty);
666         if (csis_group == nullptr) {
667           continue;
668         }
669 
670         csis_group->SetDesiredSize(size);
671         csis_group->SetSirk(sirk);
672 
673         // TODO: Save it for later, so we won't have to read it using GATT
674         group_rank_map[gid] = rank;
675       }
676     }
677 
678     return group_rank_map;
679   }
680 
StartOpportunisticConnect(const RawAddress & address)681   void StartOpportunisticConnect(const RawAddress& address) {
682     /* Oportunistic works only for direct connect,
683      * but in fact this is background connect
684      */
685     log::info(": {}", address);
686     BTA_GATTC_Open(gatt_if_, address, BTM_BLE_DIRECT_CONNECTION, true);
687   }
688 
AddFromStorage(const RawAddress & addr,const std::vector<uint8_t> & in)689   void AddFromStorage(const RawAddress& addr, const std::vector<uint8_t>& in) {
690     auto group_rank_map = DeserializeSets(addr, in);
691 
692     log::debug("{}, number of groups {}", addr, static_cast<int>(csis_groups_.size()));
693 
694     auto device = FindDeviceByAddress(addr);
695     if (device == nullptr) {
696       device = std::make_shared<CsisDevice>(addr, false);
697       devices_.push_back(device);
698     }
699 
700     for (const auto& csis_group : csis_groups_) {
701       if (!csis_group->IsDeviceInTheGroup(device)) {
702         continue;
703       }
704 
705       if (csis_group->GetUuid() != Uuid::kEmpty) {
706         auto group_id = csis_group->GetGroupId();
707         uint8_t rank = bluetooth::csis::CSIS_RANK_INVALID;
708         if (group_rank_map.count(group_id) != 0) {
709           rank = group_rank_map.at(group_id);
710         }
711 
712         callbacks_->OnDeviceAvailable(device->addr, group_id, csis_group->GetDesiredSize(), rank,
713                                       csis_group->GetUuid());
714       }
715     }
716 
717     /* For bonded devices, CSIP can be always opportunistic service */
718     StartOpportunisticConnect(addr);
719   }
720 
CleanUp()721   void CleanUp() {
722     log::debug("");
723 
724     BTA_GATTC_AppDeregister(gatt_if_);
725     for (auto& device : devices_) {
726       if (device->IsConnected()) {
727         BTA_GATTC_Close(device->conn_id);
728       }
729       DoDisconnectCleanUp(device);
730     }
731 
732     devices_.clear();
733     csis_groups_.clear();
734 
735     CsisObserverSetBackground(false);
736     dev_groups_->CleanUp(device_group_callbacks);
737   }
738 
Dump(int fd)739   void Dump(int fd) {
740     std::stringstream stream;
741 
742     stream << "  APP ID: " << +gatt_if_ << "\n"
743            << "  Groups:\n";
744     for (const auto& g : csis_groups_) {
745       stream << "    == id: " << g->GetGroupId() << " ==\n"
746              << "    uuid: " << g->GetUuid() << "\n"
747              << "    desired size: " << g->GetDesiredSize() << "\n"
748              << "    discoverable state: " << static_cast<int>(g->GetDiscoveryState()) << "\n"
749              << "    current lock state: " << static_cast<int>(g->GetCurrentLockState()) << "\n"
750              << "    target lock state: " << static_cast<int>(g->GetTargetLockState()) << "\n"
751              << "    devices: \n";
752       for (auto& device : devices_) {
753         if (!g->IsDeviceInTheGroup(device)) {
754           if (device->GetExpectedGroupIdMember() == g->GetGroupId()) {
755             stream << "        == candidate addr: " << ADDRESS_TO_LOGGABLE_STR(device->addr)
756                    << "\n";
757           }
758           continue;
759         }
760 
761         stream << "        == addr: " << ADDRESS_TO_LOGGABLE_STR(device->addr) << " ==\n"
762                << "        csis instance: data:" << "\n";
763 
764         auto instance = device->GetCsisInstanceByGroupId(g->GetGroupId());
765         if (!instance) {
766           stream << "          No csis instance available\n";
767         } else {
768           stream << "          service handle: " << loghex(instance->svc_data.start_handle)
769                  << "          rank: " << +instance->GetRank() << "\n";
770         }
771 
772         if (!device->IsConnected()) {
773           stream << "        Not connected\n";
774         } else {
775           stream << "        Connected conn_id = " << std::to_string(device->conn_id) << "\n";
776         }
777       }
778     }
779 
780     dprintf(fd, "%s", stream.str().c_str());
781   }
782 
783 private:
FindDeviceByConnId(tCONN_ID conn_id)784   std::shared_ptr<CsisDevice> FindDeviceByConnId(tCONN_ID conn_id) {
785     auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchConnId(conn_id));
786     if (it != devices_.end()) {
787       return *it;
788     }
789 
790     return nullptr;
791   }
792 
RemoveCsisDevice(std::shared_ptr<CsisDevice> & device)793   void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device) {
794     auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(device->addr));
795     devices_.erase(it);
796   }
797 
RemoveCsisDevice(std::shared_ptr<CsisDevice> & device,int group_id)798   void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device, int group_id) {
799     log::info("");
800     auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(device->addr));
801     if (it == devices_.end()) {
802       return;
803     }
804 
805     if (group_id != bluetooth::groups::kGroupUnknown) {
806       auto csis_group = FindCsisGroup(group_id);
807       if (!csis_group) {
808         /* This could happen when remove device is called when bonding is
809          * removed */
810         log::info("group not found {}", group_id);
811         return;
812       }
813 
814       csis_group->RemoveDevice(device->addr);
815 
816       if (csis_group->IsEmpty()) {
817         RemoveCsisGroup(group_id);
818 
819         /* Remove cached candidate devices for group */
820         devices_.erase(std::remove_if(devices_.begin(), devices_.end(),
821                                       [group_id](auto& dev) {
822                                         if (dev->GetNumberOfCsisInstances() == 0 &&
823                                             dev->GetExpectedGroupIdMember() == group_id &&
824                                             dev->GetPairingSirkReadFlag() == false) {
825                                           return true;
826                                         }
827 
828                                         return false;
829                                       }),
830                        devices_.end());
831       }
832 
833       device->RemoveCsisInstance(group_id);
834     }
835 
836     if (device->GetNumberOfCsisInstances() == 0) {
837       devices_.erase(it);
838     }
839   }
840 
FindDeviceByAddress(const RawAddress & addr) const841   std::shared_ptr<CsisDevice> FindDeviceByAddress(const RawAddress& addr) const {
842     auto it = find_if(devices_.cbegin(), devices_.cend(), CsisDevice::MatchAddress(addr));
843     if (it != devices_.end()) {
844       return *it;
845     }
846 
847     return nullptr;
848   }
849 
FindCsisGroup(int group_id) const850   std::shared_ptr<CsisGroup> FindCsisGroup(int group_id) const {
851     auto it = find_if(csis_groups_.cbegin(), csis_groups_.cend(),
852                       [group_id](auto& g) { return group_id == g->GetGroupId(); });
853 
854     if (it == csis_groups_.end()) {
855       return nullptr;
856     }
857     return *it;
858   }
859 
RemoveCsisGroup(int group_id)860   void RemoveCsisGroup(int group_id) {
861     for (auto it = csis_groups_.begin(); it != csis_groups_.end(); it++) {
862       if ((*it)->GetGroupId() == group_id) {
863         csis_groups_.erase(it);
864         return;
865       }
866     }
867   }
868 
869   /* Handle encryption */
OnEncrypted(std::shared_ptr<CsisDevice> & device)870   void OnEncrypted(std::shared_ptr<CsisDevice>& device) {
871     log::debug("{}", device->addr);
872 
873     if (device->is_gatt_service_valid) {
874       NotifyCsisDeviceValidAndStoreIfNeeded(device);
875     } else {
876       BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
877     }
878   }
879 
NotifyCsisDeviceValidAndStoreIfNeeded(std::shared_ptr<CsisDevice> & device)880   void NotifyCsisDeviceValidAndStoreIfNeeded(std::shared_ptr<CsisDevice>& device) {
881     /* Notify that we are ready to go. Notice that multiple callback calls
882      * for a single device address can be called if device is in more than one
883      * CSIS group.
884      */
885     bool notify_connected = false;
886     int group_id_to_discover = bluetooth::groups::kGroupUnknown;
887     for (const auto& csis_group : csis_groups_) {
888       if (!csis_group->IsDeviceInTheGroup(device)) {
889         continue;
890       }
891 
892       int group_id = csis_group->GetGroupId();
893       auto csis_instance = device->GetCsisInstanceByGroupId(group_id);
894       log::debug("group id {}", group_id);
895 
896       if (!csis_instance) {
897         /* This can happen when some other user added device to group in the
898          * context which is not existing on the peer side. e.g. LeAudio added it
899          * in the CAP context, but CSIS exist on the peer device without a
900          * context. We will endup in having device in 2 groups. One in generic
901          * context with valid csis_instance, and one in CAP context without csis
902          * instance */
903         log::info("csis_instance does not exist for group {}", group_id);
904         continue;
905       }
906 
907       callbacks_->OnDeviceAvailable(device->addr, group_id, csis_group->GetDesiredSize(),
908                                     csis_instance->GetRank(), csis_instance->GetUuid());
909       notify_connected = true;
910 
911       if (group_id_to_discover == bluetooth::groups::kGroupUnknown) {
912         group_id_to_discover = group_id;
913       }
914     }
915 
916     if (notify_connected) {
917       callbacks_->OnConnectionState(device->addr, ConnectionState::CONNECTED);
918 
919       log::debug("group_id {}", group_id_to_discover);
920       if (group_id_to_discover != bluetooth::groups::kGroupUnknown) {
921         /* Start active search for the other device
922          * b/281120322
923          */
924         auto g = FindCsisGroup(group_id_to_discover);
925         log::debug("Group size  {}  target size {}", g->GetDesiredSize(), g->GetCurrentSize());
926 
927         auto dev_waiting_for_bonding_cnt =
928                 GetNumOfKnownExpectedDevicesWaitingForBonding(g->GetGroupId());
929         log::debug("Group size: {}, desired size: {}, waiting for bonding: {}", g->GetCurrentSize(),
930                    g->GetDesiredSize(), dev_waiting_for_bonding_cnt);
931 
932         if (g->GetDesiredSize() > g->GetCurrentSize() + dev_waiting_for_bonding_cnt) {
933           CsisActiveDiscovery(g);
934         }
935       }
936     }
937   }
938 
OnGattWriteCcc(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,void *)939   void OnGattWriteCcc(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, void* /*user_data*/) {
940     auto device = FindDeviceByConnId(conn_id);
941     if (device == nullptr) {
942       log::info("unknown conn_id= 0x{:04x}", conn_id);
943       BtaGattQueue::Clean(conn_id);
944       return;
945     }
946 
947     if (status == GATT_DATABASE_OUT_OF_SYNC) {
948       log::info("Database out of sync for {}", device->addr);
949       ClearDeviceInformationAndStartSearch(device);
950       return;
951     }
952 
953     if (status == GATT_SUCCESS) {
954       log::info("Successfully registered on ccc: 0x{:04x}, device: {}", handle, device->addr);
955       return;
956     }
957 
958     log::error("Failed to register for indications: 0x{:04x}, device: {}, status: 0x{:02x}", handle,
959                device->addr, status);
960 
961     auto val_handle = device->FindValueHandleByCccHandle(handle);
962     if (!val_handle) {
963       log::error("Unknown ccc handle: 0x{:04x}, device: {}", handle, device->addr);
964       return;
965     }
966 
967     if (val_handle != GAP_INVALID_HANDLE) {
968       BTA_GATTC_DeregisterForNotifications(gatt_if_, device->addr, val_handle);
969     }
970   }
971 
OnCsisNotification(tCONN_ID conn_id,uint16_t handle,uint16_t len,const uint8_t * value)972   void OnCsisNotification(tCONN_ID conn_id, uint16_t handle, uint16_t len, const uint8_t* value) {
973     auto device = FindDeviceByConnId(conn_id);
974     if (device == nullptr) {
975       log::warn("Skipping unknown device, conn_id= 0x{:04x}", conn_id);
976       return;
977     }
978 
979     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
980     if (csis_instance == nullptr) {
981       log::error("unknown notification handle: 0x{:04x} for conn_id: 0x{:04x}", handle, conn_id);
982       return;
983     }
984 
985     if (handle == csis_instance->svc_data.sirk_handle.val_hdl) {
986       OnCsisSirkValueUpdate(conn_id, GATT_SUCCESS, handle, len, value);
987     } else if (handle == csis_instance->svc_data.lock_handle.val_hdl) {
988       OnCsisLockNotifications(device, csis_instance, len, value);
989     } else if (handle == csis_instance->svc_data.size_handle.val_hdl) {
990       OnCsisSizeValueUpdate(conn_id, GATT_SUCCESS, handle, len, value);
991     } else {
992       log::warn("unknown notification handle 0x{:04x} for conn_id= 0x{:04x}", handle, conn_id);
993     }
994   }
995 
LockError2GroupLockStatus(tGATT_STATUS status)996   static CsisGroupLockStatus LockError2GroupLockStatus(tGATT_STATUS status) {
997     switch (status) {
998       case bluetooth::csis::kCsisErrorCodeLockDenied:
999         return CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER;
1000       case bluetooth::csis::kCsisErrorCodeReleaseNotAllowed:
1001         return CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER;
1002       case bluetooth::csis::kCsisErrorCodeInvalidValue:
1003         return CsisGroupLockStatus::FAILED_OTHER_REASON;
1004       default:
1005         return CsisGroupLockStatus::FAILED_OTHER_REASON;
1006     }
1007   }
1008 
CsisLockCompleted(std::shared_ptr<CsisGroup> & csis_group,bool lock,CsisGroupLockStatus status)1009   void CsisLockCompleted(std::shared_ptr<CsisGroup>& csis_group, bool lock,
1010                          CsisGroupLockStatus status) {
1011     log::debug("group id: {}, target state {}", csis_group->GetGroupId(), lock ? "lock" : "unlock");
1012 
1013     NotifyGroupStatus(csis_group->GetGroupId(), lock, status, csis_group->GetLockCb());
1014     csis_group->SetTargetLockState(CsisLockState::CSIS_STATE_UNSET);
1015   }
1016 
OnCsisLockNotifications(std::shared_ptr<CsisDevice> &,std::shared_ptr<CsisInstance> & csis_instance,uint16_t len,const uint8_t * value)1017   void OnCsisLockNotifications(std::shared_ptr<CsisDevice>& /*device*/,
1018                                std::shared_ptr<CsisInstance>& csis_instance, uint16_t len,
1019                                const uint8_t* value) {
1020     if (len != 1) {
1021       log::error("invalid notification len: {}", len);
1022       return;
1023     }
1024 
1025     CsisLockState new_lock = (CsisLockState)(value[0]);
1026 
1027     log::debug("New lock state: {},  device rank:  {}", static_cast<int>(new_lock),
1028                csis_instance->GetRank());
1029 
1030     csis_instance->SetLockState(new_lock);
1031 
1032     auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
1033     if (!csis_group) {
1034       return;
1035     }
1036 
1037     CsisLockCb cb = csis_group->GetLockCb();
1038     if (csis_group->GetTargetLockState() == CsisLockState::CSIS_STATE_UNSET) {
1039       if (csis_group->GetCurrentLockState() == CsisLockState::CSIS_STATE_LOCKED &&
1040           new_lock == CsisLockState::CSIS_STATE_UNLOCKED) {
1041         /* We are here when members fires theirs lock timeout.
1042          * Not sure what to do with our current lock state. For now we will
1043          * change local lock state after first set member removes its lock. Then
1044          * we count that others will do the same
1045          */
1046         csis_group->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
1047         NotifyGroupStatus(csis_group->GetGroupId(), false, CsisGroupLockStatus::SUCCESS,
1048                           std::move(cb));
1049       }
1050       return;
1051     }
1052 
1053     if (csis_group->GetCurrentLockState() != csis_group->GetTargetLockState()) {
1054       /* We are in process of changing lock state. If new device lock
1055        * state is what is targeted that means all is good, we don't need
1056        * to do here nothing, as state will be changed once all the
1057        * characteristics are written. If new device state is not what is
1058        * targeted, that means, device changed stated unexpectedly and locking
1059        * procedure is broken
1060        */
1061       if (new_lock != csis_group->GetTargetLockState()) {
1062         /* Device changed back the lock state from what we expected, skip
1063          * locking and notify user about that
1064          */
1065         CsisLockCompleted(csis_group, false, CsisGroupLockStatus::FAILED_OTHER_REASON);
1066       }
1067     }
1068   }
1069 
OnCsisSizeValueUpdate(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services=false)1070   void OnCsisSizeValueUpdate(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1071                              const uint8_t* value, bool notify_valid_services = false) {
1072     auto device = FindDeviceByConnId(conn_id);
1073 
1074     if (device == nullptr) {
1075       log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id);
1076       return;
1077     }
1078 
1079     log::debug("{}, status: 0x{:02x}", device->addr, status);
1080 
1081     if (status != GATT_SUCCESS) {
1082       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1083         log::info("Database out of sync for {}", device->addr);
1084         ClearDeviceInformationAndStartSearch(device);
1085       } else {
1086         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1087         BTA_GATTC_Close(device->conn_id);
1088       }
1089       return;
1090     }
1091 
1092     if (len != 1) {
1093       log::error("Invalid size value length={} at handle= 0x{:04x}", len, handle);
1094       BTA_GATTC_Close(device->conn_id);
1095       return;
1096     }
1097 
1098     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1099     if (csis_instance == nullptr) {
1100       log::error("Unknown csis instance");
1101       BTA_GATTC_Close(device->conn_id);
1102       return;
1103     }
1104     auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
1105     if (!csis_group) {
1106       log::error("Unknown group id yet");
1107       return;
1108     }
1109 
1110     auto new_size = value[0];
1111     csis_group->SetDesiredSize(new_size);
1112 
1113     if (notify_valid_services) {
1114       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1115     }
1116   }
1117 
OnCsisLockReadRsp(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services=false)1118   void OnCsisLockReadRsp(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1119                          const uint8_t* value, bool notify_valid_services = false) {
1120     auto device = FindDeviceByConnId(conn_id);
1121     if (device == nullptr) {
1122       log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id);
1123       return;
1124     }
1125 
1126     log::info("{}, status 0x{:02x}", device->addr, status);
1127 
1128     if (status != GATT_SUCCESS) {
1129       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1130         log::info("Database out of sync for {}", device->addr);
1131         ClearDeviceInformationAndStartSearch(device);
1132       } else {
1133         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1134         BTA_GATTC_Close(device->conn_id);
1135       }
1136       return;
1137     }
1138 
1139     if (len != 1) {
1140       log::error("Invalid lock value length={}, at handle=0x{:04x}", len, handle);
1141       BTA_GATTC_Close(device->conn_id);
1142       return;
1143     }
1144 
1145     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1146     if (csis_instance == nullptr) {
1147       log::error("Unknown csis instance");
1148       BTA_GATTC_Close(device->conn_id);
1149       return;
1150     }
1151     csis_instance->SetLockState((CsisLockState)(value[0]));
1152 
1153     if (notify_valid_services) {
1154       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1155     }
1156   }
1157 
OnCsisRankReadRsp(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services)1158   void OnCsisRankReadRsp(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1159                          const uint8_t* value, bool notify_valid_services) {
1160     auto device = FindDeviceByConnId(conn_id);
1161     if (device == nullptr) {
1162       log::warn("Skipping unknown device, conn_id= 0x{:04x}", conn_id);
1163       return;
1164     }
1165 
1166     log::debug("{}, status: 0x{:02x}, rank: {}", device->addr, status, value[0]);
1167     if (status != GATT_SUCCESS) {
1168       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1169         log::info("Database out of sync for {}", device->addr);
1170         ClearDeviceInformationAndStartSearch(device);
1171       } else {
1172         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1173         BTA_GATTC_Close(device->conn_id);
1174       }
1175       return;
1176     }
1177 
1178     if (len != 1) {
1179       log::error("Invalid rank value length= {},  at handle= 0x{:04x}", len, handle);
1180       BTA_GATTC_Close(device->conn_id);
1181       return;
1182     }
1183 
1184     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1185     if (csis_instance == nullptr) {
1186       log::error("Unknown csis instance handle 0x{:04x}", handle);
1187       BTA_GATTC_Close(device->conn_id);
1188       return;
1189     }
1190 
1191     csis_instance->SetRank(value[0]);
1192     auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
1193     if (!csis_group) {
1194       log::error("Unknown group id yet");
1195       return;
1196     }
1197 
1198     csis_group->SortByCsisRank();
1199 
1200     if (notify_valid_services) {
1201       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1202     }
1203   }
1204 
OnCsisObserveCompleted(void)1205   void OnCsisObserveCompleted(void) {
1206     log::info("Group_id: {}", discovering_group_);
1207 
1208     if (discovering_group_ == bluetooth::groups::kGroupUnknown) {
1209       log::error("No ongoing CSIS discovery - disable scan");
1210       return;
1211     }
1212 
1213     auto csis_group = FindCsisGroup(discovering_group_);
1214     discovering_group_ = bluetooth::groups::kGroupUnknown;
1215 
1216     if (!csis_group) {
1217       log::warn("Group_id {} is not existing", discovering_group_);
1218       discovering_group_ = bluetooth::groups::kGroupUnknown;
1219       return;
1220     }
1221 
1222     discovering_group_ = bluetooth::groups::kGroupUnknown;
1223     if (csis_group->IsGroupComplete()) {
1224       csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
1225     } else {
1226       csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1227     }
1228   }
1229 
1230   /*
1231    * Sirk shall be in LE order
1232    * encrypted_sirk: LE order
1233    */
sdf(const RawAddress & address,const Octet16 & encrypted_sirk,Octet16 & sirk)1234   bool sdf(const RawAddress& address, const Octet16& encrypted_sirk, Octet16& sirk) {
1235     auto pltk = BTM_BleGetPeerLTK(address);
1236     if (!pltk.has_value()) {
1237       log::error("No security for {}", address);
1238       return false;
1239     }
1240 
1241 #ifdef CSIS_DEBUG
1242     auto irk = BTM_BleGetPeerIRK(address);
1243     log::info("LTK {}", base::HexEncode(*pltk.data(), 16));
1244     log::info("IRK {}", base::HexEncode(*irk.data(), 16));
1245 #endif
1246 
1247     /* Calculate salt CSIS d1.0r05 4.3 */
1248     Octet16 zero_key;
1249     memset(zero_key.data(), 0, 16);
1250 
1251     std::string msg1 = "SIRKenc";
1252     std::reverse(msg1.begin(), msg1.end());
1253 
1254     Octet16 s1 = crypto_toolbox::aes_cmac(zero_key, (uint8_t*)(msg1.c_str()), msg1.size());
1255 
1256 #ifdef CSIS_DEBUG
1257     log::info("s1 (le) {}", base::HexEncode(s1.data(), 16));
1258     /* Create K = LTK */
1259     log::info("K (le) {}", base::HexEncode(*pltk.data(), 16));
1260 #endif
1261 
1262     Octet16 T = crypto_toolbox::aes_cmac(s1, *pltk);
1263 
1264 #ifdef CSIS_DEBUG
1265     log::info("T (le) {}", base::HexEncode(T.data(), 16));
1266 #endif
1267 
1268     std::string msg2 = "csis";
1269     std::reverse(msg2.begin(), msg2.end());
1270 
1271     Octet16 k1 = crypto_toolbox::aes_cmac(T, (uint8_t*)(msg2.c_str()), msg2.size());
1272 #ifdef CSIS_DEBUG
1273     log::info("K1 (le) {}", base::HexEncode(k1.data(), 16));
1274 #endif
1275 
1276     for (int i = 0; i < 16; i++) {
1277       sirk[i] = encrypted_sirk[i] ^ k1[i];
1278     }
1279 
1280 #ifdef CSIS_DEBUG
1281     log::info("SIRK (le){}", base::HexEncode(sirk.data(), 16));
1282 #endif
1283 
1284     return true;
1285   }
1286 
GetAllRsiFromAdvertising(const tBTA_DM_INQ_RES * result)1287   std::vector<RawAddress> GetAllRsiFromAdvertising(const tBTA_DM_INQ_RES* result) {
1288     const uint8_t* p_service_data = result->p_eir;
1289     std::vector<RawAddress> devices;
1290     uint8_t service_data_len = 0;
1291 
1292     while ((p_service_data = AdvertiseDataParser::GetFieldByType(
1293                     p_service_data + service_data_len,
1294                     result->eir_len - (p_service_data - result->p_eir) - service_data_len,
1295                     BTM_BLE_AD_TYPE_RSI, &service_data_len))) {
1296       RawAddress bda;
1297       const uint8_t* p_bda = p_service_data;
1298       if (service_data_len < RawAddress::kLength) {
1299         continue;
1300       }
1301 
1302       STREAM_TO_BDADDR(bda, p_bda);
1303       devices.push_back(std::move(bda));
1304     }
1305 
1306     return devices;
1307   }
1308 
GetNumOfKnownExpectedDevicesWaitingForBonding(int group_id)1309   int GetNumOfKnownExpectedDevicesWaitingForBonding(int group_id) {
1310     return std::count_if(devices_.begin(), devices_.end(), [group_id](const auto& device) {
1311       return device->GetExpectedGroupIdMember() == group_id &&
1312              !device->GetCsisInstanceByGroupId(group_id);
1313     });
1314   }
1315 
CacheAndAdvertiseExpectedMember(const RawAddress & address,int group_id)1316   void CacheAndAdvertiseExpectedMember(const RawAddress& address, int group_id) {
1317     auto device = FindDeviceByAddress(address);
1318     if (device == nullptr) {
1319       device = std::make_shared<CsisDevice>(address, false);
1320       devices_.push_back(device);
1321     }
1322 
1323     /*
1324      * Expected group ID will be checked while reading SIRK if this device
1325      * truly is member of group.
1326      */
1327     device.get()->SetExpectedGroupIdMember(group_id);
1328     callbacks_->OnSetMemberAvailable(address, device.get()->GetExpectedGroupIdMember());
1329   }
1330 
OnActiveScanResult(const tBTA_DM_INQ_RES * result)1331   void OnActiveScanResult(const tBTA_DM_INQ_RES* result) {
1332     auto csis_device = FindDeviceByAddress(result->bd_addr);
1333     if (csis_device) {
1334       log::debug("Drop same device .. {}", result->bd_addr);
1335       return;
1336     }
1337 
1338     /* Make sure device is not already bonded which could
1339      * be a case for dual mode devices where
1340      */
1341     if (BTM_BleIsLinkKeyKnown(result->bd_addr)) {
1342       log::verbose("Device {} already bonded. Identity address: {}", result->bd_addr,
1343                    *BTM_BleGetIdentityAddress(result->bd_addr));
1344       return;
1345     }
1346 
1347     auto all_rsi = GetAllRsiFromAdvertising(result);
1348     if (all_rsi.empty()) {
1349       return;
1350     }
1351 
1352     /* Notify only the actively searched group */
1353     auto csis_group = FindCsisGroup(discovering_group_);
1354     if (csis_group == nullptr) {
1355       log::error("No ongoing CSIS discovery - disable scan");
1356       CsisActiveObserverSet(false);
1357       return;
1358     }
1359 
1360     if (csis_group->GetDesiredSize() > 0 &&
1361         (csis_group->GetDesiredSize() == csis_group->GetCurrentSize())) {
1362       log::warn("Group is already complete");
1363       return;
1364     }
1365 
1366     auto discovered_group_rsi =
1367             std::find_if(all_rsi.cbegin(), all_rsi.cend(),
1368                          [&csis_group](const auto& rsi) { return csis_group->IsRsiMatching(rsi); });
1369     if (discovered_group_rsi != all_rsi.cend()) {
1370       log::debug("Found set member {}", result->bd_addr);
1371 
1372       CacheAndAdvertiseExpectedMember(result->bd_addr, csis_group->GetGroupId());
1373 
1374       /* Switch back to the opportunistic observer mode.
1375        * When second device will pair, csis will restart active scan
1376        * to search more members if needed */
1377       CsisActiveObserverSet(false);
1378       csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1379     }
1380   }
1381 
csis_ad_type_filter_set(bool enable)1382   static void csis_ad_type_filter_set(bool enable) {
1383     bool is_ad_type_filter_supported = bluetooth::shim::is_ad_type_filter_supported();
1384 
1385     log::info("enable: {}, is_ad_type_filter_supported: {}", enable, is_ad_type_filter_supported);
1386 
1387     if (is_ad_type_filter_supported) {
1388       bluetooth::shim::set_ad_type_rsi_filter(enable);
1389     } else {
1390       bluetooth::shim::set_empty_filter(enable);
1391     }
1392   }
1393 
CsisActiveObserverSet(bool enable)1394   void CsisActiveObserverSet(bool enable) {
1395     log::info("Group_id {}: enable: {}", discovering_group_, enable);
1396     csis_ad_type_filter_set(enable);
1397 
1398     BTA_DmBleCsisObserve(enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
1399       /* If there's no instance we are most likely shutting
1400        * down the whole stack and we can ignore this event.
1401        */
1402       if (instance == nullptr) {
1403         return;
1404       }
1405 
1406       if (event == BTA_DM_OBSERVE_CMPL_EVT) {
1407         power_telemetry::GetInstance().LogBleScan(static_cast<int>(p_data->observe_cmpl.num_resps));
1408         log::info("BLE observe complete. Num Resp: {}", p_data->observe_cmpl.num_resps);
1409         csis_ad_type_filter_set(false);
1410         instance->OnCsisObserveCompleted();
1411         instance->CsisObserverSetBackground(true);
1412         return;
1413       }
1414 
1415       if (event != BTA_DM_INQ_RES_EVT) {
1416         log::warn("Unknown event: 0x{:02x}", event);
1417         return;
1418       }
1419 
1420       instance->OnActiveScanResult(&p_data->inq_res);
1421     });
1422     BTA_DmBleScan(enable, bluetooth::csis::kDefaultScanDurationS);
1423 
1424     /* Need to call it by ourselfs */
1425     if (!enable) {
1426       OnCsisObserveCompleted();
1427       CsisObserverSetBackground(true);
1428     }
1429   }
1430 
CheckForGroupInInqDb(const std::shared_ptr<CsisGroup> & csis_group)1431   void CheckForGroupInInqDb(const std::shared_ptr<CsisGroup>& csis_group) {
1432     // Check if last inquiry already found devices with RSI matching this group
1433     for (tBTM_INQ_INFO* inq_ent = get_btm_client_interface().db.BTM_InqDbFirst();
1434          inq_ent != nullptr; inq_ent = get_btm_client_interface().db.BTM_InqDbNext(inq_ent)) {
1435       RawAddress rsi = inq_ent->results.ble_ad_rsi;
1436       if (!csis_group->IsRsiMatching(rsi)) {
1437         continue;
1438       }
1439 
1440       RawAddress address = inq_ent->results.remote_bd_addr;
1441       auto device = FindDeviceByAddress(address);
1442       if (device && csis_group->IsDeviceInTheGroup(device)) {
1443         // InqDb will also contain existing devices, already in group - skip
1444         // them
1445         continue;
1446       }
1447 
1448       log::info("Device {} from inquiry cache match to group id {}", address,
1449                 csis_group->GetGroupId());
1450       callbacks_->OnSetMemberAvailable(address, csis_group->GetGroupId());
1451       break;
1452     }
1453   }
1454 
CsisActiveDiscovery(std::shared_ptr<CsisGroup> csis_group)1455   void CsisActiveDiscovery(std::shared_ptr<CsisGroup> csis_group) {
1456     if (csis_group->GetDiscoveryState() != CsisDiscoveryState::CSIS_DISCOVERY_IDLE) {
1457       log::error("Incorrect ase group: {}, state 0x{:02x}", csis_group->GetGroupId(),
1458                  static_cast<int>(csis_group->GetDiscoveryState()));
1459       return;
1460     }
1461 
1462     csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
1463     /* TODO Maybe we don't need it */
1464     discovering_group_ = csis_group->GetGroupId();
1465     CsisActiveObserverSet(true);
1466   }
1467 
OnScanBackgroundResult(const tBTA_DM_INQ_RES * result)1468   void OnScanBackgroundResult(const tBTA_DM_INQ_RES* result) {
1469     if (csis_groups_.empty()) {
1470       return;
1471     }
1472 
1473     auto csis_device = FindDeviceByAddress(result->bd_addr);
1474     if (csis_device) {
1475       log::debug("Drop known device {}", result->bd_addr);
1476       return;
1477     }
1478 
1479     /* Make sure device is not already bonded which could
1480      * be a case for dual mode devices where
1481      */
1482     if (BTM_BleIsLinkKeyKnown(result->bd_addr)) {
1483       log::verbose("Device {} already bonded. Identity address: {}", result->bd_addr,
1484                    *BTM_BleGetIdentityAddress(result->bd_addr));
1485       return;
1486     }
1487 
1488     auto all_rsi = GetAllRsiFromAdvertising(result);
1489     if (all_rsi.empty()) {
1490       return;
1491     }
1492 
1493     /* Notify all the groups this device belongs to. */
1494     for (auto& group : csis_groups_) {
1495       for (auto& rsi : all_rsi) {
1496         if (group->IsRsiMatching(rsi)) {
1497           log::info("Device {} match to group id {}", result->bd_addr, group->GetGroupId());
1498           if (group->GetDesiredSize() > 0 && (group->GetCurrentSize() == group->GetDesiredSize())) {
1499             log::warn("Group is already completed. Some other device use same SIRK");
1500             break;
1501           }
1502 
1503           CacheAndAdvertiseExpectedMember(result->bd_addr, group->GetGroupId());
1504 
1505           break;
1506         }
1507       }
1508     }
1509   }
1510 
CsisObserverSetBackground(bool enable)1511   void CsisObserverSetBackground(bool enable) {
1512     log::debug("CSIS Discovery background: {}", enable);
1513 
1514     BTA_DmBleCsisObserve(enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
1515       /* If there's no instance we are most likely shutting
1516        * down the whole stack and we can ignore this event.
1517        */
1518       if (instance == nullptr) {
1519         return;
1520       }
1521 
1522       if (event == BTA_DM_OBSERVE_CMPL_EVT) {
1523         power_telemetry::GetInstance().LogBleScan(static_cast<int>(p_data->observe_cmpl.num_resps));
1524         log::verbose("BLE observe complete. Num Resp: {}", p_data->observe_cmpl.num_resps);
1525         return;
1526       }
1527 
1528       if (event != BTA_DM_INQ_RES_EVT) {
1529         log::warn("Unknown event: 0x{:02x}", event);
1530         return;
1531       }
1532 
1533       instance->OnScanBackgroundResult(&p_data->inq_res);
1534     });
1535   }
1536 
OnCsisSirkValueUpdate(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services=true)1537   void OnCsisSirkValueUpdate(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1538                              const uint8_t* value, bool notify_valid_services = true) {
1539     auto device = FindDeviceByConnId(conn_id);
1540     if (device == nullptr) {
1541       log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id);
1542       return;
1543     }
1544 
1545     log::debug("{}, status: 0x{:02x}", device->addr, status);
1546 
1547     if (status != GATT_SUCCESS) {
1548       /* TODO handle error codes:
1549        * kCsisErrorCodeLockAccessSirkRejected
1550        * kCsisErrorCodeLockOobSirkOnly
1551        */
1552       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1553         log::info("Database out of sync for {}", device->addr);
1554         ClearDeviceInformationAndStartSearch(device);
1555       } else {
1556         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1557         BTA_GATTC_Close(device->conn_id);
1558       }
1559       return;
1560     }
1561 
1562     if (len != bluetooth::csis::kCsisSirkCharLen) {
1563       log::error("Invalid sirk value length= {} at handle= 0x{:04x}", len, handle);
1564       BTA_GATTC_Close(device->conn_id);
1565       return;
1566     }
1567 
1568     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1569     if (csis_instance == nullptr) {
1570       log::error("Unknown csis instance: handle 0x{:04x}", handle);
1571       BTA_GATTC_Close(device->conn_id);
1572       return;
1573     }
1574 
1575     uint8_t sirk_type = value[0];
1576     log::info("SIRK Type: 0x{:02x}", sirk_type);
1577 
1578     /* Verify if sirk is not all zeros */
1579     Octet16 zero{};
1580     if (memcmp(zero.data(), value + 1, 16) == 0) {
1581       log::error("Received invalid zero SIRK conn_id: 0x{:02x}. Disconnecting", device->conn_id);
1582       BTA_GATTC_Close(device->conn_id);
1583       return;
1584     }
1585 
1586     Octet16 received_sirk;
1587     memcpy(received_sirk.data(), value + 1, 16);
1588 
1589     if (sirk_type == bluetooth::csis::kCsisSirkTypeEncrypted) {
1590       /* Decrypt encrypted SIRK */
1591       Octet16 sirk;
1592       sdf(device->addr, received_sirk, sirk);
1593       received_sirk = sirk;
1594     }
1595 
1596     /* SIRK is ready. Add device to the group */
1597 
1598     std::shared_ptr<CsisGroup> csis_group;
1599     int group_id = csis_instance->GetGroupId();
1600     if (group_id != bluetooth::groups::kGroupUnknown) {
1601       /* Group already exist. */
1602       csis_group = FindCsisGroup(group_id);
1603       log::assert_that(csis_group != nullptr, "group does not exist? {}", group_id);
1604     } else {
1605       /* Now having SIRK we can decide if the device belongs to some group we
1606        * know or this is a new group
1607        */
1608       for (auto& g : csis_groups_) {
1609         if (g->IsSirkBelongsToGroup(received_sirk)) {
1610           group_id = g->GetGroupId();
1611           break;
1612         }
1613       }
1614 
1615       if (group_id == bluetooth::groups::kGroupUnknown) {
1616         /* Here it means, we have new group. Let's us create it */
1617         group_id = dev_groups_->AddDevice(device->addr, csis_instance->GetUuid());
1618         log::assert_that(group_id != bluetooth::groups::kGroupUnknown,
1619                          "assert failed: group_id != bluetooth::groups::kGroupUnknown");
1620       } else {
1621         dev_groups_->AddDevice(device->addr, csis_instance->GetUuid(), group_id);
1622       }
1623 
1624       csis_group = FindCsisGroup(group_id);
1625       csis_group->AddDevice(device);
1626       /* Let's update csis instance group id */
1627       csis_instance->SetGroupId(group_id);
1628     }
1629 
1630     csis_group->SetSirk(received_sirk);
1631     device->is_gatt_service_valid = true;
1632     btif_storage_update_csis_info(device->addr);
1633 
1634     if (notify_valid_services) {
1635       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1636     }
1637 
1638 #ifdef CSIS_DEBUG
1639     log::info("SIRK {}, address: {}", base::HexEncode(received_sirk.data(), 16), device->addr);
1640 #endif
1641 
1642     log::verbose("Expected group size {},  actual group Size: {}", csis_group->GetDesiredSize(),
1643                  csis_group->GetCurrentSize());
1644 
1645     if (csis_group->GetDesiredSize() == csis_group->GetCurrentSize()) {
1646       auto iter = devices_.cbegin();
1647 
1648       /*
1649        * Remove devices which are expected members but are not connected and
1650        * group is already completed. Those devices are cached ivalid devices
1651        * kept on list to not trigger "new device" found every time advertising
1652        * event is received.
1653        */
1654       while (iter != devices_.cend()) {
1655         if (((*iter)->GetExpectedGroupIdMember() == csis_group->GetGroupId()) &&
1656             !(*iter)->IsConnected()) {
1657           iter = devices_.erase(iter);
1658         } else {
1659           ++iter;
1660         }
1661       }
1662     }
1663   }
1664 
DeregisterNotifications(std::shared_ptr<CsisDevice> device)1665   void DeregisterNotifications(std::shared_ptr<CsisDevice> device) {
1666     device->ForEachCsisInstance([&](const std::shared_ptr<CsisInstance>& csis_inst) {
1667       DisableGattNotification(device->conn_id, device->addr,
1668                               csis_inst->svc_data.lock_handle.val_hdl);
1669       DisableGattNotification(device->conn_id, device->addr,
1670                               csis_inst->svc_data.sirk_handle.val_hdl);
1671       DisableGattNotification(device->conn_id, device->addr,
1672                               csis_inst->svc_data.size_handle.val_hdl);
1673     });
1674   }
1675 
DoDisconnectCleanUp(std::shared_ptr<CsisDevice> device)1676   void DoDisconnectCleanUp(std::shared_ptr<CsisDevice> device) {
1677     log::info("{}", device->addr);
1678 
1679     DeregisterNotifications(device);
1680 
1681     if (device->IsConnected()) {
1682       BtaGattQueue::Clean(device->conn_id);
1683       device->conn_id = GATT_INVALID_CONN_ID;
1684     }
1685   }
1686 
OnCsisServiceFound(std::shared_ptr<CsisDevice> device,const gatt::Service * service,const bluetooth::Uuid & context_uuid,bool is_last_instance)1687   bool OnCsisServiceFound(std::shared_ptr<CsisDevice> device, const gatt::Service* service,
1688                           const bluetooth::Uuid& context_uuid, bool is_last_instance) {
1689     log::debug("service handle: 0x{:04x}, end handle: 0x{:04x}, uuid: {}", service->handle,
1690                service->end_handle, context_uuid.ToString());
1691 
1692     auto csis_inst = std::make_shared<CsisInstance>((uint16_t)service->handle,
1693                                                     (uint16_t)service->end_handle, context_uuid);
1694 
1695     /* Let's check if we know group of this device */
1696     int group_id = dev_groups_->GetGroupId(device->addr, context_uuid);
1697     if (group_id != bluetooth::groups::kGroupUnknown) {
1698       csis_inst->SetGroupId(group_id);
1699     }
1700 
1701     device->SetCsisInstance(csis_inst->svc_data.start_handle, csis_inst);
1702 
1703     /* Initially validate and store GATT service discovery data */
1704     for (const gatt::Characteristic& charac : service->characteristics) {
1705       if (charac.uuid == kCsisLockUuid) {
1706         /* Find the mandatory CCC descriptor */
1707         uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle);
1708         if (ccc_handle == GAP_INVALID_HANDLE) {
1709           log::error("no HAS Active Preset CCC descriptor found!");
1710           device->RemoveCsisInstance(group_id);
1711           return false;
1712         }
1713         csis_inst->svc_data.lock_handle.val_hdl = charac.value_handle;
1714         csis_inst->svc_data.lock_handle.ccc_hdl = ccc_handle;
1715 
1716         SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle);
1717 
1718         log::debug("Lock UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: {}",
1719                    csis_inst->svc_data.lock_handle.val_hdl, csis_inst->svc_data.lock_handle.ccc_hdl,
1720                    device->addr);
1721       } else if (charac.uuid == kCsisRankUuid) {
1722         csis_inst->svc_data.rank_handle = charac.value_handle;
1723 
1724         log::debug("Rank UUID found handle: 0x{:04x}, device: {}", csis_inst->svc_data.rank_handle,
1725                    device->addr);
1726       } else if (charac.uuid == kCsisSirkUuid) {
1727         /* Find the optional CCC descriptor */
1728         uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle);
1729         csis_inst->svc_data.sirk_handle.ccc_hdl = ccc_handle;
1730         csis_inst->svc_data.sirk_handle.val_hdl = charac.value_handle;
1731 
1732         if (ccc_handle != GAP_INVALID_HANDLE) {
1733           SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle);
1734         }
1735 
1736         log::debug("SIRK UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: {}",
1737                    csis_inst->svc_data.sirk_handle.val_hdl, csis_inst->svc_data.sirk_handle.ccc_hdl,
1738                    device->addr);
1739       } else if (charac.uuid == kCsisSizeUuid) {
1740         /* Find the optional CCC descriptor */
1741         uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle);
1742         csis_inst->svc_data.size_handle.ccc_hdl = ccc_handle;
1743         csis_inst->svc_data.size_handle.val_hdl = charac.value_handle;
1744 
1745         if (ccc_handle != GAP_INVALID_HANDLE) {
1746           SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle);
1747         }
1748 
1749         log::debug("Size UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: {}",
1750                    csis_inst->svc_data.size_handle.val_hdl, csis_inst->svc_data.size_handle.ccc_hdl,
1751                    device->addr);
1752       }
1753     }
1754 
1755     /* Sirk is the only mandatory characteristic. If it is in
1756      * place, service is OK
1757      */
1758     if (csis_inst->svc_data.sirk_handle.val_hdl == GAP_INVALID_HANDLE) {
1759       /* We have some characteristics but all dependencies are not satisfied */
1760       log::error("Service has a broken structure.");
1761       device->RemoveCsisInstance(group_id);
1762       return false;
1763     }
1764 
1765     bool notify_after_sirk_read = false;
1766     bool notify_after_lock_read = false;
1767     bool notify_after_rank_read = false;
1768     bool notify_after_size_read = false;
1769 
1770     /* Find which read will be the last one*/
1771     if (is_last_instance) {
1772       if (csis_inst->svc_data.rank_handle != GAP_INVALID_HANDLE) {
1773         notify_after_rank_read = true;
1774       } else if (csis_inst->svc_data.size_handle.val_hdl != GAP_INVALID_HANDLE) {
1775         notify_after_size_read = true;
1776       } else if (csis_inst->svc_data.lock_handle.val_hdl != GAP_INVALID_HANDLE) {
1777         notify_after_lock_read = true;
1778       } else {
1779         notify_after_sirk_read = true;
1780       }
1781     }
1782 
1783     /* Read SIRK */
1784     BtaGattQueue::ReadCharacteristic(
1785             device->conn_id, csis_inst->svc_data.sirk_handle.val_hdl,
1786             [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value,
1787                void* user_data) {
1788               if (instance) {
1789                 instance->OnCsisSirkValueUpdate(conn_id, status, handle, len, value,
1790                                                 (bool)user_data);
1791               }
1792             },
1793             (void*)notify_after_sirk_read);
1794 
1795     /* Read Lock */
1796     if (csis_inst->svc_data.lock_handle.val_hdl != GAP_INVALID_HANDLE) {
1797       BtaGattQueue::ReadCharacteristic(
1798               device->conn_id, csis_inst->svc_data.lock_handle.val_hdl,
1799               [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1800                  uint8_t* value, void* user_data) {
1801                 if (instance) {
1802                   instance->OnCsisLockReadRsp(conn_id, status, handle, len, value, (bool)user_data);
1803                 }
1804               },
1805               (void*)notify_after_lock_read);
1806     }
1807 
1808     /* Read Size */
1809     if (csis_inst->svc_data.size_handle.val_hdl != GAP_INVALID_HANDLE) {
1810       BtaGattQueue::ReadCharacteristic(
1811               device->conn_id, csis_inst->svc_data.size_handle.val_hdl,
1812               [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1813                  uint8_t* value, void* user_data) {
1814                 if (instance) {
1815                   instance->OnCsisSizeValueUpdate(conn_id, status, handle, len, value,
1816                                                   (bool)user_data);
1817                 }
1818               },
1819               (void*)notify_after_size_read);
1820     }
1821 
1822     /* Read Rank */
1823     if (csis_inst->svc_data.rank_handle != GAP_INVALID_HANDLE) {
1824       BtaGattQueue::ReadCharacteristic(
1825               device->conn_id, csis_inst->svc_data.rank_handle,
1826               [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1827                  uint8_t* value, void* user_data) {
1828                 if (instance) {
1829                   instance->OnCsisRankReadRsp(conn_id, status, handle, len, value, (bool)user_data);
1830                 }
1831               },
1832               (void*)notify_after_rank_read);
1833     }
1834 
1835     return true;
1836   }
1837 
1838   /* These are all generic GATT event handlers calling HAS specific code. */
GattcCallback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)1839   void GattcCallback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
1840     log::info("event = 0x{:02x}", event);
1841 
1842     /* This is in case Csis CleanUp is already done
1843      * while GATT is still up and could send events
1844      */
1845     if (!instance) {
1846       return;
1847     }
1848 
1849     switch (event) {
1850       case BTA_GATTC_DEREG_EVT:
1851         break;
1852 
1853       case BTA_GATTC_OPEN_EVT:
1854         OnGattConnected(p_data->open);
1855         break;
1856 
1857       case BTA_GATTC_CLOSE_EVT:
1858         OnGattDisconnected(p_data->close);
1859         break;
1860 
1861       case BTA_GATTC_SEARCH_CMPL_EVT:
1862         OnGattServiceSearchComplete(p_data->search_cmpl);
1863         break;
1864 
1865       case BTA_GATTC_NOTIF_EVT:
1866         OnGattNotification(p_data->notify);
1867         break;
1868 
1869       case BTA_GATTC_ENC_CMPL_CB_EVT: {
1870         tBTM_STATUS encryption_status;
1871         if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) {
1872           encryption_status = tBTM_STATUS::BTM_SUCCESS;
1873         } else {
1874           encryption_status = tBTM_STATUS::BTM_FAILED_ON_SECURITY;
1875         }
1876         OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, encryption_status);
1877       } break;
1878 
1879       case BTA_GATTC_SRVC_CHG_EVT:
1880         OnGattServiceChangeEvent(p_data->service_changed.remote_bda);
1881         break;
1882 
1883       case BTA_GATTC_SRVC_DISC_DONE_EVT:
1884         OnGattServiceDiscoveryDoneEvent(p_data->service_discovery_done.remote_bda);
1885         break;
1886 
1887       default:
1888         break;
1889     }
1890   }
1891 
OnGattConnected(const tBTA_GATTC_OPEN & evt)1892   void OnGattConnected(const tBTA_GATTC_OPEN& evt) {
1893     log::info("{}, conn_id=0x{:04x}, transport={}, status={}(0x{:02x})", evt.remote_bda,
1894               evt.conn_id, bt_transport_text(evt.transport), gatt_status_text(evt.status),
1895               evt.status);
1896 
1897     if (evt.transport != BT_TRANSPORT_LE) {
1898       log::warn("Only LE connection is allowed (transport {})", bt_transport_text(evt.transport));
1899       BTA_GATTC_Close(evt.conn_id);
1900       return;
1901     }
1902 
1903     auto device = FindDeviceByAddress(evt.remote_bda);
1904     if (device == nullptr) {
1905       log::debug("Skipping unknown device, address= {}", evt.remote_bda);
1906       BTA_GATTC_Close(evt.conn_id);
1907       return;
1908     }
1909 
1910     if (evt.status != GATT_SUCCESS) {
1911       log::error("Failed to connect to server device {}", evt.remote_bda);
1912       if (device->connecting_actively) {
1913         callbacks_->OnConnectionState(evt.remote_bda, ConnectionState::DISCONNECTED);
1914       }
1915       DoDisconnectCleanUp(device);
1916       StartOpportunisticConnect(evt.remote_bda);
1917       return;
1918     }
1919 
1920     device->connecting_actively = false;
1921     device->conn_id = evt.conn_id;
1922     if (com::android::bluetooth::flags::gatt_queue_cleanup_connected()) {
1923       BtaGattQueue::Clean(evt.conn_id);
1924     }
1925     /* Verify bond */
1926     if (BTM_SecIsSecurityPending(device->addr)) {
1927       /* if security collision happened, wait for encryption done
1928        * (BTA_GATTC_ENC_CMPL_CB_EVT) */
1929       return;
1930     }
1931 
1932     /* verify bond */
1933     if (BTM_IsEncrypted(device->addr, BT_TRANSPORT_LE)) {
1934       /* if link has been encrypted */
1935       OnEncrypted(device);
1936       return;
1937     }
1938 
1939     tBTM_STATUS result =
1940             BTM_SetEncryption(device->addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT);
1941 
1942     log::info("Encryption required for {}. Request result: 0x{:02x}", device->addr, result);
1943 
1944     if (result == tBTM_STATUS::BTM_ERR_KEY_MISSING) {
1945       log::error("Link key unknown for {}, disconnect profile", device->addr);
1946       BTA_GATTC_Close(device->conn_id);
1947     }
1948   }
1949 
OnGattDisconnected(const tBTA_GATTC_CLOSE & evt)1950   void OnGattDisconnected(const tBTA_GATTC_CLOSE& evt) {
1951     auto device = FindDeviceByAddress(evt.remote_bda);
1952     if (device == nullptr) {
1953       log::warn("Skipping unknown device disconnect, conn_id= 0x{:04x}", evt.conn_id);
1954       return;
1955     }
1956 
1957     log::debug("device={}", device->addr);
1958 
1959     callbacks_->OnConnectionState(evt.remote_bda, ConnectionState::DISCONNECTED);
1960 
1961     // Unlock others only if device was locked by us but has disconnected
1962     // unexpectedly.
1963     if ((evt.reason == GATT_CONN_TIMEOUT) || (evt.reason == GATT_CONN_TERMINATE_PEER_USER)) {
1964       device->ForEachCsisInstance([&](const std::shared_ptr<CsisInstance>& csis_inst) {
1965         auto csis_group = FindCsisGroup(csis_inst->GetGroupId());
1966         if (csis_group == nullptr) {
1967           return;
1968         }
1969         if (csis_group->GetCurrentLockState() == CsisLockState::CSIS_STATE_LOCKED) {
1970           HandleCsisLockProcedureError(csis_group, device,
1971                                        CsisGroupLockStatus::LOCKED_GROUP_MEMBER_LOST);
1972         }
1973       });
1974     }
1975 
1976     DoDisconnectCleanUp(device);
1977   }
1978 
OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL & evt)1979   void OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL& evt) {
1980     auto device = FindDeviceByConnId(evt.conn_id);
1981 
1982     if (device == nullptr) {
1983       log::warn("Skipping unknown device, conn_id= 0x{:4x}", evt.conn_id);
1984       return;
1985     }
1986 
1987     /* verify encryption enabled */
1988     if (!BTM_IsEncrypted(device->addr, BT_TRANSPORT_LE)) {
1989       log::warn("Device not yet bonded - waiting for encryption");
1990       return;
1991     }
1992 
1993     /* Ignore if our service data is valid (discovery initiated by someone
1994      * else?) */
1995     if (!device->is_gatt_service_valid) {
1996       if (evt.status != GATT_SUCCESS) {
1997         log::error("Service discovery failed");
1998         BTA_GATTC_Close(device->conn_id);
1999         DoDisconnectCleanUp(device);
2000         return;
2001       }
2002 
2003       log::verbose("");
2004 
2005       const std::list<gatt::Service>* all_services = BTA_GATTC_GetServices(device->conn_id);
2006 
2007       std::vector<uint16_t> all_csis_start_handles;
2008 
2009       /* Le's just find all the CSIS primary services and store the start
2010        * handles */
2011       for (auto& svrc : *all_services) {
2012         if (svrc.uuid == kCsisServiceUuid) {
2013           all_csis_start_handles.push_back(svrc.handle);
2014         }
2015       }
2016 
2017       if (all_csis_start_handles.size() == 0) {
2018         log::debug("No Csis instances found");
2019         BTA_GATTC_Close(device->conn_id);
2020         RemoveCsisDevice(device, bluetooth::groups::kGroupUnknown);
2021         return;
2022       }
2023 
2024       for (auto& svrc : *all_services) {
2025         if (svrc.uuid == kCsisServiceUuid) {
2026           continue;
2027         }
2028 
2029         /* Try to find context for CSIS instances */
2030         for (auto& included_srvc : svrc.included_services) {
2031           if (included_srvc.uuid == kCsisServiceUuid) {
2032             auto csis_svrc =
2033                     BTA_GATTC_GetOwningService(device->conn_id, included_srvc.start_handle);
2034             auto iter = std::find(all_csis_start_handles.begin(), all_csis_start_handles.end(),
2035                                   included_srvc.start_handle);
2036             if (iter != all_csis_start_handles.end()) {
2037               all_csis_start_handles.erase(iter);
2038             }
2039             instance->OnCsisServiceFound(device, csis_svrc, svrc.uuid,
2040                                          all_csis_start_handles.empty());
2041           }
2042         }
2043       }
2044 
2045       /* Here if CSIS is included, all_csis_start_handles should be empty
2046        * Otherwise it means, we have some primary CSIS without a context,
2047        * which means it is for the complete device.
2048        * As per spec, there can be only one service like this.
2049        */
2050       if (all_csis_start_handles.size()) {
2051         log::debug("there is {} primary services without a context",
2052                    static_cast<int>(all_csis_start_handles.size()));
2053         auto csis_svrc = BTA_GATTC_GetOwningService(device->conn_id, all_csis_start_handles[0]);
2054         instance->OnCsisServiceFound(device, csis_svrc, bluetooth::groups::kGenericContextUuid,
2055                                      true);
2056         all_csis_start_handles.clear();
2057       }
2058     } else {
2059       /* This might be set already if there is no optional attributes to read
2060        * or write.
2061        */
2062       if (evt.status == GATT_SUCCESS) {
2063         NotifyCsisDeviceValidAndStoreIfNeeded(device);
2064       }
2065     }
2066   }
2067 
OnGattNotification(const tBTA_GATTC_NOTIFY & evt)2068   void OnGattNotification(const tBTA_GATTC_NOTIFY& evt) {
2069     /* Reject invalid lengths and indications as they are not supported */
2070     if (!evt.is_notify || evt.len > GATT_MAX_ATTR_LEN) {
2071       log::error(": rejected BTA_GATTC_NOTIF_EVT. is_notify = {}, len= {}", evt.is_notify, evt.len);
2072     }
2073 
2074     OnCsisNotification(evt.conn_id, evt.handle, evt.len, evt.value);
2075   }
2076 
OnLeEncryptionComplete(const RawAddress & address,tBTM_STATUS status)2077   void OnLeEncryptionComplete(const RawAddress& address, tBTM_STATUS status) {
2078     log::info("{}", address);
2079     auto device = FindDeviceByAddress(address);
2080     if (device == nullptr) {
2081       log::warn("Skipping unknown device {}", address);
2082       return;
2083     }
2084 
2085     if (status != tBTM_STATUS::BTM_SUCCESS) {
2086       log::error("encryption failed. status: 0x{:02x}", status);
2087 
2088       BTA_GATTC_Close(device->conn_id);
2089       return;
2090     }
2091 
2092     if (device->is_gatt_service_valid) {
2093       instance->OnEncrypted(device);
2094     } else {
2095       BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
2096     }
2097   }
2098 
ClearDeviceInformationAndStartSearch(std::shared_ptr<CsisDevice> device)2099   void ClearDeviceInformationAndStartSearch(std::shared_ptr<CsisDevice> device) {
2100     log::info("{}", device->addr);
2101     if (device->is_gatt_service_valid == false) {
2102       log::debug("Device database already invalidated.");
2103       return;
2104     }
2105 
2106     /* Invalidate service discovery results */
2107     BtaGattQueue::Clean(device->conn_id);
2108     DeregisterNotifications(device);
2109     device->ClearSvcData();
2110     BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
2111   }
2112 
OnGattServiceChangeEvent(const RawAddress & address)2113   void OnGattServiceChangeEvent(const RawAddress& address) {
2114     auto device = FindDeviceByAddress(address);
2115     if (!device) {
2116       log::warn("Skipping unknown device {}", address);
2117       return;
2118     }
2119 
2120     log::info("{}", address);
2121     ClearDeviceInformationAndStartSearch(device);
2122   }
2123 
OnGattServiceDiscoveryDoneEvent(const RawAddress & address)2124   void OnGattServiceDiscoveryDoneEvent(const RawAddress& address) {
2125     auto device = FindDeviceByAddress(address);
2126     if (!device) {
2127       log::warn("Skipping unknown device {}", address);
2128       return;
2129     }
2130 
2131     log::debug("address={}", address);
2132 
2133     if (!device->is_gatt_service_valid) {
2134       BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
2135     }
2136   }
2137 
FindCccHandle(tCONN_ID conn_id,uint16_t char_handle)2138   static uint16_t FindCccHandle(tCONN_ID conn_id, uint16_t char_handle) {
2139     const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, char_handle);
2140     if (!p_char) {
2141       log::warn("No such characteristic: 0x{:04x}", char_handle);
2142       return GAP_INVALID_HANDLE;
2143     }
2144 
2145     for (const gatt::Descriptor& desc : p_char->descriptors) {
2146       if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG)) {
2147         return desc.handle;
2148       }
2149     }
2150 
2151     return GAP_INVALID_HANDLE;
2152   }
2153 
SubscribeForNotifications(tCONN_ID conn_id,const RawAddress & address,uint16_t value_handle,uint16_t ccc_handle)2154   void SubscribeForNotifications(tCONN_ID conn_id, const RawAddress& address, uint16_t value_handle,
2155                                  uint16_t ccc_handle) {
2156     if (value_handle != GAP_INVALID_HANDLE) {
2157       tGATT_STATUS register_status =
2158               BTA_GATTC_RegisterForNotifications(gatt_if_, address, value_handle);
2159       log::debug("BTA_GATTC_RegisterForNotifications, status=0x{:02x}, value=0x{:x}, ccc=0x{:04x}",
2160                  register_status, value_handle, ccc_handle);
2161 
2162       if (register_status != GATT_SUCCESS) {
2163         return;
2164       }
2165     }
2166 
2167     std::vector<uint8_t> value(2);
2168     uint8_t* value_ptr = value.data();
2169     UINT16_TO_STREAM(value_ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
2170     BtaGattQueue::WriteDescriptor(
2171             conn_id, ccc_handle, std::move(value), GATT_WRITE,
2172             [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t /*len*/,
2173                const uint8_t* /*value*/, void* user_data) {
2174               if (instance) {
2175                 instance->OnGattWriteCcc(conn_id, status, handle, user_data);
2176               }
2177             },
2178             nullptr);
2179   }
2180 
DisableGattNotification(tCONN_ID,const RawAddress & address,uint16_t value_handle)2181   void DisableGattNotification(tCONN_ID /*conn_id*/, const RawAddress& address,
2182                                uint16_t value_handle) {
2183     if (value_handle != GAP_INVALID_HANDLE) {
2184       tGATT_STATUS register_status =
2185               BTA_GATTC_DeregisterForNotifications(gatt_if_, address, value_handle);
2186       log::debug("DisableGattNotification, status=0x{:02x}, value_handle=0x{:04x}", register_status,
2187                  value_handle);
2188 
2189       if (register_status != GATT_SUCCESS) {
2190         return;
2191       }
2192     }
2193   }
2194 
SirkValueReadCompleteDuringPairing(tGATT_STATUS status,const RawAddress & address,uint8_t sirk_type,Octet16 & received_sirk)2195   void SirkValueReadCompleteDuringPairing(tGATT_STATUS status, const RawAddress& address,
2196                                           uint8_t sirk_type, Octet16& received_sirk) {
2197     log::info("{}, status: 0x{:02x}", address, status);
2198 
2199     auto device = FindDeviceByAddress(address);
2200     if (device == nullptr) {
2201       log::error("Unknown device {}", address);
2202       BTA_DmSirkConfirmDeviceReply(address, false);
2203       return;
2204     }
2205 
2206     auto group_id_to_join = device->GetExpectedGroupIdMember();
2207     device->SetPairingSirkReadFlag(false);
2208 
2209     /* Verify group still exist, if not it means user forget the group and
2210      * paring should be rejected.
2211      */
2212     auto csis_group = FindCsisGroup(group_id_to_join);
2213     if (!csis_group) {
2214       log::error("Group {} removed during paring a set member", group_id_to_join);
2215       RemoveDevice(address);
2216       BTA_DmSirkConfirmDeviceReply(address, false);
2217       return;
2218     }
2219 
2220     if (status != GATT_SUCCESS) {
2221       log::info("Invalid member, can't read SIRK (status: 0x{:02x})", status);
2222       BTA_DmSirkConfirmDeviceReply(address, false);
2223       return;
2224     }
2225 
2226     /* Verify if sirk is not all zeros */
2227     Octet16 zero{};
2228     if (memcmp(zero.data(), received_sirk.data(), 16) == 0) {
2229       log::error("Received invalid zero SIRK address: {}", address);
2230       BTA_DmSirkConfirmDeviceReply(address, false);
2231       return;
2232     }
2233 
2234     if (sirk_type == bluetooth::csis::kCsisSirkTypeEncrypted) {
2235       /* Decrypt encrypted SIRK */
2236       Octet16 sirk;
2237       sdf(address, received_sirk, sirk);
2238       received_sirk = sirk;
2239     }
2240 
2241     if (!csis_group->IsSirkBelongsToGroup(received_sirk)) {
2242       /*
2243        * Joining member must join already existing group otherwise it means
2244        * that its SIRK is different. Device connection was triggered by RSI
2245        * match for group.
2246        */
2247       log::error("Joining device {}, does not match any existig group", address);
2248       BTA_DmSirkConfirmDeviceReply(address, false);
2249       return;
2250     }
2251 
2252     log::info("Device {}, verified successfully by SIRK", address);
2253     BTA_DmSirkConfirmDeviceReply(address, true);
2254 
2255     /* It was temporary device and we can remove it. When upper layer
2256      * decides to connect CSIS it will be added then
2257      */
2258     RemoveDevice(address);
2259   }
2260 
VerifySetMember(const RawAddress & address)2261   void VerifySetMember(const RawAddress& address) {
2262     auto device = FindDeviceByAddress(address);
2263 
2264     log::info("Device: {}", address);
2265 
2266     /* It's ok for device to not be a CSIS device at all */
2267     if (!device) {
2268       log::info("Valid - new member");
2269       BTA_DmSirkConfirmDeviceReply(address, true);
2270       return;
2271     }
2272 
2273     auto group_id_to_join = device->GetExpectedGroupIdMember();
2274     if (group_id_to_join == bluetooth::groups::kGroupUnknown) {
2275       log::warn(
2276               "Device {} (conn_id=0x{:04x}) is already known to CSIS (# of "
2277               "instances={}) but it is not scheduled to join any group.",
2278               address, device->conn_id, device->GetNumberOfCsisInstances());
2279       BTA_DmSirkConfirmDeviceReply(address, true);
2280       return;
2281     }
2282 
2283     if (!gatt_cl_read_sirk_req(address,
2284                                base::BindOnce(&CsisClientImpl::SirkValueReadCompleteDuringPairing,
2285                                               weak_factory_.GetWeakPtr()))) {
2286       log::error("Could not read SIKR of {}", address);
2287       BTA_DmSirkConfirmDeviceReply(address, false);
2288       return;
2289     }
2290     device->SetPairingSirkReadFlag(true);
2291   }
2292 
2293   uint8_t gatt_if_;
2294   bluetooth::csis::CsisClientCallbacks* callbacks_;
2295   std::list<std::shared_ptr<CsisDevice>> devices_;
2296   std::list<std::shared_ptr<CsisGroup>> csis_groups_;
2297   DeviceGroups* dev_groups_;
2298   int discovering_group_ = bluetooth::groups::kGroupUnknown;
2299 
2300   base::WeakPtrFactory<CsisClientImpl> weak_factory_{this};
2301 };
2302 
2303 class DeviceGroupsCallbacksImpl : public DeviceGroupsCallbacks {
2304 public:
OnGroupAdded(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)2305   void OnGroupAdded(const RawAddress& address, const bluetooth::Uuid& uuid, int group_id) override {
2306     if (instance) {
2307       instance->OnGroupAddedCb(address, uuid, group_id);
2308     }
2309   }
2310 
OnGroupMemberAdded(const RawAddress & address,int group_id)2311   void OnGroupMemberAdded(const RawAddress& address, int group_id) override {
2312     if (instance) {
2313       instance->OnGroupMemberAddedCb(address, group_id);
2314     }
2315   }
2316 
OnGroupRemoved(const bluetooth::Uuid & uuid,int group_id)2317   void OnGroupRemoved(const bluetooth::Uuid& uuid, int group_id) override {
2318     if (instance) {
2319       instance->OnGroupRemovedCb(uuid, group_id);
2320     }
2321   }
2322 
OnGroupMemberRemoved(const RawAddress & address,int group_id)2323   void OnGroupMemberRemoved(const RawAddress& address, int group_id) override {
2324     if (instance) {
2325       instance->OnGroupMemberRemovedCb(address, group_id);
2326     }
2327   }
2328 
OnGroupAddFromStorage(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)2329   void OnGroupAddFromStorage(const RawAddress& address, const bluetooth::Uuid& uuid,
2330                              int group_id) override {
2331     if (instance) {
2332       instance->OnGroupAddFromStorageCb(address, uuid, group_id);
2333     }
2334   }
2335 };
2336 
2337 class DeviceGroupsCallbacksImpl;
2338 DeviceGroupsCallbacksImpl deviceGroupsCallbacksImpl;
2339 
2340 }  // namespace
2341 
Initialize(bluetooth::csis::CsisClientCallbacks * callbacks,Closure initCb)2342 void CsisClient::Initialize(bluetooth::csis::CsisClientCallbacks* callbacks, Closure initCb) {
2343   std::scoped_lock<std::mutex> lock(instance_mutex);
2344   if (instance) {
2345     log::info("Already initialized!");
2346     return;
2347   }
2348 
2349   device_group_callbacks = &deviceGroupsCallbacksImpl;
2350   instance = new CsisClientImpl(callbacks, initCb);
2351 }
2352 
IsCsisClientRunning()2353 bool CsisClient::IsCsisClientRunning() { return instance; }
2354 
Get(void)2355 CsisClient* CsisClient::Get(void) {
2356   if (instance == nullptr) {
2357     log::error("instance not available");
2358   }
2359   return instance;
2360 }
2361 
AddFromStorage(const RawAddress & addr,const std::vector<uint8_t> & in)2362 void CsisClient::AddFromStorage(const RawAddress& addr, const std::vector<uint8_t>& in) {
2363   if (!instance) {
2364     log::error("Not initialized yet!");
2365     return;
2366   }
2367 
2368   instance->AddFromStorage(addr, in);
2369 }
2370 
GetForStorage(const RawAddress & addr,std::vector<uint8_t> & out)2371 bool CsisClient::GetForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
2372   if (!instance) {
2373     log::error("Not initialized yet!");
2374     return false;
2375   }
2376 
2377   return instance->SerializeSets(addr, out);
2378 }
2379 
CleanUp()2380 void CsisClient::CleanUp() {
2381   std::scoped_lock<std::mutex> lock(instance_mutex);
2382   BTA_DmSirkSecCbRegister(nullptr);
2383   CsisClientImpl* ptr = instance;
2384   instance = nullptr;
2385 
2386   if (ptr) {
2387     ptr->CleanUp();
2388     delete ptr;
2389   }
2390 }
2391 
DebugDump(int fd)2392 void CsisClient::DebugDump(int fd) {
2393   std::scoped_lock<std::mutex> lock(instance_mutex);
2394   dprintf(fd, "Coordinated Set Service Client:\n");
2395   if (instance) {
2396     instance->Dump(fd);
2397   }
2398   dprintf(fd, "\n");
2399 }
2400