Skip to content

Commit bc5b776

Browse files
olivier-le-sagerlubos
authored andcommitted
bluetooth: samples: Use real-time ranging data in RAS samples
Using real-time ranging data instead of on-demand: - requires fewer subscriptions - requires less complex logic for combining the local and remote results since the application no longer needs to initiate a data fetch through RAS-CP - Doubles the maximum frequency of channel sounding procedures by making it possible to use less than half the procedure interval while still having enough time to finish the GATT transaction and distance estimation before the next procedure begins. Signed-off-by: Olivier Lesage <[email protected]>
1 parent 5bb0759 commit bc5b776

File tree

4 files changed

+84
-36
lines changed

4 files changed

+84
-36
lines changed

include/bluetooth/services/ras.h

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ extern "C" {
9090
(BT_RAS_MAX_STEPS_PER_PROCEDURE * BT_RAS_STEP_MODE_LEN) + \
9191
(BT_RAS_MAX_STEPS_PER_PROCEDURE * BT_RAS_MAX_STEP_DATA_LEN))
9292

93+
/** @brief RAS Features as defined in RAS Specification, Table 3.3. */
94+
enum ras_feat {
95+
RAS_FEAT_REALTIME_RD = BIT(0),
96+
RAS_FEAT_RETRIEVE_LOST_RD_SEG = BIT(1),
97+
RAS_FEAT_ABORT_OP = BIT(2),
98+
RAS_FEAT_FILTER_RD = BIT(3),
99+
};
100+
93101
/** @brief Ranging Header structure as defined in RAS Specification, Table 3.7. */
94102
struct ras_ranging_header {
95103
/** Ranging Counter is lower 12-bits of CS Procedure_Counter provided by the Core Controller
@@ -333,7 +341,7 @@ typedef void (*bt_ras_rreq_rd_overwritten_cb_t)(struct bt_conn *conn, uint16_t r
333341
* the peer.
334342
*
335343
* @param[in] conn Connection Object.
336-
* @param[in] ranging_counter Ranging counter which has been received.
344+
* @param[in] ranging_counter Ranging counter that has been received.
337345
* @param[in] err Error code, 0 if successful. Otherwise a negative error code.
338346
*/
339347
typedef void (*bt_ras_rreq_ranging_data_received_t)(struct bt_conn *conn, uint16_t ranging_counter,
@@ -372,7 +380,7 @@ int bt_ras_rreq_alloc_and_assign_handles(struct bt_gatt_dm *dm, struct bt_conn *
372380
* characteristic to which the device is already subscribed or unsubscribed (respectively).
373381
*
374382
* @param[in] conn Connection object.
375-
* @param[in] subscription_change_cb CCC write request response callback
383+
* @param[in] subscription_change_cb CCC write request response callback.
376384
*
377385
* @retval 0 If the operation was successful.
378386
* Otherwise, a negative error code is returned.
@@ -525,7 +533,7 @@ int bt_ras_rreq_rd_overwritten_unsubscribe(struct bt_conn *conn);
525533
* @note The data callback will be called many times (for as long as the RRSP continues
526534
* to send notifications).
527535
*
528-
* @param[in] conn Connection Object, which already has associated RREQ context.
536+
* @param[in] conn Connection Object that already has an associated RREQ context.
529537
* @param[in] ranging_data_out Simple buffer to store received ranging data.
530538
* @param[in] data_received_cb Callback called when complete ranging data is received.
531539
*
@@ -540,7 +548,7 @@ int bt_ras_rreq_realtime_rd_subscribe(struct bt_conn *conn, struct net_buf_simpl
540548
* @note Calling from BT RX thread may return an error as bt_gatt_unsubscribe will not block if
541549
* there are no available TX buffers.
542550
*
543-
* @param[in] conn Connection Object, which already has associated RREQ context.
551+
* @param[in] conn Connection Object that already has an associated RREQ context.
544552
*
545553
* @retval 0 If the operation was successful.
546554
* Otherwise, a negative error code is returned.

samples/bluetooth/channel_sounding_ras_initiator/src/main.c

Lines changed: 71 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ static K_SEM_DEFINE(sem_connected, 0, 1);
4444
static K_SEM_DEFINE(sem_discovery_done, 0, 1);
4545
static K_SEM_DEFINE(sem_mtu_exchange_done, 0, 1);
4646
static K_SEM_DEFINE(sem_security, 0, 1);
47+
static K_SEM_DEFINE(sem_ras_features, 0, 1);
4748
static K_SEM_DEFINE(sem_local_steps, 1, 1);
4849

4950
static K_MUTEX_DEFINE(distance_estimate_buffer_mutex);
@@ -53,6 +54,7 @@ NET_BUF_SIMPLE_DEFINE_STATIC(latest_local_steps, LOCAL_PROCEDURE_MEM);
5354
NET_BUF_SIMPLE_DEFINE_STATIC(latest_peer_steps, BT_RAS_PROCEDURE_MEM);
5455
static int32_t most_recent_local_ranging_counter = PROCEDURE_COUNTER_NONE;
5556
static int32_t dropped_ranging_counter = PROCEDURE_COUNTER_NONE;
57+
static uint32_t ras_feature_bits;
5658

5759
static uint8_t buffer_index;
5860
static uint8_t buffer_num_valid;
@@ -121,17 +123,26 @@ static cs_de_dist_estimates_t get_distance(uint8_t ap)
121123
return averaged_result;
122124
}
123125

124-
static void ranging_data_get_complete_cb(struct bt_conn *conn, uint16_t ranging_counter, int err)
126+
static void ranging_data_cb(struct bt_conn *conn, uint16_t ranging_counter, int err)
125127
{
126128
ARG_UNUSED(conn);
127129

128130
if (err) {
129-
LOG_ERR("Error when getting ranging data with ranging counter %d (err %d)",
131+
LOG_ERR("Error when receiving ranging data with ranging counter %d (err %d)",
130132
ranging_counter, err);
131133
return;
132134
}
133135

134-
LOG_DBG("Ranging data get completed for ranging counter %d", ranging_counter);
136+
if (ranging_counter != most_recent_local_ranging_counter) {
137+
LOG_INF("Ranging data dropped as peer ranging counter doesn't match local ranging "
138+
"data counter. (peer: %u, local: %u)",
139+
ranging_counter, most_recent_local_ranging_counter);
140+
net_buf_simple_reset(&latest_local_steps);
141+
k_sem_give(&sem_local_steps);
142+
return;
143+
}
144+
145+
LOG_DBG("Ranging data received for ranging counter %d", ranging_counter);
135146

136147
/* This struct is static to avoid putting it on the stack (it's very large) */
137148
static cs_de_report_t cs_de_report;
@@ -140,7 +151,11 @@ static void ranging_data_get_complete_cb(struct bt_conn *conn, uint16_t ranging_
140151
&cs_de_report);
141152

142153
net_buf_simple_reset(&latest_local_steps);
143-
net_buf_simple_reset(&latest_peer_steps);
154+
155+
if (ras_feature_bits & RAS_FEAT_REALTIME_RD) {
156+
net_buf_simple_reset(&latest_peer_steps);
157+
}
158+
144159
k_sem_give(&sem_local_steps);
145160

146161
cs_de_quality_t quality = cs_de_calc(&cs_de_report);
@@ -166,7 +181,7 @@ static void subevent_result_cb(struct bt_conn *conn, struct bt_conn_le_cs_subeve
166181

167182
if (sem_state < 0) {
168183
dropped_ranging_counter = result->header.procedure_counter;
169-
LOG_DBG("Dropped subevent results due to unfinished ranging data request.");
184+
LOG_INF("Dropped subevent results. Waiting for ranging data from peer.");
170185
return;
171186
}
172187

@@ -211,7 +226,7 @@ static void ranging_data_ready_cb(struct bt_conn *conn, uint16_t ranging_counter
211226
if (ranging_counter == most_recent_local_ranging_counter) {
212227
int err = bt_ras_rreq_cp_get_ranging_data(connection, &latest_peer_steps,
213228
ranging_counter,
214-
ranging_data_get_complete_cb);
229+
ranging_data_cb);
215230
if (err) {
216231
LOG_ERR("Get ranging data failed (err %d)", err);
217232
net_buf_simple_reset(&latest_local_steps);
@@ -404,6 +419,18 @@ static void procedure_enable_cb(struct bt_conn *conn,
404419
}
405420
}
406421

422+
void ras_features_read_cb(struct bt_conn *conn, uint32_t feature_bits, int err)
423+
{
424+
if (err) {
425+
LOG_WRN("Error while reading RAS feature bits (err %d)", err);
426+
} else {
427+
LOG_INF("Read RAS feature bits: 0x%x", feature_bits);
428+
ras_feature_bits = feature_bits;
429+
}
430+
431+
k_sem_give(&sem_ras_features);
432+
}
433+
407434
static void scan_filter_match(struct bt_scan_device_info *device_info,
408435
struct bt_scan_filter_match *filter_match, bool connectable)
409436
{
@@ -534,28 +561,48 @@ int main(void)
534561
return 0;
535562
}
536563

537-
err = bt_ras_rreq_rd_overwritten_subscribe(connection, ranging_data_overwritten_cb);
564+
err = bt_ras_rreq_read_features(connection, ras_features_read_cb);
538565
if (err) {
539-
LOG_ERR("RAS RREQ ranging data overwritten subscribe failed (err %d)", err);
566+
LOG_ERR("Could not get RAS features from peer (err %d)", err);
540567
return 0;
541568
}
542569

543-
err = bt_ras_rreq_rd_ready_subscribe(connection, ranging_data_ready_cb);
544-
if (err) {
545-
LOG_ERR("RAS RREQ ranging data ready subscribe failed (err %d)", err);
546-
return 0;
547-
}
570+
k_sem_take(&sem_ras_features, K_FOREVER);
548571

549-
err = bt_ras_rreq_on_demand_rd_subscribe(connection);
550-
if (err) {
551-
LOG_ERR("RAS RREQ On-demand ranging data subscribe failed (err %d)", err);
552-
return 0;
553-
}
572+
const bool realtime_rd = ras_feature_bits & RAS_FEAT_REALTIME_RD;
554573

555-
err = bt_ras_rreq_cp_subscribe(connection);
556-
if (err) {
557-
LOG_ERR("RAS RREQ CP subscribe failed (err %d)", err);
558-
return 0;
574+
if (realtime_rd) {
575+
err = bt_ras_rreq_realtime_rd_subscribe(connection,
576+
&latest_peer_steps,
577+
ranging_data_cb);
578+
if (err) {
579+
LOG_ERR("RAS RREQ Real-time ranging data subscribe failed (err %d)", err);
580+
return 0;
581+
}
582+
} else {
583+
err = bt_ras_rreq_rd_overwritten_subscribe(connection, ranging_data_overwritten_cb);
584+
if (err) {
585+
LOG_ERR("RAS RREQ ranging data overwritten subscribe failed (err %d)", err);
586+
return 0;
587+
}
588+
589+
err = bt_ras_rreq_rd_ready_subscribe(connection, ranging_data_ready_cb);
590+
if (err) {
591+
LOG_ERR("RAS RREQ ranging data ready subscribe failed (err %d)", err);
592+
return 0;
593+
}
594+
595+
err = bt_ras_rreq_on_demand_rd_subscribe(connection);
596+
if (err) {
597+
LOG_ERR("RAS RREQ On-demand ranging data subscribe failed (err %d)", err);
598+
return 0;
599+
}
600+
601+
err = bt_ras_rreq_cp_subscribe(connection);
602+
if (err) {
603+
LOG_ERR("RAS RREQ CP subscribe failed (err %d)", err);
604+
return 0;
605+
}
559606
}
560607

561608
err = bt_le_cs_read_remote_supported_capabilities(connection);
@@ -605,8 +652,8 @@ int main(void)
605652
const struct bt_le_cs_set_procedure_parameters_param procedure_params = {
606653
.config_id = CS_CONFIG_ID,
607654
.max_procedure_len = 1000,
608-
.min_procedure_interval = 10,
609-
.max_procedure_interval = 10,
655+
.min_procedure_interval = realtime_rd ? 4 : 10,
656+
.max_procedure_interval = realtime_rd ? 4 : 10,
610657
.max_procedure_count = 0,
611658
.min_subevent_len = 60000,
612659
.max_subevent_len = 60000,

subsys/bluetooth/services/ras/ras_internal.h

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,14 +57,6 @@ enum rascp_rsp_code {
5757
RASCP_RESPONSE_NO_RECORDS_FOUND = 0x08,
5858
};
5959

60-
/** @brief RAS Features as defined in RAS Specification, Table 3.3. */
61-
enum ras_feat {
62-
RAS_FEAT_REALTIME_RD = BIT(0),
63-
RAS_FEAT_RETRIEVE_LOST_RD_SEG = BIT(1),
64-
RAS_FEAT_ABORT_OP = BIT(2),
65-
RAS_FEAT_FILTER_RD = BIT(3),
66-
};
67-
6860
/** @brief RAS ATT Application error codes as defined in RAS Specification, Table 2.1. */
6961
enum ras_att_error {
7062
RAS_ATT_ERROR_CCC_CONFIG = 0xFD,

subsys/bluetooth/services/ras/rreq/ras_rreq.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ static void data_receive_finished(struct bt_ras_rreq *rreq)
195195

196196
rreq->last_segment_received = false;
197197
rreq->next_expected_segment_counter = 0;
198+
rreq->data_error_status = 0;
198199
}
199200

200201
static uint8_t ranging_data_overwritten_notify_func(struct bt_conn *conn,

0 commit comments

Comments
 (0)