samples: Bluetooth: Add ISO Broadcaster sample
Add an application that initializes Bluetooth Subsystem, creates an Extended Advertising set, starts Periodic Advertising and creates BIG to demonstrate ISO Broadcaster functionality. Signed-off-by: Vinayak Kariappa Chettimada <vich@nordicsemi.no> Signed-off-by: Emil Gydesen <emil.gydesen@nordicsemi.no>
This commit is contained in:
parent
fb1ae4d155
commit
46700dfc49
5 changed files with 233 additions and 0 deletions
7
samples/bluetooth/iso_broadcast/CMakeLists.txt
Normal file
7
samples/bluetooth/iso_broadcast/CMakeLists.txt
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
cmake_minimum_required(VERSION 3.13.1)
|
||||||
|
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
|
||||||
|
project(iso_broadcast)
|
||||||
|
|
||||||
|
target_sources(app PRIVATE src/main.c)
|
27
samples/bluetooth/iso_broadcast/README.rst
Normal file
27
samples/bluetooth/iso_broadcast/README.rst
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
.. _bluetooth-isochronous-broadcaster-sample:
|
||||||
|
|
||||||
|
Bluetooth: Isochronous Broadcaster
|
||||||
|
##################################
|
||||||
|
|
||||||
|
Overview
|
||||||
|
********
|
||||||
|
|
||||||
|
A simple application demonstrating the Bluetooth Low Energy Isochronous
|
||||||
|
Broadcaster functionality.
|
||||||
|
|
||||||
|
Requirements
|
||||||
|
************
|
||||||
|
|
||||||
|
* A board with Bluetooth Low Energy support
|
||||||
|
|
||||||
|
Building and Running
|
||||||
|
********************
|
||||||
|
|
||||||
|
This sample can be found under :zephyr_file:`samples/bluetooth/iso_broadcast` in
|
||||||
|
the Zephyr tree.
|
||||||
|
|
||||||
|
Use the sample found under :zephyr_file:`samples/bluetooth/iso_receive` in the
|
||||||
|
Zephyr tree that will scan, establish a periodic advertising synchronization,
|
||||||
|
generate BIGInfo reports and synchronize to BIG events from this sample.
|
||||||
|
|
||||||
|
See :ref:`bluetooth samples section <bluetooth-samples>` for details.
|
11
samples/bluetooth/iso_broadcast/prj.conf
Normal file
11
samples/bluetooth/iso_broadcast/prj.conf
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
CONFIG_BT=y
|
||||||
|
CONFIG_BT_EXT_ADV=y
|
||||||
|
CONFIG_BT_PER_ADV=y
|
||||||
|
CONFIG_BT_ISO=y
|
||||||
|
CONFIG_BT_ISO_BROADCAST=y
|
||||||
|
CONFIG_BT_DEBUG_LOG=y
|
||||||
|
CONFIG_BT_DEVICE_NAME="Test ISO Broadcaster"
|
||||||
|
|
||||||
|
# Temporary, enable the following to meet BT_ISO dependencies
|
||||||
|
CONFIG_BT_OBSERVER=y
|
||||||
|
CONFIG_BT_PERIPHERAL=y
|
7
samples/bluetooth/iso_broadcast/sample.yaml
Normal file
7
samples/bluetooth/iso_broadcast/sample.yaml
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
sample:
|
||||||
|
name: Bluetooth ISO Broadcaster
|
||||||
|
tests:
|
||||||
|
sample.bluetooth.iso_broadcast:
|
||||||
|
harness: bluetooth
|
||||||
|
platform_allow: qemu_cortex_m3 qemu_x86 nrf52_bsim nrf52dk_nrf52832
|
||||||
|
tags: bluetooth
|
181
samples/bluetooth/iso_broadcast/src/main.c
Normal file
181
samples/bluetooth/iso_broadcast/src/main.c
Normal file
|
@ -0,0 +1,181 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2021 Nordic Semiconductor ASA
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <bluetooth/bluetooth.h>
|
||||||
|
#include <bluetooth/iso.h>
|
||||||
|
#include <sys/byteorder.h>
|
||||||
|
|
||||||
|
#define BIG_TERMINATE_TIMEOUT 60 /* seconds */
|
||||||
|
|
||||||
|
#define BIS_ISO_CHAN_COUNT 1
|
||||||
|
#define ISO_MTU (BT_ISO_CHAN_SEND_RESERVE + sizeof(uint32_t))
|
||||||
|
NET_BUF_POOL_FIXED_DEFINE(bis_tx_pool, BIS_ISO_CHAN_COUNT, ISO_MTU, NULL);
|
||||||
|
|
||||||
|
static K_SEM_DEFINE(sem_big_cmplt, 0, 1);
|
||||||
|
static K_SEM_DEFINE(sem_big_term, 0, 1);
|
||||||
|
|
||||||
|
static void iso_connected(struct bt_iso_chan *chan)
|
||||||
|
{
|
||||||
|
printk("ISO Channel %p connected\n", chan);
|
||||||
|
k_sem_give(&sem_big_cmplt);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void iso_disconnected(struct bt_iso_chan *chan, uint8_t reason)
|
||||||
|
{
|
||||||
|
printk("ISO Channel %p disconnected with reason 0x%02x\n",
|
||||||
|
chan, reason);
|
||||||
|
k_sem_give(&sem_big_term);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct bt_iso_chan_ops iso_ops = {
|
||||||
|
.connected = iso_connected,
|
||||||
|
.disconnected = iso_disconnected,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_iso_chan_io_qos iso_tx_qos = {
|
||||||
|
.interval = 10000, /* in microseconds */
|
||||||
|
.latency = 10, /* milliseconds */
|
||||||
|
.sdu = 502, /* bytes */
|
||||||
|
.rtn = 2,
|
||||||
|
.phy = BT_GAP_LE_PHY_2M,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_iso_chan_qos bis_iso_qos = {
|
||||||
|
.tx = &iso_tx_qos,
|
||||||
|
.packing = 0, /* 0 - sequential, 1 - interleaved */
|
||||||
|
.framing = 0, /* 0 - unframed, 1 - framed */
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_iso_chan bis_iso_chan = {
|
||||||
|
.ops = &iso_ops,
|
||||||
|
.qos = &bis_iso_qos,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct bt_iso_chan *bis[BIS_ISO_CHAN_COUNT] = { &bis_iso_chan };
|
||||||
|
|
||||||
|
static struct bt_iso_big_create_param big_create_param = {
|
||||||
|
.num_bis = BIS_ISO_CHAN_COUNT,
|
||||||
|
.bis_channels = bis,
|
||||||
|
};
|
||||||
|
|
||||||
|
void main(void)
|
||||||
|
{
|
||||||
|
struct bt_le_ext_adv *adv;
|
||||||
|
struct bt_iso_big *big;
|
||||||
|
int err;
|
||||||
|
uint32_t iso_send_count = 0;
|
||||||
|
uint8_t iso_data[sizeof(iso_send_count)] = { 0 };
|
||||||
|
struct net_buf *buf;
|
||||||
|
|
||||||
|
printk("Starting ISO Broadcast Demo\n");
|
||||||
|
|
||||||
|
/* Initialize the Bluetooth Subsystem */
|
||||||
|
err = bt_enable(NULL);
|
||||||
|
if (err) {
|
||||||
|
printk("Bluetooth init failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a non-connectable non-scannable advertising set */
|
||||||
|
err = bt_le_ext_adv_create(BT_LE_EXT_ADV_NCONN_NAME, NULL, &adv);
|
||||||
|
if (err) {
|
||||||
|
printk("Failed to create advertising set (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Set periodic advertising parameters */
|
||||||
|
err = bt_le_per_adv_set_param(adv, BT_LE_PER_ADV_DEFAULT);
|
||||||
|
if (err) {
|
||||||
|
printk("Failed to set periodic advertising parameters"
|
||||||
|
" (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Enable Periodic Advertising */
|
||||||
|
err = bt_le_per_adv_start(adv);
|
||||||
|
if (err) {
|
||||||
|
printk("Failed to enable periodic advertising (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Start extended advertising */
|
||||||
|
err = bt_le_ext_adv_start(adv, BT_LE_EXT_ADV_START_DEFAULT);
|
||||||
|
if (err) {
|
||||||
|
printk("Failed to start extended advertising (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create BIG */
|
||||||
|
err = bt_iso_big_create(adv, &big_create_param, &big);
|
||||||
|
if (err) {
|
||||||
|
printk("Failed to create BIG (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
printk("Waiting for BIG complete...");
|
||||||
|
err = k_sem_take(&sem_big_cmplt, K_FOREVER);
|
||||||
|
if (err) {
|
||||||
|
printk("failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("done.\n");
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
static uint8_t timeout = BIG_TERMINATE_TIMEOUT;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
k_sleep(K_SECONDS(1));
|
||||||
|
|
||||||
|
buf = net_buf_alloc(&bis_tx_pool, K_FOREVER);
|
||||||
|
net_buf_reserve(buf, BT_ISO_CHAN_SEND_RESERVE);
|
||||||
|
sys_put_le32(++iso_send_count, iso_data);
|
||||||
|
net_buf_add_mem(buf, iso_data, sizeof(iso_data));
|
||||||
|
ret = bt_iso_chan_send(&bis_iso_chan, buf);
|
||||||
|
if (ret < 0) {
|
||||||
|
printk("Unable to broadcast data: %d", ret);
|
||||||
|
net_buf_unref(buf);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("Sending value %u\n", iso_send_count);
|
||||||
|
|
||||||
|
timeout--;
|
||||||
|
if (!timeout) {
|
||||||
|
timeout = BIG_TERMINATE_TIMEOUT;
|
||||||
|
|
||||||
|
printk("BIG Terminate...");
|
||||||
|
err = bt_iso_big_terminate(big);
|
||||||
|
if (err) {
|
||||||
|
printk("failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("done.\n");
|
||||||
|
|
||||||
|
printk("Waiting for BIG terminate complete...");
|
||||||
|
err = k_sem_take(&sem_big_term, K_FOREVER);
|
||||||
|
if (err) {
|
||||||
|
printk("failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("done.\n");
|
||||||
|
|
||||||
|
printk("Create BIG...");
|
||||||
|
err = bt_iso_big_create(adv, &big_create_param, &big);
|
||||||
|
if (err) {
|
||||||
|
printk("failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("done.\n");
|
||||||
|
|
||||||
|
printk("Waiting for BIG complete...");
|
||||||
|
err = k_sem_take(&sem_big_cmplt, K_FOREVER);
|
||||||
|
if (err) {
|
||||||
|
printk("failed (err %d)\n", err);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printk("done.\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue