Skip to content

Commit

Permalink
Bluetooth: Samples: Add Connection event prepare callback sample
Browse files Browse the repository at this point in the history
The sample demonstrates how the connection event prepare callback
feature can used to minimize latency between data sampling
and on air transmission.

Signed-off-by: Rubin Gerritsen <[email protected]>
  • Loading branch information
rugeGerritsen committed Jun 21, 2024
1 parent d46d6cf commit 8d4a4f3
Show file tree
Hide file tree
Showing 10 changed files with 535 additions and 4 deletions.
5 changes: 1 addition & 4 deletions include/bluetooth/conn_evt_prepare_cb.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ typedef void (*bt_conn_evt_prepare_cb_t)(const struct bt_conn *conn,
*
* @param[in] conn The connection context.
* @param[in] cb The callback to be used.
* @param[in] user_data User data which will be provided in the callback.
* @param[in] prepare_distance_us The distance in time from the start of the
* callback to the start of the connection event.
*/
Expand All @@ -54,10 +55,6 @@ int bt_conn_evt_prepare_cb_set(const struct bt_conn *conn,
void *user_data,
uint32_t prepare_distance_us);

/**
* @}
*/

#ifdef __cplusplus
}
#endif
Expand Down
17 changes: 17 additions & 0 deletions samples/bluetooth/conn_evt_prepare_cb/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#
# Copyright (c) 2024 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

cmake_minimum_required(VERSION 3.20.0)

find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(NONE)

zephyr_sources_ifdef(CONFIG_BT_CENTRAL src/central.c)
zephyr_sources_ifdef(CONFIG_BT_PERIPHERAL src/peripheral.c)

target_sources(app PRIVATE
src/main.c
)
129 changes: 129 additions & 0 deletions samples/bluetooth/conn_evt_prepare_cb/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
.. _ble_conn_evt_prepare_cb:

Bluetooth: Connection event prepare callback
############################################

.. contents::
:local:
:depth: 2

The Connection event prepare callback sample demonstrates how to use the connection event prepare callback feature.
It uses the :ref:`latency_readme` and the :ref:`latency_client_readme` to showcase how this feature can be used to minimize the time between data sampling and data transmission.

Requirements
************

The sample supports the following development kits:

.. table-from-sample-yaml::

You can use any two of the development kits mentioned above and mix different development kits.

Additionally, the sample requires a connection to a computer with a serial terminal for each of the development kits.

Note that the feature involves triggering a (D)PPI task directly from the SoftDevice Controller link layer, and therefore it is expected that the application and SoftDevice Controller are running on the same core.

Building and running
********************
.. |sample path| replace:: :file:`samples/bluetooth/llpm`

.. include:: /includes/build_and_run.txt

Testing
=======

After programming the sample to both development kits, test it by performing the following steps:

1. Connect to both kits with a terminal emulator (for example, `nRF Connect Serial Terminal`_).
See :ref:`test_and_optimize` for the required settings and steps.
#. Reset both kits.
#. In one of the terminal emulators, type "c" to start the application on the connected board in the central role.
#. In the other terminal emulator, type "p" to start the application in the peripheral role.
#. Observe that latency measurements are printed in the terminals.

Sample output
=============

The result should look similar to the following output.

- For the central::

Starting connection event prepare sample.
I: SoftDevice Controller build revision:
I: 27 1c 81 55 59 3a 61 a4 |'..UY:a.
I: 6b c4 55 46 f7 c5 a4 dc |k.UF....
I: d3 69 67 45 |.igE
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF52x (0x0002)
I: Firmware: Standard Bluetooth controller (0x00) Version 39.33052 Build 1631213909
I: Identity: CF:99:32:A5:4B:11 (random)
I: HCI: version 5.4 (0x0d) revision 0x11de, manufacturer 0x0059
I: LMP: version 5.4 (0x0d) subver 0x11de
Choose device role - type c (central) or p (peripheral):
Central. Starting scanning
Scanning started
Device found: FA:BB:79:57:D6:45 (random) (RSSI -33)
Connected: FA:BB:79:57:D6:45 (random)
Service discovery completed
Latency: 2764 us, round trip latency: 52764 us
Latency: 2734 us, round trip latency: 52734 us
Latency: 2734 us, round trip latency: 52734 us
Latency: 2764 us, round trip latency: 52764 us
Latency: 2764 us, round trip latency: 52764 us

- For the peripheral::

Starting connection event prepare sample.
I: SoftDevice Controller build revision:
I: 27 1c 81 55 59 3a 61 a4 |'..UY:a.
I: 6b c4 55 46 f7 c5 a4 dc |k.UF....
I: d3 69 67 45 |.igE
I: HW Platform: Nordic Semiconductor (0x0002)
I: HW Variant: nRF52x (0x0002)
I: Firmware: Standard Bluetooth controller (0x00) Version 39.33052 Build 1631213909
I: Identity: FA:BB:79:57:D6:45 (random)
I: HCI: version 5.4 (0x0d) revision 0x11de, manufacturer 0x0059
I: LMP: version 5.4 (0x0d) subver 0x11de
Choose device role - type c (central) or p (peripheral):
Peripheral. Starting advertising
Advertising started
Connected: CF:99:32:A5:4B:11 (random)
Service discovery completed
Latency: 2612 us, round trip latency: 52612 us
Latency: 2612 us, round trip latency: 52612 us
Latency: 2642 us, round trip latency: 52642 us
Latency: 2642 us, round trip latency: 52642 us
Latency: 2642 us, round trip latency: 52642 us
Latency: 2612 us, round trip latency: 52612 us
Latency: 2612 us, round trip latency: 52612 us
Latency: 2642 us, round trip latency: 52642 us

Dependencies
*************

This sample uses the following |NCS| libraries:

* :ref:`latency_readme`
* :ref:`latency_client_readme`

This sample uses the following `sdk-nrfxlib`_ libraries:

* :ref:`nrfxlib:softdevice_controller`

In addition, it uses the following Zephyr libraries:

* :file:`include/console.h`
* :ref:`zephyr:kernel_api`:

* :file:`include/kernel.h`

* :file:`include/sys/printk.h`
* :file:`include/zephyr/types.h`
* :ref:`zephyr:bluetooth_api`:

* :file:`include/bluetooth/bluetooth.h`
* :file:`include/bluetooth/conn.h`
* :file:`include/bluetooth/gatt.h`
* :file:`include/bluetooth/scan.h`
* :file:`include/bluetooth/gatt_dm.h`
* :file:`include/bluetooth/conn_evt_prepare_cb.h`
25 changes: 25 additions & 0 deletions samples/bluetooth/conn_evt_prepare_cb/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#
# Copyright (c) 2019 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

CONFIG_NCS_SAMPLES_DEFAULTS=y

CONFIG_BT_DEVICE_NAME="Conn event Notification"
CONFIG_BT=y
CONFIG_BT_CONN_EVT_PREPARE_CB=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_MAX_CONN=2
CONFIG_BT_CTLR_SDC_PERIPHERAL_COUNT=1
CONFIG_BT_LATENCY=y
CONFIG_BT_LATENCY_CLIENT=y
CONFIG_BT_GATT_DM=y

CONFIG_CONSOLE=y
CONFIG_CONSOLE_SUBSYS=y
CONFIG_CONSOLE_HANDLER=y
CONFIG_CONSOLE_GETCHAR=y

CONFIG_HEAP_MEM_POOL_SIZE=2048
13 changes: 13 additions & 0 deletions samples/bluetooth/conn_evt_prepare_cb/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
sample:
description: Connection event prepare callback sample
name: Connection event prepare callback
tests:
sample.bluetooth.conn_evt_prepare_cb:
sysbuild: true
build_only: true
integration_platforms:
- nrf52dk/nrf52832
- nrf52840dk/nrf52840
- nrf5340dk/nrf5340/cpunet
platform_allow: nrf52dk/nrf52832 nrf52840dk/nrf52840 nrf5340dk/nrf5340/cpunet
tags: bluetooth ci_build sysbuild
78 changes: 78 additions & 0 deletions samples/bluetooth/conn_evt_prepare_cb/src/central.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/

#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/conn.h>

#define ADV_NAME_STR_MAX_LEN (sizeof(CONFIG_BT_DEVICE_NAME))

void scan_start(void);

static bool adv_data_parse_cb(struct bt_data *data, void *user_data)
{
char *name = user_data;
uint8_t len;

switch (data->type) {
case BT_DATA_NAME_SHORTENED:
case BT_DATA_NAME_COMPLETE:
len = MIN(data->data_len, ADV_NAME_STR_MAX_LEN - 1);
memcpy(name, data->data, len);
name[len] = '\0';
return false;
default:
return true;
}
}

static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
struct net_buf_simple *ad)
{
char name_str[ADV_NAME_STR_MAX_LEN] = {0};
char addr_str[BT_ADDR_LE_STR_LEN];
int err;

/* We're only interested in connectable events */
if (type != BT_GAP_ADV_TYPE_ADV_IND &&
type != BT_GAP_ADV_TYPE_ADV_DIRECT_IND) {
return;
}

bt_data_parse(ad, adv_data_parse_cb, name_str);

if (strncmp(name_str, CONFIG_BT_DEVICE_NAME, ADV_NAME_STR_MAX_LEN) != 0) {
return;
}

bt_addr_le_to_str(addr, addr_str, sizeof(addr_str));
printk("Device found: %s (RSSI %d)\n", addr_str, rssi);

if (bt_le_scan_stop()) {
return;
}

struct bt_conn *unused_conn;

err = bt_conn_le_create(addr, BT_CONN_LE_CREATE_CONN,
BT_LE_CONN_PARAM_DEFAULT, &unused_conn);
if (err) {
printk("Create conn to %s failed (%d)\n", addr_str, err);
scan_start();
}
}

void scan_start(void)
{
int err;

err = bt_le_scan_start(BT_LE_SCAN_ACTIVE, device_found);
if (err) {
printk("Scanning failed to start (err %d)\n", err);
return;
}

printk("Scanning started\n");
}
Loading

0 comments on commit 8d4a4f3

Please sign in to comment.