• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
17 #include <base/functional/bind.h>
18 #include <base/functional/callback.h>
19 #include <bluetooth/log.h>
20 
21 #include <algorithm>
22 #include <cstdint>
23 #include <cstring>
24 #include <mutex>
25 #include <unordered_map>
26 #include <vector>
27 
28 #include "bta/include/bta_gatt_api.h"
29 #include "bta/include/bta_ras_api.h"
30 #include "bta/ras/ras_types.h"
31 #include "btm_ble_api_types.h"
32 #include "gatt_api.h"
33 #include "gd/hci/controller_interface.h"
34 #include "gd/os/rand.h"
35 #include "hardware/bt_common_types.h"
36 #include "main/shim/entry.h"
37 #include "stack/include/bt_types.h"
38 #include "stack/include/btm_ble_addr.h"
39 #include "stack/include/main_thread.h"
40 #include "types/ble_address_with_type.h"
41 #include "types/bluetooth/uuid.h"
42 #include "types/bt_transport.h"
43 #include "types/raw_address.h"
44 
45 using namespace bluetooth;
46 using namespace ::ras;
47 using namespace ::ras::uuid;
48 using bluetooth::ras::VendorSpecificCharacteristic;
49 
50 namespace {
51 
52 class RasServerImpl;
53 RasServerImpl* instance;
54 
55 static constexpr uint32_t kSupportedFeatures = feature::kRealTimeRangingData;
56 static constexpr uint16_t kBufferSize = 3;
57 
58 class RasServerImpl : public bluetooth::ras::RasServer {
59 public:
60   struct RasCharacteristic {
61     bluetooth::Uuid uuid_;
62     uint16_t attribute_handle_;
63     uint16_t attribute_handle_ccc_;
64   };
65 
66   // Struct to save data of specific ranging counter
67   struct DataBuffer {
DataBuffer__anond168bd4f0111::RasServerImpl::DataBuffer68     DataBuffer(uint16_t ranging_counter) : ranging_counter_(ranging_counter), segments_() {}
69     uint16_t ranging_counter_;
70     std::vector<std::vector<uint8_t>> segments_;
71   };
72 
73   struct PendingWriteResponse {
74     tCONN_ID conn_id_;
75     uint32_t trans_id_;
76     uint16_t write_req_handle_;
77   };
78 
79   struct ClientTracker {
80     tCONN_ID conn_id_;
81     std::unordered_map<Uuid, uint16_t> ccc_values_;
82     std::vector<DataBuffer> buffers_;
83     bool handling_control_point_command_ = false;
84     uint8_t vendor_specific_reply_counter_ = 0;
85     PendingWriteResponse pending_write_response_;
86     uint16_t last_ready_procedure_ = 0;
87     uint16_t last_overwritten_procedure_ = 0;
88     uint16_t mtu = kDefaultGattMtu;
89   };
90 
Initialize()91   void Initialize() override {
92     do_in_main_thread(base::BindOnce(&RasServerImpl::do_initialize, base::Unretained(this)));
93   }
94 
do_initialize()95   void do_initialize() {
96     auto controller = bluetooth::shim::GetController();
97     if (controller && !controller->SupportsBleChannelSounding()) {
98       log::info("controller does not support channel sounding.");
99       return;
100     }
101     Uuid uuid = Uuid::From128BitBE(bluetooth::os::GenerateRandom<Uuid::kNumBytes128>());
102     app_uuid_ = uuid;
103     log::info("Register server with uuid:{}", app_uuid_.ToString());
104     BTA_GATTS_AppRegister(
105             app_uuid_,
106             [](tBTA_GATTS_EVT event, tBTA_GATTS* p_data) {
107               if (instance && p_data) {
108                 instance->GattsCallback(event, p_data);
109               }
110             },
111             false);
112   }
113 
RegisterCallbacks(bluetooth::ras::RasServerCallbacks * callbacks)114   void RegisterCallbacks(bluetooth::ras::RasServerCallbacks* callbacks) { callbacks_ = callbacks; }
115 
SetVendorSpecificCharacteristic(const std::vector<VendorSpecificCharacteristic> & vendor_specific_characteristics)116   void SetVendorSpecificCharacteristic(
117           const std::vector<VendorSpecificCharacteristic>& vendor_specific_characteristics) {
118     vendor_specific_characteristics_ = vendor_specific_characteristics;
119   }
120 
HandleVendorSpecificReplyComplete(RawAddress address,bool success)121   void HandleVendorSpecificReplyComplete(RawAddress address, bool success) {
122     log::info("address:{}, success:{}", address, success);
123     tBLE_BD_ADDR ble_bd_addr;
124     ResolveAddress(ble_bd_addr, address);
125     if (trackers_.find(ble_bd_addr.bda) == trackers_.end()) {
126       log::warn("Can't find tracker for address {}", address);
127       return;
128     }
129     auto response = trackers_[ble_bd_addr.bda].pending_write_response_;
130     tGATTS_RSP p_msg;
131     p_msg.attr_value.handle = response.write_req_handle_;
132     GattStatus status = success ? GATT_SUCCESS : GATT_ERROR;
133     BTA_GATTS_SendRsp(response.conn_id_, response.trans_id_, status, &p_msg);
134   }
135 
PushProcedureData(RawAddress address,uint16_t procedure_counter,bool is_last,std::vector<uint8_t> data)136   void PushProcedureData(RawAddress address, uint16_t procedure_counter, bool is_last,
137                          std::vector<uint8_t> data) {
138     log::debug("{}, counter:{}, is_last:{}, with size {}", address, procedure_counter, is_last,
139                data.size());
140     tBLE_BD_ADDR ble_bd_addr;
141     ResolveAddress(ble_bd_addr, address);
142 
143     if (trackers_.find(ble_bd_addr.bda) == trackers_.end()) {
144       log::warn("Can't find tracker for {}", ble_bd_addr.bda);
145       return;
146     }
147     ClientTracker& tracker = trackers_[ble_bd_addr.bda];
148     uint16_t ccc_real_time = tracker.ccc_values_[kRasRealTimeRangingDataCharacteristic];
149     uint16_t ccc_data_ready = tracker.ccc_values_[kRasRangingDataReadyCharacteristic];
150     uint16_t ccc_data_over_written = tracker.ccc_values_[kRasRangingDataOverWrittenCharacteristic];
151 
152     if (ccc_real_time != GATT_CLT_CONFIG_NONE) {
153       bool use_notification = ccc_real_time & GATT_CLT_CONFIG_NOTIFICATION;
154       uint16_t attr_id =
155               GetCharacteristic(kRasRealTimeRangingDataCharacteristic)->attribute_handle_;
156       log::debug("Send Real-time Ranging Data is_last {}", is_last);
157       BTA_GATTS_HandleValueIndication(tracker.conn_id_, attr_id, data, !use_notification);
158     }
159 
160     if (ccc_data_ready == GATT_CLT_CONFIG_NONE && ccc_data_over_written == GATT_CLT_CONFIG_NONE) {
161       return;
162     }
163     std::lock_guard<std::mutex> lock(on_demand_ranging_mutex_);
164     DataBuffer& data_buffer = InitDataBuffer(ble_bd_addr.bda, procedure_counter);
165     data_buffer.segments_.push_back(data);
166     tracker.last_ready_procedure_ = procedure_counter;
167 
168     // Send data ready
169     if (is_last) {
170       if (ccc_data_ready == GATT_CLT_CONFIG_NONE || ccc_real_time != GATT_CLT_CONFIG_NONE) {
171         log::debug("Skip Ranging Data Ready");
172       } else {
173         bool need_confirm = ccc_data_ready & GATT_CLT_CONFIG_INDICATION;
174         log::debug("Send data ready, ranging_counter {}, total fragment {}", procedure_counter,
175                    data_buffer.segments_.size());
176         uint16_t attr_id = GetCharacteristic(kRasRangingDataReadyCharacteristic)->attribute_handle_;
177         std::vector<uint8_t> value(kRingingCounterSize);
178         value[0] = (procedure_counter & 0xFF);
179         value[1] = (procedure_counter >> 8) & 0xFF;
180         BTA_GATTS_HandleValueIndication(tracker.conn_id_, attr_id, value, need_confirm);
181       }
182     }
183 
184     // Send data overwritten
185     if (tracker.buffers_.size() > kBufferSize) {
186       auto begin = tracker.buffers_.begin();
187       tracker.last_overwritten_procedure_ = begin->ranging_counter_;
188       if (ccc_data_over_written == GATT_CLT_CONFIG_NONE || ccc_real_time != GATT_CLT_CONFIG_NONE) {
189         log::debug("Skip Ranging Data Over Written");
190         tracker.buffers_.erase(begin);
191         return;
192       }
193       bool need_confirm = ccc_data_over_written & GATT_CLT_CONFIG_INDICATION;
194       log::debug("Send data over written, ranging_counter {}", begin->ranging_counter_);
195       uint16_t attr_id =
196               GetCharacteristic(kRasRangingDataOverWrittenCharacteristic)->attribute_handle_;
197       std::vector<uint8_t> value(kRingingCounterSize);
198       value[0] = (begin->ranging_counter_ & 0xFF);
199       value[1] = (begin->ranging_counter_ >> 8) & 0xFF;
200       BTA_GATTS_HandleValueIndication(tracker.conn_id_, attr_id, value, need_confirm);
201       tracker.buffers_.erase(begin);
202     }
203   }
204 
GattsCallback(tBTA_GATTS_EVT event,tBTA_GATTS * p_data)205   void GattsCallback(tBTA_GATTS_EVT event, tBTA_GATTS* p_data) {
206     log::info("event: {}", gatt_server_event_text(event));
207     switch (event) {
208       case BTA_GATTS_CONNECT_EVT: {
209         OnGattConnect(p_data);
210       } break;
211       case BTA_GATTS_DISCONNECT_EVT: {
212         OnGattDisconnect(p_data);
213       } break;
214       case BTA_GATTS_MTU_EVT: {
215         OnGattMtuChanged(p_data->req_data);
216       } break;
217       case BTA_GATTS_REG_EVT: {
218         OnGattServerRegister(p_data);
219       } break;
220       case BTA_GATTS_READ_CHARACTERISTIC_EVT: {
221         OnReadCharacteristic(p_data);
222       } break;
223       case BTA_GATTS_READ_DESCRIPTOR_EVT: {
224         OnReadDescriptor(p_data);
225       } break;
226       case BTA_GATTS_WRITE_CHARACTERISTIC_EVT: {
227         OnWriteCharacteristic(p_data);
228       } break;
229       case BTA_GATTS_WRITE_DESCRIPTOR_EVT: {
230         OnWriteDescriptor(p_data);
231       } break;
232       default:
233         log::warn("Unhandled event {}", event);
234     }
235   }
236 
OnGattConnect(tBTA_GATTS * p_data)237   void OnGattConnect(tBTA_GATTS* p_data) {
238     auto address = p_data->conn.remote_bda;
239     log::info("Address: {}, conn_id:{}", address, p_data->conn.conn_id);
240     if (p_data->conn.transport == BT_TRANSPORT_BR_EDR) {
241       log::warn("Skip BE/EDR connection");
242       return;
243     }
244 
245     if (trackers_.find(address) == trackers_.end()) {
246       log::warn("Create new tracker");
247     }
248     trackers_[address].conn_id_ = p_data->conn.conn_id;
249 
250     RawAddress identity_address = p_data->conn.remote_bda;
251     tBLE_ADDR_TYPE address_type = BLE_ADDR_PUBLIC_ID;
252     btm_random_pseudo_to_identity_addr(&identity_address, &address_type);
253     // TODO: optimize, remove this event, initialize the tracker within the GD on demand.
254     callbacks_->OnRasServerConnected(identity_address);
255   }
256 
OnGattMtuChanged(const tBTA_GATTS_REQ & req_data)257   void OnGattMtuChanged(const tBTA_GATTS_REQ& req_data) {
258     auto remote_bda = req_data.remote_bda;
259     log::info("mtu is changed as {}", req_data.p_data->mtu);
260     auto it = trackers_.find(remote_bda);
261     if (it != trackers_.end()) {
262       it->second.mtu = req_data.p_data->mtu;
263 
264       tBLE_ADDR_TYPE address_type = BLE_ADDR_PUBLIC_ID;
265       btm_random_pseudo_to_identity_addr(&remote_bda, &address_type);
266       callbacks_->OnMtuChangedFromServer(remote_bda, it->second.mtu);
267     }
268   }
269 
OnGattDisconnect(tBTA_GATTS * p_data)270   void OnGattDisconnect(tBTA_GATTS* p_data) {
271     auto remote_bda = p_data->conn.remote_bda;
272     log::info("Address: {}, conn_id:{}", remote_bda, p_data->conn.conn_id);
273     if (trackers_.find(remote_bda) != trackers_.end()) {
274       NotifyRasServerDisconnected(remote_bda);
275       trackers_.erase(remote_bda);
276     }
277   }
278 
NotifyRasServerDisconnected(const RawAddress & remote_bda)279   void NotifyRasServerDisconnected(const RawAddress& remote_bda) {
280     tBLE_BD_ADDR ble_identity_bd_addr;
281     ble_identity_bd_addr.bda = remote_bda;
282     ble_identity_bd_addr.type = BLE_ADDR_RANDOM;
283     btm_random_pseudo_to_identity_addr(&ble_identity_bd_addr.bda, &ble_identity_bd_addr.type);
284 
285     callbacks_->OnRasServerDisconnected(ble_identity_bd_addr.bda);
286   }
287 
OnGattServerRegister(tBTA_GATTS * p_data)288   void OnGattServerRegister(tBTA_GATTS* p_data) {
289     tGATT_STATUS status = p_data->reg_oper.status;
290     log::info("status: {}", gatt_status_text(p_data->reg_oper.status));
291 
292     if (status != tGATT_STATUS::GATT_SUCCESS) {
293       log::warn("Register Server fail");
294       return;
295     }
296     server_if_ = p_data->reg_oper.server_if;
297 
298     uint16_t key_mask = ((16 - 7) << 12);
299     std::vector<btgatt_db_element_t> service;
300     // RAS service
301     btgatt_db_element_t ranging_service;
302     ranging_service.uuid = kRangingService;
303     ranging_service.type = BTGATT_DB_PRIMARY_SERVICE;
304     service.push_back(ranging_service);
305 
306     // RAS Features
307     btgatt_db_element_t features_characteristic;
308     features_characteristic.uuid = kRasFeaturesCharacteristic;
309     features_characteristic.type = BTGATT_DB_CHARACTERISTIC;
310     features_characteristic.properties = GATT_CHAR_PROP_BIT_READ;
311     features_characteristic.permissions = GATT_PERM_READ_ENCRYPTED | key_mask;
312     service.push_back(features_characteristic);
313 
314     // Real-time Ranging Data (Optional)
315     btgatt_db_element_t real_time_ranging_data_characteristic;
316     real_time_ranging_data_characteristic.uuid = kRasRealTimeRangingDataCharacteristic;
317     real_time_ranging_data_characteristic.type = BTGATT_DB_CHARACTERISTIC;
318     real_time_ranging_data_characteristic.properties =
319             GATT_CHAR_PROP_BIT_NOTIFY | GATT_CHAR_PROP_BIT_INDICATE;
320     real_time_ranging_data_characteristic.permissions = GATT_PERM_READ_ENCRYPTED | key_mask;
321     service.push_back(real_time_ranging_data_characteristic);
322     btgatt_db_element_t ccc_descriptor;
323     ccc_descriptor.uuid = kClientCharacteristicConfiguration;
324     ccc_descriptor.type = BTGATT_DB_DESCRIPTOR;
325     ccc_descriptor.permissions = GATT_PERM_WRITE | GATT_PERM_READ | key_mask;
326     service.push_back(ccc_descriptor);
327 
328     // On-demand Ranging Data
329     btgatt_db_element_t on_demand_ranging_data_characteristic;
330     on_demand_ranging_data_characteristic.uuid = kRasOnDemandDataCharacteristic;
331     on_demand_ranging_data_characteristic.type = BTGATT_DB_CHARACTERISTIC;
332     on_demand_ranging_data_characteristic.properties =
333             GATT_CHAR_PROP_BIT_NOTIFY | GATT_CHAR_PROP_BIT_INDICATE;
334     on_demand_ranging_data_characteristic.permissions = GATT_PERM_READ_ENCRYPTED | key_mask;
335     service.push_back(on_demand_ranging_data_characteristic);
336     service.push_back(ccc_descriptor);
337 
338     // RAS Control Point (RAS-CP)
339     btgatt_db_element_t ras_control_point;
340     ras_control_point.uuid = kRasControlPointCharacteristic;
341     ras_control_point.type = BTGATT_DB_CHARACTERISTIC;
342     ras_control_point.properties = GATT_CHAR_PROP_BIT_WRITE_NR | GATT_CHAR_PROP_BIT_INDICATE;
343     ras_control_point.permissions = GATT_PERM_WRITE_ENCRYPTED | key_mask;
344     service.push_back(ras_control_point);
345     service.push_back(ccc_descriptor);
346 
347     // Ranging Data Ready
348     btgatt_db_element_t ranging_data_ready_characteristic;
349     ranging_data_ready_characteristic.uuid = kRasRangingDataReadyCharacteristic;
350     ranging_data_ready_characteristic.type = BTGATT_DB_CHARACTERISTIC;
351     ranging_data_ready_characteristic.properties =
352             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY | GATT_CHAR_PROP_BIT_INDICATE;
353     ranging_data_ready_characteristic.permissions = GATT_PERM_READ_ENCRYPTED | key_mask;
354     service.push_back(ranging_data_ready_characteristic);
355     service.push_back(ccc_descriptor);
356 
357     // Ranging Data Overwritten
358     btgatt_db_element_t ranging_data_overwritten_characteristic;
359     ranging_data_overwritten_characteristic.uuid = kRasRangingDataOverWrittenCharacteristic;
360     ranging_data_overwritten_characteristic.type = BTGATT_DB_CHARACTERISTIC;
361     ranging_data_overwritten_characteristic.properties =
362             GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_NOTIFY | GATT_CHAR_PROP_BIT_INDICATE;
363     ranging_data_overwritten_characteristic.permissions = GATT_PERM_READ_ENCRYPTED | key_mask;
364     service.push_back(ranging_data_overwritten_characteristic);
365     service.push_back(ccc_descriptor);
366 
367     for (auto& vendor_specific_characteristics : vendor_specific_characteristics_) {
368       btgatt_db_element_t characteristics;
369       characteristics.uuid = vendor_specific_characteristics.characteristicUuid_;
370       characteristics.type = BTGATT_DB_CHARACTERISTIC;
371       characteristics.properties = GATT_CHAR_PROP_BIT_READ | GATT_CHAR_PROP_BIT_WRITE;
372       characteristics.permissions = GATT_PERM_READ_ENCRYPTED | GATT_PERM_WRITE_ENCRYPTED | key_mask;
373       service.push_back(characteristics);
374       log::info("Push vendor_specific_characteristics uuid {}", characteristics.uuid);
375     }
376 
377     BTA_GATTS_AddService(server_if_, service,
378                          base::BindRepeating([](tGATT_STATUS status, int server_if,
379                                                 std::vector<btgatt_db_element_t> service) {
380                            if (instance) {
381                              instance->OnServiceAdded(status, server_if, service);
382                            }
383                          }));
384   }
385 
OnReadCharacteristic(tBTA_GATTS * p_data)386   void OnReadCharacteristic(tBTA_GATTS* p_data) {
387     uint16_t read_req_handle = p_data->req_data.p_data->read_req.handle;
388     log::info("read_req_handle: 0x{:04x},", read_req_handle);
389 
390     tGATTS_RSP p_msg;
391     p_msg.attr_value.handle = read_req_handle;
392     if (characteristics_.find(read_req_handle) == characteristics_.end()) {
393       log::error("Invalid handle 0x{:04x}", read_req_handle);
394       BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_INVALID_HANDLE,
395                         &p_msg);
396       return;
397     }
398 
399     auto uuid = characteristics_[read_req_handle].uuid_;
400     auto vendor_specific_characteristic = GetVendorSpecificCharacteristic(uuid);
401     if (vendor_specific_characteristic != nullptr) {
402       log::debug("Read vendor_specific_characteristic uuid {}", uuid);
403       p_msg.attr_value.len = vendor_specific_characteristic->value_.size();
404       std::copy(vendor_specific_characteristic->value_.begin(),
405                 vendor_specific_characteristic->value_.end(), p_msg.attr_value.value);
406       BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_SUCCESS, &p_msg);
407       return;
408     }
409     log::info("Read uuid, {}", getUuidName(uuid));
410     if (trackers_.find(p_data->req_data.remote_bda) == trackers_.end()) {
411       log::warn("Can't find tracker for {}", p_data->req_data.remote_bda);
412       BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_ILLEGAL_PARAMETER,
413                         &p_msg);
414       return;
415     }
416     ClientTracker* tracker = &trackers_[p_data->req_data.remote_bda];
417 
418     // Check Characteristic UUID
419     switch (uuid.As16Bit()) {
420       case kRasFeaturesCharacteristic16bit: {
421         p_msg.attr_value.len = kFeatureSize;
422         memcpy(p_msg.attr_value.value, &kSupportedFeatures, sizeof(uint32_t));
423       } break;
424       case kRasRangingDataReadyCharacteristic16bit: {
425         p_msg.attr_value.len = kRingingCounterSize;
426         p_msg.attr_value.value[0] = (tracker->last_ready_procedure_ & 0xFF);
427         p_msg.attr_value.value[1] = (tracker->last_ready_procedure_ >> 8) & 0xFF;
428       } break;
429       case kRasRangingDataOverWrittenCharacteristic16bit: {
430         p_msg.attr_value.len = kRingingCounterSize;
431         p_msg.attr_value.value[0] = (tracker->last_overwritten_procedure_ & 0xFF);
432         p_msg.attr_value.value[1] = (tracker->last_overwritten_procedure_ >> 8) & 0xFF;
433       } break;
434       default:
435         log::warn("Unhandled uuid {}", uuid.ToString());
436         BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
437                           GATT_ILLEGAL_PARAMETER, &p_msg);
438         return;
439     }
440     BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_SUCCESS, &p_msg);
441   }
442 
OnReadDescriptor(tBTA_GATTS * p_data)443   void OnReadDescriptor(tBTA_GATTS* p_data) {
444     tCONN_ID conn_id = p_data->req_data.conn_id;
445     uint16_t read_req_handle = p_data->req_data.p_data->read_req.handle;
446     RawAddress remote_bda = p_data->req_data.remote_bda;
447     log::info("conn_id:{}, read_req_handle:0x{:04x}", conn_id, read_req_handle);
448 
449     tGATTS_RSP p_msg;
450     p_msg.attr_value.handle = read_req_handle;
451 
452     // Only Client Characteristic Configuration (CCC) descriptor is expected
453     RasCharacteristic* characteristic = GetCharacteristicByCccHandle(read_req_handle);
454     if (characteristic == nullptr) {
455       log::warn("Can't find Characteristic for CCC Descriptor, handle 0x{:04x}", read_req_handle);
456       BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_INVALID_HANDLE, &p_msg);
457       return;
458     }
459     log::info("Read CCC for uuid, {}", getUuidName(characteristic->uuid_));
460     uint16_t ccc_value = 0;
461     if (trackers_.find(remote_bda) != trackers_.end()) {
462       ccc_value = trackers_[remote_bda].ccc_values_[characteristic->uuid_];
463     }
464 
465     p_msg.attr_value.len = kCccValueSize;
466     memcpy(p_msg.attr_value.value, &ccc_value, sizeof(uint16_t));
467 
468     log::info("Send response for CCC value 0x{:04x}", ccc_value);
469     BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_SUCCESS, &p_msg);
470   }
471 
OnWriteCharacteristic(tBTA_GATTS * p_data)472   void OnWriteCharacteristic(tBTA_GATTS* p_data) {
473     tCONN_ID conn_id = p_data->req_data.conn_id;
474     uint16_t write_req_handle = p_data->req_data.p_data->write_req.handle;
475     uint16_t len = p_data->req_data.p_data->write_req.len;
476     bool need_rsp = p_data->req_data.p_data->write_req.need_rsp;
477     RawAddress remote_bda = p_data->req_data.remote_bda;
478     log::info("conn_id:{}, write_req_handle:0x{:04x}, need_rsp{}, len:{}", conn_id,
479               write_req_handle, need_rsp, len);
480 
481     tGATTS_RSP p_msg;
482     p_msg.handle = write_req_handle;
483     if (characteristics_.find(write_req_handle) == characteristics_.end()) {
484       log::error("Invalid handle {}", write_req_handle);
485       BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_INVALID_HANDLE,
486                         &p_msg);
487       return;
488     }
489 
490     auto uuid = characteristics_[write_req_handle].uuid_;
491     auto vendor_specific_characteristic = GetVendorSpecificCharacteristic(uuid);
492     if (vendor_specific_characteristic != nullptr) {
493       WriteVendorSpecificCharacteristic(vendor_specific_characteristic, p_data, p_msg);
494       return;
495     }
496     log::info("Write uuid, {}", getUuidName(uuid));
497 
498     // Check Characteristic UUID
499     switch (uuid.As16Bit()) {
500       case kRasControlPointCharacteristic16bit: {
501         if (trackers_.find(p_data->req_data.remote_bda) == trackers_.end()) {
502           log::warn("Can't find trackers for {}", p_data->req_data.remote_bda);
503           BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_ILLEGAL_PARAMETER, &p_msg);
504           return;
505         }
506         ClientTracker* tracker = &trackers_[p_data->req_data.remote_bda];
507         if (need_rsp) {
508           BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_SUCCESS, &p_msg);
509         }
510         HandleControlPoint(tracker, &p_data->req_data.p_data->write_req);
511       } break;
512       default:
513         log::warn("Unhandled uuid {}", uuid.ToString());
514         BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id,
515                           GATT_ILLEGAL_PARAMETER, &p_msg);
516         return;
517     }
518   }
519 
WriteVendorSpecificCharacteristic(VendorSpecificCharacteristic * vendor_specific_characteristic,tBTA_GATTS * p_data,tGATTS_RSP & p_msg)520   void WriteVendorSpecificCharacteristic(
521           VendorSpecificCharacteristic* vendor_specific_characteristic, tBTA_GATTS* p_data,
522           tGATTS_RSP& p_msg) {
523     log::debug("uuid {}", vendor_specific_characteristic->characteristicUuid_);
524     uint16_t len = p_data->req_data.p_data->write_req.len;
525     RawAddress remote_bda = p_data->req_data.remote_bda;
526 
527     if (trackers_.find(remote_bda) == trackers_.end()) {
528       BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_INVALID_HANDLE,
529                         &p_msg);
530       log::warn("Can't find tracker for remote_bda {}", remote_bda);
531       return;
532     }
533 
534     // Update reply value
535     auto& tracker = trackers_[remote_bda];
536     auto value = p_data->req_data.p_data->write_req.value;
537     vendor_specific_characteristic->reply_value_.clear();
538     vendor_specific_characteristic->reply_value_.reserve(len);
539     vendor_specific_characteristic->reply_value_.assign(value, value + len);
540     tracker.vendor_specific_reply_counter_++;
541 
542     if (tracker.vendor_specific_reply_counter_ == vendor_specific_characteristics_.size()) {
543       log::info("All vendor specific characteristics written");
544       tBLE_BD_ADDR ble_bd_addr;
545       ble_bd_addr.bda = remote_bda;
546       ble_bd_addr.type = BLE_ADDR_RANDOM;
547       btm_random_pseudo_to_identity_addr(&ble_bd_addr.bda, &ble_bd_addr.type);
548       tracker.vendor_specific_reply_counter_ = 0;
549       tracker.pending_write_response_.conn_id_ = p_data->req_data.conn_id;
550       tracker.pending_write_response_.trans_id_ = p_data->req_data.trans_id;
551       tracker.pending_write_response_.write_req_handle_ = p_msg.handle;
552       callbacks_->OnVendorSpecificReply(ble_bd_addr.bda, vendor_specific_characteristics_);
553     } else {
554       BTA_GATTS_SendRsp(p_data->req_data.conn_id, p_data->req_data.trans_id, GATT_SUCCESS, &p_msg);
555     }
556   }
557 
OnWriteDescriptor(tBTA_GATTS * p_data)558   void OnWriteDescriptor(tBTA_GATTS* p_data) {
559     tCONN_ID conn_id = p_data->req_data.conn_id;
560     uint16_t write_req_handle = p_data->req_data.p_data->write_req.handle;
561     uint16_t len = p_data->req_data.p_data->write_req.len;
562     RawAddress remote_bda = p_data->req_data.remote_bda;
563     log::info("conn_id:{}, write_req_handle:0x{:04x}, len:{}", conn_id, write_req_handle, len);
564 
565     tGATTS_RSP p_msg;
566     p_msg.handle = write_req_handle;
567 
568     // Only Client Characteristic Configuration (CCC) descriptor is expected
569     RasCharacteristic* characteristic = GetCharacteristicByCccHandle(write_req_handle);
570     if (characteristic == nullptr) {
571       log::warn("Can't find Characteristic for CCC Descriptor, handle 0x{:04x}", write_req_handle);
572       BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_INVALID_HANDLE, &p_msg);
573       return;
574     }
575 
576     if (trackers_.find(remote_bda) == trackers_.end()) {
577       log::warn("Can't find tracker for remote_bda {}", remote_bda);
578       BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_ILLEGAL_PARAMETER, &p_msg);
579       return;
580     }
581     ClientTracker* tracker = &trackers_[p_data->req_data.remote_bda];
582     const uint8_t* value = p_data->req_data.p_data->write_req.value;
583     uint16_t ccc_value;
584     STREAM_TO_UINT16(ccc_value, value);
585 
586     // Check that On-demand and Real-time are not registered at the same time
587     uint16_t ccc_on_demand_temp = tracker->ccc_values_[kRasOnDemandDataCharacteristic];
588     uint16_t ccc_real_time_temp = tracker->ccc_values_[kRasRealTimeRangingDataCharacteristic];
589     if (characteristic->uuid_ == kRasRealTimeRangingDataCharacteristic) {
590       ccc_real_time_temp = ccc_value;
591     } else if (characteristic->uuid_ == kRasOnDemandDataCharacteristic) {
592       ccc_on_demand_temp = ccc_value;
593     }
594     if (ccc_real_time_temp != GATT_CLT_CONFIG_NONE && ccc_on_demand_temp != GATT_CLT_CONFIG_NONE) {
595       log::warn("Client Characteristic Configuration Descriptor Improperly Configured");
596       BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_CCC_CFG_ERR, &p_msg);
597       return;
598     }
599 
600     trackers_[remote_bda].ccc_values_[characteristic->uuid_] = ccc_value;
601     log::info("Write CCC for {}, conn_id:{}, value:0x{:04x}", getUuidName(characteristic->uuid_),
602               conn_id, ccc_value);
603     BTA_GATTS_SendRsp(conn_id, p_data->req_data.trans_id, GATT_SUCCESS, &p_msg);
604   }
605 
HandleControlPoint(ClientTracker * tracker,tGATT_WRITE_REQ * write_req)606   void HandleControlPoint(ClientTracker* tracker, tGATT_WRITE_REQ* write_req) {
607     ControlPointCommand command;
608     ParseControlPointCommand(&command, write_req->value, write_req->len);
609 
610     if (!command.isValid_) {
611       SendResponseCode(ResponseCodeValue::INVALID_PARAMETER, tracker);
612       return;
613     }
614 
615     if (tracker->handling_control_point_command_ && command.opcode_ != Opcode::ABORT_OPERATION) {
616       log::warn("Server busy");
617       SendResponseCode(ResponseCodeValue::SERVER_BUSY, tracker);
618       return;
619     }
620 
621     tracker->handling_control_point_command_ = true;
622 
623     switch (command.opcode_) {
624       case Opcode::GET_RANGING_DATA:
625         OnGetRangingData(&command, tracker);
626         break;
627       case Opcode::ACK_RANGING_DATA:
628         OnAckRangingData(&command, tracker);
629         break;
630       case Opcode::RETRIEVE_LOST_RANGING_DATA_SEGMENTS:
631       case Opcode::ABORT_OPERATION:
632       case Opcode::FILTER:
633         log::warn("Unsupported opcode:0x{:02x}, {}", (uint16_t)command.opcode_,
634                   GetOpcodeText(command.opcode_));
635         SendResponseCode(ResponseCodeValue::OP_CODE_NOT_SUPPORTED, tracker);
636         break;
637       default:
638         log::warn("Unknown opcode:0x{:02x}", (uint16_t)command.opcode_);
639         SendResponseCode(ResponseCodeValue::OP_CODE_NOT_SUPPORTED, tracker);
640     }
641   }
642 
OnGetRangingData(ControlPointCommand * command,ClientTracker * tracker)643   void OnGetRangingData(ControlPointCommand* command, ClientTracker* tracker) {
644     const uint8_t* value = command->parameter_;
645     uint16_t ranging_counter;
646     STREAM_TO_UINT16(ranging_counter, value);
647     log::info("ranging_counter:{}", ranging_counter);
648 
649     uint16_t ccc_value = tracker->ccc_values_[kRasOnDemandDataCharacteristic];
650     uint16_t attr_id = GetCharacteristic(kRasOnDemandDataCharacteristic)->attribute_handle_;
651     bool use_notification = ccc_value & GATT_CLT_CONFIG_NOTIFICATION;
652 
653     std::lock_guard<std::mutex> lock(on_demand_ranging_mutex_);
654     auto it = std::find_if(tracker->buffers_.begin(), tracker->buffers_.end(),
655                            [&ranging_counter](const DataBuffer& buffer) {
656                              return buffer.ranging_counter_ == ranging_counter;
657                            });
658     if (it != tracker->buffers_.end()) {
659       for (uint16_t i = 0; i < it->segments_.size(); i++) {
660         if (ccc_value == GATT_CLT_CONFIG_NONE) {
661           log::warn("On Demand Data is not subscribed, Skip");
662           break;
663         }
664         log::info("Send On Demand Ranging Data, segment {}", i);
665         BTA_GATTS_HandleValueIndication(tracker->conn_id_, attr_id, it->segments_[i],
666                                         !use_notification);
667       }
668       log::info("Send COMPLETE_RANGING_DATA_RESPONSE, ranging_counter:{}", ranging_counter);
669       std::vector<uint8_t> response(3, 0);
670       response[0] = (uint8_t)EventCode::COMPLETE_RANGING_DATA_RESPONSE;
671       response[1] = (ranging_counter & 0xFF);
672       response[2] = (ranging_counter >> 8) & 0xFF;
673       BTA_GATTS_HandleValueIndication(
674               tracker->conn_id_,
675               GetCharacteristic(kRasControlPointCharacteristic)->attribute_handle_, response, true);
676       tracker->handling_control_point_command_ = false;
677       return;
678     } else {
679       log::warn("No Records Found");
680       SendResponseCode(ResponseCodeValue::NO_RECORDS_FOUND, tracker);
681     }
682   }
683 
OnAckRangingData(ControlPointCommand * command,ClientTracker * tracker)684   void OnAckRangingData(ControlPointCommand* command, ClientTracker* tracker) {
685     const uint8_t* value = command->parameter_;
686     uint16_t ranging_counter;
687     STREAM_TO_UINT16(ranging_counter, value);
688     log::info("ranging_counter:{}", ranging_counter);
689 
690     std::lock_guard<std::mutex> lock(on_demand_ranging_mutex_);
691     auto it = std::find_if(tracker->buffers_.begin(), tracker->buffers_.end(),
692                            [&ranging_counter](const DataBuffer& buffer) {
693                              return buffer.ranging_counter_ == ranging_counter;
694                            });
695     // If found, erase it
696     if (it != tracker->buffers_.end()) {
697       tracker->buffers_.erase(it);
698       tracker->handling_control_point_command_ = false;
699       SendResponseCode(ResponseCodeValue::SUCCESS, tracker);
700     } else {
701       log::warn("No Records Found");
702       SendResponseCode(ResponseCodeValue::NO_RECORDS_FOUND, tracker);
703     }
704   }
705 
SendResponseCode(ResponseCodeValue response_code_value,ClientTracker * tracker)706   void SendResponseCode(ResponseCodeValue response_code_value, ClientTracker* tracker) {
707     log::info("0x{:02x}, {}", (uint16_t)response_code_value,
708               GetResponseOpcodeValueText(response_code_value));
709     std::vector<uint8_t> response(2, 0);
710     response[0] = (uint8_t)EventCode::RESPONSE_CODE;
711     response[1] = (uint8_t)response_code_value;
712     BTA_GATTS_HandleValueIndication(
713             tracker->conn_id_, GetCharacteristic(kRasControlPointCharacteristic)->attribute_handle_,
714             response, true);
715     tracker->handling_control_point_command_ = false;
716   }
717 
OnServiceAdded(tGATT_STATUS status,int server_if,std::vector<btgatt_db_element_t> service)718   void OnServiceAdded(tGATT_STATUS status, int server_if,
719                       std::vector<btgatt_db_element_t> service) {
720     log::info("status: {}, server_if: {}", gatt_status_text(status), server_if);
721     RasCharacteristic* current_characteristic;
722     for (uint16_t i = 0; i < service.size(); i++) {
723       uint16_t attribute_handle = service[i].attribute_handle;
724       Uuid uuid = service[i].uuid;
725       if (service[i].type == BTGATT_DB_CHARACTERISTIC) {
726         log::info("Characteristic uuid: 0x{:04x}, handle:0x{:04x}, {}", uuid.As16Bit(),
727                   attribute_handle, getUuidName(uuid));
728         characteristics_[attribute_handle].attribute_handle_ = attribute_handle;
729         characteristics_[attribute_handle].uuid_ = uuid;
730         current_characteristic = &characteristics_[attribute_handle];
731       } else if (service[i].type == BTGATT_DB_DESCRIPTOR) {
732         log::info("\tDescriptor uuid: 0x{:04x}, handle: 0x{:04x}, {}", uuid.As16Bit(),
733                   attribute_handle, getUuidName(uuid));
734         if (service[i].uuid == kClientCharacteristicConfiguration) {
735           current_characteristic->attribute_handle_ccc_ = attribute_handle;
736         }
737       }
738     }
739   }
740 
GetCharacteristic(Uuid uuid)741   RasCharacteristic* GetCharacteristic(Uuid uuid) {
742     for (auto& [attribute_handle, characteristic] : characteristics_) {
743       if (characteristic.uuid_ == uuid) {
744         return &characteristic;
745       }
746     }
747     return nullptr;
748   }
749 
GetCharacteristicByCccHandle(uint16_t descriptor_handle)750   RasCharacteristic* GetCharacteristicByCccHandle(uint16_t descriptor_handle) {
751     for (auto& [attribute_handle, characteristic] : characteristics_) {
752       if (characteristic.attribute_handle_ccc_ == descriptor_handle) {
753         return &characteristic;
754       }
755     }
756     return nullptr;
757   }
758 
ResolveAddress(tBLE_BD_ADDR & ble_bd_addr,const RawAddress & address)759   void ResolveAddress(tBLE_BD_ADDR& ble_bd_addr, const RawAddress& address) {
760     ble_bd_addr.bda = address;
761     ble_bd_addr.type = BLE_ADDR_RANDOM;
762     maybe_resolve_address(&ble_bd_addr.bda, &ble_bd_addr.type);
763   }
764 
InitDataBuffer(RawAddress address,uint16_t procedure_counter)765   DataBuffer& InitDataBuffer(RawAddress address, uint16_t procedure_counter) {
766     std::vector<DataBuffer>& buffers = trackers_[address].buffers_;
767     for (DataBuffer& data_buffer : buffers) {
768       if (data_buffer.ranging_counter_ == procedure_counter) {
769         // Data already exist, return
770         return data_buffer;
771       }
772     }
773     log::info("Create data for ranging_counter: {}, current size {}", procedure_counter,
774               buffers.size());
775     buffers.emplace_back(procedure_counter);
776     return buffers.back();
777   }
778 
GetVendorSpecificCharacteristic(const bluetooth::Uuid & uuid)779   VendorSpecificCharacteristic* GetVendorSpecificCharacteristic(const bluetooth::Uuid& uuid) {
780     for (auto& characteristic : vendor_specific_characteristics_) {
781       if (characteristic.characteristicUuid_ == uuid) {
782         return &characteristic;
783       }
784     }
785     return nullptr;
786   }
787 
788 private:
789   bluetooth::Uuid app_uuid_;
790   uint16_t server_if_;
791   // A map to associate characteristics with handles
792   std::unordered_map<uint16_t, RasCharacteristic> characteristics_;
793   // A map to client trackers with address
794   std::unordered_map<RawAddress, ClientTracker> trackers_;
795   bluetooth::ras::RasServerCallbacks* callbacks_;
796   std::mutex on_demand_ranging_mutex_;
797   std::vector<VendorSpecificCharacteristic> vendor_specific_characteristics_;
798 };
799 
800 }  // namespace
801 
GetRasServer()802 bluetooth::ras::RasServer* bluetooth::ras::GetRasServer() {
803   if (instance == nullptr) {
804     instance = new RasServerImpl();
805   }
806   return instance;
807 }
808