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)); } }