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
|
for i in $(seq ${RETRIES}); do
|
||||||
# Load manually the kernel module
|
# Load manually the kernel module
|
||||||
modprobe "${MODULE_NAME}"
|
timeout 3 modprobe "${MODULE_NAME}"
|
||||||
sleep 1
|
sleep 1
|
||||||
# Reconfigure the HCI interface with the expected MAC address
|
is_kernel_module_loaded || continue
|
||||||
is_kernel_module_loaded && set_btaddr && log info "Bluetooth activated" && 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 "Bluetooth activated" && return 0
|
||||||
|
fi
|
||||||
bt_stop
|
bt_stop
|
||||||
|
|
||||||
if [ "$i" -lt "$RETRIES" ]; then
|
if [ "$i" -lt "$RETRIES" ]; then
|
||||||
log err "Cannot initialize Bluetooth, retrying..."
|
log err "Cannot initialize Bluetooth, retrying..."
|
||||||
fi
|
fi
|
||||||
|
|
|
||||||
|
|
@ -26,9 +26,15 @@ bluetooth_init() {
|
||||||
for RETRY in $(seq 1 5)
|
for RETRY in $(seq 1 5)
|
||||||
do
|
do
|
||||||
killproc hciattach
|
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
|
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
|
fi
|
||||||
rmmod btdigi
|
rmmod btdigi
|
||||||
sleep 1
|
sleep 1
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,10 @@ is_kernel_module_loaded() {
|
||||||
lsmod | grep -qs -w "^${MODULE_NAME}"
|
lsmod | grep -qs -w "^${MODULE_NAME}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unload_module() {
|
||||||
|
hciconfig "${HCI_IFACE}" up && rmmod "${MODULE_NAME}"
|
||||||
|
}
|
||||||
|
|
||||||
bluetooth_start() {
|
bluetooth_start() {
|
||||||
if ! [ -e "/proc/device-tree/bluetooth/mac-address" ]; then
|
if ! [ -e "/proc/device-tree/bluetooth/mac-address" ]; then
|
||||||
log "[ERROR] Bluetooth mac-address not found"
|
log "[ERROR] Bluetooth mac-address not found"
|
||||||
|
|
@ -59,18 +63,31 @@ bluetooth_start() {
|
||||||
# If module is already loaded, skip
|
# If module is already loaded, skip
|
||||||
is_kernel_module_loaded && log "[ERROR] kernel module already present, skipping" && return 1
|
is_kernel_module_loaded && log "[ERROR] kernel module already present, skipping" && return 1
|
||||||
|
|
||||||
power 0 && sleep 0.2 && power 1
|
for RETRY in $(seq 1 3)
|
||||||
# Load manually the kernel module
|
do
|
||||||
modprobe "${MODULE_NAME}"
|
power 0 && sleep 0.2 && power 1
|
||||||
# Reconfigure the HCI interface with the expected MAC address and power levels
|
# Load manually the kernel module
|
||||||
is_kernel_module_loaded && set_btaddr && set_power_config && log "Bluetooth activated" && return 0
|
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
|
log "[ERROR] Cannot initialize Bluetooth correctly" && return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
is_system_running() {
|
is_system_running() {
|
||||||
state=$(systemctl is-system-running 2>/dev/null)
|
state=$(systemctl is-system-running 2>/dev/null)
|
||||||
case "$state" in
|
case "$state" in
|
||||||
running|degraded)
|
starting|running|degraded)
|
||||||
return 0 ;; # System is operational
|
return 0 ;; # System is operational
|
||||||
*)
|
*)
|
||||||
return 1 ;; # Assume not running
|
return 1 ;; # Assume not running
|
||||||
|
|
@ -84,7 +101,7 @@ bluetooth_stop() {
|
||||||
# sure the interface is UP before unloading the module.
|
# sure the interface is UP before unloading the module.
|
||||||
#
|
#
|
||||||
if is_system_running; then
|
if is_system_running; then
|
||||||
hciconfig "${HCI_IFACE}" up && rmmod "${MODULE_NAME}"
|
unload_module
|
||||||
power 0
|
power 0
|
||||||
else
|
else
|
||||||
log "System rebooting... not taking any action"
|
log "System rebooting... not taking any action"
|
||||||
|
|
|
||||||
|
|
@ -49,7 +49,13 @@ bluetooth_init() {
|
||||||
killproc hciattach
|
killproc hciattach
|
||||||
powercycle_gpio "${BT_EN_QCA_GPIO_NR}"
|
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
|
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
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
done
|
done
|
||||||
|
|
|
||||||
|
|
@ -53,9 +53,12 @@ bt_init() {
|
||||||
# Attach serial UART to the Bluetooth stack
|
# Attach serial UART to the Bluetooth stack
|
||||||
btattach -B /dev/ttySTM1 -P bcm -S 3000000 &
|
btattach -B /dev/ttySTM1 -P bcm -S 3000000 &
|
||||||
sleep 2
|
sleep 2
|
||||||
|
# Validate that the controller is available through the
|
||||||
# Reconfigure the HCI interface with the expected MAC address
|
# kernel management interface used by bluetoothd.
|
||||||
set_btaddr && log info "OK" && return 0
|
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
|
fi
|
||||||
log err "FAILED to bring hci0 up, retrying..."
|
log err "FAILED to bring hci0 up, retrying..."
|
||||||
killall btattach 2> /dev/null
|
killall btattach 2> /dev/null
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue