diff --git a/net/modemmanager/Makefile b/net/modemmanager/Makefile index d617cc022..e616bc070 100644 --- a/net/modemmanager/Makefile +++ b/net/modemmanager/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=modemmanager PKG_VERSION:=1.12.0 -PKG_RELEASE:=3 +PKG_RELEASE:=8 PKG_SOURCE:=ModemManager-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=https://www.freedesktop.org/software/ModemManager @@ -119,19 +119,20 @@ define Package/modemmanager/install $(INSTALL_DIR) $(1)/usr/share/ModemManager $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/ModemManager/*.conf $(1)/usr/share/ModemManager + $(INSTALL_DATA) ./files/modemmanager.common $(1)/usr/share/ModemManager $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_BIN) ./files/modemmanager.init $(1)/etc/init.d/modemmanager + $(INSTALL_DIR) $(1)/etc/hotplug.d/usb + $(INSTALL_DATA) ./files/25-modemmanager-usb $(1)/etc/hotplug.d/usb + $(INSTALL_DIR) $(1)/etc/hotplug.d/net $(INSTALL_DATA) ./files/25-modemmanager-net $(1)/etc/hotplug.d/net $(INSTALL_DIR) $(1)/etc/hotplug.d/tty $(INSTALL_DATA) ./files/25-modemmanager-tty $(1)/etc/hotplug.d/tty - $(INSTALL_DIR) $(1)/etc/modemmanager - $(INSTALL_DATA) ./files/modemmanager.common $(1)/etc/modemmanager/modemmanager.common - $(INSTALL_DIR) $(1)/lib/netifd/proto $(INSTALL_BIN) ./files/modemmanager.proto $(1)/lib/netifd/proto/modemmanager.sh endef diff --git a/net/modemmanager/files/25-modemmanager-net b/net/modemmanager/files/25-modemmanager-net index df15dafb2..e87231e31 100644 --- a/net/modemmanager/files/25-modemmanager-net +++ b/net/modemmanager/files/25-modemmanager-net @@ -3,7 +3,7 @@ # Copyright (C) 2016 Aleksander Morgado # Load common utilities -. /etc/modemmanager/modemmanager.common +. /usr/share/ModemManager/modemmanager.common # We require a interface name [ -n "${INTERFACE}" ] || exit diff --git a/net/modemmanager/files/25-modemmanager-tty b/net/modemmanager/files/25-modemmanager-tty index 60548dd66..c13148a33 100644 --- a/net/modemmanager/files/25-modemmanager-tty +++ b/net/modemmanager/files/25-modemmanager-tty @@ -3,7 +3,7 @@ # Copyright (C) 2016 Aleksander Morgado # Load hotplug common utilities -. /etc/modemmanager/modemmanager.common +. /usr/share/ModemManager/modemmanager.common # We require a device name [ -n "$DEVNAME" ] || exit diff --git a/net/modemmanager/files/25-modemmanager-usb b/net/modemmanager/files/25-modemmanager-usb new file mode 100644 index 000000000..93d0bf70a --- /dev/null +++ b/net/modemmanager/files/25-modemmanager-usb @@ -0,0 +1,13 @@ +#!/bin/sh +# Copyright (C) 2019 Aleksander Morgado + +# We need to process only full USB device removal events, we don't +# want to process specific interface removal events. +[ "$ACTION" = remove ] || exit +[ -z "${INTERFACE}" ] || exit + +# Load common utilities +. /usr/share/ModemManager/modemmanager.common + +mm_clear_modem_wait_status "/sys${DEVPATH}" +mm_cleanup_interface_by_sysfspath "/sys${DEVPATH}" diff --git a/net/modemmanager/files/modemmanager.common b/net/modemmanager/files/modemmanager.common index 2f882e496..532d90ac0 100644 --- a/net/modemmanager/files/modemmanager.common +++ b/net/modemmanager/files/modemmanager.common @@ -26,6 +26,9 @@ mm_log() { ################################################################################ # 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" @@ -96,14 +99,26 @@ mm_get_modem_wait_status() { 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 - [ -f "${MODEMMANAGER_SYSFS_CACHE}" ] && - sed -i "/${sysfspath}/d" "${MODEMMANAGER_SYSFS_CACHE}" + mm_clear_modem_wait_status "${sysfspath}" # Add the new status echo "${sysfspath} ${status}" >> "${MODEMMANAGER_SYSFS_CACHE}" @@ -171,8 +186,7 @@ mm_wait_for_modem() { } mm_report_modem_wait() { - local action=$1 - local sysfspath=$2 + local sysfspath=$1 local parent_sysfspath status @@ -183,53 +197,31 @@ mm_report_modem_wait() { } status=$(mm_get_modem_wait_status "${parent_sysfspath}") - - [ "$action" = "add" ] && { - case "${status}" in - "") - local cfg - - cfg=$(mm_get_modem_config "${parent_sysfspath}") - if [ -n "${cfg}" ]; then - mm_log "interface '${cfg}' is set to configure device '${parent_sysfspath}'" - mm_log "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 "no need to wait for modem at sysfs path ${parent_sysfspath}" - mm_set_modem_wait_status "${parent_sysfspath}" "ignored" - fi - ;; - "processed") - mm_log "already waiting for modem at sysfs path ${parent_sysfspath}" - ;; - "ignored") - ;; - *) - mm_log "error: unknown status read for device at sysfs path ${parent_sysfspath}" - ;; - esac - return - } - - [ "$action" = "remove" ] && { - local cfg - - [ -n "$status" ] && { + case "${status}" in + "") local cfg - mm_log "cleanup wait for modem at sysfs path ${parent_sysfspath}" - mm_set_modem_wait_status "${parent_sysfspath}" "" - cfg=$(mm_get_modem_config "${parent_sysfspath}") - [ -n "${cfg}" ] && { - mm_log "setting interface '$cfg' as unavailable" - proto_set_available "${cfg}" 0 - } - } - return - } + if [ -n "${cfg}" ]; then + mm_log "interface '${cfg}' is set to configure device '${parent_sysfspath}'" + mm_log "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 "no need to wait for modem at sysfs path ${parent_sysfspath}" + mm_set_modem_wait_status "${parent_sysfspath}" "ignored" + fi + ;; + "processed") + mm_log "already waiting for modem at sysfs path ${parent_sysfspath}" + ;; + "ignored") + ;; + *) + mm_log "error: unknown status read for device at sysfs path ${parent_sysfspath}" + ;; + esac } ################################################################################ @@ -250,6 +242,17 @@ mm_cleanup_interfaces() { 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 "setting interface '$cfg' as unavailable" + proto_set_available "${cfg}" 0 +} + ################################################################################ # Event reporting @@ -277,8 +280,8 @@ mm_report_event() { mm_log "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 modem if a sysfspath is given - [ -n "${sysfspath}" ] && mm_report_modem_wait "${action}" "${sysfspath}" + # Wait for added modem if a sysfspath is given + [ -n "${sysfspath}" ] && [ "$action" = "add" ] && mm_report_modem_wait "${sysfspath}" } mm_report_event_from_cache_line() { diff --git a/net/modemmanager/files/modemmanager.init b/net/modemmanager/files/modemmanager.init index 45a2ba11a..4c9548654 100755 --- a/net/modemmanager/files/modemmanager.init +++ b/net/modemmanager/files/modemmanager.init @@ -6,14 +6,14 @@ START=70 stop_service() { # Load common utils - . /etc/modemmanager/modemmanager.common + . /usr/share/ModemManager/modemmanager.common # Set all configured interfaces as unavailable mm_cleanup_interfaces } start_service() { # Load common utils - . /etc/modemmanager/modemmanager.common + . /usr/share/ModemManager/modemmanager.common # Always make sure the rundir exists mkdir -m 0755 -p "${MODEMMANAGER_RUNDIR}" diff --git a/net/modemmanager/files/modemmanager.proto b/net/modemmanager/files/modemmanager.proto index 94cf0abce..536073dce 100755 --- a/net/modemmanager/files/modemmanager.proto +++ b/net/modemmanager/files/modemmanager.proto @@ -304,13 +304,16 @@ modemmanager_disconnected_method_common() { } proto_modemmanager_init_config() { - proto_config_add_string "device:device" + available=1 + no_device=1 + proto_config_add_string device proto_config_add_string apn proto_config_add_string username proto_config_add_string password proto_config_add_string pincode proto_config_add_string iptype proto_config_add_boolean lowpower + proto_config_add_defaults } proto_modemmanager_setup() {