Skip to content

samples: bluetooth: fix no ble advertising after disconnecting #90441

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

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
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
170 changes: 78 additions & 92 deletions samples/bluetooth/peripheral/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -27,38 +27,35 @@
#include <zephyr/bluetooth/services/ias.h>

/* Custom Service Variables */
#define BT_UUID_CUSTOM_SERVICE_VAL \
#define BT_UUID_CUSTOM_SERVICE_VAL \
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef0)

static const struct bt_uuid_128 vnd_uuid = BT_UUID_INIT_128(
BT_UUID_CUSTOM_SERVICE_VAL);
static const struct bt_uuid_128 vnd_uuid = BT_UUID_INIT_128(BT_UUID_CUSTOM_SERVICE_VAL);

static const struct bt_uuid_128 vnd_enc_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1));
static const struct bt_uuid_128 vnd_enc_uuid =
BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef1));

static const struct bt_uuid_128 vnd_auth_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef2));
static const struct bt_uuid_128 vnd_auth_uuid =
BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef2));

#define VND_MAX_LEN 20
#define VND_MAX_LEN 20
#define BT_HR_HEARTRATE_DEFAULT_MIN 90U
#define BT_HR_HEARTRATE_DEFAULT_MAX 160U

static uint8_t vnd_value[VND_MAX_LEN + 1] = { 'V', 'e', 'n', 'd', 'o', 'r'};
static uint8_t vnd_auth_value[VND_MAX_LEN + 1] = { 'V', 'e', 'n', 'd', 'o', 'r'};
static uint8_t vnd_wwr_value[VND_MAX_LEN + 1] = { 'V', 'e', 'n', 'd', 'o', 'r' };
static uint8_t vnd_value[VND_MAX_LEN + 1] = {'V', 'e', 'n', 'd', 'o', 'r'};
static uint8_t vnd_auth_value[VND_MAX_LEN + 1] = {'V', 'e', 'n', 'd', 'o', 'r'};
static uint8_t vnd_wwr_value[VND_MAX_LEN + 1] = {'V', 'e', 'n', 'd', 'o', 'r'};

static ssize_t read_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
static ssize_t read_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
uint16_t len, uint16_t offset)
{
const char *value = attr->user_data;

return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
strlen(value));
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, strlen(value));
}

static ssize_t write_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags)
static ssize_t write_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
uint16_t len, uint16_t offset, uint8_t flags)
{
uint8_t *value = attr->user_data;

Expand All @@ -81,8 +78,7 @@
simulate_vnd = (value == BT_GATT_CCC_INDICATE) ? 1 : 0;
}

static void indicate_cb(struct bt_conn *conn,
struct bt_gatt_indicate_params *params, uint8_t err)
static void indicate_cb(struct bt_conn *conn, struct bt_gatt_indicate_params *params, uint8_t err)
{
printk("Indication %s\n", err != 0U ? "fail" : "success");
}
Expand All @@ -95,17 +91,14 @@

#define VND_LONG_MAX_LEN 74
static uint8_t vnd_long_value[VND_LONG_MAX_LEN + 1] = {
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '1',
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '2',
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '3',
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '4',
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '5',
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '6',
'.', ' ' };

static ssize_t write_long_vnd(struct bt_conn *conn,
const struct bt_gatt_attr *attr, const void *buf,
uint16_t len, uint16_t offset, uint8_t flags)
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '1', 'V', 'e', 'n',
'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '2', 'V', 'e', 'n', 'd', 'o', 'r',
' ', 'd', 'a', 't', 'a', '3', 'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a',
't', 'a', '4', 'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '5',
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '6', '.', ' '};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '6', '.', ' '};
'V', 'e', 'n', 'd', 'o', 'r', ' ', 'd', 'a', 't', 'a', '6', '.', ' ', };

It helps with clang-format if you always have a final ,


static ssize_t write_long_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
uint8_t *value = attr->user_data;

Expand All @@ -123,27 +116,25 @@
return len;
}

static const struct bt_uuid_128 vnd_long_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef3));
static const struct bt_uuid_128 vnd_long_uuid =
BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef3));

static struct bt_gatt_cep vnd_long_cep = {
.properties = BT_GATT_CEP_RELIABLE_WRITE,
};

static int signed_value;

static ssize_t read_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr,
void *buf, uint16_t len, uint16_t offset)
static ssize_t read_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, void *buf,
uint16_t len, uint16_t offset)
{
const char *value = attr->user_data;

return bt_gatt_attr_read(conn, attr, buf, len, offset, value,
sizeof(signed_value));
return bt_gatt_attr_read(conn, attr, buf, len, offset, value, sizeof(signed_value));
}

static ssize_t write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags)
static ssize_t write_signed(struct bt_conn *conn, const struct bt_gatt_attr *attr, const void *buf,
uint16_t len, uint16_t offset, uint8_t flags)
{
uint8_t *value = attr->user_data;

Expand All @@ -156,16 +147,14 @@
return len;
}

static const struct bt_uuid_128 vnd_signed_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x13345678, 0x1234, 0x5678, 0x1334, 0x56789abcdef3));
static const struct bt_uuid_128 vnd_signed_uuid =
BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x13345678, 0x1234, 0x5678, 0x1334, 0x56789abcdef3));

static const struct bt_uuid_128 vnd_write_cmd_uuid = BT_UUID_INIT_128(
BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef4));
static const struct bt_uuid_128 vnd_write_cmd_uuid =
BT_UUID_INIT_128(BT_UUID_128_ENCODE(0x12345678, 0x1234, 0x5678, 0x1234, 0x56789abcdef4));

static ssize_t write_without_rsp_vnd(struct bt_conn *conn,
const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset,
uint8_t flags)
static ssize_t write_without_rsp_vnd(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags)
{
uint8_t *value = attr->user_data;

Expand All @@ -187,73 +176,70 @@
}

/* Vendor Primary Service Declaration */
BT_GATT_SERVICE_DEFINE(vnd_svc,
BT_GATT_PRIMARY_SERVICE(&vnd_uuid),
BT_GATT_SERVICE_DEFINE(
vnd_svc, BT_GATT_PRIMARY_SERVICE(&vnd_uuid),
BT_GATT_CHARACTERISTIC(&vnd_enc_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE |
BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_READ_ENCRYPT |
BT_GATT_PERM_WRITE_ENCRYPT,
read_vnd, write_vnd, vnd_value),
BT_GATT_CCC(vnd_ccc_cfg_changed,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
BT_GATT_CHARACTERISTIC(&vnd_auth_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
BT_GATT_PERM_READ_AUTHEN |
BT_GATT_PERM_WRITE_AUTHEN,
read_vnd, write_vnd, vnd_auth_value),
BT_GATT_CHARACTERISTIC(&vnd_long_uuid.uuid, BT_GATT_CHRC_READ |
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_EXT_PROP,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE |
BT_GATT_PERM_PREPARE_WRITE,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_INDICATE,
BT_GATT_PERM_READ_ENCRYPT | BT_GATT_PERM_WRITE_ENCRYPT, read_vnd,
write_vnd, vnd_value),
BT_GATT_CCC(vnd_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE_ENCRYPT),
BT_GATT_CHARACTERISTIC(&vnd_auth_uuid.uuid, BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE,
BT_GATT_PERM_READ_AUTHEN | BT_GATT_PERM_WRITE_AUTHEN, read_vnd,
write_vnd, vnd_auth_value),
BT_GATT_CHARACTERISTIC(&vnd_long_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_EXT_PROP,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE | BT_GATT_PERM_PREPARE_WRITE,
read_vnd, write_long_vnd, &vnd_long_value),
BT_GATT_CEP(&vnd_long_cep),
BT_GATT_CHARACTERISTIC(&vnd_signed_uuid.uuid, BT_GATT_CHRC_READ |
BT_GATT_CHRC_WRITE | BT_GATT_CHRC_AUTH,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE,
read_signed, write_signed, &signed_value),
BT_GATT_CHARACTERISTIC(&vnd_write_cmd_uuid.uuid,
BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_WRITE, NULL,
write_without_rsp_vnd, &vnd_wwr_value),
);
BT_GATT_CHARACTERISTIC(&vnd_signed_uuid.uuid,
BT_GATT_CHRC_READ | BT_GATT_CHRC_WRITE | BT_GATT_CHRC_AUTH,
BT_GATT_PERM_READ | BT_GATT_PERM_WRITE, read_signed, write_signed,
&signed_value),
BT_GATT_CHARACTERISTIC(&vnd_write_cmd_uuid.uuid, BT_GATT_CHRC_WRITE_WITHOUT_RESP,
BT_GATT_PERM_WRITE, NULL, write_without_rsp_vnd, &vnd_wwr_value), );

Check failure on line 199 in samples/bluetooth/peripheral/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

SPACING

samples/bluetooth/peripheral/src/main.c:199 space prohibited before that close parenthesis ')'

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_HRS_VAL),
BT_UUID_16_ENCODE(BT_UUID_BAS_VAL),
BT_UUID_16_ENCODE(BT_UUID_CTS_VAL)),
BT_DATA_BYTES(BT_DATA_UUID16_ALL, BT_UUID_16_ENCODE(BT_UUID_HRS_VAL),
BT_UUID_16_ENCODE(BT_UUID_BAS_VAL), BT_UUID_16_ENCODE(BT_UUID_CTS_VAL)),
BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_CUSTOM_SERVICE_VAL),
};

static const struct bt_data sd[] = {
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME) - 1),
};

void mtu_updated(struct bt_conn *conn, uint16_t tx, uint16_t rx)
void mtu_updated_cb(struct bt_conn *conn, uint16_t tx, uint16_t rx)
{
printk("Updated MTU: TX: %d RX: %d bytes\n", tx, rx);
}

static struct bt_gatt_cb gatt_callbacks = {
.att_mtu_updated = mtu_updated
};
static struct bt_gatt_cb gatt_callbacks = {.att_mtu_updated = mtu_updated_cb, };

static void connected(struct bt_conn *conn, uint8_t err)
static void connected_cb(struct bt_conn *conn, uint8_t err)
{
if (err) {
if (0 != err) {

Check warning on line 221 in samples/bluetooth/peripheral/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CONSTANT_COMPARISON

samples/bluetooth/peripheral/src/main.c:221 Comparisons should place the constant on the right side of the test
printk("Connection failed, err 0x%02x %s\n", err, bt_hci_err_to_str(err));
} else {
printk("Connected\n");
}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
static void disconnected_cb(struct bt_conn *conn, uint8_t reason)
{
printk("Disconnected, reason 0x%02x %s\n", reason, bt_hci_err_to_str(reason));
}

static void recycled_cb(void)
{
printk("connection recycled. Restart advertising a connection");
const int err =
bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (0 != err) {

Check warning on line 238 in samples/bluetooth/peripheral/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CONSTANT_COMPARISON

samples/bluetooth/peripheral/src/main.c:238 Comparisons should place the constant on the right side of the test
Comment on lines +236 to +238
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
const int err =
bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (0 != err) {
const int err =
bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err != 0) {

printk("Advertising failed to start (err %d)\n", err);
}
}

static void alert_stop(void)
{
printk("Alert stopped\n");
Expand All @@ -270,8 +256,9 @@
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
.connected = connected,
.disconnected = disconnected,
.connected = connected_cb,
.disconnected = disconnected_cb,
.recycled = recycled_cb,
};

BT_IAS_CB_DEFINE(ias_callbacks) = {
Expand All @@ -291,7 +278,7 @@
}

err = bt_le_adv_start(BT_LE_ADV_CONN_FAST_1, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd));
if (err) {
if (0 != err) {

Check warning on line 281 in samples/bluetooth/peripheral/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CONSTANT_COMPARISON

samples/bluetooth/peripheral/src/main.c:281 Comparisons should place the constant on the right side of the test
printk("Advertising failed to start (err %d)\n", err);
return;
}
Expand Down Expand Up @@ -420,7 +407,7 @@
int err;

err = bt_enable(NULL);
if (err) {
if (0 != err) {

Check warning on line 410 in samples/bluetooth/peripheral/src/main.c

View workflow job for this annotation

GitHub Actions / Run compliance checks on patch series (PR)

CONSTANT_COMPARISON

samples/bluetooth/peripheral/src/main.c:410 Comparisons should place the constant on the right side of the test
printk("Bluetooth init failed (err %d)\n", err);
return 0;
}
Expand All @@ -432,8 +419,7 @@
bt_gatt_cb_register(&gatt_callbacks);
bt_conn_auth_cb_register(&auth_cb_display);

vnd_ind_attr = bt_gatt_find_by_uuid(vnd_svc.attrs, vnd_svc.attr_count,
&vnd_enc_uuid.uuid);
vnd_ind_attr = bt_gatt_find_by_uuid(vnd_svc.attrs, vnd_svc.attr_count, &vnd_enc_uuid.uuid);
bt_uuid_to_str(&vnd_enc_uuid.uuid, str, sizeof(str));
printk("Indicate VND attr %p (UUID %s)\n", vnd_ind_attr, str);

Expand Down
Loading
Loading