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