150 lines
3.7 KiB
Bash
Executable File
150 lines
3.7 KiB
Bash
Executable File
#!/bin/sh
|
|
#
|
|
# MQTT Bridge monitor daemon
|
|
# Scans configured USB adapters/presets and updates UCI with live metadata.
|
|
|
|
. /lib/functions.sh
|
|
|
|
UCI_NAMESPACE="mqtt-bridge"
|
|
LOGTAG="mqtt-bridge-monitor"
|
|
SCAN_INTERVAL=10
|
|
COMMIT_NEEDED=0
|
|
|
|
log_msg() {
|
|
logger -t "$LOGTAG" "$*"
|
|
}
|
|
|
|
find_usb_device() {
|
|
local vendor="$1"
|
|
local product="$2"
|
|
local dev
|
|
|
|
for dev in /sys/bus/usb/devices/*; do
|
|
[ -f "$dev/idVendor" ] || continue
|
|
[ -f "$dev/idProduct" ] || continue
|
|
local idVendor idProduct
|
|
idVendor="$(cat "$dev/idVendor" 2>/dev/null)"
|
|
idProduct="$(cat "$dev/idProduct" 2>/dev/null)"
|
|
[ "$idVendor" = "$vendor" ] || continue
|
|
[ "$idProduct" = "$product" ] || continue
|
|
echo "$dev"
|
|
return 0
|
|
done
|
|
|
|
return 1
|
|
}
|
|
|
|
find_usb_tty() {
|
|
local base="$1"
|
|
local path node
|
|
for path in "$base" "$base"/* "$base"/*/*; do
|
|
[ -d "$path/tty" ] || continue
|
|
for node in "$path"/tty/*; do
|
|
[ -e "$node" ] || continue
|
|
local tty
|
|
tty="$(basename "$node")"
|
|
[ -e "/dev/$tty" ] && { echo "/dev/$tty"; return 0; }
|
|
done
|
|
done
|
|
return 1
|
|
}
|
|
|
|
set_option_if_changed() {
|
|
local section="$1"
|
|
local key="$2"
|
|
local value="$3"
|
|
local current
|
|
current="$(uci -q get ${UCI_NAMESPACE}.adapter.${section}.${key} 2>/dev/null)"
|
|
[ "$current" = "$value" ] && return
|
|
uci set ${UCI_NAMESPACE}.adapter.${section}.${key}="$value"
|
|
COMMIT_NEEDED=1
|
|
}
|
|
|
|
clear_option_if_needed() {
|
|
local section="$1"
|
|
local key="$2"
|
|
local current
|
|
current="$(uci -q get ${UCI_NAMESPACE}.adapter.${section}.${key} 2>/dev/null)"
|
|
[ -z "$current" ] && return
|
|
uci delete ${UCI_NAMESPACE}.adapter.${section}.${key}
|
|
COMMIT_NEEDED=1
|
|
}
|
|
|
|
update_adapter_section() {
|
|
local section="$1"
|
|
local enabled vendor product title preset
|
|
|
|
config_get enabled "$section" enabled "1"
|
|
config_get vendor "$section" vendor
|
|
config_get product "$section" product
|
|
config_get preset "$section" preset
|
|
config_get title "$section" title
|
|
|
|
if [ "$enabled" != "1" ]; then
|
|
set_option_if_changed "$section" detected "0"
|
|
set_option_if_changed "$section" health "disabled"
|
|
return
|
|
fi
|
|
|
|
if [ -z "$vendor" ] || [ -z "$product" ]; then
|
|
set_option_if_changed "$section" detected "0"
|
|
set_option_if_changed "$section" health "unknown"
|
|
return
|
|
fi
|
|
|
|
local dev_path
|
|
dev_path="$(find_usb_device "$vendor" "$product")" || dev_path=""
|
|
|
|
local prev_detected
|
|
prev_detected="$(uci -q get ${UCI_NAMESPACE}.adapter.${section}.detected 2>/dev/null)"
|
|
|
|
if [ -n "$dev_path" ]; then
|
|
local bus devnum port ts
|
|
bus="$(cat "$dev_path/busnum" 2>/dev/null)"
|
|
devnum="$(cat "$dev_path/devnum" 2>/dev/null)"
|
|
port="$(find_usb_tty "$dev_path")"
|
|
ts="$(date -Iseconds)"
|
|
|
|
set_option_if_changed "$section" detected "1"
|
|
set_option_if_changed "$section" health "online"
|
|
[ -n "$bus" ] && set_option_if_changed "$section" bus "$bus"
|
|
[ -n "$devnum" ] && set_option_if_changed "$section" device "$devnum"
|
|
if [ -n "$port" ]; then
|
|
set_option_if_changed "$section" port "$port"
|
|
else
|
|
clear_option_if_needed "$section" port
|
|
fi
|
|
set_option_if_changed "$section" last_seen "$ts"
|
|
|
|
if [ "$prev_detected" != "1" ]; then
|
|
log_msg "Adapter $section ($title) detected on bus $bus dev $devnum $port"
|
|
fi
|
|
else
|
|
set_option_if_changed "$section" detected "0"
|
|
set_option_if_changed "$section" health "missing"
|
|
clear_option_if_needed "$section" port
|
|
clear_option_if_needed "$section" bus
|
|
clear_option_if_needed "$section" device
|
|
if [ "$prev_detected" = "1" ]; then
|
|
log_msg "Adapter $section ($title) disconnected"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
scan_loop() {
|
|
while true; do
|
|
COMMIT_NEEDED=0
|
|
config_load "$UCI_NAMESPACE"
|
|
local interval
|
|
config_get interval monitor interval
|
|
[ -n "$interval" ] && SCAN_INTERVAL="$interval"
|
|
config_foreach update_adapter_section adapter
|
|
if [ "$COMMIT_NEEDED" -eq 1 ]; then
|
|
uci commit "$UCI_NAMESPACE"
|
|
fi
|
|
sleep "$SCAN_INTERVAL"
|
|
done
|
|
}
|
|
|
|
scan_loop
|