Before this change, the status of the sysfs paths from the kernel events was cached with a cache file. This is necessary to mark configured modems as available for the netifd. Using the new monitor service via the mmcli command 'mmcli -M' simplifies the whole process. There is no need to start sub shells in the background anymore that monitors whether the modem has already been added to the ModemManager. For this purpose, a new service was added that reacts on add and remove events for modems in the ModemManager and, if necessary, marks the logical netifd interface as available. Signed-off-by: Florian Eckert <fe@dev.tdt.de>
155 lines
3.5 KiB
Bash
155 lines
3.5 KiB
Bash
#!/bin/sh
|
|
|
|
. /lib/functions.sh
|
|
. /lib/netifd/netifd-proto.sh
|
|
. /usr/share/ModemManager/modemmanager.common
|
|
|
|
trap_with_arg() {
|
|
func="$1" ; shift
|
|
for sig ; do
|
|
# shellcheck disable=SC2064
|
|
trap "$func $sig" "$sig"
|
|
done
|
|
}
|
|
|
|
func_trap() {
|
|
local monitor_cache_line object
|
|
|
|
logger "ModemManager-monitor[$$]" "Sending signal ${1} ..."
|
|
|
|
# Set all configured logical interfaces to unavailable
|
|
while IFS= read -r monitor_cache_line; do
|
|
object=$(echo "${monitor_cache_line}" | awk '{print $1}')
|
|
mm_monitor_cache_remove "$object"
|
|
done < ${MODEMMANAGER_MONITOR_CACHE}
|
|
|
|
kill "-${1}" "$CHILD" 2>/dev/null
|
|
}
|
|
|
|
mm_monitor_get_sysfspath() {
|
|
local object="$1"
|
|
|
|
# If no monitor cache file, we're done
|
|
[ -f "${MODEMMANAGER_MONITOR_CACHE}" ] || return
|
|
|
|
awk -v object="${object}" '!/^#/ && $0 ~ object { print $2 }' "${MODEMMANAGER_MONITOR_CACHE}"
|
|
}
|
|
|
|
mm_monitor_cache_remove() {
|
|
local object="$1"
|
|
|
|
local device cfg
|
|
|
|
device=$(mm_monitor_get_sysfspath "${object}")
|
|
|
|
cfg=$(mm_get_modem_config "${device}")
|
|
if [ -n "${cfg}" ]; then
|
|
mm_log "debug" "interface '${cfg}' set '${device}' state unavailable"
|
|
proto_set_available "${cfg}" 0
|
|
fi
|
|
|
|
mm_log "debug" "delete object '$object' from monitore cache"
|
|
|
|
# On monitor remove event, remove old events from cache
|
|
# Also substitute object path '/org/freedesktop/ModemManager1/Modem/<number>'
|
|
# all '/' with '\/' to make sed happy with shell expansion
|
|
sed -i "/${object//\//\\/}/d" "${MODEMMANAGER_MONITOR_CACHE}"
|
|
}
|
|
|
|
mm_monitor_cache_add() {
|
|
local object="$1"
|
|
local modemstatus device sysfspath cfg
|
|
|
|
modemstatus="$(mmcli --modem="${object}" --output-keyvalue)"
|
|
|
|
device=$(modemmanager_get_field "${modemstatus}" "modem.generic.device")
|
|
[ -n "${device}" ] || {
|
|
mm_log "err" "No 'device' for object '$object' not found..."
|
|
return 1
|
|
}
|
|
|
|
sysfspath=$(modemmanager_get_field "${modemstatus}" "modem.generic.physdev")
|
|
[ -n "${sysfspath}" ] || {
|
|
mm_log "err" "No 'sysfspath' for object '$object' not found..."
|
|
return 2
|
|
}
|
|
|
|
mm_log "debug" "add object '$object' to monitore cache (device=${device},sysfspath=${sysfspath})"
|
|
|
|
# On monitor add event, store event details in cache (if not exists yet)
|
|
grep -qs "${sysfspath}" "${MODEMMANAGER_MONITOR_CACHE}" || \
|
|
echo "${object} ${device} ${sysfspath}" >> "${MODEMMANAGER_MONITOR_CACHE}"
|
|
|
|
cfg=$(mm_get_modem_config "${device}")
|
|
if [ -n "${cfg}" ]; then
|
|
mm_log "info" "interface '${cfg}' set '${device}' state available"
|
|
proto_set_available "${cfg}" 1
|
|
fi
|
|
}
|
|
|
|
mm_monitor_cache_del() {
|
|
local object="$1"
|
|
|
|
mm_monitor_cache_remove "$object"
|
|
}
|
|
|
|
mm_monitor_cache() {
|
|
local line="$1"
|
|
local event object modemstatus device pyhsdev
|
|
|
|
event="$(echo "$line" | cut -d " " -f 1)"
|
|
object="$(echo "$line" | cut -d " " -f 2)"
|
|
|
|
case "$event" in
|
|
"(+)")
|
|
mm_monitor_cache_add "$object"
|
|
;;
|
|
"(-)")
|
|
mm_monitor_cache_del "$object"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
main() {
|
|
|
|
local n=60
|
|
local step=1
|
|
local mmrunning=0
|
|
|
|
trap_with_arg func_trap INT TERM KILL
|
|
|
|
mkdir -p "${MODEMMANAGER_RUNDIR}"
|
|
chmod 0755 "${MODEMMANAGER_RUNDIR}"
|
|
|
|
# Wait for ModemManager to be available in the bus
|
|
while [ $n -ge 0 ]; do
|
|
sleep $step
|
|
mm_log "info" "Checking if ModemManager is available..."
|
|
|
|
if ! /usr/bin/mmcli -L >/dev/null 2>&1; then
|
|
mm_log "info" "ModemManager not yet available"
|
|
else
|
|
mmrunning=1
|
|
break
|
|
fi
|
|
n=$((n-step))
|
|
done
|
|
|
|
[ ${mmrunning} -eq 1 ] || {
|
|
mm_log "error" "couldn't report initial kernel events: ModemManager not running"
|
|
return
|
|
}
|
|
|
|
/usr/bin/mmcli -M | {
|
|
local line
|
|
while read -r line; do
|
|
mm_log "debug" "Monitor cache line: ${line}"
|
|
mm_monitor_cache "$line"
|
|
done
|
|
} &
|
|
CHILD="$!"
|
|
|
|
wait $CHILD
|
|
}
|
|
|
|
main "$@"
|