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