Skip to content

Commit 59130f5

Browse files
alexstanoev-nordicrlubos
authored andcommitted
samples: bluetooth: Add Channel Sounding Reflector with RRSP sample
This sample can be used to set up a Channel Sounding Reflector with the GATT Ranging Responder service. A Channel Sounding Initiator with Ranging Requestor can connect to this sample to receive CS Ranging Data and perform distance estimation. Signed-off-by: Aleksandar Stanoev <[email protected]>
1 parent b68faea commit 59130f5

File tree

7 files changed

+280
-1
lines changed

7 files changed

+280
-1
lines changed

CODEOWNERS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,7 @@
413413
/samples/bluetooth/central_nfc_pairing/ @nrfconnect/ncs-si-muffin
414414
/samples/bluetooth/central_smp_client/ @nrfconnect/ncs-si-muffin
415415
/samples/bluetooth/central_uart/ @nrfconnect/ncs-si-muffin
416+
/samples/bluetooth/channel_sounding_ras_reflector/ @nrfconnect/ncs-dragoon
416417
/samples/bluetooth/conn_time_sync/ @nrfconnect/ncs-dragoon
417418
/samples/bluetooth/direction_finding_central/ @nrfconnect/ncs-dragoon
418419
/samples/bluetooth/direction_finding_connectionless_rx/ @nrfconnect/ncs-dragoon

doc/nrf/releases_and_maturity/releases/release-notes-changelog.rst

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,9 @@ Amazon Sidewalk samples
233233
Bluetooth samples
234234
-----------------
235235

236-
|no_changes_yet_note|
236+
* Added:
237+
238+
* The :ref:`channel_sounding_ras_reflector` sample demonstrating how to implement a Channel Sounding Reflector that exposes the Ranging Responder GATT Service.
237239

238240
Bluetooth Fast Pair samples
239241
---------------------------
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
cmake_minimum_required(VERSION 3.20.0)
7+
8+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
9+
project(channel_sounding_ras_reflector)
10+
11+
# NORDIC SDK APP START
12+
target_sources(app PRIVATE
13+
src/main.c
14+
)
15+
# NORDIC SDK APP END
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
.. _channel_sounding_ras_reflector:
2+
3+
Bluetooth: Channel Sounding Reflector with Ranging Responder
4+
############################################################
5+
6+
.. contents::
7+
:local:
8+
:depth: 2
9+
10+
This sample demonstrates how to use the ranging service to provide ranging data to a client.
11+
12+
Requirements
13+
************
14+
15+
The sample supports the following development kits:
16+
17+
.. table-from-sample-yaml::
18+
19+
The sample also requires a device running a Channel Sounding Initiator with Ranging Requestor to connect to.
20+
21+
Overview
22+
********
23+
24+
The sample demonstrates a basic Bluetooth® Low Energy Peripheral role functionality that exposes the GATT Ranging Responder Service and configures the Channel Sounding reflector role.
25+
When Channel Sounding Ranging Data is generated by the controller, it will be automatically stored by the Ranging Service, and can be queried at any time by the Ranging Requestor.
26+
The Channel Sounding Ranging Data can then be used by the peer device to perform distance estimation.
27+
28+
User interface
29+
**************
30+
31+
The sample does not require user input and will advertise using the GATT Ranging Service UUID.
32+
The first LED on the development kit will be lit when a connection has been established.
33+
34+
Building and running
35+
********************
36+
.. |sample path| replace:: :file:`samples/bluetooth/channel_sounding_ras_reflector`
37+
38+
.. include:: /includes/build_and_run.txt
39+
40+
Testing
41+
=======
42+
43+
After programming the sample to your development kit, you can test it by connecting to another development kit with a Channel Sounding Initiator role with Ranging Requestor.
44+
45+
1. |connect_terminal_specific|
46+
#. Reset the kit.
47+
#. Program the other kit with the Channel Sounding Initiator with Ranging Requestor sample.
48+
#. Wait until the advertiser is detected by the Central.
49+
In the terminal window, check for information similar to the following::
50+
51+
I: Connected to xx.xx.xx.xx.xx.xx (random) (err 0x00)
52+
I: CS capability exchange completed.
53+
I: CS config creation complete. ID: 0
54+
I: CS security enabled.
55+
I: CS procedures enabled.
56+
57+
Dependencies
58+
************
59+
60+
This sample uses the following |NCS| libraries:
61+
62+
* :ref:`dk_buttons_and_leds_readme`
63+
* :file:`include/bluetooth/services/ras.h`
64+
65+
This sample uses the following Zephyr libraries:
66+
67+
* :ref:`zephyr:logging_api`:
68+
69+
* :file:`include/logging/log.h`
70+
71+
* :file:`include/zephyr/types.h`
72+
* :ref:`zephyr:kernel_api`:
73+
74+
* :file:`include/kernel.h`
75+
76+
* :ref:`zephyr:bluetooth_api`:
77+
78+
* :file:`include/bluetooth/bluetooth.h`
79+
* :file:`include/bluetooth/conn.h`
80+
* :file:`include/bluetooth/uuid.h`
81+
* :file:`include/bluetooth/cs.h`
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
#
2+
# Copyright (c) 2024 Nordic Semiconductor ASA
3+
#
4+
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
#
6+
7+
CONFIG_NCS_SAMPLES_DEFAULTS=y
8+
CONFIG_DK_LIBRARY=y
9+
10+
CONFIG_BT=y
11+
CONFIG_BT_PERIPHERAL=y
12+
CONFIG_BT_SMP=y
13+
CONFIG_BT_DEVICE_NAME="Nordic CS Reflector"
14+
CONFIG_BT_MAX_CONN=1
15+
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n
16+
CONFIG_BT_BONDABLE=n
17+
18+
# The Ranging Profile recommends a MTU of at least 247 octets.
19+
CONFIG_BT_L2CAP_TX_MTU=498
20+
CONFIG_BT_BUF_ACL_TX_SIZE=502
21+
CONFIG_BT_BUF_ACL_RX_SIZE=502
22+
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251
23+
CONFIG_BT_CTLR_PHY_2M=y
24+
25+
CONFIG_BT_CHANNEL_SOUNDING=y
26+
CONFIG_BT_RAS=y
27+
CONFIG_BT_RAS_RRSP=y
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
sample:
2+
description: Bluetooth Low Energy Channel Sounding Reflector with Ranging Service Responder
3+
name: Bluetooth LE Channel Sounding Reflector with RRSP
4+
tests:
5+
sample.bluetooth.channel_sounding_ras_reflector:
6+
sysbuild: true
7+
build_only: true
8+
integration_platforms:
9+
- nrf54l15dk/nrf54l15/cpuapp
10+
platform_allow:
11+
- nrf54l15dk/nrf54l15/cpuapp
12+
tags: bluetooth ci_build sysbuild
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
/*
2+
* Copyright (c) 2024 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
5+
*/
6+
7+
/** @file
8+
* @brief Channel Sounding Reflector with Ranging Responder sample
9+
*/
10+
11+
#include <zephyr/types.h>
12+
#include <zephyr/kernel.h>
13+
#include <zephyr/bluetooth/bluetooth.h>
14+
#include <zephyr/bluetooth/conn.h>
15+
#include <zephyr/bluetooth/uuid.h>
16+
#include <zephyr/bluetooth/cs.h>
17+
#include <bluetooth/services/ras.h>
18+
19+
#include <dk_buttons_and_leds.h>
20+
21+
#include <zephyr/logging/log.h>
22+
LOG_MODULE_REGISTER(app_main, LOG_LEVEL_INF);
23+
24+
#define CON_STATUS_LED DK_LED1
25+
26+
static K_SEM_DEFINE(sem_connected, 0, 1);
27+
28+
static struct bt_conn *connection;
29+
30+
static const struct bt_data ad[] = {
31+
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
32+
BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_RANGING_SERVICE_VAL)),
33+
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
34+
};
35+
36+
static void connected_cb(struct bt_conn *conn, uint8_t err)
37+
{
38+
char addr[BT_ADDR_LE_STR_LEN];
39+
40+
(void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
41+
LOG_INF("Connected to %s (err 0x%02X)", addr, err);
42+
43+
if (err) {
44+
bt_conn_unref(conn);
45+
connection = NULL;
46+
}
47+
48+
connection = bt_conn_ref(conn);
49+
50+
k_sem_give(&sem_connected);
51+
52+
dk_set_led_on(CON_STATUS_LED);
53+
}
54+
55+
static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
56+
{
57+
LOG_INF("Disconnected (reason 0x%02X)", reason);
58+
59+
bt_conn_unref(conn);
60+
connection = NULL;
61+
62+
dk_set_led_off(CON_STATUS_LED);
63+
}
64+
65+
static void remote_capabilities_cb(struct bt_conn *conn, struct bt_conn_le_cs_capabilities *params)
66+
{
67+
ARG_UNUSED(conn);
68+
ARG_UNUSED(params);
69+
LOG_INF("CS capability exchange completed.");
70+
}
71+
72+
static void config_created_cb(struct bt_conn *conn, struct bt_conn_le_cs_config *config)
73+
{
74+
ARG_UNUSED(conn);
75+
LOG_INF("CS config creation complete. ID: %d", config->id);
76+
}
77+
78+
static void security_enabled_cb(struct bt_conn *conn)
79+
{
80+
ARG_UNUSED(conn);
81+
LOG_INF("CS security enabled.");
82+
}
83+
84+
static void procedure_enabled_cb(struct bt_conn *conn,
85+
struct bt_conn_le_cs_procedure_enable_complete *params)
86+
{
87+
ARG_UNUSED(conn);
88+
if (params->state == 1) {
89+
LOG_INF("CS procedures enabled.");
90+
} else {
91+
LOG_INF("CS procedures disabled.");
92+
}
93+
}
94+
95+
BT_CONN_CB_DEFINE(conn_cb) = {
96+
.connected = connected_cb,
97+
.disconnected = disconnected_cb,
98+
.le_cs_remote_capabilities_available = remote_capabilities_cb,
99+
.le_cs_config_created = config_created_cb,
100+
.le_cs_security_enabled = security_enabled_cb,
101+
.le_cs_procedure_enabled = procedure_enabled_cb,
102+
};
103+
104+
int main(void)
105+
{
106+
int err;
107+
108+
LOG_INF("Starting Channel Sounding Reflector Sample");
109+
110+
dk_leds_init();
111+
112+
err = bt_enable(NULL);
113+
if (err) {
114+
LOG_ERR("Bluetooth init failed (err %d)", err);
115+
return 0;
116+
}
117+
118+
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0);
119+
if (err) {
120+
LOG_ERR("Advertising failed to start (err %d)", err);
121+
return 0;
122+
}
123+
124+
while (true) {
125+
k_sem_take(&sem_connected, K_FOREVER);
126+
127+
const struct bt_le_cs_set_default_settings_param default_settings = {
128+
.enable_initiator_role = false,
129+
.enable_reflector_role = true,
130+
.cs_sync_antenna_selection = BT_LE_CS_ANTENNA_SELECTION_OPT_REPETITIVE,
131+
.max_tx_power = BT_HCI_OP_LE_CS_MAX_MAX_TX_POWER,
132+
};
133+
134+
err = bt_le_cs_set_default_settings(connection, &default_settings);
135+
if (err) {
136+
LOG_ERR("Failed to configure default CS settings (err %d)", err);
137+
}
138+
}
139+
140+
return 0;
141+
}

0 commit comments

Comments
 (0)