From 7ac8242a9d970e709493bf82e0e2d864ee7d33b0 Mon Sep 17 00:00:00 2001 From: coolsnowwolf Date: Tue, 9 Apr 2024 23:25:24 +0800 Subject: [PATCH] modemmanager: bump to 1.22.0 --- libs/libmbim/Makefile | 5 +- libs/libqmi/Makefile | 10 +- libs/libxml2/Makefile | 10 +- libs/libxslt/Makefile | 57 +-- net/modemmanager/Makefile | 44 ++- net/modemmanager/README.md | 19 + net/modemmanager/files/25-modemmanager-usb | 13 - .../hotplug.d/net}/25-modemmanager-net | 0 .../hotplug.d/tty}/25-modemmanager-tty | 0 .../hotplug.d/wwan}/25-modemmanager-wwan | 0 .../init.d/modemmanager} | 13 +- .../netifd/proto/modemmanager.sh} | 370 +++++++++++++----- .../ModemManager/connection.d}/10-report-down | 14 +- .../files/usr/sbin/ModemManager-monitor | 155 ++++++++ .../files/usr/sbin/ModemManager-wrapper | 5 +- .../share/ModemManager}/modemmanager.common | 257 +++++------- .../100-ublox-remove-ID_MM_PROCESS-tags.patch | 13 + 17 files changed, 638 insertions(+), 347 deletions(-) delete mode 100644 net/modemmanager/files/25-modemmanager-usb rename net/modemmanager/files/{ => etc/hotplug.d/net}/25-modemmanager-net (100%) rename net/modemmanager/files/{ => etc/hotplug.d/tty}/25-modemmanager-tty (100%) rename net/modemmanager/files/{ => etc/hotplug.d/wwan}/25-modemmanager-wwan (100%) rename net/modemmanager/files/{modemmanager.init => etc/init.d/modemmanager} (81%) mode change 100755 => 100644 rename net/modemmanager/files/{modemmanager.proto => lib/netifd/proto/modemmanager.sh} (65%) mode change 100755 => 100644 rename net/modemmanager/files/{ => usr/lib/ModemManager/connection.d}/10-report-down (73%) mode change 100755 => 100644 create mode 100644 net/modemmanager/files/usr/sbin/ModemManager-monitor rename net/modemmanager/files/{ => usr/share/ModemManager}/modemmanager.common (54%) create mode 100644 net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch diff --git a/libs/libmbim/Makefile b/libs/libmbim/Makefile index 0d74b542..5374d76a 100644 --- a/libs/libmbim/Makefile +++ b/libs/libmbim/Makefile @@ -8,16 +8,17 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libmbim -PKG_SOURCE_VERSION:=1.28.4 +PKG_SOURCE_VERSION:=1.30.0 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libmbim.git -PKG_MIRROR_HASH:=7ecc6d1e565392817311254045337907bbad015b46ec88542ea63594f47778be +PKG_MIRROR_HASH:=8fc4e2d78d6a1003bf89303d3ce779283b176d74e84a241ba8efb0d468605268 PKG_BUILD_FLAGS:=gc-sections PKG_MAINTAINER:=Nicholas Smith +PKG_CPE_ID:=cpe:/a:freedesktop:libmbim include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/nls.mk diff --git a/libs/libqmi/Makefile b/libs/libqmi/Makefile index bfa3bab7..4e82d9cd 100644 --- a/libs/libqmi/Makefile +++ b/libs/libqmi/Makefile @@ -8,21 +8,23 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libqmi -PKG_SOURCE_VERSION:=1.32.2 +PKG_SOURCE_VERSION:=1.34.0 PKG_RELEASE:=1 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/libqmi.git -PKG_MIRROR_HASH:=711d16d75a6a9afaefcf2be1bc845a4a6181dff786dfbd079e41e91279a0be91 +PKG_MIRROR_HASH:=af3dc760d0c40ef8af1f8b424435daa12bff698ed45b1cc9a9e38ea62ed047f0 + +PKG_BUILD_FLAGS:=gc-sections PKG_MAINTAINER:=Nicholas Smith +PKG_CPE_ID:=cpe:/a:libqmi_project:libqmi include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/nls.mk include $(INCLUDE_DIR)/meson.mk -TARGET_CFLAGS += -ffunction-sections -fdata-sections -fno-merge-all-constants -fmerge-constants -TARGET_LDFLAGS += -Wl,--gc-sections +TARGET_CFLAGS += -fno-merge-all-constants -fmerge-constants define Package/libqmi/config source "$(SOURCE)/Config.in" diff --git a/libs/libxml2/Makefile b/libs/libxml2/Makefile index 4ab4fd94..b599257b 100644 --- a/libs/libxml2/Makefile +++ b/libs/libxml2/Makefile @@ -8,14 +8,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=libxml2 -PKG_VERSION:=2.10.3 -PKG_RELEASE:=2 +PKG_VERSION:=2.10.4 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz PKG_SOURCE_URL:=@GNOME/libxml2/$(basename $(PKG_VERSION)) -PKG_HASH:=5d2cc3d78bec3dbe212a9d7fa629ada25a7da928af432c93060ff5c17ee28a9c +PKG_HASH:=ed0c91c5845008f1936739e4eee2035531c1c94742c6541f44ee66d885948d45 -PKG_MAINTAINER:=Michael Heimpold PKG_LICENSE:=MIT PKG_LICENSE_FILES:=COPYING PKG_CPE_ID:=cpe:/a:xmlsoft:libxml2 @@ -99,7 +98,6 @@ CONFIGURE_ARGS += \ --with-xpath \ --with-xptr \ --with-zlib=$(STAGING_DIR)/usr \ - --with-iconv$(if $(ICONV_PREFIX),="$(ICONV_PREFIX)") \ --without-lzma HOST_CONFIGURE_ARGS += \ @@ -198,4 +196,4 @@ endef $(eval $(call HostBuild)) $(eval $(call BuildPackage,libxml2)) $(eval $(call BuildPackage,libxml2-dev)) -$(eval $(call BuildPackage,libxml2-utils)) \ No newline at end of file +$(eval $(call BuildPackage,libxml2-utils)) diff --git a/libs/libxslt/Makefile b/libs/libxslt/Makefile index d9c0873c..09fd2d4b 100644 --- a/libs/libxslt/Makefile +++ b/libs/libxslt/Makefile @@ -20,12 +20,13 @@ PKG_LICENSE:=MIT PKG_LICENSE_FILES:=COPYING PKG_CPE_ID:=cpe:/a:xmlsoft:libxslt +PKG_FIXUP:=autoreconf +PKG_INSTALL:=1 +PKG_BUILD_PARALLEL:=1 HOST_BUILD_DEPENDS:=libxml2/host -CMAKE_BINARY_SUBDIR:=openwrt-build include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/host-build.mk -include $(INCLUDE_DIR)/cmake.mk include $(INCLUDE_DIR)/nls.mk define Package/libxslt @@ -64,40 +65,36 @@ define Package/xsltproc/description XSLT XML transformation utility. endef -CMAKE_HOST_OPTIONS += \ - -DBUILD_SHARED_LIBS=OFF \ - -DLIBXSLT_WITH_DEBUGGER=OFF \ - -DLIBXSLT_WITH_CRYPTO=OFF \ - -DLIBXSLT_WITH_MEM_DEBUG=OFF \ - -DLIBXSLT_WITH_MODULES=OFF \ - -DLIBXSLT_WITH_PROFILER=OFF \ - -DLIBXSLT_WITH_PYTHON=OFF \ - -DLIBXSLT_WITH_TESTS=OFF \ - -DLIBXSLT_WITH_THREADS=ON \ - -DLIBXSLT_WITH_XSLT_DEBUG=OFF +CONFIGURE_ARGS += \ + --enable-shared \ + --enable-static \ + --without-python \ + --without-crypto \ + --without-debug \ + --without-mem-debug \ + --without-debugger \ + --without-plugins -CMAKE_OPTIONS += \ - -DBUILD_SHARED_LIBS=ON \ - -DLIBXSLT_WITH_DEBUGGER=OFF \ - -DLIBXSLT_WITH_CRYPTO=OFF \ - -DLIBXSLT_WITH_MEM_DEBUG=OFF \ - -DLIBXSLT_WITH_MODULES=OFF \ - -DLIBXSLT_WITH_PROFILER=ON \ - -DLIBXSLT_WITH_PYTHON=OFF \ - -DLIBXSLT_WITH_TESTS=OFF \ - -DLIBXSLT_WITH_THREADS=ON \ - -DLIBXSLT_WITH_XSLT_DEBUG=OFF +HOST_CONFIGURE_ARGS += \ + --with-libxml-prefix=$(STAGING_DIR_HOSTPKG) \ + --without-python \ + --without-crypto \ + --without-debug \ + --without-mem-debug \ + --without-debugger \ + --without-profiler \ + --without-plugins define Build/InstallDev/Xslt $(INSTALL_DIR) $(1)/usr/bin $(2)/bin $(1)/usr/include/libxslt \ $(1)/usr/include/libexslt $(1)/usr/lib \ - $(1)/usr/lib/pkgconfig + $(1)/usr/lib/pkgconfig $(2)/share/aclocal $(INSTALL_BIN) \ $(PKG_INSTALL_DIR)/usr/bin/xslt-config \ $(2)/bin/ - $(LN) $(STAGING_DIR)/host/bin/xslt-config $(1)/usr/bin/xslt-config + ln -sf $(STAGING_DIR)/host/bin/xslt-config $(1)/usr/bin/xslt-config $(SED) \ 's,^\(prefix\|exec_prefix\)=.*,\1=$(STAGING_DIR)/usr,g' \ @@ -108,12 +105,16 @@ define Build/InstallDev/Xslt $(1)/usr/include/libxslt/ $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/libxslt.so* \ + $(PKG_INSTALL_DIR)/usr/lib/libxslt.{la,a,so*} \ $(1)/usr/lib/ $(INSTALL_DATA) \ $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/libxslt.pc \ $(1)/usr/lib/pkgconfig/ + + $(INSTALL_DATA) \ + $(PKG_INSTALL_DIR)/usr/share/aclocal/* \ + $(2)/share/aclocal endef define Build/InstallDev/Exslt @@ -123,7 +124,7 @@ define Build/InstallDev/Exslt $(1)/usr/include/libexslt/ $(CP) \ - $(PKG_INSTALL_DIR)/usr/lib/libexslt.so* \ + $(PKG_INSTALL_DIR)/usr/lib/libexslt.{la,a,so*} \ $(1)/usr/lib/ $(INSTALL_DATA) \ diff --git a/net/modemmanager/Makefile b/net/modemmanager/Makefile index 6cbd6f73..8759cd40 100644 --- a/net/modemmanager/Makefile +++ b/net/modemmanager/Makefile @@ -8,25 +8,25 @@ include $(TOPDIR)/rules.mk PKG_NAME:=modemmanager -PKG_SOURCE_VERSION:=1.20.2 -PKG_RELEASE:=1 +PKG_SOURCE_VERSION:=1.22.0 +PKG_RELEASE:=12 PKG_SOURCE_PROTO:=git PKG_SOURCE_URL:=https://gitlab.freedesktop.org/mobile-broadband/ModemManager.git -PKG_MIRROR_HASH:=f138effc693456c5040ec22e17c0a8b41143c3b17b62437462995c297a9150dc +PKG_MIRROR_HASH:=98daa1a15075c88afb3ed0de20dc83fe51d2ba3c66318ce3f731da4616a2e192 PKG_MAINTAINER:=Nicholas Smith PKG_LICENSE:=GPL-2.0-or-later PKG_LICENSE_FILES:=COPYING PKG_BUILD_DEPENDS:=glib2/host libxslt/host +PKG_BUILD_FLAGS:=gc-sections include $(INCLUDE_DIR)/package.mk include $(INCLUDE_DIR)/nls.mk include $(INCLUDE_DIR)/meson.mk -TARGET_CFLAGS += -ffunction-sections -fdata-sections -fno-merge-all-constants -fmerge-constants -TARGET_LDFLAGS += -Wl,--gc-sections +TARGET_CFLAGS += -fno-merge-all-constants -fmerge-constants define Package/modemmanager/config source "$(SOURCE)/Config.in" @@ -64,6 +64,7 @@ MESON_ARGS += \ -Dintrospection=false \ -Dman=false \ -Dbash_completion=false \ + -Dbuiltin_plugins=true \ -Db_lto=true \ -Dmbim=$(if $(CONFIG_MODEMMANAGER_WITH_MBIM),true,false) \ -Dqmi=$(if $(CONFIG_MODEMMANAGER_WITH_QMI),true,false) \ @@ -80,6 +81,8 @@ define Build/InstallDev $(INSTALL_DIR) $(1)/usr/lib/pkgconfig $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/ModemManager.pc $(1)/usr/lib/pkgconfig $(CP) $(PKG_INSTALL_DIR)/usr/lib/pkgconfig/mm-glib.pc $(1)/usr/lib/pkgconfig + $(INSTALL_DIR) $(1)/usr/share/dbus-1/interfaces + $(CP) $(PKG_BUILD_DIR)/introspection/org.freedesktop.ModemManager1.* $(1)/usr/share/dbus-1/interfaces endef define Package/modemmanager/install @@ -89,6 +92,7 @@ define Package/modemmanager/install $(INSTALL_DIR) $(1)/usr/sbin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/ModemManager $(1)/usr/sbin $(INSTALL_BIN) ./files/usr/sbin/ModemManager-wrapper $(1)/usr/sbin + $(INSTALL_BIN) ./files/usr/sbin/ModemManager-monitor $(1)/usr/sbin $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/mmcli $(1)/usr/bin @@ -96,12 +100,9 @@ define Package/modemmanager/install $(INSTALL_DIR) $(1)/usr/lib $(CP) $(PKG_INSTALL_DIR)/usr/lib/libmm-glib.so.* $(1)/usr/lib - $(INSTALL_DIR) $(1)/usr/lib/ModemManager - $(CP) $(PKG_INSTALL_DIR)/usr/lib/ModemManager/libmm-shared-*.so* $(1)/usr/lib/ModemManager - $(CP) $(PKG_INSTALL_DIR)/usr/lib/ModemManager/libmm-plugin-*.so* $(1)/usr/lib/ModemManager - $(INSTALL_DIR) $(1)/usr/lib/ModemManager/connection.d - $(INSTALL_BIN) ./files/10-report-down $(1)/usr/lib/ModemManager/connection.d + $(INSTALL_BIN) ./files/usr/lib/ModemManager/connection.d/10-report-down \ + $(1)/usr/lib/ModemManager/connection.d $(INSTALL_DIR) $(1)/etc/dbus-1/system.d $(INSTALL_CONF) $(PKG_INSTALL_DIR)/etc/dbus-1/system.d/org.freedesktop.ModemManager1.conf $(1)/etc/dbus-1/system.d @@ -110,29 +111,32 @@ define Package/modemmanager/install $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/dbus-1/system-services/org.freedesktop.ModemManager1.service $(1)/usr/share/dbus-1/system-services $(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 + $$(if $$(wildcard $(PKG_INSTALL_DIR)/usr/share/ModemManager/*.conf),$(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/ModemManager/*.conf $(1)/usr/share/ModemManager,) + $(INSTALL_DATA) ./files/usr/share/ModemManager/modemmanager.common \ + $(1)/usr/share/ModemManager $(INSTALL_DIR) $(1)/usr/share/ModemManager/fcc-unlock.available.d $(INSTALL_DATA) $(PKG_INSTALL_DIR)/usr/share/ModemManager/fcc-unlock.available.d/* $(1)/usr/share/ModemManager/fcc-unlock.available.d $(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_BIN) ./files/etc/init.d/modemmanager \ + $(1)/etc/init.d/modemmanager $(INSTALL_DIR) $(1)/etc/hotplug.d/net - $(INSTALL_DATA) ./files/25-modemmanager-net $(1)/etc/hotplug.d/net + $(INSTALL_DATA) ./files/etc/hotplug.d/net/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_DATA) ./files/etc/hotplug.d/tty/25-modemmanager-tty \ + $(1)/etc/hotplug.d/tty $(INSTALL_DIR) $(1)/etc/hotplug.d/wwan - $(INSTALL_DATA) ./files/25-modemmanager-wwan $(1)/etc/hotplug.d/wwan + $(INSTALL_DATA) ./files/etc/hotplug.d/wwan/25-modemmanager-wwan \ + $(1)/etc/hotplug.d/wwan $(INSTALL_DIR) $(1)/lib/netifd/proto - $(INSTALL_BIN) ./files/modemmanager.proto $(1)/lib/netifd/proto/modemmanager.sh + $(INSTALL_BIN) ./files/lib/netifd/proto/modemmanager.sh \ + $(1)/lib/netifd/proto endef $(eval $(call BuildPackage,modemmanager)) diff --git a/net/modemmanager/README.md b/net/modemmanager/README.md index c9d880ea..1def1c35 100644 --- a/net/modemmanager/README.md +++ b/net/modemmanager/README.md @@ -22,8 +22,11 @@ Once installed, you can configure the 2G/3G/4G modem connections directly in option password 'vodafone' option pincode '7423' option iptype 'ipv4' + option plmn '214001' option lowpower '1' option signalrate '30' + option allow_roaming '1' + option init_epsbearer '' Only 'device' and 'proto' are mandatory options, the remaining ones are all optional. @@ -36,5 +39,21 @@ allowing all protocols. The 'iptype' option supports any of these values: 'ipv4', 'ipv6' or 'ipv4v6'. It will default to 'ipv4' if not given. +The 'plmn' option allows to set the network operator MCCMNC. + The 'signalrate' option set's the signal refresh rate (in seconds) for the device. You can call signal info with command: mmcli -m 0 --signal-get + +If there is no Circuit switch network available, then an initial EPS +bearer must be set, so this could be used during the network registration +process in 4G and 5G network. For this resaon a new configuration option +'init_epsbearer' was added, which could have the following values. +* none: Do not set an initial EPS bearer (default) +* default: Use the configuration option 'apn', 'iptype', 'allowedauth', + 'username' and 'password' for setting the initial EPS bearer. + These are the same options as when establishing a connection. +* custom: This could be used to use diffrent options when establishing a + connection. The options are prefixed with an 'init'. So we have + the following options 'init_apn', 'init_iptype', + 'init_allowedauth', 'init_username' and 'init_password' for + setting the initial EPS bearer. diff --git a/net/modemmanager/files/25-modemmanager-usb b/net/modemmanager/files/25-modemmanager-usb deleted file mode 100644 index 93d0bf70..00000000 --- a/net/modemmanager/files/25-modemmanager-usb +++ /dev/null @@ -1,13 +0,0 @@ -#!/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/25-modemmanager-net b/net/modemmanager/files/etc/hotplug.d/net/25-modemmanager-net similarity index 100% rename from net/modemmanager/files/25-modemmanager-net rename to net/modemmanager/files/etc/hotplug.d/net/25-modemmanager-net diff --git a/net/modemmanager/files/25-modemmanager-tty b/net/modemmanager/files/etc/hotplug.d/tty/25-modemmanager-tty similarity index 100% rename from net/modemmanager/files/25-modemmanager-tty rename to net/modemmanager/files/etc/hotplug.d/tty/25-modemmanager-tty diff --git a/net/modemmanager/files/25-modemmanager-wwan b/net/modemmanager/files/etc/hotplug.d/wwan/25-modemmanager-wwan similarity index 100% rename from net/modemmanager/files/25-modemmanager-wwan rename to net/modemmanager/files/etc/hotplug.d/wwan/25-modemmanager-wwan diff --git a/net/modemmanager/files/modemmanager.init b/net/modemmanager/files/etc/init.d/modemmanager old mode 100755 new mode 100644 similarity index 81% rename from net/modemmanager/files/modemmanager.init rename to net/modemmanager/files/etc/init.d/modemmanager index 7f014dc5..ccc1953a --- a/net/modemmanager/files/modemmanager.init +++ b/net/modemmanager/files/etc/init.d/modemmanager @@ -6,13 +6,6 @@ START=70 LOG_LEVEL="INFO" -stop_service() { - # Load common utils - . /usr/share/ModemManager/modemmanager.common - # Set all configured interfaces as unavailable - mm_cleanup_interfaces -} - start_service() { # Setup ModemManager service # @@ -28,11 +21,15 @@ start_service() { # wrapper script called '/usr/sbin/ModemManager-wrapper'. # . /usr/share/ModemManager/modemmanager.common - procd_open_instance + procd_open_instance "service" procd_set_param command /usr/sbin/ModemManager-wrapper procd_append_param command --log-level="$LOG_LEVEL" [ "$LOG_LEVEL" = "DEBUG" ] && procd_append_param command --debug procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}" procd_set_param pidfile "${MODEMMANAGER_PID_FILE}" procd_close_instance + procd_open_instance "monitor" + procd_set_param command /usr/sbin/ModemManager-monitor + procd_set_param respawn "${respawn_threshold:-3600}" "${respawn_timeout:-5}" "${respawn_retry:-5}" + procd_close_instance } diff --git a/net/modemmanager/files/modemmanager.proto b/net/modemmanager/files/lib/netifd/proto/modemmanager.sh old mode 100755 new mode 100644 similarity index 65% rename from net/modemmanager/files/modemmanager.proto rename to net/modemmanager/files/lib/netifd/proto/modemmanager.sh index e6ec9e20..67545513 --- a/net/modemmanager/files/modemmanager.proto +++ b/net/modemmanager/files/lib/netifd/proto/modemmanager.sh @@ -8,6 +8,7 @@ . /lib/functions.sh . ../netifd-proto.sh . ./ppp.sh + . /usr/share/ModemManager/modemmanager.common init_proto "$@" } @@ -24,72 +25,6 @@ cdr2mask () echo "${1-0}"."${2-0}"."${3-0}"."${4-0}" } -# This method expects as first argument a list of key-value pairs, as returned by mmcli --output-keyvalue -# The second argument must be exactly the name of the field to read -# -# Sample output: -# $ mmcli -m 0 -K -# modem.dbus-path : /org/freedesktop/ModemManager1/Modem/0 -# modem.generic.device-identifier : ed6eff2e3e0f90463da1c2a755b2acacd1335752 -# modem.generic.manufacturer : Dell Inc. -# modem.generic.model : DW5821e Snapdragon X20 LTE -# modem.generic.revision : T77W968.F1.0.0.4.0.GC.009\n026 -# modem.generic.carrier-configuration : GCF -# modem.generic.carrier-configuration-revision : 08E00009 -# modem.generic.hardware-revision : DW5821e Snapdragon X20 LTE -# .... -modemmanager_get_field() { - local list=$1 - local field=$2 - local value="" - - [ -z "${list}" ] || [ -z "${field}" ] && return - - # there is always at least a whitespace after each key, and we use that as part of the - # key matching we do (e.g. to avoid getting 'modem.generic.state-failed-reason' as a result - # when grepping for 'modem.generic.state'. - line=$(echo "${list}" | grep "${field} ") - value=$(echo ${line#*:}) - - # not found? - [ -n "${value}" ] || return 2 - - # only print value if set - [ "${value}" != "--" ] && echo "${value}" - return 0 -} - -# build a comma-separated list of values from the list -modemmanager_get_multivalue_field() { - local list=$1 - local field=$2 - local value="" - local length idx item - - [ -z "${list}" ] || [ -z "${field}" ] && return - - length=$(modemmanager_get_field "${list}" "${field}.length") - [ -n "${length}" ] || return 0 - [ "$length" -ge 1 ] || return 0 - - idx=1 - while [ $idx -le "$length" ]; do - item=$(modemmanager_get_field "${list}" "${field}.value\[$idx\]") - [ -n "${item}" ] && [ "${item}" != "--" ] && { - [ -n "${value}" ] && value="${value}, " - value="${value}${item}" - } - idx=$((idx + 1)) - done - - # nothing built? - [ -n "${value}" ] || return 2 - - # only print value if set - echo "${value}" - return 0 -} - modemmanager_cleanup_connection() { local modemstatus="$1" @@ -323,43 +258,183 @@ modemmanager_connected_method_static_ipv6() { proto_send_update "${interface}" } -modemmanager_disconnected_method_common() { - local interface="$1" - - echo "running disconnection (common)" - proto_notify_error "${interface}" MM_DISCONNECT_IN_PROGRESS - - proto_init_update "*" 0 - proto_send_update "${interface}" -} - proto_modemmanager_init_config() { available=1 no_device=1 - proto_config_add_string device - proto_config_add_string apn - proto_config_add_string 'allowedauth:list(string)' - proto_config_add_string username - proto_config_add_string password - proto_config_add_string pincode - proto_config_add_string iptype - proto_config_add_int signalrate + proto_config_add_string device + proto_config_add_string apn + proto_config_add_string 'allowedauth:list(string)' + proto_config_add_string username + proto_config_add_string password + proto_config_add_string allowedmode + proto_config_add_string preferredmode + proto_config_add_string pincode + proto_config_add_string iptype + proto_config_add_string plmn + proto_config_add_int signalrate proto_config_add_boolean lowpower + proto_config_add_boolean allow_roaming + proto_config_add_string init_epsbearer + proto_config_add_string init_iptype + proto_config_add_string 'init_allowedauth:list(string)' + proto_config_add_string init_password + proto_config_add_string init_user + proto_config_add_string init_apn proto_config_add_defaults } +# Append param to the global 'connectargs' variable. +append_param() { + local param="$1" + + [ -z "$param" ] && return + [ -z "$connectargs" ] || connectargs="${connectargs}," + connectargs="${connectargs}${param}" +} + +modemmanager_set_allowed_mode() { + local device="$1" + local interface="$2" + local allowedmode="$3" + + echo "setting allowed mode to '${allowedmode}'" + mmcli --modem="${device}" --set-allowed-modes="${allowedmode}" || { + proto_notify_error "${interface}" MM_INVALID_ALLOWED_MODES_LIST + proto_block_restart "${interface}" + return 1 + } +} + +modemmanager_check_state() { + local device="$1" + local modemstatus="$2" + local pincode="$3" + + local state reason + + state="$(modemmanager_get_field "${modemstatus}" "state")" + state="${state%% *}" + reason="$(modemmanager_get_field "${modemstatus}" "state-failed-reason")" + + case "$state" in + "failed") + case "$reason" in + "sim-missing") + echo "SIM missing" + proto_notify_error "${interface}" MM_FAILED_REASON_SIM_MISSING + proto_block_restart "${interface}" + return 1 + ;; + *) + proto_notify_error "${interface}" MM_FAILED_REASON_UNKNOWN + proto_block_restart "${interface}" + return 1 + ;; + esac + ;; + "locked") + if [ -n "$pincode" ]; then + mmcli --modem="${device}" -i any --pin=${pincode} || { + proto_notify_error "${interface}" MM_PINCODE_WRONG + proto_block_restart "${interface}" + return 1 + } + else + echo "PIN required" + proto_notify_error "${interface}" MM_PINCODE_REQUIRED + proto_block_restart "${interface}" + return 1 + fi + ;; + esac +} + +modemmanager_set_preferred_mode() { + local device="$1" + local interface="$2" + local allowedmode="$3" + local preferredmode="$4" + + [ -z "${preferredmode}" ] && { + echo "no preferred mode configured" + proto_notify_error "${interface}" MM_NO_PREFERRED_MODE_CONFIGURED + proto_block_restart "${interface}" + return 1 + } + + [ -z "${allowedmode}" ] && { + echo "no allowed mode configured" + proto_notify_error "${interface}" MM_NO_ALLOWED_MODE_CONFIGURED + proto_block_restart "${interface}" + return 1 + } + + echo "setting preferred mode to '${preferredmode}' (${allowedmode})" + mmcli --modem="${device}" \ + --set-preferred-mode="${preferredmode}" \ + --set-allowed-modes="${allowedmode}" || { + proto_notify_error "${interface}" MM_FAILED_SETTING_PREFERRED_MODE + proto_block_restart "${interface}" + return 1 + } +} + +modemmanager_init_epsbearer() { + local eps="$1" + local device="$2" + local connectargs="$3" + local apn="$4" + + [ "$eps" != 'none' ] && [ -z "${apn}" ] && { + echo "No '$eps' init eps bearer apn configured" + proto_notify_error "${interface}" MM_INIT_EPS_BEARER_APN_NOT_CONFIGURED + proto_block_restart "${interface}" + return 1 + } + + if [ "$eps" = "none" ]; then + echo "Deleting inital EPS bearer..." + else + echo "Setting '$eps' inital EPS bearer apn to '$apn'..." + fi + + mmcli --modem="${device}" \ + --timeout 120 \ + --3gpp-set-initial-eps-bearer-settings="${connectargs}" || { + proto_notify_error "${interface}" MM_INIT_EPS_BEARER_SET_FAILED + proto_block_restart "${interface}" + return 1 + } + + # Wait here so that the modem can set the init EPS bearer + # for registration + sleep 2 +} + proto_modemmanager_setup() { local interface="$1" local modempath modemstatus bearercount bearerpath connectargs bearerstatus beareriface local bearermethod_ipv4 bearermethod_ipv6 auth cliauth local operatorname operatorid registration accesstech signalquality + local allowedmode preferredmode - local device apn allowedauth username password pincode iptype metric signalrate + local device apn allowedauth username password pincode + local iptype plmn metric signalrate allow_roaming + + local init_epsbearer + local init_iptype init_allowedauth + local init_password init_user init_apn local address prefix gateway mtu dns1 dns2 - json_get_vars device apn allowedauth username password pincode iptype metric signalrate + json_get_vars device apn allowedauth username password + json_get_vars pincode iptype plmn metric signalrate allow_roaming + json_get_vars allowedmode preferredmode + + json_get_vars init_epsbearer + json_get_vars init_iptype init_allowedauth + json_get_vars init_password init_user init_apn # validate sysfs path given in config [ -n "${device}" ] || { @@ -368,11 +443,6 @@ proto_modemmanager_setup() { proto_set_available "${interface}" 0 return 1 } - [ -e "${device}" ] || { - echo "Device not found in sysfs" - proto_set_available "${interface}" 0 - return 1 - } # validate that ModemManager is handling the modem at the sysfs path modemstatus=$(mmcli --modem="${device}" --output-keyvalue) @@ -385,19 +455,124 @@ proto_modemmanager_setup() { } echo "modem available at ${modempath}" + modemmanager_check_state "$device" "${modemstatus}" "$pincode" + [ "$?" -ne "0" ] && return 1 + # always cleanup before attempting a new connection, just in case modemmanager_cleanup_connection "${modemstatus}" - # if allowedauth list given, build option string - for auth in $allowedauth; do - cliauth="${cliauth}${cliauth:+|}$auth" - done + mmcli --modem="${device}" --timeout 120 --enable || { + proto_notify_error "${interface}" MM_MODEM_DISABLED + return 1 + } + + [ -z "${plmn}" ] || { + echo "starting network registraion with plmn '${plmn}'..." + mmcli --modem="${device}" \ + --timeout 120 \ + --3gpp-register-in-operator="${plmn}" || { + proto_notify_error "${interface}" MM_3GPP_OPERATOR_REGISTRATION_FAILED + proto_block_restart "${interface}" + return 1 + } + } + + if [ -z "${allowedmode}" ]; then + modemmanager_set_allowed_mode "$device" "$interface" "any" + else + case "$allowedmode" in + "2g") + modemmanager_set_allowed_mode "$device" \ + "$interface" "2g" + ;; + "3g") + modemmanager_set_allowed_mode "$device" \ + "$interface" "3g" + ;; + "4g") + modemmanager_set_allowed_mode "$device" \ + "$interface" "4g" + ;; + "5g") + modemmanager_set_allowed_mode "$device" \ + "$interface" "5g" + ;; + *) + modemmanager_set_preferred_mode "$device" \ + "$interface" "${allowedmode}" "${preferredmode}" + ;; + esac + # check error for allowed_mode and preferred_mode function call + [ "$?" -ne "0" ] && return 1 + fi + + # set initial eps bearer settings + [ -z "${init_epsbearer}" ] || { + case "$init_epsbearer" in + "none") + connectargs="" + modemmanager_init_epsbearer "none" \ + "$device" "${connectargs}" "$apn" + ;; + "default") + cliauth="" + for auth in $allowedauth; do + cliauth="${cliauth}${cliauth:+|}$auth" + done + connectargs="" + append_param "apn=${apn}" + append_param "${iptype:+ip-type=${iptype}}" + append_param "${cliauth:+allowed-auth=${cliauth}}" + append_param "${username:+user=${username}}" + append_param "${password:+password=${password}}" + modemmanager_init_epsbearer "default" \ + "$device" "${connectargs}" "$apn" + ;; + "custom") + cliauth="" + for auth in $init_allowedauth; do + cliauth="${cliauth}${cliauth:+|}$auth" + done + connectargs="" + append_param "apn=${init_apn}" + append_param "${init_iptype:+ip-type=${init_iptype}}" + append_param "${cliauth:+allowed-auth=${cliauth}}" + append_param "${init_username:+user=${init_username}}" + append_param "${init_password:+password=${init_password}}" + modemmanager_init_epsbearer "custom" \ + "$device" "${connectargs}" "$init_apn" + ;; + esac + # check error for init_epsbearer function call + [ "$?" -ne "0" ] && return 1 + } # setup connect args; APN mandatory (even if it may be empty) echo "starting connection with apn '${apn}'..." proto_notify_error "${interface}" MM_CONNECT_IN_PROGRESS - connectargs="apn=${apn}${iptype:+,ip-type=${iptype}}${cliauth:+,allowed-auth=${cliauth}}${username:+,user=${username}}${password:+,password=${password}}${pincode:+,pin=${pincode}}" + # setup allow-roaming parameter + if [ -n "${allow_roaming}" ] && [ "${allow_roaming}" -eq 0 ];then + allow_roaming="no" + else + # allowed unless a user set the opposite + allow_roaming="yes" + fi + + cliauth="" + for auth in $allowedauth; do + cliauth="${cliauth}${cliauth:+|}$auth" + done + # Append options to 'connectargs' variable + connectargs="" + append_param "apn=${apn}" + append_param "allow-roaming=${allow_roaming}" + append_param "${iptype:+ip-type=${iptype}}" + append_param "${plmn:+operator-id=${plmn}}" + append_param "${cliauth:+allowed-auth=${cliauth}}" + append_param "${username:+user=${username}}" + append_param "${password:+password=${password}}" + mmcli --modem="${device}" --timeout 120 --simple-connect="${connectargs}" || { proto_notify_error "${interface}" MM_CONNECT_FAILED proto_block_restart "${interface}" @@ -509,7 +684,6 @@ proto_modemmanager_teardown() { json_get_vars device lowpower iptype echo "stopping network" - proto_notify_error "${interface}" MM_TEARDOWN_IN_PROGRESS # load connected bearer information, just the first one should be ok modemstatus=$(mmcli --modem="${device}" --output-keyvalue) @@ -531,7 +705,6 @@ proto_modemmanager_teardown() { # disconnection handling only requires special treatment in IPv4/PPP [ "${bearermethod_ipv4}" = "ppp" ] && modemmanager_disconnected_method_ppp_ipv4 "${interface}" - modemmanager_disconnected_method_common "${interface}" # disconnect mmcli --modem="${device}" --simple-disconnect || @@ -539,7 +712,6 @@ proto_modemmanager_teardown() { # disable mmcli --modem="${device}" --disable - proto_notify_error "${interface}" MM_MODEM_DISABLED # low power, only if requested [ "${lowpower:-0}" -lt 1 ] || diff --git a/net/modemmanager/files/10-report-down b/net/modemmanager/files/usr/lib/ModemManager/connection.d/10-report-down old mode 100755 new mode 100644 similarity index 73% rename from net/modemmanager/files/10-report-down rename to net/modemmanager/files/usr/lib/ModemManager/connection.d/10-report-down index a3e5fb4b..b8feb267 --- a/net/modemmanager/files/10-report-down +++ b/net/modemmanager/files/usr/lib/ModemManager/connection.d/10-report-down @@ -16,9 +16,8 @@ STATE="$4" [ "${STATE}" = "disconnected" ] || exit 0 -. /usr/share/ModemManager/modemmanager.common . /lib/netifd/netifd-proto.sh -INCLUDE_ONLY=1 . /lib/netifd/proto/modemmanager.sh +. /usr/share/ModemManager/modemmanager.common MODEM_STATUS=$(mmcli --modem="${MODEM_PATH}" --output-keyvalue) [ -n "${MODEM_STATUS}" ] || exit 1 @@ -29,7 +28,12 @@ MODEM_DEVICE=$(modemmanager_get_field "${MODEM_STATUS}" "modem.generic.device") CFG=$(mm_get_modem_config "${MODEM_DEVICE}") [ -n "${CFG}" ] || exit 3 -logger -t "modemmanager" "interface ${CFG} (network device ${INTERFACE}) ${STATE}" -proto_init_update $INTERFACE 0 -proto_send_update $CFG +IFUP=$(ifstatus "${CFG}" | jsonfilter -e "@.up") + +[ "${IFUP}" = "true" ] && { + mm_log "info" "Reconnecting '${CFG}' on '${STATE}' event" + ubus call network.interface down "{ 'interface': '${CFG}'}" + ubus call network.interface up "{ 'interface': '${CFG}'}" +} + exit 0 diff --git a/net/modemmanager/files/usr/sbin/ModemManager-monitor b/net/modemmanager/files/usr/sbin/ModemManager-monitor new file mode 100644 index 00000000..8a88ab51 --- /dev/null +++ b/net/modemmanager/files/usr/sbin/ModemManager-monitor @@ -0,0 +1,155 @@ +#!/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/' + # 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 "$@" diff --git a/net/modemmanager/files/usr/sbin/ModemManager-wrapper b/net/modemmanager/files/usr/sbin/ModemManager-wrapper index 4fd64227..b0f36c26 100644 --- a/net/modemmanager/files/usr/sbin/ModemManager-wrapper +++ b/net/modemmanager/files/usr/sbin/ModemManager-wrapper @@ -1,5 +1,7 @@ #!/bin/sh +. /usr/share/ModemManager/modemmanager.common + trap_with_arg() { func="$1" ; shift for sig ; do @@ -14,13 +16,10 @@ func_trap() { } main() { - . /usr/share/ModemManager/modemmanager.common - trap_with_arg func_trap INT TERM KILL mkdir -p "${MODEMMANAGER_RUNDIR}" chmod 0755 "${MODEMMANAGER_RUNDIR}" - mm_cleanup_interfaces /usr/sbin/ModemManager "$@" 1>/dev/null 2>/dev/null & CHILD="$!" diff --git a/net/modemmanager/files/modemmanager.common b/net/modemmanager/files/usr/share/ModemManager/modemmanager.common similarity index 54% rename from net/modemmanager/files/modemmanager.common rename to net/modemmanager/files/usr/share/ModemManager/modemmanager.common index 6367eb32..0315673d 100644 --- a/net/modemmanager/files/modemmanager.common +++ b/net/modemmanager/files/usr/share/ModemManager/modemmanager.common @@ -13,7 +13,7 @@ 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_MONITOR_CACHE="${MODEMMANAGER_RUNDIR}/monitor.cache" MODEMMANAGER_EVENTS_CACHE="${MODEMMANAGER_RUNDIR}/events.cache" ################################################################################ @@ -21,6 +21,8 @@ MODEMMANAGER_EVENTS_CACHE="${MODEMMANAGER_RUNDIR}/events.cache" mm_log() { local level="$1"; shift + + [ "${level}" = "debug" ] && return logger -p "daemon.${level}" -t "ModemManager[$$]" "hotplug: $*" } @@ -92,57 +94,11 @@ mm_untrack_cdcwdm() { 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 @@ -159,110 +115,6 @@ mm_get_modem_config() { 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 @@ -273,6 +125,27 @@ mm_report_event() { local subsystem="$3" local sysfspath="$4" + # Do not save virtual devices + local virtual result + virtual="$(echo "$sysfspath" | cut -d'/' -f4)" + [ "$virtual" = "virtual" ] && { + mm_log "debug" "sysfspath is a virtual device ($sysfspath)" + case "$name" in + "qmapmux"*) + mm_log "debug" "rmnet netdevice $name" + ;; + "qmimux"*) + mm_log "debug" "qmi_wwan qmap netdevice $name" + ;; + "mbimmux"*) + mm_log "debug" "mbim vlan netdevice $name" + ;; + *) + return + ;; + esac + } + # Track/untrack events in cache case "${action}" in "add") @@ -287,11 +160,11 @@ mm_report_event() { 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_log "debug" "Report event: action=${action}, name=${name}, subsystem=${subsystem}" + result=$(mmcli --report-kernel-event="action=${action},name=${name},subsystem=${subsystem}" 2>&1) + if [ "$?" -ne "0" ]; then + mm_log "error" "Couldn't report kernel event: ${result}" + fi } mm_report_event_from_cache_line() { @@ -308,9 +181,6 @@ mm_report_event_from_cache_line() { } mm_report_events_from_cache() { - # Remove the sysfs cache - rm -f "${MODEMMANAGER_SYSFS_CACHE}" - local n=60 local step=1 local mmrunning=0 @@ -335,8 +205,77 @@ mm_report_events_from_cache() { return } + # Remove the sysfs cache + rm -f "${MODEMMANAGER_SYSFS_CACHE}" + # Report cached kernel events while IFS= read -r event_line; do mm_report_event_from_cache_line "${event_line}" done < ${MODEMMANAGER_EVENTS_CACHE} } + +# This method expects as first argument a list of key-value pairs, as returned by mmcli --output-keyvalue +# The second argument must be exactly the name of the field to read +# +# Sample output: +# $ mmcli -m 0 -K +# modem.dbus-path : /org/freedesktop/ModemManager1/Modem/0 +# modem.generic.device-identifier : ed6eff2e3e0f90463da1c2a755b2acacd1335752 +# modem.generic.manufacturer : Dell Inc. +# modem.generic.model : DW5821e Snapdragon X20 LTE +# modem.generic.revision : T77W968.F1.0.0.4.0.GC.009\n026 +# modem.generic.carrier-configuration : GCF +# modem.generic.carrier-configuration-revision : 08E00009 +# modem.generic.hardware-revision : DW5821e Snapdragon X20 LTE +# .... +modemmanager_get_field() { + local list=$1 + local field=$2 + local value="" + + [ -z "${list}" ] || [ -z "${field}" ] && return + + # there is always at least a whitespace after each key, and we use that as part of the + # key matching we do (e.g. to avoid getting 'modem.generic.state-failed-reason' as a result + # when grepping for 'modem.generic.state'. + line=$(echo "${list}" | grep "${field} ") + value=$(echo ${line#*:}) + + # not found? + [ -n "${value}" ] || return 2 + + # only print value if set + [ "${value}" != "--" ] && echo "${value}" + return 0 +} + +# build a comma-separated list of values from the list +modemmanager_get_multivalue_field() { + local list=$1 + local field=$2 + local value="" + local length idx item + + [ -z "${list}" ] || [ -z "${field}" ] && return + + length=$(modemmanager_get_field "${list}" "${field}.length") + [ -n "${length}" ] || return 0 + [ "$length" -ge 1 ] || return 0 + + idx=1 + while [ $idx -le "$length" ]; do + item=$(modemmanager_get_field "${list}" "${field}.value\[$idx\]") + [ -n "${item}" ] && [ "${item}" != "--" ] && { + [ -n "${value}" ] && value="${value}, " + value="${value}${item}" + } + idx=$((idx + 1)) + done + + # nothing built? + [ -n "${value}" ] || return 2 + + # only print value if set + echo "${value}" + return 0 +} diff --git a/net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch b/net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch new file mode 100644 index 00000000..d1f67537 --- /dev/null +++ b/net/modemmanager/patches/100-ublox-remove-ID_MM_PROCESS-tags.patch @@ -0,0 +1,13 @@ +--- a/src/plugins/ublox/77-mm-ublox-port-types.rules ++++ b/src/plugins/ublox/77-mm-ublox-port-types.rules +@@ -88,8 +88,8 @@ SUBSYSTEMS=="usb", ATTRS{bInterfaceNumbe + # ttyUSB2 (if #2): secondary + # ttyUSB3 (if #3): unused (ignore) + ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="00", ENV{ID_MM_PORT_IGNORE}="1" +-ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1", ENV{ID_MM_DEVICE_PROCESS}="1" +-ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1", ENV{ID_MM_DEVICE_PROCESS}="1" ++ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="01", ENV{ID_MM_PORT_TYPE_AT_PRIMARY}="1" ++ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="02", ENV{ID_MM_PORT_TYPE_AT_SECONDARY}="1" + ATTRS{idVendor}=="05c6", ATTRS{idProduct}=="908b", ENV{.MM_USBIFNUM}=="03", ENV{ID_MM_PORT_IGNORE}="1" + + LABEL="mm_ublox_port_types_end"