Hello everyone,
I'm working on a Bluetooth device using the Zephyr framework. I need to maintain a current connection while also continuing to advertise. If another device tries to connect simultaneously, I want to send a specific message indicating that only one connection is allowed at a time. Currently, the device stops advertising as soon as it connects to a device and resumes advertising only after the disconnection.
Summary of the Current Code and Issue:
- Bluetooth connection: Advertising stops after a device connects; attempts to restart advertising fail.
- Bluetooth disconnection: Advertising restarts properly after a device disconnects.
- Desired behavior: Keep advertising even after a device connects, and send a custom message when another connection attempt is made.
Could anyone help me understand how to achieve this behavior? Is there a way to keep advertising after a connection is established and properly handle simultaneous connection attempts?
Thank you in advance for your assistance!
// Callbacks de conexão e desconexão Bluetooth
static void bluetooth_connected(struct bt_conn *conn, uint8_t error) {
if (error) {
_LOG_ERR("Failed to connect with BLE device!");
return;
}
if (bt_conn_le_data_len_update(conn, BT_LE_DATA_LEN_PARAM_MAX) != 0) {
_LOG_DBG("Error updating bt_conn length");
}
system_data.ble_connection_current = bt_conn_ref(conn);
k_timer_start(&system_data.timer_disconnect, K_MSEC(TIMEOUT_MS_TO_DISCONNECT_BEFORE_AUTHORIZE), K_NO_WAIT);
}
static void bluetooth_disconnected(struct bt_conn *conn, uint8_t reason) {
_LOG_INF("BLE disconnected, reason: %u", reason);
if (system_data.state == OTA_TRANSFER) {
free_all_ota_channels_memory();
system_data.state = IDLE;
}
bt_conn_unref(system_data.ble_connection_current);
system_data.ble_connection_current = NULL;
k_timer_stop(&system_data.timer_disconnect);
}
// Parâmetros de publicidade Bluetooth
static struct bt_data packet_advertisement[] = {
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),
};
static const struct bt_le_adv_param advertising_params = {
.options = BT_LE_ADV_OPT_CONNECTABLE,
.interval_min = BT_GAP_ADV_SLOW_INT_MIN,
.interval_max = BT_GAP_ADV_SLOW_INT_MAX,
};
// Inicialização do Bluetooth
static int bluetooth_initialize() {
if (bt_enable(NULL) != 0) {
_LOG_ERR("Failed to enable Bluetooth!");
return -1;
}
if (bt_le_adv_start(&advertising_params, packet_advertisement, ARRAY_SIZE(packet_advertisement), packet_scan_response, ARRAY_SIZE(packet_scan_response)) != 0) {
_LOG_ERR("Failed to start advertising!");
return -1;
}
return 0;
}
// Método para atualizar dados do fabricante
static void bluetooth_set_manufacturer_data(uint8_t* data) {
memcpy(manufacturer_data.device_identifier, data, 8);
if (bt_le_adv_update_data(packet_advertisement, ARRAY_SIZE(packet_advertisement), packet_scan_response, ARRAY_SIZE(packet_scan_response)) != 0) {
_LOG_ERR("Could not update advertising data");
}
}
// Notificação Bluetooth
static void bluetooth_notify_log(char level, char *format, ...) {
if (level != 'E') {
return;
}
char output[MAX_BLUETOOTH_LOG_MESSAGE_LENGTH];
vsnprintf(output, sizeof(output), format, args);
bt_gatt_notify(NULL, &gatt_service.attrs[14], output, strlen(output));
}
// Timer para desconectar Bluetooth
static void timer_disconnect_expiry_fn(struct k_timer *timer_id) {
struct bt_conn_info connection_info;
if (bt_conn_get_info(system_data.ble_connection_current, &connection_info) != 0) {
_LOG_DBG("Could not get connection info from the current connection");
return;
}
k_sem_give(&system_data.semaphore_disconnect);
}