mirror of
https://github.com/coolsnowwolf/packages.git
synced 2025-05-02 06:19:14 +08:00

* modemmanager: bump to 1.16.10
Signed-off-by: Nicholas Smith <nicholas@nbembedded.com>
* modemmanager: switch to autorelease
Signed-off-by: Nicholas Smith <nicholas@nbembedded.com>
* modemmanager: bump to 1.18.2
Signed-off-by: Kuan-Yi Li <kyli@abysm.org>
* modemmanager: add support for wwan subsystem in hotplug
WWAN devices may now be exposed in the new 'wwan' subsystem in the
kernel (since 5.13), initially applicable to devices exposed in PCIe
(no USB), but at some point may also apply to USB devices that until
now were exposed via other subsystems (e.g. usbmisc, tty).
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
* modemmanager: fix physdev sysfs path detection in PCIe modems
The PCIe physdev path lookup relies on the 'vendor' and 'device'
attribute files, instead of the 'idVendor' and 'idProduct' ones, which
are USB specific.
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
* ModemManager: refactoring procd init script
The way the init script is written now, we get a bad output when calling
the ubus service backend.
ubus call service list "{'verbose':true,'name':'modemmanager'}"
>{
> "modemmanager": {
> "instances": {
> "instance1": {
> "running": true,
> "pid": 20511,
> "command": [
> "sh",
> "-c",
> ".
>/usr/share/ModemManager/modemmanager.common; \t
>mkdir -m 0755 -p /var/run/modemmanager; \t
>mm_cleanup_interfaces; \t
>( mm_report_events_from_cache ) >/dev/null 2>&1 & \t
>/usr/sbin/ModemManager"
> ],
> "term_timeout": 5,
> "respawn": {
> "threshold": 3600,
> "timeout": 5,
> "retry": 5
> },
> "pidfile":"/var/run/modemmanager/modemmanager.pid"
> }
> }
> }
>}"
I also get the output in the log that the PID file cannot be created.
> daemon.err procd: Failed to remove pidfile: :No such file or directory
The changes in this commit fixes this issues, by moving startup into a
wrapper script.
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
* ModemManager: add service options
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
* modemmanager: refactoring hotplug debug logging
The output of the hotplug is very chatty and floods the log with
messages that are not necessary in functioning operation.
So that the log can be filtered. A log level was added to each message
as the first opiton on mm_log function call.
In addition, the facility of the hotplug script has been set to daemon,
which in my view fits better than user.
Signed-off-by: Florian Eckert <fe@dev.tdt.de>
* modemmanager: remove 2s timeout before reporting cached events
When ModemManager is started on boot we may end up with hotplug events
reported directly to the daemon, plus some others already cached in
the cache file before the daemon was started.
If the cached events correspond to the same device that is still
notifying ports directly, we may end up with a modem object created
before the cached events have been emitted, so the modem may not
handle all control/data ports it should.
E.g.:
- modem detected
- hotplug event for wwan0 port, cached as MM not running
- hotplug event for cdc-wdm0 port, cached as MM not running
- hotplug event for ttyUSB0, cached as MM not running
- MM starts
- hotplug event for ttyUSB1, directly processed as MM is running
- hotplug event for ttyUSB2, directly processed as MM is running
- modem object created with ttyUSB1 and ttyUSB2
- 2s after MM starts, cached events for wwan0, cdc-wdm0 and ttyUSB0
happen, but are ignored because the modem object has already been
created
MM expects that ports of the same device are reported with less than
1500ms in between ports. In other words, if ports are reported more
than 1500ms after the last reported port, they may get ignored.
If we remove the 2s timeout, the report of the cached events will
happen as soon as MM starts, which makes it much more likely to happen
in the timeslot that MM expects for ports of the same device reported.
The logic is still not perfect, and we may also need to increase that
1500ms timeout inside MM, but removing the 2s timeout right away here
makes sense.
This 2s timeout was introduced along with the new wrapper launcher for
the daemon, it didn't exist before.
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
* modemmanager: bump to 1.18.4 with patch
The included patch corrects an issue preventing udev rules from
being parsed correctly. [1][2]
This patch should not be needed after the next release. [3]
More information:
[1] e9f254ba3f
[2] https://lists.freedesktop.org/archives/modemmanager-devel/2021-December/009024.html
[3] https://lists.freedesktop.org/archives/modemmanager-devel/2021-December/009022.html
Signed-off-by: Nicholas Smith <nicholas@nbembedded.com>
* modemmanager: bump to 1.18.6
Remove upstreamed patch.
Signed-off-by: Kuan-Yi Li <kyli@abysm.org>
* modemmanager: switch to meson build tools
Using https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git to download the source code.
Added compile option to compile qrtr support.
Enabled lto and additional gcc flags for perfomance and less size.
Modified to use meson as upstream has abandoned autotools.
Removed BUILD_PARALLEL options. These are default with ninja/meson.
Signed-off-by: Maxim Anisimov <maxim.anisimov.ua@gmail.com>
* modemmanager: bump to 1.18.8
Also removed two patches that are already included in the upstream
release.
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
* modemmanager: install available FCC unlock scripts
The FCC unlock scripts are installed but not enabled by default.
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
* modemmanager: report network initiated disconnections to netifd
The new connection dispatcher scripts support integrated in
ModemManager 1.18.8 allows us to provide a openwrt-specific dispatcher
script used to report netifd that the underlying network connection is
down.
See also https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/merge_requests/775
Fixes https://github.com/openwrt/openwrt/issues/8368
Fixes https://github.com/openwrt/packages/issues/14096
Signed-off-by: Aleksander Morgado <aleksander@aleksander.es>
Co-authored-by: Nicholas Smith <nicholas@nbembedded.com>
Co-authored-by: Kuan-Yi Li <kyli@abysm.org>
Co-authored-by: Aleksander Morgado <aleksander@aleksander.es>
Co-authored-by: Florian Eckert <fe@dev.tdt.de>
Co-authored-by: Maxim Anisimov <maxim.anisimov.ua@gmail.com>
343 lines
9.4 KiB
Bash
343 lines
9.4 KiB
Bash
#!/bin/sh
|
|
# Copyright (C) 2016 Velocloud Inc
|
|
# Copyright (C) 2016 Aleksander Morgado <aleksander@aleksander.es>
|
|
|
|
################################################################################
|
|
|
|
. /lib/functions.sh
|
|
. /lib/netifd/netifd-proto.sh
|
|
|
|
################################################################################
|
|
# Runtime state
|
|
|
|
MODEMMANAGER_RUNDIR="/var/run/modemmanager"
|
|
MODEMMANAGER_PID_FILE="${MODEMMANAGER_RUNDIR}/modemmanager.pid"
|
|
MODEMMANAGER_CDCWDM_CACHE="${MODEMMANAGER_RUNDIR}/cdcwdm.cache"
|
|
MODEMMANAGER_SYSFS_CACHE="${MODEMMANAGER_RUNDIR}/sysfs.cache"
|
|
MODEMMANAGER_EVENTS_CACHE="${MODEMMANAGER_RUNDIR}/events.cache"
|
|
|
|
################################################################################
|
|
# Common logging
|
|
|
|
mm_log() {
|
|
local level="$1"; shift
|
|
logger -p "daemon.${level}" -t "ModemManager[$$]" "hotplug: $*"
|
|
}
|
|
|
|
################################################################################
|
|
# Receives as input argument the full sysfs path of the device
|
|
# Returns the physical device sysfs path
|
|
#
|
|
# NOTE: this method only works when the device exists, i.e. it cannot be used
|
|
# on removal hotplug events
|
|
|
|
mm_find_physdev_sysfs_path() {
|
|
local tmp_path="$1"
|
|
|
|
while true; do
|
|
tmp_path=$(dirname "${tmp_path}")
|
|
|
|
# avoid infinite loops iterating
|
|
[ -z "${tmp_path}" ] || [ "${tmp_path}" = "/" ] && return
|
|
|
|
# For USB devices, the physical device will be that with a idVendor
|
|
# and idProduct pair of files
|
|
[ -f "${tmp_path}"/idVendor ] && [ -f "${tmp_path}"/idProduct ] && {
|
|
tmp_path=$(readlink -f "$tmp_path")
|
|
echo "${tmp_path}"
|
|
return
|
|
}
|
|
|
|
# For PCI devices, the physical device will be that with a vendor
|
|
# and device pair of files
|
|
[ -f "${tmp_path}"/vendor ] && [ -f "${tmp_path}"/device ] && {
|
|
tmp_path=$(readlink -f "$tmp_path")
|
|
echo "${tmp_path}"
|
|
return
|
|
}
|
|
done
|
|
}
|
|
|
|
################################################################################
|
|
|
|
# Returns the cdc-wdm name retrieved from sysfs
|
|
mm_track_cdcwdm() {
|
|
local wwan="$1"
|
|
local cdcwdm
|
|
|
|
cdcwdm=$(ls "/sys/class/net/${wwan}/device/usbmisc/")
|
|
[ -n "${cdcwdm}" ] || return
|
|
|
|
# We have to cache it for later, as we won't be able to get the
|
|
# associated cdc-wdm device on a remove event
|
|
echo "${wwan} ${cdcwdm}" >> "${MODEMMANAGER_CDCWDM_CACHE}"
|
|
|
|
echo "${cdcwdm}"
|
|
}
|
|
|
|
# Returns the cdc-wdm name retrieved from the cache
|
|
mm_untrack_cdcwdm() {
|
|
local wwan="$1"
|
|
local cdcwdm
|
|
|
|
# Look for the cached associated cdc-wdm device
|
|
[ -f "${MODEMMANAGER_CDCWDM_CACHE}" ] || return
|
|
|
|
cdcwdm=$(awk -v wwan="${wwan}" '!/^#/ && $0 ~ wwan { print $2 }' "${MODEMMANAGER_CDCWDM_CACHE}")
|
|
[ -n "${cdcwdm}" ] || return
|
|
|
|
# Remove from cache
|
|
sed -i "/${wwan} ${cdcwdm}/d" "${MODEMMANAGER_CDCWDM_CACHE}"
|
|
|
|
echo "${cdcwdm}"
|
|
}
|
|
|
|
################################################################################
|
|
# ModemManager needs some time from the ports being added until a modem object
|
|
# is exposed in DBus. With the logic here we do an explicit wait of N seconds
|
|
# for ModemManager to expose the new modem object, making sure that the wait is
|
|
# unique per device (i.e. per physical device sysfs path).
|
|
|
|
# Gets the modem wait status as retrieved from the cache
|
|
mm_get_modem_wait_status() {
|
|
local sysfspath="$1"
|
|
|
|
# If no sysfs cache file, we're done
|
|
[ -f "${MODEMMANAGER_SYSFS_CACHE}" ] || return
|
|
|
|
# Get status of the sysfs path
|
|
awk -v sysfspath="${sysfspath}" '!/^#/ && $0 ~ sysfspath { print $2 }' "${MODEMMANAGER_SYSFS_CACHE}"
|
|
}
|
|
|
|
# Clear the modem wait status from the cache, if any
|
|
mm_clear_modem_wait_status() {
|
|
local sysfspath="$1"
|
|
|
|
local escaped_sysfspath
|
|
|
|
[ -f "${MODEMMANAGER_SYSFS_CACHE}" ] && {
|
|
# escape '/', '\' and '&' for sed...
|
|
escaped_sysfspath=$(echo "$sysfspath" | sed -e 's/[\/&]/\\&/g')
|
|
sed -i "/${escaped_sysfspath}/d" "${MODEMMANAGER_SYSFS_CACHE}"
|
|
}
|
|
}
|
|
|
|
# Sets the modem wait status in the cache
|
|
mm_set_modem_wait_status() {
|
|
local sysfspath="$1"
|
|
local status="$2"
|
|
|
|
# Remove sysfs line before adding the new one with the new state
|
|
mm_clear_modem_wait_status "${sysfspath}"
|
|
|
|
# Add the new status
|
|
echo "${sysfspath} ${status}" >> "${MODEMMANAGER_SYSFS_CACHE}"
|
|
}
|
|
|
|
# Callback for config_foreach()
|
|
mm_get_modem_config_foreach_cb() {
|
|
local cfg="$1"
|
|
local sysfspath="$2"
|
|
|
|
local proto
|
|
config_get proto "${cfg}" proto
|
|
[ "${proto}" = modemmanager ] || return 0
|
|
|
|
local dev
|
|
dev=$(uci_get network "${cfg}" device)
|
|
[ "${dev}" = "${sysfspath}" ] || return 0
|
|
|
|
echo "${cfg}"
|
|
}
|
|
|
|
# Returns the name of the interface configured for this device
|
|
mm_get_modem_config() {
|
|
local sysfspath="$1"
|
|
|
|
# Look for configuration for the given sysfs path
|
|
config_load network
|
|
config_foreach mm_get_modem_config_foreach_cb interface "${sysfspath}"
|
|
}
|
|
|
|
# Wait for a modem in the specified sysfspath
|
|
mm_wait_for_modem() {
|
|
local cfg="$1"
|
|
local sysfspath="$2"
|
|
|
|
# TODO: config max wait
|
|
local n=45
|
|
local step=5
|
|
|
|
while [ $n -ge 0 ]; do
|
|
[ -d "${sysfspath}" ] || {
|
|
mm_log "error" "ignoring modem detection request: no device at ${sysfspath}"
|
|
proto_set_available "${cfg}" 0
|
|
return 1
|
|
}
|
|
|
|
# Check if the modem exists at the given sysfs path
|
|
if ! mmcli -m "${sysfspath}" > /dev/null 2>&1
|
|
then
|
|
mm_log "error" "modem not detected at sysfs path"
|
|
else
|
|
mm_log "info" "modem exported successfully at ${sysfspath}"
|
|
mm_log "info" "setting interface '${cfg}' as available"
|
|
proto_set_available "${cfg}" 1
|
|
return 0
|
|
fi
|
|
|
|
sleep $step
|
|
n=$((n-step))
|
|
done
|
|
|
|
mm_log "error" "timed out waiting for the modem to get exported at ${sysfspath}"
|
|
proto_set_available "${cfg}" 0
|
|
return 2
|
|
}
|
|
|
|
mm_report_modem_wait() {
|
|
local sysfspath=$1
|
|
|
|
local parent_sysfspath status
|
|
|
|
parent_sysfspath=$(mm_find_physdev_sysfs_path "$sysfspath")
|
|
[ -n "${parent_sysfspath}" ] || {
|
|
mm_log "error" "parent device sysfspath not found"
|
|
return
|
|
}
|
|
|
|
status=$(mm_get_modem_wait_status "${parent_sysfspath}")
|
|
case "${status}" in
|
|
"")
|
|
local cfg
|
|
|
|
cfg=$(mm_get_modem_config "${parent_sysfspath}")
|
|
if [ -n "${cfg}" ]; then
|
|
mm_log "info" "interface '${cfg}' is set to configure device '${parent_sysfspath}'"
|
|
mm_log "info" "now waiting for modem at sysfs path ${parent_sysfspath}"
|
|
mm_set_modem_wait_status "${parent_sysfspath}" "processed"
|
|
# Launch subshell for the explicit wait
|
|
( mm_wait_for_modem "${cfg}" "${parent_sysfspath}" ) > /dev/null 2>&1 &
|
|
else
|
|
mm_log "info" "no need to wait for modem at sysfs path ${parent_sysfspath}"
|
|
mm_set_modem_wait_status "${parent_sysfspath}" "ignored"
|
|
fi
|
|
;;
|
|
"processed")
|
|
mm_log "info" "already waiting for modem at sysfs path ${parent_sysfspath}"
|
|
;;
|
|
"ignored")
|
|
;;
|
|
*)
|
|
mm_log "error" "unknown status read for device at sysfs path ${parent_sysfspath}"
|
|
;;
|
|
esac
|
|
}
|
|
|
|
################################################################################
|
|
# Cleanup interfaces
|
|
|
|
mm_cleanup_interface_cb() {
|
|
local cfg="$1"
|
|
|
|
local proto
|
|
config_get proto "${cfg}" proto
|
|
[ "${proto}" = modemmanager ] || return 0
|
|
|
|
proto_set_available "${cfg}" 0
|
|
}
|
|
|
|
mm_cleanup_interfaces() {
|
|
config_load network
|
|
config_foreach mm_cleanup_interface_cb interface
|
|
}
|
|
|
|
mm_cleanup_interface_by_sysfspath() {
|
|
local dev="$1"
|
|
|
|
local cfg
|
|
cfg=$(mm_get_modem_config "$dev")
|
|
[ -n "${cfg}" ] || return
|
|
|
|
mm_log "info" "setting interface '$cfg' as unavailable"
|
|
proto_set_available "${cfg}" 0
|
|
}
|
|
|
|
################################################################################
|
|
# Event reporting
|
|
|
|
# Receives as input the action, the device name and the subsystem
|
|
mm_report_event() {
|
|
local action="$1"
|
|
local name="$2"
|
|
local subsystem="$3"
|
|
local sysfspath="$4"
|
|
|
|
# Track/untrack events in cache
|
|
case "${action}" in
|
|
"add")
|
|
# On add events, store event details in cache (if not exists yet)
|
|
grep -qs "${name},${subsystem}" "${MODEMMANAGER_EVENTS_CACHE}" || \
|
|
echo "${action},${name},${subsystem},${sysfspath}" >> "${MODEMMANAGER_EVENTS_CACHE}"
|
|
;;
|
|
"remove")
|
|
# On remove events, remove old events from cache (match by subsystem+name)
|
|
sed -i "/${name},${subsystem}/d" "${MODEMMANAGER_EVENTS_CACHE}"
|
|
;;
|
|
esac
|
|
|
|
# Report the event
|
|
mm_log "debug" "event reported: action=${action}, name=${name}, subsystem=${subsystem}"
|
|
mmcli --report-kernel-event="action=${action},name=${name},subsystem=${subsystem}" 1>/dev/null 2>&1 &
|
|
|
|
# Wait for added modem if a sysfspath is given
|
|
[ -n "${sysfspath}" ] && [ "$action" = "add" ] && mm_report_modem_wait "${sysfspath}"
|
|
}
|
|
|
|
mm_report_event_from_cache_line() {
|
|
local event_line="$1"
|
|
|
|
local action name subsystem sysfspath
|
|
action=$(echo "${event_line}" | awk -F ',' '{ print $1 }')
|
|
name=$(echo "${event_line}" | awk -F ',' '{ print $2 }')
|
|
subsystem=$(echo "${event_line}" | awk -F ',' '{ print $3 }')
|
|
sysfspath=$(echo "${event_line}" | awk -F ',' '{ print $4 }')
|
|
|
|
mm_log "debug" "cached event found: action=${action}, name=${name}, subsystem=${subsystem}, sysfspath=${sysfspath}"
|
|
mm_report_event "${action}" "${name}" "${subsystem}" "${sysfspath}"
|
|
}
|
|
|
|
mm_report_events_from_cache() {
|
|
# Remove the sysfs cache
|
|
rm -f "${MODEMMANAGER_SYSFS_CACHE}"
|
|
|
|
local n=60
|
|
local step=1
|
|
local mmrunning=0
|
|
|
|
# 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 ! 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
|
|
}
|
|
|
|
# Report cached kernel events
|
|
while IFS= read -r event_line; do
|
|
mm_report_event_from_cache_line "${event_line}"
|
|
done < ${MODEMMANAGER_EVENTS_CACHE}
|
|
}
|