1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16 #include <base/functional/bind.h>
17
18 #include "bta/include/bta_gatt_api.h"
19 #include "bta/include/bta_ras_api.h"
20 #include "bta/ras/ras_types.h"
21 #include "os/logging/log_adapter.h"
22 #include "stack/include/bt_types.h"
23 #include "stack/include/btm_ble_addr.h"
24 #include "stack/include/gap_api.h"
25
26 using namespace bluetooth;
27 using namespace ::ras;
28 using namespace ::ras::feature;
29 using namespace ::ras::uuid;
30 using bluetooth::ras::VendorSpecificCharacteristic;
31
32 namespace {
33
34 class RasClientImpl;
35 RasClientImpl* instance;
36
37 enum CallbackDataType { VENDOR_SPECIFIC_REPLY };
38
39 class RasClientImpl : public bluetooth::ras::RasClient {
40 public:
41 struct GattWriteCallbackData {
42 const CallbackDataType type_;
43 };
44
45 struct RasTracker {
RasTracker__anon21296e410111::RasClientImpl::RasTracker46 RasTracker(const RawAddress& address, const RawAddress& address_for_cs)
47 : address_(address), address_for_cs_(address_for_cs) {}
48 uint16_t conn_id_;
49 RawAddress address_;
50 RawAddress address_for_cs_;
51 const gatt::Service* service_ = nullptr;
52 uint32_t remote_supported_features_;
53 uint16_t latest_ranging_counter_ = 0;
54 bool handling_on_demand_data_ = false;
55 std::vector<VendorSpecificCharacteristic> vendor_specific_characteristics_;
56 uint8_t writeReplyCounter_ = 0;
57 uint8_t writeReplySuccessCounter_ = 0;
58
FindCharacteristicByUuid__anon21296e410111::RasClientImpl::RasTracker59 const gatt::Characteristic* FindCharacteristicByUuid(Uuid uuid) {
60 for (auto& characteristic : service_->characteristics) {
61 if (characteristic.uuid == uuid) {
62 return &characteristic;
63 }
64 }
65 return nullptr;
66 }
FindCharacteristicByHandle__anon21296e410111::RasClientImpl::RasTracker67 const gatt::Characteristic* FindCharacteristicByHandle(uint16_t handle) {
68 for (auto& characteristic : service_->characteristics) {
69 if (characteristic.value_handle == handle) {
70 return &characteristic;
71 }
72 }
73 return nullptr;
74 }
75
GetVendorSpecificCharacteristic__anon21296e410111::RasClientImpl::RasTracker76 VendorSpecificCharacteristic* GetVendorSpecificCharacteristic(
77 const bluetooth::Uuid& uuid) {
78 for (auto& characteristic : vendor_specific_characteristics_) {
79 if (characteristic.characteristicUuid_ == uuid) {
80 return &characteristic;
81 }
82 }
83 return nullptr;
84 }
85 };
86
Initialize()87 void Initialize() override {
88 BTA_GATTC_AppRegister(
89 [](tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
90 if (instance && p_data) instance->GattcCallback(event, p_data);
91 },
92 base::Bind([](uint8_t client_id, uint8_t status) {
93 if (status != GATT_SUCCESS) {
94 log::error("Can't start Gatt client for Ranging Service");
95 return;
96 }
97 log::info("Initialize, client_id {}", client_id);
98 instance->gatt_if_ = client_id;
99 }),
100 true);
101 }
102
RegisterCallbacks(bluetooth::ras::RasClientCallbacks * callbacks)103 void RegisterCallbacks(bluetooth::ras::RasClientCallbacks* callbacks) {
104 callbacks_ = callbacks;
105 }
106
Connect(const RawAddress & address)107 void Connect(const RawAddress& address) override {
108 tBLE_BD_ADDR ble_bd_addr;
109 ResolveAddress(ble_bd_addr, address);
110 log::info("address {}, resolve {}", address, ble_bd_addr.bda);
111
112 auto tracker = FindTrackerByAddress(ble_bd_addr.bda);
113 if (tracker == nullptr) {
114 trackers_.emplace_back(
115 std::make_shared<RasTracker>(ble_bd_addr.bda, address));
116 }
117 BTA_GATTC_Open(gatt_if_, ble_bd_addr.bda, BTM_BLE_DIRECT_CONNECTION, false);
118 }
119
SendVendorSpecificReply(const RawAddress & address,const std::vector<VendorSpecificCharacteristic> & vendor_specific_data)120 void SendVendorSpecificReply(
121 const RawAddress& address,
122 const std::vector<VendorSpecificCharacteristic>& vendor_specific_data) {
123 tBLE_BD_ADDR ble_bd_addr;
124 ResolveAddress(ble_bd_addr, address);
125 log::info("address {}, resolve {}", address, ble_bd_addr.bda);
126 auto tracker = FindTrackerByAddress(ble_bd_addr.bda);
127
128 for (auto& vendor_specific_characteristic : vendor_specific_data) {
129 auto characteristic = tracker->FindCharacteristicByUuid(
130 vendor_specific_characteristic.characteristicUuid_);
131 if (characteristic == nullptr) {
132 log::warn("Can't find characteristic uuid {}",
133 vendor_specific_characteristic.characteristicUuid_);
134 return;
135 }
136 log::debug("write to remote, uuid {}, len {}",
137 vendor_specific_characteristic.characteristicUuid_,
138 vendor_specific_characteristic.value_.size());
139 BTA_GATTC_WriteCharValue(
140 tracker->conn_id_, characteristic->value_handle, GATT_WRITE,
141 vendor_specific_characteristic.value_, GATT_AUTH_REQ_MITM,
142 GattWriteCallback, &gatt_write_callback_data_);
143 }
144 }
145
GattcCallback(tBTA_GATTC_EVT event,tBTA_GATTC * p_data)146 void GattcCallback(tBTA_GATTC_EVT event, tBTA_GATTC* p_data) {
147 log::debug("event: {}", gatt_client_event_text(event));
148 switch (event) {
149 case BTA_GATTC_OPEN_EVT: {
150 OnGattConnected(p_data->open);
151 } break;
152 case BTA_GATTC_SEARCH_CMPL_EVT: {
153 OnGattServiceSearchComplete(p_data->search_cmpl);
154 } break;
155 case BTA_GATTC_NOTIF_EVT: {
156 OnGattNotification(p_data->notify);
157 } break;
158 default:
159 log::warn("Unhandled event: {}", gatt_client_event_text(event));
160 }
161 }
162
OnGattConnected(const tBTA_GATTC_OPEN & evt)163 void OnGattConnected(const tBTA_GATTC_OPEN& evt) {
164 log::info("{}, conn_id=0x{:04x}, transport:{}, status:{}", evt.remote_bda,
165 evt.conn_id, bt_transport_text(evt.transport),
166 gatt_status_text(evt.status));
167
168 if (evt.transport != BT_TRANSPORT_LE) {
169 log::warn("Only LE connection is allowed (transport {})",
170 bt_transport_text(evt.transport));
171 BTA_GATTC_Close(evt.conn_id);
172 return;
173 }
174
175 auto tracker = FindTrackerByAddress(evt.remote_bda);
176 if (tracker == nullptr) {
177 log::warn("Skipping unknown device, address: {}", evt.remote_bda);
178 BTA_GATTC_Close(evt.conn_id);
179 return;
180 }
181
182 if (evt.status != GATT_SUCCESS) {
183 log::error("Failed to connect to server device {}", evt.remote_bda);
184 return;
185 }
186 tracker->conn_id_ = evt.conn_id;
187 log::info("Search service");
188 BTA_GATTC_ServiceSearchRequest(tracker->conn_id_, kRangingService);
189 }
190
OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL & evt)191 void OnGattServiceSearchComplete(const tBTA_GATTC_SEARCH_CMPL& evt) {
192 auto tracker = FindTrackerByHandle(evt.conn_id);
193 if (tracker == nullptr) {
194 log::warn("Can't find tracker for conn_id:{}", evt.conn_id);
195 return;
196 }
197
198 // Get Ranging Service
199 bool service_found = false;
200 const std::list<gatt::Service>* all_services =
201 BTA_GATTC_GetServices(evt.conn_id);
202 for (const auto& service : *all_services) {
203 if (service.uuid == kRangingService) {
204 tracker->service_ = &service;
205 service_found = true;
206 break;
207 }
208 }
209
210 if (!service_found) {
211 log::error("Can't find Ranging Service in the services list");
212 return;
213 } else {
214 log::info("Found Ranging Service");
215 ListCharacteristic(tracker);
216 }
217
218 // Read Vendor Specific Uuid
219 if (!tracker->vendor_specific_characteristics_.empty()) {
220 for (auto& vendor_specific_characteristic :
221 tracker->vendor_specific_characteristics_) {
222 log::debug("Read vendor specific characteristic uuid {}",
223 vendor_specific_characteristic.characteristicUuid_);
224 auto characteristic = tracker->FindCharacteristicByUuid(
225 vendor_specific_characteristic.characteristicUuid_);
226
227 BTA_GATTC_ReadCharacteristic(
228 tracker->conn_id_, characteristic->value_handle, GATT_AUTH_REQ_MITM,
229 [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
230 uint16_t len, uint8_t* value, void* data) {
231 instance->OnReadCharacteristicCallback(conn_id, status, handle,
232 len, value, data);
233 },
234 nullptr);
235 }
236 }
237
238 // Read Ras Features
239 log::info("Read Ras Features");
240 auto characteristic =
241 tracker->FindCharacteristicByUuid(kRasFeaturesCharacteristic);
242 if (characteristic == nullptr) {
243 log::error("Can not find Characteristic for Ras Features");
244 return;
245 }
246 BTA_GATTC_ReadCharacteristic(
247 tracker->conn_id_, characteristic->value_handle, GATT_AUTH_REQ_MITM,
248 [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
249 uint8_t* value, void* data) {
250 instance->OnReadCharacteristicCallback(conn_id, status, handle, len,
251 value, data);
252 },
253 nullptr);
254
255 SubscribeCharacteristic(tracker, kRasControlPointCharacteristic);
256 }
257
OnGattNotification(const tBTA_GATTC_NOTIFY & evt)258 void OnGattNotification(const tBTA_GATTC_NOTIFY& evt) {
259 auto tracker = FindTrackerByHandle(evt.conn_id);
260 if (tracker == nullptr) {
261 log::warn("Can't find tracker for conn_id:{}", evt.conn_id);
262 return;
263 }
264 auto characteristic = tracker->FindCharacteristicByHandle(evt.handle);
265 if (characteristic == nullptr) {
266 log::warn("Can't find characteristic for handle:{}", evt.handle);
267 return;
268 }
269
270 uint16_t uuid_16bit = characteristic->uuid.As16Bit();
271 log::debug("Handle uuid 0x{:04x}, {}, size {}", uuid_16bit,
272 getUuidName(characteristic->uuid), evt.len);
273
274 switch (uuid_16bit) {
275 case kRasRealTimeRangingDataCharacteristic16bit:
276 case kRasOnDemandDataCharacteristic16bit: {
277 OnRemoteData(evt, tracker);
278 break;
279 }
280 case kRasControlPointCharacteristic16bit: {
281 OnControlPointEvent(evt, tracker);
282 } break;
283 case kRasRangingDataReadyCharacteristic16bit: {
284 OnRangingDataReady(evt, tracker);
285 } break;
286 default:
287 log::warn("Unexpected UUID");
288 }
289 }
290
OnRemoteData(const tBTA_GATTC_NOTIFY & evt,std::shared_ptr<RasTracker> tracker)291 void OnRemoteData(const tBTA_GATTC_NOTIFY& evt,
292 std::shared_ptr<RasTracker> tracker) {
293 std::vector<uint8_t> data;
294 data.resize(evt.len);
295 std::copy(evt.value, evt.value + evt.len, data.begin());
296 callbacks_->OnRemoteData(tracker->address_for_cs_, data);
297 }
298
OnControlPointEvent(const tBTA_GATTC_NOTIFY & evt,std::shared_ptr<RasTracker> tracker)299 void OnControlPointEvent(const tBTA_GATTC_NOTIFY& evt,
300 std::shared_ptr<RasTracker> tracker) {
301 switch (evt.value[0]) {
302 case (uint8_t)EventCode::COMPLETE_RANGING_DATA_RESPONSE: {
303 uint16_t ranging_counter = evt.value[1];
304 ranging_counter |= (evt.value[2] << 8);
305 log::debug(
306 "Received complete ranging data response, ranging_counter: {}",
307 ranging_counter);
308 AckRangingData(ranging_counter, tracker);
309 } break;
310 case (uint8_t)EventCode::RESPONSE_CODE: {
311 tracker->handling_on_demand_data_ = false;
312 log::debug("Received response code 0x{:02x}", evt.value[1]);
313 } break;
314 default:
315 log::warn("Unexpected event code 0x{:02x}", evt.value[0]);
316 }
317 }
318
OnRangingDataReady(const tBTA_GATTC_NOTIFY & evt,std::shared_ptr<RasTracker> tracker)319 void OnRangingDataReady(const tBTA_GATTC_NOTIFY& evt,
320 std::shared_ptr<RasTracker> tracker) {
321 if (evt.len != kRingingCounterSize) {
322 log::error("Invalid len for ranging data ready");
323 return;
324 }
325 uint16_t ranging_counter = evt.value[0];
326 ranging_counter |= (evt.value[1] << 8);
327 log::debug("ranging_counter: {}", ranging_counter);
328
329 // Send get ranging data command
330 tracker->latest_ranging_counter_ = ranging_counter;
331 GetRangingData(ranging_counter, tracker);
332 }
333
GetRangingData(uint16_t ranging_counter,std::shared_ptr<RasTracker> tracker)334 void GetRangingData(uint16_t ranging_counter,
335 std::shared_ptr<RasTracker> tracker) {
336 log::debug("ranging_counter:{}", ranging_counter);
337 if (tracker->handling_on_demand_data_) {
338 log::warn("Handling other procedure, skip");
339 return;
340 }
341
342 auto characteristic =
343 tracker->FindCharacteristicByUuid(kRasControlPointCharacteristic);
344 if (characteristic == nullptr) {
345 log::warn("Can't find characteristic for RAS-CP");
346 return;
347 }
348
349 tracker->handling_on_demand_data_ = true;
350 std::vector<uint8_t> value(3);
351 value[0] = (uint8_t)Opcode::GET_RANGING_DATA;
352 value[1] = (uint8_t)(ranging_counter & 0xFF);
353 value[2] = (uint8_t)((ranging_counter >> 8) & 0xFF);
354 BTA_GATTC_WriteCharValue(tracker->conn_id_, characteristic->value_handle,
355 GATT_WRITE, value, GATT_AUTH_REQ_MITM,
356 GattWriteCallback, nullptr);
357 }
358
AckRangingData(uint16_t ranging_counter,std::shared_ptr<RasTracker> tracker)359 void AckRangingData(uint16_t ranging_counter,
360 std::shared_ptr<RasTracker> tracker) {
361 log::debug("ranging_counter:{}", ranging_counter);
362 auto characteristic =
363 tracker->FindCharacteristicByUuid(kRasControlPointCharacteristic);
364 if (characteristic == nullptr) {
365 log::warn("Can't find characteristic for RAS-CP");
366 return;
367 }
368 tracker->handling_on_demand_data_ = false;
369 std::vector<uint8_t> value(3);
370 value[0] = (uint8_t)Opcode::ACK_RANGING_DATA;
371 value[1] = (uint8_t)(ranging_counter & 0xFF);
372 value[2] = (uint8_t)((ranging_counter >> 8) & 0xFF);
373 BTA_GATTC_WriteCharValue(tracker->conn_id_, characteristic->value_handle,
374 GATT_WRITE, value, GATT_AUTH_REQ_MITM,
375 GattWriteCallback, nullptr);
376 if (ranging_counter != tracker->latest_ranging_counter_) {
377 GetRangingData(tracker->latest_ranging_counter_, tracker);
378 }
379 }
380
GattWriteCallbackForVendorSpecificData(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,const uint8_t * value,GattWriteCallbackData * data)381 void GattWriteCallbackForVendorSpecificData(uint16_t conn_id,
382 tGATT_STATUS status,
383 uint16_t handle,
384 const uint8_t* value,
385 GattWriteCallbackData* data) {
386 if (data != nullptr) {
387 GattWriteCallbackData* structPtr =
388 static_cast<GattWriteCallbackData*>(data);
389 if (structPtr->type_ == CallbackDataType::VENDOR_SPECIFIC_REPLY) {
390 log::info("Write vendor specific reply complete");
391 auto tracker = FindTrackerByHandle(conn_id);
392 tracker->writeReplyCounter_++;
393 if (status == GATT_SUCCESS) {
394 tracker->writeReplySuccessCounter_++;
395 } else {
396 log::error(
397 "Fail to write vendor specific reply conn_id {}, status {}, "
398 "handle {}",
399 conn_id, gatt_status_text(status), handle);
400 }
401 // All reply complete
402 if (tracker->writeReplyCounter_ ==
403 tracker->vendor_specific_characteristics_.size()) {
404 log::info(
405 "All vendor specific reply write complete, size {} "
406 "successCounter {}",
407 tracker->vendor_specific_characteristics_.size(),
408 tracker->writeReplySuccessCounter_);
409 bool success = tracker->writeReplySuccessCounter_ ==
410 tracker->vendor_specific_characteristics_.size();
411 tracker->writeReplyCounter_ = 0;
412 tracker->writeReplySuccessCounter_ = 0;
413 callbacks_->OnWriteVendorSpecificReplyComplete(
414 tracker->address_for_cs_, success);
415 }
416 return;
417 }
418 }
419 }
420
GattWriteCallback(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,const uint8_t * value)421 void GattWriteCallback(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
422 const uint8_t* value) {
423 if (status != GATT_SUCCESS) {
424 log::error("Fail to write conn_id {}, status {}, handle {}", conn_id,
425 gatt_status_text(status), handle);
426 auto tracker = FindTrackerByHandle(conn_id);
427 if (tracker == nullptr) {
428 log::warn("Can't find tracker for conn_id:{}", conn_id);
429 return;
430 }
431 auto characteristic = tracker->FindCharacteristicByHandle(handle);
432 if (characteristic == nullptr) {
433 log::warn("Can't find characteristic for handle:{}", handle);
434 return;
435 }
436
437 if (characteristic->uuid == kRasControlPointCharacteristic) {
438 log::error("Write RAS-CP command fail");
439 tracker->handling_on_demand_data_ = false;
440 }
441 return;
442 }
443 }
444
GattWriteCallback(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void * data)445 static void GattWriteCallback(uint16_t conn_id, tGATT_STATUS status,
446 uint16_t handle, uint16_t len,
447 const uint8_t* value, void* data) {
448 if (instance != nullptr) {
449 if (data != nullptr) {
450 GattWriteCallbackData* structPtr =
451 static_cast<GattWriteCallbackData*>(data);
452 if (structPtr->type_ == CallbackDataType::VENDOR_SPECIFIC_REPLY) {
453 instance->GattWriteCallbackForVendorSpecificData(
454 conn_id, status, handle, value, structPtr);
455 return;
456 }
457 }
458 instance->GattWriteCallback(conn_id, status, handle, value);
459 }
460 }
461
SubscribeCharacteristic(std::shared_ptr<RasTracker> tracker,const Uuid uuid)462 void SubscribeCharacteristic(std::shared_ptr<RasTracker> tracker,
463 const Uuid uuid) {
464 auto characteristic = tracker->FindCharacteristicByUuid(uuid);
465 if (characteristic == nullptr) {
466 log::warn("Can't find characteristic 0x{:04x}", uuid.As16Bit());
467 return;
468 }
469 uint16_t ccc_handle = FindCccHandle(characteristic);
470 if (ccc_handle == GAP_INVALID_HANDLE) {
471 log::warn("Can't find Client Characteristic Configuration descriptor");
472 return;
473 }
474
475 tGATT_STATUS register_status = BTA_GATTC_RegisterForNotifications(
476 gatt_if_, tracker->address_, characteristic->value_handle);
477 if (register_status != GATT_SUCCESS) {
478 log::error("Fail to register, {}", gatt_status_text(register_status));
479 return;
480 }
481
482 std::vector<uint8_t> value(2);
483 uint8_t* value_ptr = value.data();
484 // Register notify is supported
485 if (characteristic->properties & GATT_CHAR_PROP_BIT_NOTIFY) {
486 UINT16_TO_STREAM(value_ptr, GATT_CHAR_CLIENT_CONFIG_NOTIFICATION);
487 } else {
488 UINT16_TO_STREAM(value_ptr, GATT_CHAR_CLIENT_CONFIG_INDICTION);
489 }
490 BTA_GATTC_WriteCharDescr(
491 tracker->conn_id_, ccc_handle, value, GATT_AUTH_REQ_NONE,
492 [](uint16_t conn_id, tGATT_STATUS status, uint16_t handle, uint16_t len,
493 const uint8_t* value, void* data) {
494 if (instance)
495 instance->OnDescriptorWrite(conn_id, status, handle, len, value,
496 data);
497 },
498 nullptr);
499 }
500
OnDescriptorWrite(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,const uint8_t * value,void * data)501 void OnDescriptorWrite(uint16_t conn_id, tGATT_STATUS status, uint16_t handle,
502 uint16_t len, const uint8_t* value, void* data) {
503 log::info("conn_id:{}, handle:{}, status:{}", conn_id, handle,
504 gatt_status_text(status));
505 }
506
ListCharacteristic(std::shared_ptr<RasTracker> tracker)507 void ListCharacteristic(std::shared_ptr<RasTracker> tracker) {
508 for (auto& characteristic : tracker->service_->characteristics) {
509 bool vendor_specific =
510 !IsRangingServiceCharacteristic(characteristic.uuid);
511 log::info(
512 "{}Characteristic uuid:0x{:04x}, handle:0x{:04x}, "
513 "properties:0x{:02x}, "
514 "{}",
515 vendor_specific ? "Vendor Specific " : "",
516 characteristic.uuid.As16Bit(), characteristic.value_handle,
517 characteristic.properties, getUuidName(characteristic.uuid));
518 if (vendor_specific) {
519 VendorSpecificCharacteristic vendor_specific_characteristic;
520 vendor_specific_characteristic.characteristicUuid_ =
521 characteristic.uuid;
522 tracker->vendor_specific_characteristics_.emplace_back(
523 vendor_specific_characteristic);
524 }
525 for (auto& descriptor : characteristic.descriptors) {
526 log::info("\tDescriptor uuid:0x{:04x}, handle:0x{:04x}, {}",
527 descriptor.uuid.As16Bit(), descriptor.handle,
528 getUuidName(descriptor.uuid));
529 }
530 }
531 }
532
ResolveAddress(tBLE_BD_ADDR & ble_bd_addr,const RawAddress & address)533 void ResolveAddress(tBLE_BD_ADDR& ble_bd_addr, const RawAddress& address) {
534 ble_bd_addr.bda = address;
535 ble_bd_addr.type = BLE_ADDR_RANDOM;
536 maybe_resolve_address(&ble_bd_addr.bda, &ble_bd_addr.type);
537 }
538
OnReadCharacteristicCallback(uint16_t conn_id,tGATT_STATUS status,uint16_t handle,uint16_t len,uint8_t * value,void * data)539 void OnReadCharacteristicCallback(uint16_t conn_id, tGATT_STATUS status,
540 uint16_t handle, uint16_t len,
541 uint8_t* value, void* data) {
542 log::info("conn_id: {}, handle: {}, len: {}", conn_id, handle, len);
543 if (status != GATT_SUCCESS) {
544 log::error("Fail with status {}", gatt_status_text(status));
545 return;
546 }
547 auto tracker = FindTrackerByHandle(conn_id);
548 if (tracker == nullptr) {
549 log::warn("Can't find tracker for conn_id:{}", conn_id);
550 return;
551 }
552 auto characteristic = tracker->FindCharacteristicByHandle(handle);
553 if (characteristic == nullptr) {
554 log::warn("Can't find characteristic for handle:{}", handle);
555 return;
556 }
557
558 auto vendor_specific_characteristic =
559 tracker->GetVendorSpecificCharacteristic(characteristic->uuid);
560 if (vendor_specific_characteristic != nullptr) {
561 log::info("Update vendor specific data, uuid: {}",
562 vendor_specific_characteristic->characteristicUuid_);
563 vendor_specific_characteristic->value_.clear();
564 vendor_specific_characteristic->value_.reserve(len);
565 vendor_specific_characteristic->value_.assign(value, value + len);
566 return;
567 }
568
569 uint16_t uuid_16bit = characteristic->uuid.As16Bit();
570 log::info("Handle uuid 0x{:04x}, {}", uuid_16bit,
571 getUuidName(characteristic->uuid));
572
573 switch (uuid_16bit) {
574 case kRasFeaturesCharacteristic16bit: {
575 if (len != kFeatureSize) {
576 log::error("Invalid len for Ras features");
577 return;
578 }
579 STREAM_TO_UINT32(tracker->remote_supported_features_, value);
580 log::info("Remote supported features : {}",
581 getFeaturesString(tracker->remote_supported_features_));
582 if (tracker->remote_supported_features_ &
583 feature::kRealTimeRangingData) {
584 log::info("Subscribe Real-time Ranging Data");
585 SubscribeCharacteristic(tracker,
586 kRasRealTimeRangingDataCharacteristic);
587 } else {
588 log::info("Subscribe On-demand Ranging Data");
589 SubscribeCharacteristic(tracker, kRasOnDemandDataCharacteristic);
590 SubscribeCharacteristic(tracker, kRasRangingDataReadyCharacteristic);
591 SubscribeCharacteristic(tracker,
592 kRasRangingDataOverWrittenCharacteristic);
593 }
594 uint16_t att_handle = tracker
595 ->FindCharacteristicByUuid(
596 kRasRealTimeRangingDataCharacteristic)
597 ->value_handle;
598 callbacks_->OnConnected(tracker->address_for_cs_, att_handle,
599 tracker->vendor_specific_characteristics_);
600 } break;
601 default:
602 log::warn("Unexpected UUID");
603 }
604 }
605
getFeaturesString(uint32_t value)606 std::string getFeaturesString(uint32_t value) {
607 std::stringstream ss;
608 ss << value;
609 if (value == 0) {
610 ss << "|No feature supported";
611 } else {
612 if ((value & kRealTimeRangingData) != 0) {
613 ss << "|Real-time Ranging Data";
614 }
615 if ((value & kRetrieveLostRangingDataSegments) != 0) {
616 ss << "|Retrieve Lost Ranging Data Segments";
617 }
618 if ((value & kAbortOperation) != 0) {
619 ss << "|Abort Operation";
620 }
621 if ((value & kFilterRangingData) != 0) {
622 ss << "|Filter Ranging Data";
623 }
624 if ((value & kPctPhaseFormat) != 0) {
625 ss << "|PCT Phase Format";
626 }
627 }
628 return ss.str();
629 }
630
FindCccHandle(const gatt::Characteristic * characteristic)631 uint16_t FindCccHandle(const gatt::Characteristic* characteristic) {
632 for (auto descriptor : characteristic->descriptors) {
633 if (descriptor.uuid == kClientCharacteristicConfiguration) {
634 return descriptor.handle;
635 }
636 }
637 return GAP_INVALID_HANDLE;
638 }
639
FindTrackerByHandle(uint16_t conn_id) const640 std::shared_ptr<RasTracker> FindTrackerByHandle(uint16_t conn_id) const {
641 for (auto tracker : trackers_) {
642 if (tracker->conn_id_ == conn_id) {
643 return tracker;
644 }
645 }
646 return nullptr;
647 }
648
FindTrackerByAddress(const RawAddress & address) const649 std::shared_ptr<RasTracker> FindTrackerByAddress(
650 const RawAddress& address) const {
651 for (auto tracker : trackers_) {
652 if (tracker->address_ == address) {
653 return tracker;
654 }
655 }
656 return nullptr;
657 }
658
659 private:
660 uint16_t gatt_if_;
661 std::list<std::shared_ptr<RasTracker>> trackers_;
662 bluetooth::ras::RasClientCallbacks* callbacks_;
663 GattWriteCallbackData gatt_write_callback_data_{
664 CallbackDataType::VENDOR_SPECIFIC_REPLY};
665 };
666
667 } // namespace
668
GetRasClient()669 bluetooth::ras::RasClient* bluetooth::ras::GetRasClient() {
670 if (instance == nullptr) {
671 instance = new RasClientImpl();
672 }
673 return instance;
674 };
675