Skip to content
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: multiple central connections to peripherals #30735

Merged
merged 5 commits into from
Jul 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions samples/bluetooth/central_multilink/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(central_multilink)

target_sources(app PRIVATE
src/main.c
src/central_multilink.c
)

zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth)
24 changes: 24 additions & 0 deletions samples/bluetooth/central_multilink/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. _bluetooth_central_multilink:

Bluetooth: Central
##################

Overview
********

Application demonstrating BLE Central role functionality by scanning for other
BLE devices and establishing connection to upto 62 peripherals with a strong
enough signal.

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

* BlueZ running on the host, or
* A board with BLE support

Building and Running
********************
This sample can be found under :zephyr_file:`samples/bluetooth/central_multilink`
in the Zephyr tree.

See :ref:`bluetooth samples section <bluetooth-samples>` for details.
11 changes: 11 additions & 0 deletions samples/bluetooth/central_multilink/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
CONFIG_BT=y
CONFIG_BT_CENTRAL=y
CONFIG_BT_AUTO_PHY_UPDATE=n
CONFIG_BT_PRIVACY=y

CONFIG_BT_MAX_CONN=62

# CONFIG_BT_GATT_CLIENT=y

# CONFIG_BT_SMP=y
# CONFIG_BT_MAX_PAIRED=62
7 changes: 7 additions & 0 deletions samples/bluetooth/central_multilink/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sample:
name: Bluetooth Central Multilink
tests:
sample.bluetooth.central.multilink:
harness: bluetooth
platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840
tags: bluetooth
264 changes: 264 additions & 0 deletions samples/bluetooth/central_multilink/src/central_multilink.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
/* main.c - Application main entry point */

/*
* Copyright (c) 2021 Nordic Semiconductor ASA
* Copyright (c) 2015-2016 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/

#include <zephyr/types.h>
#include <stddef.h>
#include <errno.h>
#include <zephyr.h>
#include <sys/printk.h>

#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/conn.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt.h>
#include <sys/byteorder.h>

#define SCAN_INTERVAL 0x0140 /* 200 ms */
#define SCAN_WINDOW 0x0030 /* 30 ms */
#define INIT_INTERVAL 0x0010 /* 10 ms */
#define INIT_WINDOW 0x0010 /* 10 ms */
#define CONN_INTERVAL 0x00A0 /* 200 ms */
#define CONN_LATENCY 0
#define CONN_TIMEOUT MIN(MAX((CONN_INTERVAL * 125 * \
MAX(CONFIG_BT_MAX_CONN, 6) / 1000), 10), 3200)

static void start_scan(void);

static struct bt_conn *conn_connecting;
static uint8_t volatile conn_count;

static void device_found(const bt_addr_le_t *addr, int8_t rssi, uint8_t type,
struct net_buf_simple *ad)
{
struct bt_conn_le_create_param create_param = {
.options = BT_CONN_LE_OPT_NONE,
.interval = INIT_INTERVAL,
.window = INIT_WINDOW,
.interval_coded = 0,
.window_coded = 0,
.timeout = 0,
};
struct bt_le_conn_param conn_param = {
.interval_min = CONN_INTERVAL,
.interval_max = CONN_INTERVAL,
.latency = CONN_LATENCY,
.timeout = CONN_TIMEOUT,
};
char addr_str[BT_ADDR_LE_STR_LEN];
int err;

if (conn_connecting) {
return;
}

/* 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_addr_le_to_str(addr, addr_str, sizeof(addr_str));
printk("Device found: %s (RSSI %d)\n", addr_str, rssi);

/* connect only to devices in close proximity */
if (rssi < -35) {
return;
}

if (bt_le_scan_stop()) {
return;
}

err = bt_conn_le_create(addr, &create_param, &conn_param,
&conn_connecting);
if (err) {
printk("Create conn to %s failed (%d)\n", addr_str, err);
start_scan();
}
}

static void start_scan(void)
{
struct bt_le_scan_param scan_param = {
.type = BT_HCI_LE_SCAN_PASSIVE,
.options = BT_LE_SCAN_OPT_NONE,
.interval = SCAN_INTERVAL,
.window = SCAN_WINDOW,
};
int err;

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

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

#if defined(CONFIG_BT_GATT_CLIENT)
static void mtu_exchange_cb(struct bt_conn *conn, uint8_t err,
struct bt_gatt_exchange_params *params)
{
printk("MTU exchange %u %s (%u)\n", bt_conn_index(conn),
err == 0U ? "successful" : "failed", bt_gatt_get_mtu(conn));
}

static struct bt_gatt_exchange_params mtu_exchange_params[CONFIG_BT_MAX_CONN];

static int mtu_exchange(struct bt_conn *conn)
{
uint8_t conn_index;
int err;

conn_index = bt_conn_index(conn);

printk("MTU (%u): %u\n", conn_index, bt_gatt_get_mtu(conn));

mtu_exchange_params[conn_index].func = mtu_exchange_cb;

err = bt_gatt_exchange_mtu(conn, &mtu_exchange_params[conn_index]);
if (err) {
printk("MTU exchange failed (err %d)", err);
} else {
printk("Exchange pending...");
}

return err;
}
#endif /* CONFIG_BT_GATT_CLIENT */

static void connected(struct bt_conn *conn, uint8_t reason)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

if (reason) {
printk("Failed to connect to %s (%u)\n", addr, reason);

bt_conn_unref(conn_connecting);
conn_connecting = NULL;

start_scan();
return;
}

conn_connecting = NULL;

conn_count++;
if (conn_count < CONFIG_BT_MAX_CONN) {
start_scan();
}

printk("Connected (%u): %s\n", conn_count, addr);

#if defined(CONFIG_BT_SMP)
int err = bt_conn_set_security(conn, BT_SECURITY_L2);

if (err) {
printk("Failed to set security (%d).\n", err);
}
#endif

#if defined(CONFIG_BT_GATT_CLIENT)
mtu_exchange(conn);
#endif
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("Disconnected: %s (reason 0x%02x)\n", addr, reason);

bt_conn_unref(conn);

if (conn_count == CONFIG_BT_MAX_CONN) {
start_scan();
}
conn_count--;
}

static bool le_param_req(struct bt_conn *conn, struct bt_le_conn_param *param)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("LE conn param req: %s int (0x%04x, 0x%04x) lat %d to %d\n",
addr, param->interval_min, param->interval_max, param->latency,
param->timeout);

return true;
}

static void le_param_updated(struct bt_conn *conn, uint16_t interval,
uint16_t latency, uint16_t timeout)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

printk("LE conn param updated: %s int 0x%04x lat %d to %d\n",
addr, interval, latency, timeout);
}

#if defined(CONFIG_BT_SMP)
static void security_changed(struct bt_conn *conn, bt_security_t level,
enum bt_security_err err)
{
char addr[BT_ADDR_LE_STR_LEN];

bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

if (!err) {
printk("Security changed: %s level %u\n", addr, level);
} else {
printk("Security failed: %s level %u err %d\n", addr, level,
err);
}
}
#endif

static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected,
.le_param_req = le_param_req,
.le_param_updated = le_param_updated,
#if defined(CONFIG_BT_SMP)
.security_changed = security_changed,
#endif
};

int init_central(void)
{
int err;

err = bt_enable(NULL);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return err;
}

printk("Bluetooth initialized\n");

bt_conn_cb_register(&conn_callbacks);

start_scan();

while (conn_count < CONFIG_BT_MAX_CONN) {
k_sleep(K_SECONDS(1));
}

return 0;
}
14 changes: 14 additions & 0 deletions samples/bluetooth/central_multilink/src/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* main.c - Application main entry point */

/*
* Copyright (c) 2021 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/

int init_central(void);

void main(void)
{
(void)init_central();
}
12 changes: 12 additions & 0 deletions samples/bluetooth/peripheral_identity/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# SPDX-License-Identifier: Apache-2.0

cmake_minimum_required(VERSION 3.13.1)
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
project(peripheral_identity)

target_sources(app PRIVATE
src/main.c
src/peripheral_identity.c
)

zephyr_library_include_directories(${ZEPHYR_BASE}/samples/bluetooth)
24 changes: 24 additions & 0 deletions samples/bluetooth/peripheral_identity/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.. _peripheral_identity:

Bluetooth: Peripheral Identity
##############################

Overview
********

This sample demonstrates use of multiple identity and the ability to be
connected to from multiple central devices.

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

* BlueZ running on the host, or
* A board with BLE support

Building and Running
********************

This sample can be found under :zephyr_file:`samples/bluetooth/peripheral_identity`
in the Zephyr tree.

See :ref:`bluetooth samples section <bluetooth-samples>` for details.
13 changes: 13 additions & 0 deletions samples/bluetooth/peripheral_identity/prj.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_AUTO_PHY_UPDATE=n
CONFIG_BT_PRIVACY=y

CONFIG_BT_DEVICE_NAME="Zephyr Peripheral"
CONFIG_BT_GAP_AUTO_UPDATE_CONN_PARAMS=n

CONFIG_BT_MAX_CONN=62
CONFIG_BT_ID_MAX=62

# CONFIG_BT_SMP=y
# CONFIG_BT_MAX_PAIRED=62
8 changes: 8 additions & 0 deletions samples/bluetooth/peripheral_identity/sample.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
sample:
description: TBD
name: TBD
tests:
sample.bluetooth.peripheral_identity:
harness: bluetooth
platform_allow: qemu_cortex_m3 qemu_x86 nrf52840dk_nrf52840
tags: bluetooth
Loading