commit:     a0b69349707b4aaaefc01fd37f1b386935d75c90
Author:     Alon Bar-Lev <alon.barlev <AT> gmail <DOT> com>
AuthorDate: Sun May 14 21:38:28 2023 +0000
Commit:     Robin H. Johnson <robbat2 <AT> gentoo <DOT> org>
CommitDate: Sat Nov 25 04:54:01 2023 +0000
URL:        https://gitweb.gentoo.org/proj/netifrc.git/commit/?id=a0b69349

net: add qmi interface support

qmi is useful for cellular modem connection, the management interface is
implemented using libqmi's qmicli utility.

Signed-off-by: Alon Bar-Lev <alon.barlev <AT> gmail.com>
Signed-off-by: Robin H. Johnson <robbat2 <AT> gentoo.org>
Closes: https://github.com/gentoo/netifrc/pull/44

 doc/net.example.Linux.in |  13 +++++
 net/Makefile             |   2 +-
 net/qmi.sh               | 133 +++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+), 1 deletion(-)

diff --git a/doc/net.example.Linux.in b/doc/net.example.Linux.in
index 42b8071..cbd81e7 100644
--- a/doc/net.example.Linux.in
+++ b/doc/net.example.Linux.in
@@ -1132,6 +1132,19 @@
 #l2tpsession_l2tpeth2="tunnel_id 2 session_id 1 peer_session_id 1"
 #config_l2tpeth2="10.100.2.1/24"
 
+#-----------------------------------------------------------------------------
+# QMI
+# For QMI support, emerge net-libs/libqmi
+# QMI is used for some cellular modems.
+#
+# Each QMI interface may have the following configuration:
+#qmi_apn_wwan0=                                # The name of the APN
+#qmi_auth_wwan0=                       # none, pop, chap, both, Default: none
+#qmi_username_wwan0=                   # Default: dummy
+#qmi_password_wwan0=                   # Default dummy
+#qmi_cdc_wwan0=                                # Default: /dev/cdc-wmiX where 
X is taken from IFACE
+#-----------------------------------------------------------------------------
+
 #-----------------------------------------------------------------------------
 # Advanced Routing
 # WARNING: For advanced routing you MUST be using sys-apps/iproute2

diff --git a/net/Makefile b/net/Makefile
index 58483cd..f562d15 100644
--- a/net/Makefile
+++ b/net/Makefile
@@ -14,7 +14,7 @@ INC-Linux=    adsl.sh apipa.sh arping.sh bonding.sh 
br2684ctl.sh bridge.sh \
                ccwgroup.sh clip.sh ethtool.sh iproute2.sh ifplugd.sh ip6to4.sh 
\
                ipppd.sh iwconfig.sh netplugd.sh pppd.sh pump.sh tuntap.sh 
udhcpc.sh \
                vlan.sh macvlan.sh ip6rd.sh firewalld.sh dummy.sh hsr.sh 
l2tp.sh \
-               iw.sh iwd.sh wireguard.sh veth.sh dhclientv6.sh
+               iw.sh iwd.sh wireguard.sh veth.sh dhclientv6.sh qmi.sh
 
 SRCS-NetBSD= ifwatchd.sh.in
 INC-NetBSD=    ifwatchd.sh

diff --git a/net/qmi.sh b/net/qmi.sh
new file mode 100644
index 0000000..ac1b2dd
--- /dev/null
+++ b/net/qmi.sh
@@ -0,0 +1,133 @@
+# Copyright (c) 2011 by Gentoo Foundation
+# Released under the 2-clause BSD license.
+# shellcheck shell=sh disable=SC1008
+
+_is_qmi() {
+       [ -d "/sys/class/net/${IFACE}/qmi" ]
+}
+
+_get_state() {
+       echo "/run/net.${IFACE}.qmi.state"
+}
+
+_get_device() {
+       echo "/dev/cdc-$(echo "${IFACE}" | sed 's/wwan/wdm/')"
+}
+
+qmi_depend()
+{
+       program qmicli
+       program ip
+       before interface
+}
+
+qmi_pre_start() {
+
+       _is_qmi || return 0
+
+       local device
+       local apn
+       local auth
+       local username
+       local password
+       local out
+       local rc
+
+       eval device=\$qmi_cdc_${IFVAR}
+       eval apn=\$qmi_apn_${IFVAR}
+       eval auth=\$qmi_auth_${IFVAR}
+       eval username=\$qmi_username_${IFVAR}
+       eval password=\$qmi_password_${IFVAR}
+
+       [ -n "${apn}" ] || return 0
+
+       [ -n "${device}" ] || device="$(_get_device)"
+       [ -n "${auth}" ] || auth="none"
+       [ -n "${username}" ] || username="dummy"
+       [ -n "${password}" ] || password="dummy"
+
+       if ! [ -c "${device}" ]; then
+               ewarn "Cannot open device ${device} for ${IFACE}, aborting 
configuration"
+               return 1
+       fi
+
+       if ! cat "/sys/class/net/${IFACE}/qmi/raw_ip" | grep -q Y; then
+               ebegin "Configuring QMI raw IP"
+
+               ip link set "${IFACE}" down
+               if ! echo Y > "/sys/class/net/${IFACE}/qmi/raw_ip"; then
+                       eend 1 "Cannot set raw IP mode for ${IFACE}, aborting 
configuration"
+                       return 1
+               else
+                       eend 0
+               fi
+       fi
+
+       local 
wwan_connection="apn='${apn}',auth='${auth}',username='${username}',password='${password}',autoconnect=yes,ip-type=4"
+       local n
+       for n in 1 2 3; do
+               ebegin "Connecting QMI APN '${apn}' using '${username}'"
+
+               if out="$( \
+                       qmicli \
+                               --device="${device}" \
+                               --wds-start-network="${wwan_connection}" \
+                               --device-open-proxy \
+                               --client-no-release-cid \
+               )"; then
+                       eend 0
+                       break
+               elif echo "${out}" | grep -qi "timed out"; then
+                       eend 1 "QMI start network timeout"
+               else
+                       eend 1 "QMI start network failed for ${IFACE}, aborting"
+                       return 1
+               fi
+       done
+
+       local handle="$(echo "${out}" | grep "Packet data handle:" | sed 
"s/.*'\(.*\)'.*/\1/")"
+       local cid="$(echo "${out}" | grep "CID:" | sed "s/.*'\(.*\)'.*/\1/")"
+
+       if [ -z "${handle}" ]; then
+               ewarn 1 "No QMI connection handle ${IFACE}, aborting 
configuration"
+               return 1
+       fi
+
+       if [ -z "${cid}" ]; then
+               ewarn "No QMI connection id ${IFACE}, aborting configuration"
+               return 1
+       fi
+
+       cat > "$(_get_state)" << __EOF__
+device="${device}"
+handle="${handle}"
+cid="${cid}"
+__EOF__
+}
+
+qmi_post_stop() {
+
+       _is_qmi || return 0
+
+       local state="$(_get_state)"
+
+       [ -f "${state}" ] || return 0
+
+       ebegin "Disconnecting QMI ${IFACE}"
+
+       local device
+       local handle
+       local cid
+
+       . "${state}"
+
+       qmicli \
+               --device="${device}" \
+               --client-cid="${cid}" \
+               --wds-stop-network="${handle}"
+       rc="$?"
+
+       rm -f "${state}"
+
+       eend "${rc}"
+}

Reply via email to