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