I have a call to bt_scan_start after a device disconnects.
When the device connects again, I get this error:
ASSERTION FAIL [params->value] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/gatt.c:4060
invalid parameters
I have a call to bt_scan_start after a device disconnects.
When the device connects again, I get this error:
ASSERTION FAIL [params->value] @ WEST_TOPDIR/zephyr/subsys/bluetooth/host/gatt.c:4060
invalid parameters
You should set the field params->value to either BT_GATT_CCC_NOTIFY or BT_GATT_CCC_INDICATE. Right now you are providing a field value that is equal to 0.
Best regards,
Simon
params -> value does seem to be set in the code. Does this look right?
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
*/
#include <zephyr.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/gatt.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt_dm.h>
#include <bluetooth/scan.h>
#include <dk_buttons_and_leds.h>
#include <sys/byteorder.h>
#include <net/nrf_cloud.h>
#include "aggregator.h"
/* Thinghy advertisement UUID */
#define BT_UUID_THINGY \
BT_UUID_DECLARE_128(0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB)
/* Thingy service UUID */
#define BT_UUID_TMS \
BT_UUID_DECLARE_128(0xFB, 0x34, 0x9B, 0X5F, 0x80, 0x00, 0x00, 0x80, \
0x00, 0x10, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00)
// BT_UUID_DECLARE_128(0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x10, 0x00, \
// 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB)
/* Thingy characteristic UUID */
#define BT_UUID_TOC \
BT_UUID_DECLARE_128(0xFB, 0x34, 0x9B, 0X5F, 0x80, 0x00, 0x00, 0x80, \
0x00, 0x10, 0x00, 0x00, 0xF1, 0xFF, 0x00, 0x00)
// BT_UUID_DECLARE_128(0x00, 0x00, 0xFF, 0xF1, 0x00, 0x00, 0x10, 0x00, \
// 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB)
#define DEVICE_NAME "Bluetooth BP"
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
extern void alarm(void);
static void scan_start(void);
static uint8_t on_received(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
if (length == 7) {
printk("Orientation: %x %x %x %x %x %x %x\n", ((uint8_t *)data)[0], ((uint8_t *)data)[1], ((uint8_t *)data)[2], ((uint8_t *)data)[3], ((uint8_t *)data)[4], ((uint8_t *)data)[5], ((uint8_t *)data)[6]);
struct sensor_data in_data;
/*in_data.type = THINGY_ORIENTATION;
in_data.length = 1;
in_data.data[0] = ((uint8_t *)data)[0];
if (aggregator_put(in_data) != 0) {
printk("Was not able to insert Thingy orientation data into aggregator.\n");
}
// If the thingy is upside down, trigger an alarm.
if (((uint8_t *)data)[0] == 3) {
alarm();
}
*/
} else if (length == 8) {
printk("Diastolic: %x\n", ((uint8_t *)data)[4]);
printk("Systolic: %x\n", ((uint8_t *)data)[5]);
printk("Heart Rate: %x\n", ((uint8_t *)data)[6]);
}
return BT_GATT_ITER_CONTINUE;
}
static void discovery_completed(struct bt_gatt_dm *disc, void *ctx)
{
int err;
/* Must be statically allocated */
static struct bt_gatt_subscribe_params param = {
.notify = on_received,
.value = BT_GATT_CCC_NOTIFY,
};
const struct bt_gatt_dm_attr *chrc;
const struct bt_gatt_dm_attr *desc;
chrc = bt_gatt_dm_char_by_uuid(disc, BT_UUID_TOC);
if (!chrc) {
printk("Missing Thingy orientation characteristic\n");
goto release;
}
desc = bt_gatt_dm_desc_by_uuid(disc, chrc, BT_UUID_TOC);
if (!desc) {
printk("Missing Thingy orientation char value descriptor\n");
goto release;
}
param.value_handle = desc->handle,
desc = bt_gatt_dm_desc_by_uuid(disc, chrc, BT_UUID_GATT_CCC);
if (!desc) {
printk("Missing Thingy orientation char CCC descriptor\n");
goto release;
}
param.ccc_handle = desc->handle;
err = bt_gatt_subscribe(bt_gatt_dm_conn_get(disc), ¶m);
if (err) {
printk("Subscribe failed (err %d)\n", err);
}
release:
err = bt_gatt_dm_data_release(disc);
if (err) {
printk("Could not release discovery data, err: %d\n", err);
}
}
static void discovery_service_not_found(struct bt_conn *conn, void *ctx)
{
printk("Thingy orientation service not found!\n");
}
static void discovery_error_found(struct bt_conn *conn, int err, void *ctx)
{
printk("The discovery procedure failed, err %d\n", err);
}
static struct bt_gatt_dm_cb discovery_cb = {
.completed = discovery_completed,
.service_not_found = discovery_service_not_found,
.error_found = discovery_error_found,
};
static void connected(struct bt_conn *conn, uint8_t conn_err)
{
int err;
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (conn_err) {
printk("Failed to connect to %s (%u)\n", addr, conn_err);
return;
}
printk("Connected: %s\n", addr);
err = bt_gatt_dm_start(conn, BT_UUID_TMS, &discovery_cb, NULL);
if (err) {
printk("Could not start service discovery, err %d\n", err);
}
}
static void disconnected(struct bt_conn *conn, uint8_t conn_err)
{
printk("Disconnected\n");
bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
}
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected
};
void scan_filter_match(struct bt_scan_device_info *device_info,
struct bt_scan_filter_match *filter_match,
bool connectable)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr));
printk("Device found: %s\n", addr);
}
void scan_connecting_error(struct bt_scan_device_info *device_info)
{
printk("Connection to peer failed!\n");
}
BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL, scan_connecting_error, NULL);
static void scan_start(void)
{
int err;
struct bt_le_scan_param scan_param = {
.type = BT_LE_SCAN_TYPE_ACTIVE,
.options = BT_LE_SCAN_OPT_NONE, //BT_LE_SCAN_OPT_FILTER_DUPLICATE,
.interval = 0x0010,
.window = 0x0010,
};
struct bt_scan_init_param scan_init = {
.connect_if_match = 1,
.scan_param = &scan_param,
.conn_param = BT_LE_CONN_PARAM_DEFAULT,
};
bt_scan_init(&scan_init);
bt_scan_cb_register(&scan_cb);
err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, &DEVICE_NAME);
if (err) {
printk("Name filter cannot be added (err %d)", err);
printk("%d\n", CONFIG_BT_SCAN_NAME_CNT);
}
err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, false);
if (err) {
printk("Filters cannot be turned on (err %d)", err);
}
err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
if (err) {
printk("Scanning failed to start, err %d\n", err);
}
printk("Scanning...\n");
}
static void ble_ready(int err)
{
printk("Bluetooth ready\n");
bt_conn_cb_register(&conn_callbacks);
scan_start();
}
void ble_init(void)
{
int err;
printk("Initializing Bluetooth..\n");
err = bt_enable(ble_ready);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
}
params -> value does seem to be set in the code. Does this look right?
/*
* Copyright (c) 2018 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-BSD-5-Clause-Nordic
*/
#include <zephyr.h>
#include <bluetooth/bluetooth.h>
#include <bluetooth/gatt.h>
#include <bluetooth/uuid.h>
#include <bluetooth/gatt_dm.h>
#include <bluetooth/scan.h>
#include <dk_buttons_and_leds.h>
#include <sys/byteorder.h>
#include <net/nrf_cloud.h>
#include "aggregator.h"
/* Thinghy advertisement UUID */
#define BT_UUID_THINGY \
BT_UUID_DECLARE_128(0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x10, 0x00, \
0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB)
/* Thingy service UUID */
#define BT_UUID_TMS \
BT_UUID_DECLARE_128(0xFB, 0x34, 0x9B, 0X5F, 0x80, 0x00, 0x00, 0x80, \
0x00, 0x10, 0x00, 0x00, 0xF0, 0xFF, 0x00, 0x00)
// BT_UUID_DECLARE_128(0x00, 0x00, 0xFF, 0xF0, 0x00, 0x00, 0x10, 0x00, \
// 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB)
/* Thingy characteristic UUID */
#define BT_UUID_TOC \
BT_UUID_DECLARE_128(0xFB, 0x34, 0x9B, 0X5F, 0x80, 0x00, 0x00, 0x80, \
0x00, 0x10, 0x00, 0x00, 0xF1, 0xFF, 0x00, 0x00)
// BT_UUID_DECLARE_128(0x00, 0x00, 0xFF, 0xF1, 0x00, 0x00, 0x10, 0x00, \
// 0x80, 0x00, 0x00, 0x80, 0x5F, 0x9B, 0x34, 0xFB)
#define DEVICE_NAME "Bluetooth BP"
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
extern void alarm(void);
static void scan_start(void);
static uint8_t on_received(struct bt_conn *conn,
struct bt_gatt_subscribe_params *params,
const void *data, uint16_t length)
{
if (length == 7) {
printk("Orientation: %x %x %x %x %x %x %x\n", ((uint8_t *)data)[0], ((uint8_t *)data)[1], ((uint8_t *)data)[2], ((uint8_t *)data)[3], ((uint8_t *)data)[4], ((uint8_t *)data)[5], ((uint8_t *)data)[6]);
struct sensor_data in_data;
/*in_data.type = THINGY_ORIENTATION;
in_data.length = 1;
in_data.data[0] = ((uint8_t *)data)[0];
if (aggregator_put(in_data) != 0) {
printk("Was not able to insert Thingy orientation data into aggregator.\n");
}
// If the thingy is upside down, trigger an alarm.
if (((uint8_t *)data)[0] == 3) {
alarm();
}
*/
} else if (length == 8) {
printk("Diastolic: %x\n", ((uint8_t *)data)[4]);
printk("Systolic: %x\n", ((uint8_t *)data)[5]);
printk("Heart Rate: %x\n", ((uint8_t *)data)[6]);
}
return BT_GATT_ITER_CONTINUE;
}
static void discovery_completed(struct bt_gatt_dm *disc, void *ctx)
{
int err;
/* Must be statically allocated */
static struct bt_gatt_subscribe_params param = {
.notify = on_received,
.value = BT_GATT_CCC_NOTIFY,
};
const struct bt_gatt_dm_attr *chrc;
const struct bt_gatt_dm_attr *desc;
chrc = bt_gatt_dm_char_by_uuid(disc, BT_UUID_TOC);
if (!chrc) {
printk("Missing Thingy orientation characteristic\n");
goto release;
}
desc = bt_gatt_dm_desc_by_uuid(disc, chrc, BT_UUID_TOC);
if (!desc) {
printk("Missing Thingy orientation char value descriptor\n");
goto release;
}
param.value_handle = desc->handle,
desc = bt_gatt_dm_desc_by_uuid(disc, chrc, BT_UUID_GATT_CCC);
if (!desc) {
printk("Missing Thingy orientation char CCC descriptor\n");
goto release;
}
param.ccc_handle = desc->handle;
err = bt_gatt_subscribe(bt_gatt_dm_conn_get(disc), ¶m);
if (err) {
printk("Subscribe failed (err %d)\n", err);
}
release:
err = bt_gatt_dm_data_release(disc);
if (err) {
printk("Could not release discovery data, err: %d\n", err);
}
}
static void discovery_service_not_found(struct bt_conn *conn, void *ctx)
{
printk("Thingy orientation service not found!\n");
}
static void discovery_error_found(struct bt_conn *conn, int err, void *ctx)
{
printk("The discovery procedure failed, err %d\n", err);
}
static struct bt_gatt_dm_cb discovery_cb = {
.completed = discovery_completed,
.service_not_found = discovery_service_not_found,
.error_found = discovery_error_found,
};
static void connected(struct bt_conn *conn, uint8_t conn_err)
{
int err;
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (conn_err) {
printk("Failed to connect to %s (%u)\n", addr, conn_err);
return;
}
printk("Connected: %s\n", addr);
err = bt_gatt_dm_start(conn, BT_UUID_TMS, &discovery_cb, NULL);
if (err) {
printk("Could not start service discovery, err %d\n", err);
}
}
static void disconnected(struct bt_conn *conn, uint8_t conn_err)
{
printk("Disconnected\n");
bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
}
static struct bt_conn_cb conn_callbacks = {
.connected = connected,
.disconnected = disconnected
};
void scan_filter_match(struct bt_scan_device_info *device_info,
struct bt_scan_filter_match *filter_match,
bool connectable)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(device_info->recv_info->addr, addr, sizeof(addr));
printk("Device found: %s\n", addr);
}
void scan_connecting_error(struct bt_scan_device_info *device_info)
{
printk("Connection to peer failed!\n");
}
BT_SCAN_CB_INIT(scan_cb, scan_filter_match, NULL, scan_connecting_error, NULL);
static void scan_start(void)
{
int err;
struct bt_le_scan_param scan_param = {
.type = BT_LE_SCAN_TYPE_ACTIVE,
.options = BT_LE_SCAN_OPT_NONE, //BT_LE_SCAN_OPT_FILTER_DUPLICATE,
.interval = 0x0010,
.window = 0x0010,
};
struct bt_scan_init_param scan_init = {
.connect_if_match = 1,
.scan_param = &scan_param,
.conn_param = BT_LE_CONN_PARAM_DEFAULT,
};
bt_scan_init(&scan_init);
bt_scan_cb_register(&scan_cb);
err = bt_scan_filter_add(BT_SCAN_FILTER_TYPE_NAME, &DEVICE_NAME);
if (err) {
printk("Name filter cannot be added (err %d)", err);
printk("%d\n", CONFIG_BT_SCAN_NAME_CNT);
}
err = bt_scan_filter_enable(BT_SCAN_NAME_FILTER, false);
if (err) {
printk("Filters cannot be turned on (err %d)", err);
}
err = bt_scan_start(BT_SCAN_TYPE_SCAN_ACTIVE);
if (err) {
printk("Scanning failed to start, err %d\n", err);
}
printk("Scanning...\n");
}
static void ble_ready(int err)
{
printk("Bluetooth ready\n");
bt_conn_cb_register(&conn_callbacks);
scan_start();
}
void ble_init(void)
{
int err;
printk("Initializing Bluetooth..\n");
err = bt_enable(ble_ready);
if (err) {
printk("Bluetooth init failed (err %d)\n", err);
return;
}
}
I'm not exactly sure what's causing this error, but I would recommend you to look at the central_uart example and to see how it's done there: https://github.com/nrfconnect/sdk-nrf/blob/v1.4.0/samples/bluetooth/central_uart/src/main.c#L371-L393
I tested the central_uart example with the peripheral_uart sample and triggered the disconnect-->scan start from the central by resetting the peripheral. Everything worked fine, the scanning started again, the device connected and I was able to send commands forth and back.
Best regards,
Simon