-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
samples: bluetooth: Add Channel Sounding Reflector with Ranging Responder sample #18894
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
cmake_minimum_required(VERSION 3.20.0) | ||
|
||
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE}) | ||
project(channel_sounding_ras_reflector) | ||
|
||
# NORDIC SDK APP START | ||
target_sources(app PRIVATE | ||
src/main.c | ||
) | ||
# NORDIC SDK APP END |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,79 @@ | ||
.. _channel_sounding_ras_reflector: | ||
|
||
Bluetooth: Channel Sounding Reflector with Ranging Responder | ||
############################################################ | ||
|
||
.. contents:: | ||
:local: | ||
:depth: 2 | ||
|
||
This sample demonstrates how to use the ranging service to provide ranging data to a client. | ||
|
||
Requirements | ||
************ | ||
|
||
The sample supports the following development kits: | ||
|
||
.. table-from-sample-yaml:: | ||
|
||
The sample also requires a device running a Channel Sounding Initiator with Ranging Requestor to connect to. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same question as above about the capitalization. In all places. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will take whatever decision is made in #18894 (comment) and update all instances accordingly |
||
|
||
Overview | ||
******** | ||
|
||
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. | ||
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. | ||
The Channel Sounding Ranging Data can then be used by the peer device to perform distance estimation. | ||
|
||
User interface | ||
************** | ||
|
||
The sample does not require user input and will advertise using the GATT Ranging Service UUID. | ||
The first LED on the development kit will be lit when a connection has been established. | ||
|
||
Building and running | ||
******************** | ||
.. |sample path| replace:: :file:`samples/bluetooth/channel_sounding_ras/reflector` | ||
|
||
.. include:: /includes/build_and_run.txt | ||
|
||
Testing | ||
======= | ||
|
||
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. | ||
|
||
1. |connect_terminal_specific| | ||
#. Reset the kit. | ||
#. Program the other kit with the Channel Sounding Initiator with Ranging Requestor sample. | ||
#. Wait until the advertiser is detected by the Central. | ||
In the terminal window, check for information similar to the following:: | ||
|
||
Connected to xx.xx.xx.xx.xx.xx (random) (err 0x00) | ||
Pairing completed: xx.xx.xx.xx.xx.xx (random), bonded: 1 | ||
CS capability exchange completed. | ||
CS config creation complete. ID: 0 | ||
CS security enabled. | ||
CS procedures enabled. | ||
|
||
Dependencies | ||
************ | ||
|
||
This sample uses the following |NCS| libraries: | ||
|
||
* :ref:`dk_buttons_and_leds_readme` | ||
* :file:`include/bluetooth/services/ras.h` | ||
|
||
This sample uses the following Zephyr libraries: | ||
|
||
* :file:`include/sys/printk.h` | ||
* :file:`include/zephyr/types.h` | ||
* :ref:`zephyr:kernel_api`: | ||
|
||
* :file:`include/kernel.h` | ||
|
||
* :ref:`zephyr:bluetooth_api`: | ||
|
||
* :file:`include/bluetooth/bluetooth.h` | ||
* :file:`include/bluetooth/conn.h` | ||
* :file:`include/bluetooth/uuid.h` | ||
* :file:`include/bluetooth/cs.h` |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
# | ||
# Copyright (c) 2024 Nordic Semiconductor ASA | ||
# | ||
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
# | ||
|
||
CONFIG_NCS_SAMPLES_DEFAULTS=y | ||
CONFIG_DK_LIBRARY=y | ||
|
||
CONFIG_BT=y | ||
CONFIG_BT_PERIPHERAL=y | ||
CONFIG_BT_SMP=y | ||
CONFIG_BT_DEVICE_NAME="Nordic CS Reflector" | ||
CONFIG_BT_MAX_CONN=1 | ||
|
||
# The Ranging Profile recommends a MTU of at least 247 octets. | ||
CONFIG_BT_L2CAP_TX_MTU=498 | ||
CONFIG_BT_BUF_ACL_TX_SIZE=502 | ||
CONFIG_BT_BUF_ACL_RX_SIZE=502 | ||
CONFIG_BT_CTLR_DATA_LENGTH_MAX=251 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is DLE needed ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's selected by defining a larger TX and RX size: |
||
CONFIG_BT_CTLR_PHY_2M=y | ||
|
||
CONFIG_BT_CHANNEL_SOUNDING=y | ||
CONFIG_BT_RAS=y | ||
CONFIG_BT_RAS_RRSP=y |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
sample: | ||
description: Bluetooth Low Energy Channel Sounding Reflector with Ranging Service Responder | ||
name: Bluetooth LE Channel Sounding Reflector with RRSP | ||
tests: | ||
sample.bluetooth.channel_sounding_ras.reflector: | ||
sysbuild: true | ||
build_only: true | ||
integration_platforms: | ||
- nrf54l15dk/nrf54l15/cpuapp | ||
platform_allow: | ||
- nrf54l15dk/nrf54l15/cpuapp | ||
tags: bluetooth ci_build sysbuild |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,167 @@ | ||
/* | ||
* Copyright (c) 2024 Nordic Semiconductor ASA | ||
* | ||
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause | ||
*/ | ||
|
||
/** @file | ||
* @brief Channel Sounding Reflector with Ranging Responder sample | ||
*/ | ||
|
||
#include <zephyr/sys/printk.h> | ||
#include <zephyr/types.h> | ||
#include <zephyr/kernel.h> | ||
#include <zephyr/bluetooth/bluetooth.h> | ||
#include <zephyr/bluetooth/conn.h> | ||
#include <zephyr/bluetooth/uuid.h> | ||
#include <zephyr/bluetooth/cs.h> | ||
#include <bluetooth/services/ras.h> | ||
|
||
#include <dk_buttons_and_leds.h> | ||
|
||
#define CON_STATUS_LED DK_LED1 | ||
|
||
static K_SEM_DEFINE(sem_connected, 0, 1); | ||
|
||
static struct bt_conn *connection; | ||
|
||
static const struct bt_data ad[] = { | ||
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)), | ||
BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_RANGING_SERVICE_VAL)), | ||
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1), | ||
}; | ||
|
||
static void pairing_complete(struct bt_conn *conn, bool bonded) | ||
{ | ||
char addr[BT_ADDR_LE_STR_LEN]; | ||
|
||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | ||
|
||
printk("Pairing completed: %s, bonded: %d\n", addr, bonded); | ||
} | ||
|
||
static void pairing_failed(struct bt_conn *conn, enum bt_security_err reason) | ||
{ | ||
char addr[BT_ADDR_LE_STR_LEN]; | ||
|
||
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | ||
|
||
printk("Pairing failed conn: %s, reason %d %s\n", addr, reason, | ||
bt_security_err_to_str(reason)); | ||
} | ||
|
||
static struct bt_conn_auth_info_cb conn_auth_info_callbacks = {.pairing_complete = pairing_complete, | ||
.pairing_failed = pairing_failed}; | ||
|
||
static void connected_cb(struct bt_conn *conn, uint8_t err) | ||
{ | ||
char addr[BT_ADDR_LE_STR_LEN]; | ||
|
||
(void)bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr)); | ||
printk("Connected to %s (err 0x%02X)\n", addr, err); | ||
|
||
if (err) { | ||
bt_conn_unref(conn); | ||
connection = NULL; | ||
} | ||
|
||
connection = bt_conn_ref(conn); | ||
|
||
k_sem_give(&sem_connected); | ||
|
||
dk_set_led_on(CON_STATUS_LED); | ||
} | ||
|
||
static void disconnected_cb(struct bt_conn *conn, uint8_t reason) | ||
{ | ||
printk("Disconnected (reason 0x%02X)\n", reason); | ||
|
||
bt_conn_unref(conn); | ||
connection = NULL; | ||
|
||
dk_set_led_off(CON_STATUS_LED); | ||
} | ||
|
||
static void remote_capabilities_cb(struct bt_conn *conn, struct bt_conn_le_cs_capabilities *params) | ||
{ | ||
ARG_UNUSED(conn); | ||
ARG_UNUSED(params); | ||
printk("CS capability exchange completed.\n"); | ||
} | ||
|
||
static void config_created_cb(struct bt_conn *conn, struct bt_conn_le_cs_config *config) | ||
{ | ||
ARG_UNUSED(conn); | ||
printk("CS config creation complete. ID: %d\n", config->id); | ||
} | ||
|
||
static void security_enabled_cb(struct bt_conn *conn) | ||
{ | ||
ARG_UNUSED(conn); | ||
printk("CS security enabled.\n"); | ||
} | ||
|
||
static void procedure_enabled_cb(struct bt_conn *conn, | ||
struct bt_conn_le_cs_procedure_enable_complete *params) | ||
{ | ||
ARG_UNUSED(conn); | ||
if (params->state == 1) { | ||
printk("CS procedures enabled.\n"); | ||
} else { | ||
printk("CS procedures disabled.\n"); | ||
} | ||
} | ||
|
||
BT_CONN_CB_DEFINE(conn_cb) = { | ||
.connected = connected_cb, | ||
.disconnected = disconnected_cb, | ||
.le_cs_remote_capabilities_available = remote_capabilities_cb, | ||
.le_cs_config_created = config_created_cb, | ||
.le_cs_security_enabled = security_enabled_cb, | ||
.le_cs_procedure_enabled = procedure_enabled_cb, | ||
}; | ||
|
||
int main(void) | ||
{ | ||
int err; | ||
|
||
printk("Starting Channel Sounding Reflector Sample\n"); | ||
|
||
dk_leds_init(); | ||
|
||
err = bt_conn_auth_info_cb_register(&conn_auth_info_callbacks); | ||
if (err) { | ||
printk("Failed to register authorization info callbacks.\n"); | ||
return 0; | ||
} | ||
|
||
err = bt_enable(NULL); | ||
if (err) { | ||
printk("Bluetooth init failed (err %d)\n", err); | ||
return 0; | ||
} | ||
|
||
err = bt_le_adv_start(BT_LE_ADV_CONN, ad, ARRAY_SIZE(ad), NULL, 0); | ||
if (err) { | ||
printk("Advertising failed to start (err %d)\n", err); | ||
return 0; | ||
} | ||
|
||
while (true) { | ||
k_sem_take(&sem_connected, K_FOREVER); | ||
|
||
const struct bt_le_cs_set_default_settings_param default_settings = { | ||
.enable_initiator_role = false, | ||
.enable_reflector_role = true, | ||
.cs_sync_antenna_selection = BT_LE_CS_ANTENNA_SELECTION_OPT_REPETITIVE, | ||
.max_tx_power = BT_HCI_OP_LE_CS_MAX_MAX_TX_POWER, | ||
}; | ||
|
||
err = bt_le_cs_set_default_settings(connection, &default_settings); | ||
if (err) { | ||
printk("Failed to configure default CS settings (err %d)\n", err); | ||
} | ||
} | ||
|
||
return 0; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this name from a BT spec or something? If not, no need to capitalize other than the first word.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Channel Sounding, Ranging Responder and Reflector are names from BT specs where they're capitalized as such, but I can change this if you think it's better.