It seems BLE stops advertising after the first connection. Is this expected behavior? Should I restart advertising in my "connected" connection callback?
prj.conf:
# Enable logging system to USB CONFIG_LOG=y # <BLE> CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="bale module" # Allow multiple devices to connect at once CONFIG_BT_MAX_CONN=6 CONFIG_BT_BUF_ACL_RX_COUNT=7 # Enable Security Management Protocol # CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 # CONFIG_BT_GATT_DYNAMIC_DB=y # </BLE> # Needed for LEDs CONFIG_DK_LIBRARY=y CONFIG_BT_HCI_ERR_TO_STR=y # <CRYPTO> # Enable nordic security backend and PSA APIs CONFIG_NRF_SECURITY=y CONFIG_MBEDTLS_PSA_CRYPTO_C=y CONFIG_PSA_WANT_ALG_ECDH=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_GENERATE=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_IMPORT=y CONFIG_PSA_WANT_KEY_TYPE_ECC_KEY_PAIR_EXPORT=y CONFIG_PSA_WANT_ECC_SECP_R1_256=y # For key generation CONFIG_PSA_WANT_GENERATE_RANDOM=y CONFIG_SYS_CLOCK_TICKS_PER_SEC=1000 CONFIG_MBEDTLS_ENABLE_HEAP=y CONFIG_MBEDTLS_HEAP_SIZE=8192 CONFIG_MAIN_STACK_SIZE=4096 CONFIG_HEAP_MEM_POOL_SIZE=4096 # </CRYPTO>
main.c:
#include <zephyr/types.h>
#include <stddef.h>
#include <string.h>
#include <errno.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/byteorder.h>
#include <zephyr/sys/reboot.h>
#include <zephyr/kernel.h>
#include <soc.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <zephyr/bluetooth/services/dis.h>
#include <zephyr/settings/settings.h>
#include <dk_buttons_and_leds.h>
#include <zephyr/logging/log.h>
#include <app_version.h>
#include "rcs.h"
LOG_MODULE_REGISTER(main);
#define DEVICE_NAME CONFIG_BT_DEVICE_NAME
#define DEVICE_NAME_LEN (sizeof(DEVICE_NAME) - 1)
#define RUN_STATUS_LED DK_LED1
#define CON_STATUS_LED DK_LED2
#define RPC_LED DK_LED3
#define RUN_LED_BLINK_INTERVAL 200
// Bonding: Define advertising parameter for no Accept List
#define BT_LE_ADV_CONN_NO_ACCEPT_LIST \
BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE | BT_LE_ADV_OPT_ONE_TIME, \
BT_GAP_ADV_FAST_INT_MIN_2, BT_GAP_ADV_FAST_INT_MAX_2, NULL)
// Data to be used in advertisement packets.
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, DEVICE_NAME, DEVICE_NAME_LEN),
};
// Data to be used in scan response packets.
static const struct bt_data sd[] = {
// BT_DATA_UUID128_SOME indicates that some but not all services are listed in the scan response
BT_DATA_BYTES(BT_DATA_UUID128_SOME, BT_UUID_RCS_VAL),
};
void bt_advertise(struct k_work* work)
{
int err = 0;
// int err = bt_le_filter_accept_list_clear();
LOG_INF("BLE: Advertising\n");
err = bt_le_adv_start(BT_LE_ADV_CONN_NO_ACCEPT_LIST, ad, ARRAY_SIZE(ad), sd,
ARRAY_SIZE(sd));
if (err)
{
LOG_ERR("BLE: Advertising failed to start (err %d)\n", err);
return;
}
}
K_WORK_DEFINE(bt_advertise_work, bt_advertise);
static void on_connected(struct bt_conn* conn, uint8_t err)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
if (err)
{
LOG_ERR("BLE[%s]: on_connected failed, err 0x%02x %s", addr, err, bt_hci_err_to_str(err));
return;
}
LOG_INF("BLE[%s]: on_connected", addr);
dk_set_led_on(CON_STATUS_LED);
}
static void on_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));
remove_conn_secret(conn);
LOG_INF("BLE[%s]: on_disconnected, reason 0x%02x %s", addr, reason, bt_hci_err_to_str(reason));
dk_set_led_off(CON_STATUS_LED);
}
struct bt_conn_cb connection_callbacks = {
.connected = on_connected,
.disconnected = on_disconnected,
};
static void rcs_received_cb(struct bt_conn* conn, const uint8_t* const data, uint16_t len)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("RCS: %s: received data: %.*s", addr, len, data);
// echo back the data
bt_rcs_send(conn, data, len);
}
static void rcs_sent_cb(struct bt_conn* conn)
{
char addr[BT_ADDR_LE_STR_LEN];
bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));
LOG_INF("RCS: %s: data sent", addr);
}
struct bt_rcs_cb rcs_callbacks = {
.received = rcs_received_cb,
.sent = rcs_sent_cb
};
int main(void) {
int err;
LOG_INF("Starting BALE firmware");
LOG_INF("Firmware version: %s", APP_VERSION_STRING);
err = dk_leds_init();
if (err)
{
LOG_ERR("LEDs init failed (err %d)", err);
return 1;
}
err = bt_conn_cb_register(&connection_callbacks);
if (err)
{
LOG_INF("Failed to register connection callbacks.\n");
return -1;
}
err = bt_enable(NULL);
if (err)
{
LOG_ERR("BLE init failed (err %d)", err);
return -1;
}
LOG_INF("Bluetooth initialized");
// Initialize bluetooth services
LOG_INF("Initializing Bluetooth services");
err = bt_rcs_init(&rcs_callbacks);
if (err)
{
LOG_ERR("bt_rcs_init failed (err %d)", err);
return -1;
}
k_work_submit(&bt_advertise_work);
int blink_status = 0; // Declare and initialize blink_status
for (;;)
{
dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
}
}