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