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 <isaac.hermida@digi.com>
This commit is contained in:
parent
23c969f954
commit
c7adf015f9
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue