From c7adf015f93c694e9dd61d3eef184a8d4639ce04 Mon Sep 17 00:00:00 2001 From: Isaac Hermida Date: Fri, 15 May 2026 13:52:23 +0200 Subject: [PATCH] bluetooth-init: validate HCI interface after initialization Some Bluetooth controllers may expose hci0 even when the firmware initialization has not completed correctly. In that state, the init script may report success but bluetoothd cannot use the controller. Validate the controller through the kernel management interface before accepting the initialization as successful. This matches the interface used by bluetoothd and catches controllers that are visible through HCI but not registered in MGMT yet. Use a timeout for the MGMT query so a broken controller state cannot block the init script instead of falling back to the retry loop. https://onedigi.atlassian.net/browse/DEL-9512 Signed-off-by: Isaac Hermida --- .../bluez5-init/bluetooth-init_btbcm_hciuart | 12 ++++--- .../bluez5-init/bluetooth-init_btdigi_qca65x4 | 10 ++++-- .../bluez5-init/bluetooth-init_btnxpuart | 31 ++++++++++++++----- .../bluez/bluez5-init/ccimx6/bluetooth-init | 8 ++++- .../bluez/bluez5-init/ccmp2/bluetooth-init | 9 ++++-- 5 files changed, 53 insertions(+), 17 deletions(-) diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btbcm_hciuart b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btbcm_hciuart index f2fbfe111..6cd2c8631 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btbcm_hciuart +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btbcm_hciuart @@ -48,12 +48,16 @@ bt_init() { for i in $(seq ${RETRIES}); do # Load manually the kernel module - modprobe "${MODULE_NAME}" + timeout 3 modprobe "${MODULE_NAME}" sleep 1 - # Reconfigure the HCI interface with the expected MAC address - is_kernel_module_loaded && set_btaddr && log info "Bluetooth activated" && return 0 + is_kernel_module_loaded || continue + # Validate that the controller is available through the + # kernel management interface used by bluetoothd. + if timeout 3 btmgmt --index 0 info >/dev/null 2>&1; then + # Reconfigure the HCI interface with the expected MAC address + set_btaddr && log info "Bluetooth activated" && return 0 + fi bt_stop - if [ "$i" -lt "$RETRIES" ]; then log err "Cannot initialize Bluetooth, retrying..." fi diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btdigi_qca65x4 b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btdigi_qca65x4 index 01f57c95f..d40d05020 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btdigi_qca65x4 +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btdigi_qca65x4 @@ -26,9 +26,15 @@ bluetooth_init() { for RETRY in $(seq 1 5) do killproc hciattach - modprobe btdigi + timeout 3 modprobe btdigi if hciattach ttyBt qca ${BT_RATE:-3000000} -t30 ${BT_FLOW:-flow} unused ${BT_MACADDR} >${HCIATTACH_LOG} 2>&1; then - return + # hciattach performs a reset to load the new firmware and needs some time to be ready + sleep 1 + # Validate that the controller is available through the + # kernel management interface used by bluetoothd. + if timeout 3 btmgmt --index 0 info >/dev/null 2>&1; then + return + fi fi rmmod btdigi sleep 1 diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btnxpuart b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btnxpuart index b3e93dab7..100812d07 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btnxpuart +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/bluetooth-init_btnxpuart @@ -50,6 +50,10 @@ is_kernel_module_loaded() { lsmod | grep -qs -w "^${MODULE_NAME}" } +unload_module() { + hciconfig "${HCI_IFACE}" up && rmmod "${MODULE_NAME}" +} + bluetooth_start() { if ! [ -e "/proc/device-tree/bluetooth/mac-address" ]; then log "[ERROR] Bluetooth mac-address not found" @@ -59,18 +63,31 @@ bluetooth_start() { # If module is already loaded, skip is_kernel_module_loaded && log "[ERROR] kernel module already present, skipping" && return 1 - power 0 && sleep 0.2 && power 1 - # Load manually the kernel module - modprobe "${MODULE_NAME}" - # Reconfigure the HCI interface with the expected MAC address and power levels - is_kernel_module_loaded && set_btaddr && set_power_config && log "Bluetooth activated" && return 0 + for RETRY in $(seq 1 3) + do + power 0 && sleep 0.2 && power 1 + # Load manually the kernel module + timeout 3 modprobe "${MODULE_NAME}" + is_kernel_module_loaded || continue + # Validate that the controller is available through the + # kernel management interface used by bluetoothd. + if timeout 3 btmgmt --index 0 info >/dev/null 2>&1; then + # Reconfigure the HCI interface with the expected MAC address and power levels + if set_btaddr && set_power_config; then + log "Bluetooth activated" + return 0 + fi + fi + unload_module + power 0 + done log "[ERROR] Cannot initialize Bluetooth correctly" && return 1 } is_system_running() { state=$(systemctl is-system-running 2>/dev/null) case "$state" in - running|degraded) + starting|running|degraded) return 0 ;; # System is operational *) return 1 ;; # Assume not running @@ -84,7 +101,7 @@ bluetooth_stop() { # sure the interface is UP before unloading the module. # if is_system_running; then - hciconfig "${HCI_IFACE}" up && rmmod "${MODULE_NAME}" + unload_module power 0 else log "System rebooting... not taking any action" diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccimx6/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccimx6/bluetooth-init index 65b226bd9..3b8052c19 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccimx6/bluetooth-init +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccimx6/bluetooth-init @@ -49,7 +49,13 @@ bluetooth_init() { killproc hciattach powercycle_gpio "${BT_EN_QCA_GPIO_NR}" if hciattach ttyBt qca ${BT_RATE:-3000000} -t30 ${BT_FLOW:-flow} unused ${BT_MACADDR} >${HCIATTACH_LOG} 2>&1; then - return + # hciattach performs a reset to load the new firmware and needs some time to be ready + sleep 1 + # Validate that the controller is available through the + # kernel management interface used by bluetoothd. + if timeout 3 btmgmt --index 0 info >/dev/null 2>&1; then + return + fi fi sleep 1 done diff --git a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccmp2/bluetooth-init b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccmp2/bluetooth-init index f478dbf60..528f04a44 100644 --- a/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccmp2/bluetooth-init +++ b/meta-digi-dey/recipes-connectivity/bluez/bluez5-init/ccmp2/bluetooth-init @@ -53,9 +53,12 @@ bt_init() { # Attach serial UART to the Bluetooth stack btattach -B /dev/ttySTM1 -P bcm -S 3000000 & sleep 2 - - # Reconfigure the HCI interface with the expected MAC address - set_btaddr && log info "OK" && return 0 + # Validate that the controller is available through the + # kernel management interface used by bluetoothd. + if timeout 3 btmgmt --index 0 info >/dev/null 2>&1; then + # Reconfigure the HCI interface with the expected MAC address + set_btaddr && log info "OK" && return 0 + fi fi log err "FAILED to bring hci0 up, retrying..." killall btattach 2> /dev/null