• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "osi/include/osi.h"
63 #include "osi/include/stack_power_telemetry.h"
64 #include "stack/btm/btm_sec.h"
65 #include "stack/gatt/gatt_int.h"
66 #include "stack/include/bt_types.h"
67 #include "stack/include/btm_ble_sec_api.h"
68 #include "stack/include/btm_client_interface.h"
69 #include "stack/include/btm_status.h"
70 #include "types/bluetooth/uuid.h"
71 #include "types/bt_transport.h"
72 #include "types/raw_address.h"
73 
74 using base::Closure;
75 using bluetooth::Uuid;
76 using bluetooth::csis::ConnectionState;
77 using bluetooth::csis::CsisClient;
78 using bluetooth::csis::CsisDevice;
79 using bluetooth::csis::CsisDiscoveryState;
80 using bluetooth::csis::CsisGroup;
81 using bluetooth::csis::CsisGroupLockStatus;
82 using bluetooth::csis::CsisInstance;
83 using bluetooth::csis::CsisLockCb;
84 using bluetooth::csis::CsisLockState;
85 using bluetooth::csis::kCsisLockUuid;
86 using bluetooth::csis::kCsisRankUuid;
87 using bluetooth::csis::kCsisServiceUuid;
88 using bluetooth::csis::kCsisSirkUuid;
89 using bluetooth::csis::kCsisSizeUuid;
90 
91 using bluetooth::groups::DeviceGroups;
92 using bluetooth::groups::DeviceGroupsCallbacks;
93 
94 using namespace bluetooth;
95 
96 namespace {
97 class CsisClientImpl;
98 CsisClientImpl* instance;
99 std::mutex instance_mutex;
100 DeviceGroupsCallbacks* device_group_callbacks;
101 
102 /**
103  * -----------------------------------------------------------------------------
104  * Coordinated Set Service - Client role
105  * -----------------------------------------------------------------------------
106  *
107  * CSIP allows to organize audio servers into sets e.g. Stereo Set, 5.1 Set
108  * and speed up connecting it.
109  *
110  * Since leaudio has already grouping API it was decided to integrate here CSIS
111  * and allow it to group devices semi-automatically.
112  *
113  * Flow:
114  * If connected device contains CSIS services, and it is included into CAP
115  * service or is not included at all, implementation reads all its
116  * characteristisc. The only mandatory characteristic is Set Identity Resolving
117  * Key (SIRK) and once this is read implementation assumes there is at least 2
118  * devices in the set and start to search for other members by looking for new
119  * Advertising Type (RSI Type) and Resolvable Set Identifier (RSI) in it.
120  * In the meantime other CSIS characteristics are read and Set Size might be
121  * updated. When new set member is found, there is callback called to upper
122  * layer with the address and group id for which member has been found. During
123  * this time Search is stopped. Upper layers bonds new devices and connect Le
124  * Audio profile. If there are other members to find, implementations repeats
125  * the procedure.
126  *
127  */
128 
129 class CsisClientImpl : public CsisClient {
130   static constexpr uint8_t CSIS_STORAGE_CURRENT_LAYOUT_MAGIC = 0x10;
131   static constexpr size_t CSIS_STORAGE_HEADER_SZ =
132           sizeof(CSIS_STORAGE_CURRENT_LAYOUT_MAGIC) + sizeof(uint8_t); /* num_of_sets */
133   static constexpr size_t CSIS_STORAGE_ENTRY_SZ = sizeof(uint8_t) /* set_id */ +
134                                                   sizeof(uint8_t) /* desired_size */ +
135                                                   sizeof(uint8_t) /* rank */ + Octet16().size();
136 
137 public:
CsisClientImpl(bluetooth::csis::CsisClientCallbacks * callbacks,Closure initCb)138   CsisClientImpl(bluetooth::csis::CsisClientCallbacks* callbacks, Closure initCb)
139       : gatt_if_(0), callbacks_(callbacks) {
140     BTA_GATTC_AppRegister(
141             "csis",
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_IsBonded(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: " << device->addr.ToRedactedStringForLogging()
756                    << "\n";
757           }
758           continue;
759         }
760 
761         stream << "        == addr: " << device->addr.ToRedactedStringForLogging() << " ==\n"
762                << "        csis instance: data:"
763                << "\n";
764 
765         auto instance = device->GetCsisInstanceByGroupId(g->GetGroupId());
766         if (!instance) {
767           stream << "          No csis instance available\n";
768         } else {
769           stream << "          service handle: " << loghex(instance->svc_data.start_handle)
770                  << "          rank: " << +instance->GetRank() << "\n";
771         }
772 
773         if (!device->IsConnected()) {
774           stream << "        Not connected\n";
775         } else {
776           stream << "        Connected conn_id = " << std::to_string(device->conn_id) << "\n";
777         }
778       }
779     }
780 
781     dprintf(fd, "%s", stream.str().c_str());
782   }
783 
784 private:
FindDeviceByConnId(tCONN_ID conn_id)785   std::shared_ptr<CsisDevice> FindDeviceByConnId(tCONN_ID conn_id) {
786     auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchConnId(conn_id));
787     if (it != devices_.end()) {
788       return *it;
789     }
790 
791     return nullptr;
792   }
793 
RemoveCsisDevice(std::shared_ptr<CsisDevice> & device)794   void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device) {
795     auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(device->addr));
796     devices_.erase(it);
797   }
798 
RemoveCsisDevice(std::shared_ptr<CsisDevice> & device,int group_id)799   void RemoveCsisDevice(std::shared_ptr<CsisDevice>& device, int group_id) {
800     log::info("");
801     auto it = find_if(devices_.begin(), devices_.end(), CsisDevice::MatchAddress(device->addr));
802     if (it == devices_.end()) {
803       return;
804     }
805 
806     if (group_id != bluetooth::groups::kGroupUnknown) {
807       auto csis_group = FindCsisGroup(group_id);
808       if (!csis_group) {
809         /* This could happen when remove device is called when bonding is
810          * removed */
811         log::info("group not found {}", group_id);
812         return;
813       }
814 
815       csis_group->RemoveDevice(device->addr);
816 
817       if (csis_group->IsEmpty()) {
818         RemoveCsisGroup(group_id);
819 
820         /* Remove cached candidate devices for group */
821         devices_.erase(std::remove_if(devices_.begin(), devices_.end(),
822                                       [group_id](auto& dev) {
823                                         if (dev->GetNumberOfCsisInstances() == 0 &&
824                                             dev->GetExpectedGroupIdMember() == group_id &&
825                                             dev->GetPairingSirkReadFlag() == false) {
826                                           return true;
827                                         }
828 
829                                         return false;
830                                       }),
831                        devices_.end());
832       }
833 
834       device->RemoveCsisInstance(group_id);
835     }
836 
837     if (device->GetNumberOfCsisInstances() == 0) {
838       devices_.erase(it);
839     }
840   }
841 
FindDeviceByAddress(const RawAddress & addr) const842   std::shared_ptr<CsisDevice> FindDeviceByAddress(const RawAddress& addr) const {
843     auto it = find_if(devices_.cbegin(), devices_.cend(), CsisDevice::MatchAddress(addr));
844     if (it != devices_.end()) {
845       return *it;
846     }
847 
848     return nullptr;
849   }
850 
FindCsisGroup(int group_id) const851   std::shared_ptr<CsisGroup> FindCsisGroup(int group_id) const {
852     auto it = find_if(csis_groups_.cbegin(), csis_groups_.cend(),
853                       [group_id](auto& g) { return group_id == g->GetGroupId(); });
854 
855     if (it == csis_groups_.end()) {
856       return nullptr;
857     }
858     return *it;
859   }
860 
RemoveCsisGroup(int group_id)861   void RemoveCsisGroup(int group_id) {
862     for (auto it = csis_groups_.begin(); it != csis_groups_.end(); it++) {
863       if ((*it)->GetGroupId() == group_id) {
864         csis_groups_.erase(it);
865         return;
866       }
867     }
868   }
869 
870   /* Handle encryption */
OnEncrypted(std::shared_ptr<CsisDevice> & device)871   void OnEncrypted(std::shared_ptr<CsisDevice>& device) {
872     log::debug("{}", device->addr);
873 
874     if (device->is_gatt_service_valid) {
875       NotifyCsisDeviceValidAndStoreIfNeeded(device);
876     } else {
877       BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
878     }
879   }
880 
NotifyCsisDeviceValidAndStoreIfNeeded(std::shared_ptr<CsisDevice> & device)881   void NotifyCsisDeviceValidAndStoreIfNeeded(std::shared_ptr<CsisDevice>& device) {
882     /* Notify that we are ready to go. Notice that multiple callback calls
883      * for a single device address can be called if device is in more than one
884      * CSIS group.
885      */
886     bool notify_connected = false;
887     int group_id_to_discover = bluetooth::groups::kGroupUnknown;
888     for (const auto& csis_group : csis_groups_) {
889       if (!csis_group->IsDeviceInTheGroup(device)) {
890         continue;
891       }
892 
893       int group_id = csis_group->GetGroupId();
894       auto csis_instance = device->GetCsisInstanceByGroupId(group_id);
895       log::debug("group id {}", group_id);
896 
897       if (!csis_instance) {
898         /* This can happen when some other user added device to group in the
899          * context which is not existing on the peer side. e.g. LeAudio added it
900          * in the CAP context, but CSIS exist on the peer device without a
901          * context. We will endup in having device in 2 groups. One in generic
902          * context with valid csis_instance, and one in CAP context without csis
903          * instance */
904         log::info("csis_instance does not exist for group {}", group_id);
905         continue;
906       }
907 
908       callbacks_->OnDeviceAvailable(device->addr, group_id, csis_group->GetDesiredSize(),
909                                     csis_instance->GetRank(), csis_instance->GetUuid());
910       notify_connected = true;
911 
912       if (group_id_to_discover == bluetooth::groups::kGroupUnknown) {
913         group_id_to_discover = group_id;
914       }
915     }
916 
917     if (notify_connected) {
918       callbacks_->OnConnectionState(device->addr, ConnectionState::CONNECTED);
919 
920       log::debug("group_id {}", group_id_to_discover);
921       if (group_id_to_discover != bluetooth::groups::kGroupUnknown) {
922         /* Start active search for the other device
923          * b/281120322
924          */
925         auto g = FindCsisGroup(group_id_to_discover);
926         log::debug("Group size  {}  target size {}", g->GetDesiredSize(), g->GetCurrentSize());
927 
928         auto dev_waiting_for_bonding_cnt =
929                 GetNumOfKnownExpectedDevicesWaitingForBonding(g->GetGroupId());
930         log::debug("Group size: {}, desired size: {}, waiting for bonding: {}", g->GetCurrentSize(),
931                    g->GetDesiredSize(), dev_waiting_for_bonding_cnt);
932 
933         if (g->GetDesiredSize() > g->GetCurrentSize() + dev_waiting_for_bonding_cnt) {
934           CsisActiveDiscovery(g);
935         }
936       }
937     }
938   }
939 
OnGattWriteCcc(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,void *)940   void OnGattWriteCcc(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, void* /*user_data*/) {
941     auto device = FindDeviceByConnId(conn_id);
942     if (device == nullptr) {
943       log::info("unknown conn_id= 0x{:04x}", conn_id);
944       BtaGattQueue::Clean(conn_id);
945       return;
946     }
947 
948     if (status == GATT_DATABASE_OUT_OF_SYNC) {
949       log::info("Database out of sync for {}", device->addr);
950       ClearDeviceInformationAndStartSearch(device);
951       return;
952     }
953 
954     if (status == GATT_SUCCESS) {
955       log::info("Successfully registered on ccc: 0x{:04x}, device: {}", handle, device->addr);
956       return;
957     }
958 
959     log::error("Failed to register for indications: 0x{:04x}, device: {}, status: 0x{:02x}", handle,
960                device->addr, status);
961 
962     auto val_handle = device->FindValueHandleByCccHandle(handle);
963     if (!val_handle) {
964       log::error("Unknown ccc handle: 0x{:04x}, device: {}", handle, device->addr);
965       return;
966     }
967 
968     if (val_handle != GAP_INVALID_HANDLE) {
969       BTA_GATTC_DeregisterForNotifications(gatt_if_, device->addr, val_handle);
970     }
971   }
972 
OnCsisNotification(tCONN_ID conn_id,uint16_t handle,uint16_t len,const uint8_t * value)973   void OnCsisNotification(tCONN_ID conn_id, uint16_t handle, uint16_t len, const uint8_t* value) {
974     auto device = FindDeviceByConnId(conn_id);
975     if (device == nullptr) {
976       log::warn("Skipping unknown device, conn_id= 0x{:04x}", conn_id);
977       return;
978     }
979 
980     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
981     if (csis_instance == nullptr) {
982       log::error("unknown notification handle: 0x{:04x} for conn_id: 0x{:04x}", handle, conn_id);
983       return;
984     }
985 
986     if (handle == csis_instance->svc_data.sirk_handle.val_hdl) {
987       OnCsisSirkValueUpdate(conn_id, GATT_SUCCESS, handle, len, value);
988     } else if (handle == csis_instance->svc_data.lock_handle.val_hdl) {
989       OnCsisLockNotifications(device, csis_instance, len, value);
990     } else if (handle == csis_instance->svc_data.size_handle.val_hdl) {
991       OnCsisSizeValueUpdate(conn_id, GATT_SUCCESS, handle, len, value);
992     } else {
993       log::warn("unknown notification handle 0x{:04x} for conn_id= 0x{:04x}", handle, conn_id);
994     }
995   }
996 
LockError2GroupLockStatus(tGATT_STATUS status)997   static CsisGroupLockStatus LockError2GroupLockStatus(tGATT_STATUS status) {
998     switch (status) {
999       case bluetooth::csis::kCsisErrorCodeLockDenied:
1000         return CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER;
1001       case bluetooth::csis::kCsisErrorCodeReleaseNotAllowed:
1002         return CsisGroupLockStatus::FAILED_LOCKED_BY_OTHER;
1003       case bluetooth::csis::kCsisErrorCodeInvalidValue:
1004         return CsisGroupLockStatus::FAILED_OTHER_REASON;
1005       default:
1006         return CsisGroupLockStatus::FAILED_OTHER_REASON;
1007     }
1008   }
1009 
CsisLockCompleted(std::shared_ptr<CsisGroup> & csis_group,bool lock,CsisGroupLockStatus status)1010   void CsisLockCompleted(std::shared_ptr<CsisGroup>& csis_group, bool lock,
1011                          CsisGroupLockStatus status) {
1012     log::debug("group id: {}, target state {}", csis_group->GetGroupId(), lock ? "lock" : "unlock");
1013 
1014     NotifyGroupStatus(csis_group->GetGroupId(), lock, status, csis_group->GetLockCb());
1015     csis_group->SetTargetLockState(CsisLockState::CSIS_STATE_UNSET);
1016   }
1017 
OnCsisLockNotifications(std::shared_ptr<CsisDevice> &,std::shared_ptr<CsisInstance> & csis_instance,uint16_t len,const uint8_t * value)1018   void OnCsisLockNotifications(std::shared_ptr<CsisDevice>& /*device*/,
1019                                std::shared_ptr<CsisInstance>& csis_instance, uint16_t len,
1020                                const uint8_t* value) {
1021     if (len != 1) {
1022       log::error("invalid notification len: {}", len);
1023       return;
1024     }
1025 
1026     CsisLockState new_lock = (CsisLockState)(value[0]);
1027 
1028     log::debug("New lock state: {},  device rank:  {}", static_cast<int>(new_lock),
1029                csis_instance->GetRank());
1030 
1031     csis_instance->SetLockState(new_lock);
1032 
1033     auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
1034     if (!csis_group) {
1035       return;
1036     }
1037 
1038     CsisLockCb cb = csis_group->GetLockCb();
1039     if (csis_group->GetTargetLockState() == CsisLockState::CSIS_STATE_UNSET) {
1040       if (csis_group->GetCurrentLockState() == CsisLockState::CSIS_STATE_LOCKED &&
1041           new_lock == CsisLockState::CSIS_STATE_UNLOCKED) {
1042         /* We are here when members fires theirs lock timeout.
1043          * Not sure what to do with our current lock state. For now we will
1044          * change local lock state after first set member removes its lock. Then
1045          * we count that others will do the same
1046          */
1047         csis_group->SetCurrentLockState(CsisLockState::CSIS_STATE_UNLOCKED);
1048         NotifyGroupStatus(csis_group->GetGroupId(), false, CsisGroupLockStatus::SUCCESS,
1049                           std::move(cb));
1050       }
1051       return;
1052     }
1053 
1054     if (csis_group->GetCurrentLockState() != csis_group->GetTargetLockState()) {
1055       /* We are in process of changing lock state. If new device lock
1056        * state is what is targeted that means all is good, we don't need
1057        * to do here nothing, as state will be changed once all the
1058        * characteristics are written. If new device state is not what is
1059        * targeted, that means, device changed stated unexpectedly and locking
1060        * procedure is broken
1061        */
1062       if (new_lock != csis_group->GetTargetLockState()) {
1063         /* Device changed back the lock state from what we expected, skip
1064          * locking and notify user about that
1065          */
1066         CsisLockCompleted(csis_group, false, CsisGroupLockStatus::FAILED_OTHER_REASON);
1067       }
1068     }
1069   }
1070 
OnCsisSizeValueUpdate(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services=false)1071   void OnCsisSizeValueUpdate(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1072                              const uint8_t* value, bool notify_valid_services = false) {
1073     auto device = FindDeviceByConnId(conn_id);
1074 
1075     if (device == nullptr) {
1076       log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id);
1077       return;
1078     }
1079 
1080     log::debug("{}, status: 0x{:02x}", device->addr, status);
1081 
1082     if (status != GATT_SUCCESS) {
1083       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1084         log::info("Database out of sync for {}", device->addr);
1085         ClearDeviceInformationAndStartSearch(device);
1086       } else {
1087         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1088         BTA_GATTC_Close(device->conn_id);
1089       }
1090       return;
1091     }
1092 
1093     if (len != 1) {
1094       log::error("Invalid size value length={} at handle= 0x{:04x}", len, handle);
1095       BTA_GATTC_Close(device->conn_id);
1096       return;
1097     }
1098 
1099     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1100     if (csis_instance == nullptr) {
1101       log::error("Unknown csis instance");
1102       BTA_GATTC_Close(device->conn_id);
1103       return;
1104     }
1105     auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
1106     if (!csis_group) {
1107       log::error("Unknown group id yet");
1108       return;
1109     }
1110 
1111     auto new_size = value[0];
1112     csis_group->SetDesiredSize(new_size);
1113 
1114     if (notify_valid_services) {
1115       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1116     }
1117   }
1118 
OnCsisLockReadRsp(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services=false)1119   void OnCsisLockReadRsp(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1120                          const uint8_t* value, bool notify_valid_services = false) {
1121     auto device = FindDeviceByConnId(conn_id);
1122     if (device == nullptr) {
1123       log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id);
1124       return;
1125     }
1126 
1127     log::info("{}, status 0x{:02x}", device->addr, status);
1128 
1129     if (status != GATT_SUCCESS) {
1130       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1131         log::info("Database out of sync for {}", device->addr);
1132         ClearDeviceInformationAndStartSearch(device);
1133       } else {
1134         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1135         BTA_GATTC_Close(device->conn_id);
1136       }
1137       return;
1138     }
1139 
1140     if (len != 1) {
1141       log::error("Invalid lock value length={}, at handle=0x{:04x}", len, handle);
1142       BTA_GATTC_Close(device->conn_id);
1143       return;
1144     }
1145 
1146     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1147     if (csis_instance == nullptr) {
1148       log::error("Unknown csis instance");
1149       BTA_GATTC_Close(device->conn_id);
1150       return;
1151     }
1152     csis_instance->SetLockState((CsisLockState)(value[0]));
1153 
1154     if (notify_valid_services) {
1155       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1156     }
1157   }
1158 
OnCsisRankReadRsp(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services)1159   void OnCsisRankReadRsp(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1160                          const uint8_t* value, bool notify_valid_services) {
1161     auto device = FindDeviceByConnId(conn_id);
1162     if (device == nullptr) {
1163       log::warn("Skipping unknown device, conn_id= 0x{:04x}", conn_id);
1164       return;
1165     }
1166 
1167     log::debug("{}, status: 0x{:02x}, rank: {}", device->addr, status, value[0]);
1168     if (status != GATT_SUCCESS) {
1169       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1170         log::info("Database out of sync for {}", device->addr);
1171         ClearDeviceInformationAndStartSearch(device);
1172       } else {
1173         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1174         BTA_GATTC_Close(device->conn_id);
1175       }
1176       return;
1177     }
1178 
1179     if (len != 1) {
1180       log::error("Invalid rank value length= {},  at handle= 0x{:04x}", len, handle);
1181       BTA_GATTC_Close(device->conn_id);
1182       return;
1183     }
1184 
1185     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1186     if (csis_instance == nullptr) {
1187       log::error("Unknown csis instance handle 0x{:04x}", handle);
1188       BTA_GATTC_Close(device->conn_id);
1189       return;
1190     }
1191 
1192     csis_instance->SetRank(value[0]);
1193     auto csis_group = FindCsisGroup(csis_instance->GetGroupId());
1194     if (!csis_group) {
1195       log::error("Unknown group id yet");
1196       return;
1197     }
1198 
1199     csis_group->SortByCsisRank();
1200 
1201     if (notify_valid_services) {
1202       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1203     }
1204   }
1205 
OnCsisObserveCompleted(void)1206   void OnCsisObserveCompleted(void) {
1207     log::info("Group_id: {}", discovering_group_);
1208 
1209     if (discovering_group_ == bluetooth::groups::kGroupUnknown) {
1210       log::error("No ongoing CSIS discovery - disable scan");
1211       return;
1212     }
1213 
1214     auto csis_group = FindCsisGroup(discovering_group_);
1215     discovering_group_ = bluetooth::groups::kGroupUnknown;
1216 
1217     if (!csis_group) {
1218       log::warn("Group_id {} is not existing", discovering_group_);
1219       discovering_group_ = bluetooth::groups::kGroupUnknown;
1220       return;
1221     }
1222 
1223     discovering_group_ = bluetooth::groups::kGroupUnknown;
1224     if (csis_group->IsGroupComplete()) {
1225       csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_COMPLETED);
1226     } else {
1227       csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1228     }
1229   }
1230 
1231   /*
1232    * Sirk shall be in LE order
1233    * encrypted_sirk: LE order
1234    */
sdf(const RawAddress & address,const Octet16 & encrypted_sirk,Octet16 & sirk)1235   bool sdf(const RawAddress& address, const Octet16& encrypted_sirk, Octet16& sirk) {
1236     auto pltk = BTM_BleGetPeerLTK(address);
1237     if (!pltk.has_value()) {
1238       log::error("No security for {}", address);
1239       return false;
1240     }
1241 
1242 #ifdef CSIS_DEBUG
1243     auto irk = BTM_BleGetPeerIRK(address);
1244     log::info("LTK {}", base::HexEncode(*pltk.data(), 16));
1245     log::info("IRK {}", base::HexEncode(*irk.data(), 16));
1246 #endif
1247 
1248     /* Calculate salt CSIS d1.0r05 4.3 */
1249     Octet16 zero_key;
1250     memset(zero_key.data(), 0, 16);
1251 
1252     std::string msg1 = "SIRKenc";
1253     std::reverse(msg1.begin(), msg1.end());
1254 
1255     Octet16 s1 = crypto_toolbox::aes_cmac(zero_key, (uint8_t*)(msg1.c_str()), msg1.size());
1256 
1257 #ifdef CSIS_DEBUG
1258     log::info("s1 (le) {}", base::HexEncode(s1.data(), 16));
1259     /* Create K = LTK */
1260     log::info("K (le) {}", base::HexEncode(*pltk.data(), 16));
1261 #endif
1262 
1263     Octet16 T = crypto_toolbox::aes_cmac(s1, *pltk);
1264 
1265 #ifdef CSIS_DEBUG
1266     log::info("T (le) {}", base::HexEncode(T.data(), 16));
1267 #endif
1268 
1269     std::string msg2 = "csis";
1270     std::reverse(msg2.begin(), msg2.end());
1271 
1272     Octet16 k1 = crypto_toolbox::aes_cmac(T, (uint8_t*)(msg2.c_str()), msg2.size());
1273 #ifdef CSIS_DEBUG
1274     log::info("K1 (le) {}", base::HexEncode(k1.data(), 16));
1275 #endif
1276 
1277     for (int i = 0; i < 16; i++) {
1278       sirk[i] = encrypted_sirk[i] ^ k1[i];
1279     }
1280 
1281 #ifdef CSIS_DEBUG
1282     log::info("SIRK (le){}", base::HexEncode(sirk.data(), 16));
1283 #endif
1284 
1285     return true;
1286   }
1287 
GetAllRsiFromAdvertising(const tBTA_DM_INQ_RES * result)1288   std::vector<RawAddress> GetAllRsiFromAdvertising(const tBTA_DM_INQ_RES* result) {
1289     const uint8_t* p_service_data = result->p_eir;
1290     std::vector<RawAddress> devices;
1291     uint8_t service_data_len = 0;
1292 
1293     while ((p_service_data = AdvertiseDataParser::GetFieldByType(
1294                     p_service_data + service_data_len,
1295                     result->eir_len - (p_service_data - result->p_eir) - service_data_len,
1296                     BTM_BLE_AD_TYPE_RSI, &service_data_len))) {
1297       RawAddress bda;
1298       const uint8_t* p_bda = p_service_data;
1299       if (service_data_len < RawAddress::kLength) {
1300         continue;
1301       }
1302 
1303       STREAM_TO_BDADDR(bda, p_bda);
1304       devices.push_back(std::move(bda));
1305     }
1306 
1307     return devices;
1308   }
1309 
GetNumOfKnownExpectedDevicesWaitingForBonding(int group_id)1310   int GetNumOfKnownExpectedDevicesWaitingForBonding(int group_id) {
1311     return std::count_if(devices_.begin(), devices_.end(), [group_id](const auto& device) {
1312       return device->GetExpectedGroupIdMember() == group_id &&
1313              !device->GetCsisInstanceByGroupId(group_id);
1314     });
1315   }
1316 
CacheAndAdvertiseExpectedMember(const RawAddress & address,int group_id)1317   void CacheAndAdvertiseExpectedMember(const RawAddress& address, int group_id) {
1318     auto device = FindDeviceByAddress(address);
1319     if (device == nullptr) {
1320       device = std::make_shared<CsisDevice>(address, false);
1321       devices_.push_back(device);
1322     }
1323 
1324     /*
1325      * Expected group ID will be checked while reading SIRK if this device
1326      * truly is member of group.
1327      */
1328     device.get()->SetExpectedGroupIdMember(group_id);
1329     callbacks_->OnSetMemberAvailable(address, device.get()->GetExpectedGroupIdMember());
1330   }
1331 
OnActiveScanResult(const tBTA_DM_INQ_RES * result)1332   void OnActiveScanResult(const tBTA_DM_INQ_RES* result) {
1333     auto csis_device = FindDeviceByAddress(result->bd_addr);
1334     if (csis_device) {
1335       log::debug("Drop same device .. {}", result->bd_addr);
1336       return;
1337     }
1338 
1339     /* Make sure device is not already bonded which could
1340      * be a case for dual mode devices where
1341      */
1342     if (BTM_IsBonded(result->bd_addr, BT_TRANSPORT_LE)) {
1343       log::verbose("Device {} already bonded. Identity address: {}", result->bd_addr,
1344                    *BTM_BleGetIdentityAddress(result->bd_addr));
1345       return;
1346     }
1347 
1348     auto all_rsi = GetAllRsiFromAdvertising(result);
1349     if (all_rsi.empty()) {
1350       return;
1351     }
1352 
1353     /* Notify only the actively searched group */
1354     auto csis_group = FindCsisGroup(discovering_group_);
1355     if (csis_group == nullptr) {
1356       log::error("No ongoing CSIS discovery - disable scan");
1357       CsisActiveObserverSet(false);
1358       return;
1359     }
1360 
1361     if (csis_group->GetDesiredSize() > 0 &&
1362         (csis_group->GetDesiredSize() == csis_group->GetCurrentSize())) {
1363       log::warn("Group is already complete");
1364       return;
1365     }
1366 
1367     auto discovered_group_rsi =
1368             std::find_if(all_rsi.cbegin(), all_rsi.cend(),
1369                          [&csis_group](const auto& rsi) { return csis_group->IsRsiMatching(rsi); });
1370     if (discovered_group_rsi != all_rsi.cend()) {
1371       log::debug("Found set member {}", result->bd_addr);
1372 
1373       CacheAndAdvertiseExpectedMember(result->bd_addr, csis_group->GetGroupId());
1374 
1375       /* Switch back to the opportunistic observer mode.
1376        * When second device will pair, csis will restart active scan
1377        * to search more members if needed */
1378       CsisActiveObserverSet(false);
1379       csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_IDLE);
1380     }
1381   }
1382 
csis_ad_type_filter_set(bool enable)1383   static void csis_ad_type_filter_set(bool enable) {
1384     bool is_ad_type_filter_supported = bluetooth::shim::is_ad_type_filter_supported();
1385 
1386     log::info("enable: {}, is_ad_type_filter_supported: {}", enable, is_ad_type_filter_supported);
1387 
1388     if (is_ad_type_filter_supported) {
1389       bluetooth::shim::set_ad_type_rsi_filter(enable);
1390     } else {
1391       bluetooth::shim::set_empty_filter(enable);
1392     }
1393   }
1394 
CsisActiveObserverSet(bool enable)1395   void CsisActiveObserverSet(bool enable) {
1396     log::info("Group_id {}: enable: {}", discovering_group_, enable);
1397     csis_ad_type_filter_set(enable);
1398 
1399     BTA_DmBleCsisObserve(enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
1400       /* If there's no instance we are most likely shutting
1401        * down the whole stack and we can ignore this event.
1402        */
1403       if (instance == nullptr) {
1404         return;
1405       }
1406 
1407       if (event == BTA_DM_OBSERVE_CMPL_EVT) {
1408         power_telemetry::GetInstance().LogBleScan(static_cast<int>(p_data->observe_cmpl.num_resps));
1409         log::info("BLE observe complete. Num Resp: {}", p_data->observe_cmpl.num_resps);
1410         csis_ad_type_filter_set(false);
1411         instance->OnCsisObserveCompleted();
1412         instance->CsisObserverSetBackground(true);
1413         return;
1414       }
1415 
1416       if (event != BTA_DM_INQ_RES_EVT) {
1417         log::warn("Unknown event: 0x{:02x}", event);
1418         return;
1419       }
1420 
1421       instance->OnActiveScanResult(&p_data->inq_res);
1422     });
1423     BTA_DmBleScan(enable, bluetooth::csis::kDefaultScanDurationS);
1424 
1425     /* Need to call it by ourselfs */
1426     if (!enable) {
1427       OnCsisObserveCompleted();
1428       CsisObserverSetBackground(true);
1429     }
1430   }
1431 
CheckForGroupInInqDb(const std::shared_ptr<CsisGroup> & csis_group)1432   void CheckForGroupInInqDb(const std::shared_ptr<CsisGroup>& csis_group) {
1433     // Check if last inquiry already found devices with RSI matching this group
1434     for (tBTM_INQ_INFO* inq_ent = get_btm_client_interface().db.BTM_InqDbFirst();
1435          inq_ent != nullptr; inq_ent = get_btm_client_interface().db.BTM_InqDbNext(inq_ent)) {
1436       RawAddress rsi = inq_ent->results.ble_ad_rsi;
1437       if (!csis_group->IsRsiMatching(rsi)) {
1438         continue;
1439       }
1440 
1441       RawAddress address = inq_ent->results.remote_bd_addr;
1442       auto device = FindDeviceByAddress(address);
1443       if (device && csis_group->IsDeviceInTheGroup(device)) {
1444         // InqDb will also contain existing devices, already in group - skip
1445         // them
1446         continue;
1447       }
1448 
1449       log::info("Device {} from inquiry cache match to group id {}", address,
1450                 csis_group->GetGroupId());
1451       callbacks_->OnSetMemberAvailable(address, csis_group->GetGroupId());
1452       break;
1453     }
1454   }
1455 
CsisActiveDiscovery(std::shared_ptr<CsisGroup> csis_group)1456   void CsisActiveDiscovery(std::shared_ptr<CsisGroup> csis_group) {
1457     if (csis_group->GetDiscoveryState() != CsisDiscoveryState::CSIS_DISCOVERY_IDLE) {
1458       log::error("Incorrect ase group: {}, state 0x{:02x}", csis_group->GetGroupId(),
1459                  static_cast<int>(csis_group->GetDiscoveryState()));
1460       return;
1461     }
1462 
1463     csis_group->SetDiscoveryState(CsisDiscoveryState::CSIS_DISCOVERY_ONGOING);
1464     /* TODO Maybe we don't need it */
1465     discovering_group_ = csis_group->GetGroupId();
1466     CsisActiveObserverSet(true);
1467   }
1468 
OnScanBackgroundResult(const tBTA_DM_INQ_RES * result)1469   void OnScanBackgroundResult(const tBTA_DM_INQ_RES* result) {
1470     if (csis_groups_.empty()) {
1471       return;
1472     }
1473 
1474     auto csis_device = FindDeviceByAddress(result->bd_addr);
1475     if (csis_device) {
1476       log::debug("Drop known device {}", result->bd_addr);
1477       return;
1478     }
1479 
1480     /* Make sure device is not already bonded which could
1481      * be a case for dual mode devices where
1482      */
1483     if (BTM_IsBonded(result->bd_addr, BT_TRANSPORT_LE)) {
1484       log::verbose("Device {} already bonded. Identity address: {}", result->bd_addr,
1485                    *BTM_BleGetIdentityAddress(result->bd_addr));
1486       return;
1487     }
1488 
1489     auto all_rsi = GetAllRsiFromAdvertising(result);
1490     if (all_rsi.empty()) {
1491       return;
1492     }
1493 
1494     /* Notify all the groups this device belongs to. */
1495     for (auto& group : csis_groups_) {
1496       for (auto& rsi : all_rsi) {
1497         if (group->IsRsiMatching(rsi)) {
1498           log::info("Device {} match to group id {}", result->bd_addr, group->GetGroupId());
1499           if (group->GetDesiredSize() > 0 && (group->GetCurrentSize() == group->GetDesiredSize())) {
1500             log::warn("Group is already completed. Some other device use same SIRK");
1501             break;
1502           }
1503 
1504           CacheAndAdvertiseExpectedMember(result->bd_addr, group->GetGroupId());
1505 
1506           break;
1507         }
1508       }
1509     }
1510   }
1511 
CsisObserverSetBackground(bool enable)1512   void CsisObserverSetBackground(bool enable) {
1513     log::debug("CSIS Discovery background: {}", enable);
1514 
1515     BTA_DmBleCsisObserve(enable, [](tBTA_DM_SEARCH_EVT event, tBTA_DM_SEARCH* p_data) {
1516       /* If there's no instance we are most likely shutting
1517        * down the whole stack and we can ignore this event.
1518        */
1519       if (instance == nullptr) {
1520         return;
1521       }
1522 
1523       if (event == BTA_DM_OBSERVE_CMPL_EVT) {
1524         power_telemetry::GetInstance().LogBleScan(static_cast<int>(p_data->observe_cmpl.num_resps));
1525         log::verbose("BLE observe complete. Num Resp: {}", p_data->observe_cmpl.num_resps);
1526         return;
1527       }
1528 
1529       if (event != BTA_DM_INQ_RES_EVT) {
1530         log::warn("Unknown event: 0x{:02x}", event);
1531         return;
1532       }
1533 
1534       instance->OnScanBackgroundResult(&p_data->inq_res);
1535     });
1536   }
1537 
OnCsisSirkValueUpdate(tCONN_ID conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,bool notify_valid_services=true)1538   void OnCsisSirkValueUpdate(tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1539                              const uint8_t* value, bool notify_valid_services = true) {
1540     auto device = FindDeviceByConnId(conn_id);
1541     if (device == nullptr) {
1542       log::warn("Skipping unknown device, conn_id=0x{:04x}", conn_id);
1543       return;
1544     }
1545 
1546     log::debug("{}, status: 0x{:02x}", device->addr, status);
1547 
1548     if (status != GATT_SUCCESS) {
1549       /* TODO handle error codes:
1550        * kCsisErrorCodeLockAccessSirkRejected
1551        * kCsisErrorCodeLockOobSirkOnly
1552        */
1553       if (status == GATT_DATABASE_OUT_OF_SYNC) {
1554         log::info("Database out of sync for {}", device->addr);
1555         ClearDeviceInformationAndStartSearch(device);
1556       } else {
1557         log::error("Could not read characteristic at handle=0x{:04x}", handle);
1558         BTA_GATTC_Close(device->conn_id);
1559       }
1560       return;
1561     }
1562 
1563     if (len != bluetooth::csis::kCsisSirkCharLen) {
1564       log::error("Invalid sirk value length= {} at handle= 0x{:04x}", len, handle);
1565       BTA_GATTC_Close(device->conn_id);
1566       return;
1567     }
1568 
1569     auto csis_instance = device->GetCsisInstanceByOwningHandle(handle);
1570     if (csis_instance == nullptr) {
1571       log::error("Unknown csis instance: handle 0x{:04x}", handle);
1572       BTA_GATTC_Close(device->conn_id);
1573       return;
1574     }
1575 
1576     uint8_t sirk_type = value[0];
1577     log::info("SIRK Type: 0x{:02x}", sirk_type);
1578 
1579     /* Verify if sirk is not all zeros */
1580     Octet16 zero{};
1581     if (memcmp(zero.data(), value + 1, 16) == 0) {
1582       log::error("Received invalid zero SIRK conn_id: 0x{:02x}. Disconnecting", device->conn_id);
1583       BTA_GATTC_Close(device->conn_id);
1584       return;
1585     }
1586 
1587     Octet16 received_sirk;
1588     memcpy(received_sirk.data(), value + 1, 16);
1589 
1590     if (sirk_type == bluetooth::csis::kCsisSirkTypeEncrypted) {
1591       /* Decrypt encrypted SIRK */
1592       Octet16 sirk;
1593       sdf(device->addr, received_sirk, sirk);
1594       received_sirk = sirk;
1595     }
1596 
1597     /* SIRK is ready. Add device to the group */
1598 
1599     std::shared_ptr<CsisGroup> csis_group;
1600     int group_id = csis_instance->GetGroupId();
1601     if (group_id != bluetooth::groups::kGroupUnknown) {
1602       /* Group already exist. */
1603       csis_group = FindCsisGroup(group_id);
1604       log::assert_that(csis_group != nullptr, "group does not exist? {}", group_id);
1605     } else {
1606       /* Now having SIRK we can decide if the device belongs to some group we
1607        * know or this is a new group
1608        */
1609       for (auto& g : csis_groups_) {
1610         if (g->IsSirkBelongsToGroup(received_sirk)) {
1611           group_id = g->GetGroupId();
1612           break;
1613         }
1614       }
1615 
1616       if (group_id == bluetooth::groups::kGroupUnknown) {
1617         /* Here it means, we have new group. Let's us create it */
1618         group_id = dev_groups_->AddDevice(device->addr, csis_instance->GetUuid());
1619         log::assert_that(group_id != bluetooth::groups::kGroupUnknown,
1620                          "assert failed: group_id != bluetooth::groups::kGroupUnknown");
1621       } else {
1622         dev_groups_->AddDevice(device->addr, csis_instance->GetUuid(), group_id);
1623       }
1624 
1625       csis_group = FindCsisGroup(group_id);
1626       csis_group->AddDevice(device);
1627       /* Let's update csis instance group id */
1628       csis_instance->SetGroupId(group_id);
1629     }
1630 
1631     csis_group->SetSirk(received_sirk);
1632     device->is_gatt_service_valid = true;
1633     btif_storage_update_csis_info(device->addr);
1634 
1635     if (notify_valid_services) {
1636       NotifyCsisDeviceValidAndStoreIfNeeded(device);
1637     }
1638 
1639 #ifdef CSIS_DEBUG
1640     log::info("SIRK {}, address: {}", base::HexEncode(received_sirk.data(), 16), device->addr);
1641 #endif
1642 
1643     log::verbose("Expected group size {},  actual group Size: {}", csis_group->GetDesiredSize(),
1644                  csis_group->GetCurrentSize());
1645 
1646     if (csis_group->GetDesiredSize() == csis_group->GetCurrentSize()) {
1647       auto iter = devices_.cbegin();
1648 
1649       /*
1650        * Remove devices which are expected members but are not connected and
1651        * group is already completed. Those devices are cached ivalid devices
1652        * kept on list to not trigger "new device" found every time advertising
1653        * event is received.
1654        */
1655       while (iter != devices_.cend()) {
1656         if (((*iter)->GetExpectedGroupIdMember() == csis_group->GetGroupId()) &&
1657             !(*iter)->IsConnected()) {
1658           iter = devices_.erase(iter);
1659         } else {
1660           ++iter;
1661         }
1662       }
1663     }
1664   }
1665 
DeregisterNotifications(std::shared_ptr<CsisDevice> device)1666   void DeregisterNotifications(std::shared_ptr<CsisDevice> device) {
1667     device->ForEachCsisInstance([&](const std::shared_ptr<CsisInstance>& csis_inst) {
1668       DisableGattNotification(device->conn_id, device->addr,
1669                               csis_inst->svc_data.lock_handle.val_hdl);
1670       DisableGattNotification(device->conn_id, device->addr,
1671                               csis_inst->svc_data.sirk_handle.val_hdl);
1672       DisableGattNotification(device->conn_id, device->addr,
1673                               csis_inst->svc_data.size_handle.val_hdl);
1674     });
1675   }
1676 
DoDisconnectCleanUp(std::shared_ptr<CsisDevice> device)1677   void DoDisconnectCleanUp(std::shared_ptr<CsisDevice> device) {
1678     log::info("{}", device->addr);
1679 
1680     DeregisterNotifications(device);
1681 
1682     if (device->IsConnected()) {
1683       BtaGattQueue::Clean(device->conn_id);
1684       device->conn_id = GATT_INVALID_CONN_ID;
1685     }
1686   }
1687 
OnCsisServiceFound(std::shared_ptr<CsisDevice> device,const gatt::Service * service,const bluetooth::Uuid & context_uuid,bool is_last_instance)1688   bool OnCsisServiceFound(std::shared_ptr<CsisDevice> device, const gatt::Service* service,
1689                           const bluetooth::Uuid& context_uuid, bool is_last_instance) {
1690     log::debug("service handle: 0x{:04x}, end handle: 0x{:04x}, uuid: {}", service->handle,
1691                service->end_handle, context_uuid.ToString());
1692 
1693     auto csis_inst = std::make_shared<CsisInstance>((uint16_t)service->handle,
1694                                                     (uint16_t)service->end_handle, context_uuid);
1695 
1696     /* Let's check if we know group of this device */
1697     int group_id = dev_groups_->GetGroupId(device->addr, context_uuid);
1698     if (group_id != bluetooth::groups::kGroupUnknown) {
1699       csis_inst->SetGroupId(group_id);
1700     }
1701 
1702     device->SetCsisInstance(csis_inst->svc_data.start_handle, csis_inst);
1703 
1704     /* Initially validate and store GATT service discovery data */
1705     for (const gatt::Characteristic& charac : service->characteristics) {
1706       if (charac.uuid == kCsisLockUuid) {
1707         /* Find the mandatory CCC descriptor */
1708         uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle);
1709         if (ccc_handle == GAP_INVALID_HANDLE) {
1710           log::error("no HAS Active Preset CCC descriptor found!");
1711           device->RemoveCsisInstance(group_id);
1712           return false;
1713         }
1714         csis_inst->svc_data.lock_handle.val_hdl = charac.value_handle;
1715         csis_inst->svc_data.lock_handle.ccc_hdl = ccc_handle;
1716 
1717         SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle);
1718 
1719         log::debug("Lock UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: {}",
1720                    csis_inst->svc_data.lock_handle.val_hdl, csis_inst->svc_data.lock_handle.ccc_hdl,
1721                    device->addr);
1722       } else if (charac.uuid == kCsisRankUuid) {
1723         csis_inst->svc_data.rank_handle = charac.value_handle;
1724 
1725         log::debug("Rank UUID found handle: 0x{:04x}, device: {}", csis_inst->svc_data.rank_handle,
1726                    device->addr);
1727       } else if (charac.uuid == kCsisSirkUuid) {
1728         /* Find the optional CCC descriptor */
1729         uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle);
1730         csis_inst->svc_data.sirk_handle.ccc_hdl = ccc_handle;
1731         csis_inst->svc_data.sirk_handle.val_hdl = charac.value_handle;
1732 
1733         if (ccc_handle != GAP_INVALID_HANDLE) {
1734           SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle);
1735         }
1736 
1737         log::debug("SIRK UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: {}",
1738                    csis_inst->svc_data.sirk_handle.val_hdl, csis_inst->svc_data.sirk_handle.ccc_hdl,
1739                    device->addr);
1740       } else if (charac.uuid == kCsisSizeUuid) {
1741         /* Find the optional CCC descriptor */
1742         uint16_t ccc_handle = FindCccHandle(device->conn_id, charac.value_handle);
1743         csis_inst->svc_data.size_handle.ccc_hdl = ccc_handle;
1744         csis_inst->svc_data.size_handle.val_hdl = charac.value_handle;
1745 
1746         if (ccc_handle != GAP_INVALID_HANDLE) {
1747           SubscribeForNotifications(device->conn_id, device->addr, charac.value_handle, ccc_handle);
1748         }
1749 
1750         log::debug("Size UUID found handle: 0x{:04x}, ccc handle: 0x{:04x}, device: {}",
1751                    csis_inst->svc_data.size_handle.val_hdl, csis_inst->svc_data.size_handle.ccc_hdl,
1752                    device->addr);
1753       }
1754     }
1755 
1756     /* Sirk is the only mandatory characteristic. If it is in
1757      * place, service is OK
1758      */
1759     if (csis_inst->svc_data.sirk_handle.val_hdl == GAP_INVALID_HANDLE) {
1760       /* We have some characteristics but all dependencies are not satisfied */
1761       log::error("Service has a broken structure.");
1762       device->RemoveCsisInstance(group_id);
1763       return false;
1764     }
1765 
1766     bool notify_after_sirk_read = false;
1767     bool notify_after_lock_read = false;
1768     bool notify_after_rank_read = false;
1769     bool notify_after_size_read = false;
1770 
1771     /* Find which read will be the last one*/
1772     if (is_last_instance) {
1773       if (csis_inst->svc_data.rank_handle != GAP_INVALID_HANDLE) {
1774         notify_after_rank_read = true;
1775       } else if (csis_inst->svc_data.size_handle.val_hdl != GAP_INVALID_HANDLE) {
1776         notify_after_size_read = true;
1777       } else if (csis_inst->svc_data.lock_handle.val_hdl != GAP_INVALID_HANDLE) {
1778         notify_after_lock_read = true;
1779       } else {
1780         notify_after_sirk_read = true;
1781       }
1782     }
1783 
1784     /* Read SIRK */
1785     BtaGattQueue::ReadCharacteristic(
1786             device->conn_id, csis_inst->svc_data.sirk_handle.val_hdl,
1787             [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len, uint8_t* value,
1788                void* user_data) {
1789               if (instance) {
1790                 instance->OnCsisSirkValueUpdate(conn_id, status, handle, len, value,
1791                                                 (bool)user_data);
1792               }
1793             },
1794             (void*)notify_after_sirk_read);
1795 
1796     /* Read Lock */
1797     if (csis_inst->svc_data.lock_handle.val_hdl != GAP_INVALID_HANDLE) {
1798       BtaGattQueue::ReadCharacteristic(
1799               device->conn_id, csis_inst->svc_data.lock_handle.val_hdl,
1800               [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1801                  uint8_t* value, void* user_data) {
1802                 if (instance) {
1803                   instance->OnCsisLockReadRsp(conn_id, status, handle, len, value, (bool)user_data);
1804                 }
1805               },
1806               (void*)notify_after_lock_read);
1807     }
1808 
1809     /* Read Size */
1810     if (csis_inst->svc_data.size_handle.val_hdl != GAP_INVALID_HANDLE) {
1811       BtaGattQueue::ReadCharacteristic(
1812               device->conn_id, csis_inst->svc_data.size_handle.val_hdl,
1813               [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1814                  uint8_t* value, void* user_data) {
1815                 if (instance) {
1816                   instance->OnCsisSizeValueUpdate(conn_id, status, handle, len, value,
1817                                                   (bool)user_data);
1818                 }
1819               },
1820               (void*)notify_after_size_read);
1821     }
1822 
1823     /* Read Rank */
1824     if (csis_inst->svc_data.rank_handle != GAP_INVALID_HANDLE) {
1825       BtaGattQueue::ReadCharacteristic(
1826               device->conn_id, csis_inst->svc_data.rank_handle,
1827               [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
1828                  uint8_t* value, void* user_data) {
1829                 if (instance) {
1830                   instance->OnCsisRankReadRsp(conn_id, status, handle, len, value, (bool)user_data);
1831                 }
1832               },
1833               (void*)notify_after_rank_read);
1834     }
1835 
1836     return true;
1837   }
1838 
1839   /* These are all generic GATT event handlers calling HAS specific code. */
GattcCallback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)1840   void GattcCallback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
1841     log::info("event = 0x{:02x}", event);
1842 
1843     /* This is in case Csis CleanUp is already done
1844      * while GATT is still up and could send events
1845      */
1846     if (!instance) {
1847       return;
1848     }
1849 
1850     switch (event) {
1851       case BTA_GATTC_DEREG_EVT:
1852         break;
1853 
1854       case BTA_GATTC_OPEN_EVT:
1855         OnGattConnected(p_data->open);
1856         break;
1857 
1858       case BTA_GATTC_CLOSE_EVT:
1859         OnGattDisconnected(p_data->close);
1860         break;
1861 
1862       case BTA_GATTC_SEARCH_CMPL_EVT:
1863         OnGattServiceSearchComplete(p_data->search_cmpl);
1864         break;
1865 
1866       case BTA_GATTC_NOTIF_EVT:
1867         OnGattNotification(p_data->notify);
1868         break;
1869 
1870       case BTA_GATTC_ENC_CMPL_CB_EVT: {
1871         tBTM_STATUS encryption_status;
1872         if (BTM_IsEncrypted(p_data->enc_cmpl.remote_bda, BT_TRANSPORT_LE)) {
1873           encryption_status = tBTM_STATUS::BTM_SUCCESS;
1874         } else {
1875           encryption_status = tBTM_STATUS::BTM_FAILED_ON_SECURITY;
1876         }
1877         OnLeEncryptionComplete(p_data->enc_cmpl.remote_bda, encryption_status);
1878       } break;
1879 
1880       case BTA_GATTC_SRVC_CHG_EVT:
1881         OnGattServiceChangeEvent(p_data->service_changed.remote_bda);
1882         break;
1883 
1884       case BTA_GATTC_SRVC_DISC_DONE_EVT:
1885         OnGattServiceDiscoveryDoneEvent(p_data->service_discovery_done.remote_bda);
1886         break;
1887 
1888       default:
1889         break;
1890     }
1891   }
1892 
OnGattConnected(const tBTA_GATTC_OPEN & evt)1893   void OnGattConnected(const tBTA_GATTC_OPEN& evt) {
1894     log::info("{}, conn_id=0x{:04x}, transport={}, status={}(0x{:02x})", evt.remote_bda,
1895               evt.conn_id, bt_transport_text(evt.transport), gatt_status_text(evt.status),
1896               evt.status);
1897 
1898     if (evt.transport != BT_TRANSPORT_LE) {
1899       log::warn("Only LE connection is allowed (transport {})", bt_transport_text(evt.transport));
1900       BTA_GATTC_Close(evt.conn_id);
1901       return;
1902     }
1903 
1904     auto device = FindDeviceByAddress(evt.remote_bda);
1905     if (device == nullptr) {
1906       log::debug("Skipping unknown device, address= {}", evt.remote_bda);
1907       BTA_GATTC_Close(evt.conn_id);
1908       return;
1909     }
1910 
1911     if (evt.status != GATT_SUCCESS) {
1912       log::error("Failed to connect to server device {}", evt.remote_bda);
1913       if (device->connecting_actively) {
1914         callbacks_->OnConnectionState(evt.remote_bda, ConnectionState::DISCONNECTED);
1915       }
1916       DoDisconnectCleanUp(device);
1917       StartOpportunisticConnect(evt.remote_bda);
1918       return;
1919     }
1920 
1921     device->connecting_actively = false;
1922     device->conn_id = evt.conn_id;
1923     if (com::android::bluetooth::flags::gatt_queue_cleanup_connected()) {
1924       BtaGattQueue::Clean(evt.conn_id);
1925     }
1926     /* Verify bond */
1927     if (BTM_SecIsLeSecurityPending(device->addr)) {
1928       /* if security collision happened, wait for encryption done
1929        * (BTA_GATTC_ENC_CMPL_CB_EVT) */
1930       return;
1931     }
1932 
1933     /* verify bond */
1934     if (BTM_IsEncrypted(device->addr, BT_TRANSPORT_LE)) {
1935       /* if link has been encrypted */
1936       OnEncrypted(device);
1937       return;
1938     }
1939 
1940     tBTM_STATUS result =
1941             BTM_SetEncryption(device->addr, BT_TRANSPORT_LE, nullptr, nullptr, BTM_BLE_SEC_ENCRYPT);
1942 
1943     log::info("Encryption required for {}. Request result: 0x{:02x}", device->addr, result);
1944 
1945     if (result == tBTM_STATUS::BTM_ERR_KEY_MISSING) {
1946       log::error("Link key unknown for {}, disconnect profile", device->addr);
1947       BTA_GATTC_Close(device->conn_id);
1948     }
1949   }
1950 
OnGattDisconnected(const tBTA_GATTC_CLOSE & evt)1951   void OnGattDisconnected(const tBTA_GATTC_CLOSE& evt) {
1952     auto device = FindDeviceByAddress(evt.remote_bda);
1953     if (device == nullptr) {
1954       log::warn("Skipping unknown device disconnect, conn_id= 0x{:04x}", evt.conn_id);
1955       return;
1956     }
1957 
1958     log::debug("device={}", device->addr);
1959 
1960     callbacks_->OnConnectionState(evt.remote_bda, ConnectionState::DISCONNECTED);
1961 
1962     // Unlock others only if device was locked by us but has disconnected
1963     // unexpectedly.
1964     if ((evt.reason == GATT_CONN_TIMEOUT) || (evt.reason == GATT_CONN_TERMINATE_PEER_USER)) {
1965       device->ForEachCsisInstance([&](const std::shared_ptr<CsisInstance>& csis_inst) {
1966         auto csis_group = FindCsisGroup(csis_inst->GetGroupId());
1967         if (csis_group == nullptr) {
1968           return;
1969         }
1970         if (csis_group->GetCurrentLockState() == CsisLockState::CSIS_STATE_LOCKED) {
1971           HandleCsisLockProcedureError(csis_group, device,
1972                                        CsisGroupLockStatus::LOCKED_GROUP_MEMBER_LOST);
1973         }
1974       });
1975     }
1976 
1977     DoDisconnectCleanUp(device);
1978   }
1979 
OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL & evt)1980   void OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL& evt) {
1981     auto device = FindDeviceByConnId(evt.conn_id);
1982 
1983     if (device == nullptr) {
1984       log::warn("Skipping unknown device, conn_id= 0x{:4x}", evt.conn_id);
1985       return;
1986     }
1987 
1988     /* verify encryption enabled */
1989     if (!BTM_IsEncrypted(device->addr, BT_TRANSPORT_LE)) {
1990       log::warn("Device not yet bonded - waiting for encryption");
1991       return;
1992     }
1993 
1994     /* Ignore if our service data is valid (discovery initiated by someone
1995      * else?) */
1996     if (!device->is_gatt_service_valid) {
1997       if (evt.status != GATT_SUCCESS) {
1998         log::error("Service discovery failed");
1999         BTA_GATTC_Close(device->conn_id);
2000         DoDisconnectCleanUp(device);
2001         return;
2002       }
2003 
2004       log::verbose("");
2005 
2006       const std::list<gatt::Service>* all_services = BTA_GATTC_GetServices(device->conn_id);
2007 
2008       std::vector<uint16_t> all_csis_start_handles;
2009 
2010       /* Le's just find all the CSIS primary services and store the start
2011        * handles */
2012       for (auto& svrc : *all_services) {
2013         if (svrc.uuid == kCsisServiceUuid) {
2014           all_csis_start_handles.push_back(svrc.handle);
2015         }
2016       }
2017 
2018       if (all_csis_start_handles.size() == 0) {
2019         log::debug("No Csis instances found");
2020         BTA_GATTC_Close(device->conn_id);
2021         RemoveCsisDevice(device, bluetooth::groups::kGroupUnknown);
2022         return;
2023       }
2024 
2025       for (auto& svrc : *all_services) {
2026         if (svrc.uuid == kCsisServiceUuid) {
2027           continue;
2028         }
2029 
2030         /* Try to find context for CSIS instances */
2031         for (auto& included_srvc : svrc.included_services) {
2032           if (included_srvc.uuid == kCsisServiceUuid) {
2033             auto csis_svrc =
2034                     BTA_GATTC_GetOwningService(device->conn_id, included_srvc.start_handle);
2035             auto iter = std::find(all_csis_start_handles.begin(), all_csis_start_handles.end(),
2036                                   included_srvc.start_handle);
2037             if (iter != all_csis_start_handles.end()) {
2038               all_csis_start_handles.erase(iter);
2039             }
2040             instance->OnCsisServiceFound(device, csis_svrc, svrc.uuid,
2041                                          all_csis_start_handles.empty());
2042           }
2043         }
2044       }
2045 
2046       /* Here if CSIS is included, all_csis_start_handles should be empty
2047        * Otherwise it means, we have some primary CSIS without a context,
2048        * which means it is for the complete device.
2049        * As per spec, there can be only one service like this.
2050        */
2051       if (all_csis_start_handles.size()) {
2052         log::debug("there is {} primary services without a context",
2053                    static_cast<int>(all_csis_start_handles.size()));
2054         auto csis_svrc = BTA_GATTC_GetOwningService(device->conn_id, all_csis_start_handles[0]);
2055         instance->OnCsisServiceFound(device, csis_svrc, bluetooth::groups::kGenericContextUuid,
2056                                      true);
2057         all_csis_start_handles.clear();
2058       }
2059     } else {
2060       /* This might be set already if there is no optional attributes to read
2061        * or write.
2062        */
2063       if (evt.status == GATT_SUCCESS) {
2064         NotifyCsisDeviceValidAndStoreIfNeeded(device);
2065       }
2066     }
2067   }
2068 
OnGattNotification(const tBTA_GATTC_NOTIFY & evt)2069   void OnGattNotification(const tBTA_GATTC_NOTIFY& evt) {
2070     /* Reject invalid lengths and indications as they are not supported */
2071     if (!evt.is_notify || evt.len > GATT_MAX_ATTR_LEN) {
2072       log::error(": rejected BTA_GATTC_NOTIF_EVT. is_notify = {}, len= {}", evt.is_notify, evt.len);
2073     }
2074 
2075     OnCsisNotification(evt.conn_id, evt.handle, evt.len, evt.value);
2076   }
2077 
OnLeEncryptionComplete(const RawAddress & address,tBTM_STATUS status)2078   void OnLeEncryptionComplete(const RawAddress& address, tBTM_STATUS status) {
2079     log::info("{}", address);
2080     auto device = FindDeviceByAddress(address);
2081     if (device == nullptr) {
2082       log::warn("Skipping unknown device {}", address);
2083       return;
2084     }
2085 
2086     if (status != tBTM_STATUS::BTM_SUCCESS) {
2087       log::error("encryption failed. status: 0x{:02x}", status);
2088 
2089       BTA_GATTC_Close(device->conn_id);
2090       return;
2091     }
2092 
2093     if (device->is_gatt_service_valid) {
2094       instance->OnEncrypted(device);
2095     } else {
2096       BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
2097     }
2098   }
2099 
ClearDeviceInformationAndStartSearch(std::shared_ptr<CsisDevice> device)2100   void ClearDeviceInformationAndStartSearch(std::shared_ptr<CsisDevice> device) {
2101     log::info("{}", device->addr);
2102     if (device->is_gatt_service_valid == false) {
2103       log::debug("Device database already invalidated.");
2104       return;
2105     }
2106 
2107     /* Invalidate service discovery results */
2108     BtaGattQueue::Clean(device->conn_id);
2109     DeregisterNotifications(device);
2110     device->ClearSvcData();
2111     BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
2112   }
2113 
OnGattServiceChangeEvent(const RawAddress & address)2114   void OnGattServiceChangeEvent(const RawAddress& address) {
2115     auto device = FindDeviceByAddress(address);
2116     if (!device) {
2117       log::warn("Skipping unknown device {}", address);
2118       return;
2119     }
2120 
2121     log::info("{}", address);
2122     ClearDeviceInformationAndStartSearch(device);
2123   }
2124 
OnGattServiceDiscoveryDoneEvent(const RawAddress & address)2125   void OnGattServiceDiscoveryDoneEvent(const RawAddress& address) {
2126     auto device = FindDeviceByAddress(address);
2127     if (!device) {
2128       log::warn("Skipping unknown device {}", address);
2129       return;
2130     }
2131 
2132     log::debug("address={}", address);
2133 
2134     if (!device->is_gatt_service_valid) {
2135       BTA_GATTC_ServiceSearchRequest(device->conn_id, kCsisServiceUuid);
2136     }
2137   }
2138 
FindCccHandle(tCONN_ID conn_id,uint16_t char_handle)2139   static uint16_t FindCccHandle(tCONN_ID conn_id, uint16_t char_handle) {
2140     const gatt::Characteristic* p_char = BTA_GATTC_GetCharacteristic(conn_id, char_handle);
2141     if (!p_char) {
2142       log::warn("No such characteristic: 0x{:04x}", char_handle);
2143       return GAP_INVALID_HANDLE;
2144     }
2145 
2146     for (const gatt::Descriptor& desc : p_char->descriptors) {
2147       if (desc.uuid == Uuid::From16Bit(GATT_UUID_CHAR_CLIENT_CONFIG)) {
2148         return desc.handle;
2149       }
2150     }
2151 
2152     return GAP_INVALID_HANDLE;
2153   }
2154 
SubscribeForNotifications(tCONN_ID conn_id,const RawAddress & address,uint16_t value_handle,uint16_t ccc_handle)2155   void SubscribeForNotifications(tCONN_ID conn_id, const RawAddress& address, uint16_t value_handle,
2156                                  uint16_t ccc_handle) {
2157     if (value_handle != GAP_INVALID_HANDLE) {
2158       tGATT_STATUS register_status =
2159               BTA_GATTC_RegisterForNotifications(gatt_if_, address, value_handle);
2160       log::debug("BTA_GATTC_RegisterForNotifications, status=0x{:02x}, value=0x{:x}, ccc=0x{:04x}",
2161                  register_status, value_handle, ccc_handle);
2162 
2163       if (register_status != GATT_SUCCESS) {
2164         return;
2165       }
2166     }
2167 
2168     std::vector<uint8_t> value(2);
2169     uint8_t* value_ptr = value.data();
2170     UINT16_TO_STREAM(value_ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
2171     BtaGattQueue::WriteDescriptor(
2172             conn_id, ccc_handle, std::move(value), GATT_WRITE,
2173             [](tCONN_ID conn_id, tGATT_STATUS status, uint16_t handle, uint16_t /*len*/,
2174                const uint8_t* /*value*/, void* user_data) {
2175               if (instance) {
2176                 instance->OnGattWriteCcc(conn_id, status, handle, user_data);
2177               }
2178             },
2179             nullptr);
2180   }
2181 
DisableGattNotification(tCONN_ID,const RawAddress & address,uint16_t value_handle)2182   void DisableGattNotification(tCONN_ID /*conn_id*/, const RawAddress& address,
2183                                uint16_t value_handle) {
2184     if (value_handle != GAP_INVALID_HANDLE) {
2185       tGATT_STATUS register_status =
2186               BTA_GATTC_DeregisterForNotifications(gatt_if_, address, value_handle);
2187       log::debug("DisableGattNotification, status=0x{:02x}, value_handle=0x{:04x}", register_status,
2188                  value_handle);
2189 
2190       if (register_status != GATT_SUCCESS) {
2191         return;
2192       }
2193     }
2194   }
2195 
SirkValueReadCompleteDuringPairing(tGATT_STATUS status,const RawAddress & address,uint8_t sirk_type,Octet16 & received_sirk)2196   void SirkValueReadCompleteDuringPairing(tGATT_STATUS status, const RawAddress& address,
2197                                           uint8_t sirk_type, Octet16& received_sirk) {
2198     log::info("{}, status: 0x{:02x}", address, status);
2199 
2200     auto device = FindDeviceByAddress(address);
2201     if (device == nullptr) {
2202       log::error("Unknown device {}", address);
2203       BTA_DmSirkConfirmDeviceReply(address, false);
2204       return;
2205     }
2206 
2207     auto group_id_to_join = device->GetExpectedGroupIdMember();
2208     device->SetPairingSirkReadFlag(false);
2209 
2210     /* Verify group still exist, if not it means user forget the group and
2211      * paring should be rejected.
2212      */
2213     auto csis_group = FindCsisGroup(group_id_to_join);
2214     if (!csis_group) {
2215       log::error("Group {} removed during paring a set member", group_id_to_join);
2216       RemoveDevice(address);
2217       BTA_DmSirkConfirmDeviceReply(address, false);
2218       return;
2219     }
2220 
2221     if (status != GATT_SUCCESS) {
2222       log::info("Invalid member, can't read SIRK (status: 0x{:02x})", status);
2223       BTA_DmSirkConfirmDeviceReply(address, false);
2224       return;
2225     }
2226 
2227     /* Verify if sirk is not all zeros */
2228     Octet16 zero{};
2229     if (memcmp(zero.data(), received_sirk.data(), 16) == 0) {
2230       log::error("Received invalid zero SIRK address: {}", address);
2231       BTA_DmSirkConfirmDeviceReply(address, false);
2232       return;
2233     }
2234 
2235     if (sirk_type == bluetooth::csis::kCsisSirkTypeEncrypted) {
2236       /* Decrypt encrypted SIRK */
2237       Octet16 sirk;
2238       sdf(address, received_sirk, sirk);
2239       received_sirk = sirk;
2240     }
2241 
2242     if (!csis_group->IsSirkBelongsToGroup(received_sirk)) {
2243       /*
2244        * Joining member must join already existing group otherwise it means
2245        * that its SIRK is different. Device connection was triggered by RSI
2246        * match for group.
2247        */
2248       log::error("Joining device {}, does not match any existig group", address);
2249       BTA_DmSirkConfirmDeviceReply(address, false);
2250       return;
2251     }
2252 
2253     log::info("Device {}, verified successfully by SIRK", address);
2254     BTA_DmSirkConfirmDeviceReply(address, true);
2255 
2256     /* It was temporary device and we can remove it. When upper layer
2257      * decides to connect CSIS it will be added then
2258      */
2259     RemoveDevice(address);
2260   }
2261 
VerifySetMember(const RawAddress & address)2262   void VerifySetMember(const RawAddress& address) {
2263     auto device = FindDeviceByAddress(address);
2264 
2265     log::info("Device: {}", address);
2266 
2267     /* It's ok for device to not be a CSIS device at all */
2268     if (!device) {
2269       log::info("Valid - new member");
2270       BTA_DmSirkConfirmDeviceReply(address, true);
2271       return;
2272     }
2273 
2274     auto group_id_to_join = device->GetExpectedGroupIdMember();
2275     if (group_id_to_join == bluetooth::groups::kGroupUnknown) {
2276       log::warn(
2277               "Device {} (conn_id=0x{:04x}) is already known to CSIS (# of "
2278               "instances={}) but it is not scheduled to join any group.",
2279               address, device->conn_id, device->GetNumberOfCsisInstances());
2280       BTA_DmSirkConfirmDeviceReply(address, true);
2281       return;
2282     }
2283 
2284     if (!gatt_cl_read_sirk_req(address,
2285                                base::BindOnce(&CsisClientImpl::SirkValueReadCompleteDuringPairing,
2286                                               weak_factory_.GetWeakPtr()))) {
2287       log::error("Could not read SIKR of {}", address);
2288       BTA_DmSirkConfirmDeviceReply(address, false);
2289       return;
2290     }
2291     device->SetPairingSirkReadFlag(true);
2292   }
2293 
2294   uint8_t gatt_if_;
2295   bluetooth::csis::CsisClientCallbacks* callbacks_;
2296   std::list<std::shared_ptr<CsisDevice>> devices_;
2297   std::list<std::shared_ptr<CsisGroup>> csis_groups_;
2298   DeviceGroups* dev_groups_;
2299   int discovering_group_ = bluetooth::groups::kGroupUnknown;
2300 
2301   base::WeakPtrFactory<CsisClientImpl> weak_factory_{this};
2302 };
2303 
2304 class DeviceGroupsCallbacksImpl : public DeviceGroupsCallbacks {
2305 public:
OnGroupAdded(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)2306   void OnGroupAdded(const RawAddress& address, const bluetooth::Uuid& uuid, int group_id) override {
2307     if (instance) {
2308       instance->OnGroupAddedCb(address, uuid, group_id);
2309     }
2310   }
2311 
OnGroupMemberAdded(const RawAddress & address,int group_id)2312   void OnGroupMemberAdded(const RawAddress& address, int group_id) override {
2313     if (instance) {
2314       instance->OnGroupMemberAddedCb(address, group_id);
2315     }
2316   }
2317 
OnGroupRemoved(const bluetooth::Uuid & uuid,int group_id)2318   void OnGroupRemoved(const bluetooth::Uuid& uuid, int group_id) override {
2319     if (instance) {
2320       instance->OnGroupRemovedCb(uuid, group_id);
2321     }
2322   }
2323 
OnGroupMemberRemoved(const RawAddress & address,int group_id)2324   void OnGroupMemberRemoved(const RawAddress& address, int group_id) override {
2325     if (instance) {
2326       instance->OnGroupMemberRemovedCb(address, group_id);
2327     }
2328   }
2329 
OnGroupAddFromStorage(const RawAddress & address,const bluetooth::Uuid & uuid,int group_id)2330   void OnGroupAddFromStorage(const RawAddress& address, const bluetooth::Uuid& uuid,
2331                              int group_id) override {
2332     if (instance) {
2333       instance->OnGroupAddFromStorageCb(address, uuid, group_id);
2334     }
2335   }
2336 };
2337 
2338 class DeviceGroupsCallbacksImpl;
2339 DeviceGroupsCallbacksImpl deviceGroupsCallbacksImpl;
2340 
2341 }  // namespace
2342 
Initialize(bluetooth::csis::CsisClientCallbacks * callbacks,Closure initCb)2343 void CsisClient::Initialize(bluetooth::csis::CsisClientCallbacks* callbacks, Closure initCb) {
2344   std::scoped_lock<std::mutex> lock(instance_mutex);
2345   if (instance) {
2346     log::info("Already initialized!");
2347     return;
2348   }
2349 
2350   device_group_callbacks = &deviceGroupsCallbacksImpl;
2351   instance = new CsisClientImpl(callbacks, initCb);
2352 }
2353 
IsCsisClientRunning()2354 bool CsisClient::IsCsisClientRunning() { return instance; }
2355 
Get(void)2356 CsisClient* CsisClient::Get(void) {
2357   if (instance == nullptr) {
2358     log::error("instance not available");
2359   }
2360   return instance;
2361 }
2362 
AddFromStorage(const RawAddress & addr,const std::vector<uint8_t> & in)2363 void CsisClient::AddFromStorage(const RawAddress& addr, const std::vector<uint8_t>& in) {
2364   if (!instance) {
2365     log::error("Not initialized yet!");
2366     return;
2367   }
2368 
2369   instance->AddFromStorage(addr, in);
2370 }
2371 
GetForStorage(const RawAddress & addr,std::vector<uint8_t> & out)2372 bool CsisClient::GetForStorage(const RawAddress& addr, std::vector<uint8_t>& out) {
2373   if (!instance) {
2374     log::error("Not initialized yet!");
2375     return false;
2376   }
2377 
2378   return instance->SerializeSets(addr, out);
2379 }
2380 
CleanUp()2381 void CsisClient::CleanUp() {
2382   std::scoped_lock<std::mutex> lock(instance_mutex);
2383   BTA_DmSirkSecCbRegister(nullptr);
2384   CsisClientImpl* ptr = instance;
2385   instance = nullptr;
2386 
2387   if (ptr) {
2388     ptr->CleanUp();
2389     delete ptr;
2390   }
2391 }
2392 
DebugDump(int fd)2393 void CsisClient::DebugDump(int fd) {
2394   std::scoped_lock<std::mutex> lock(instance_mutex);
2395   dprintf(fd, "Coordinated Set Service Client:\n");
2396   if (instance) {
2397     instance->Dump(fd);
2398   }
2399   dprintf(fd, "\n");
2400 }
2401