diff options
author | Max Wölfing | 2021-10-02 16:14:08 +0200 |
---|---|---|
committer | Max Wölfing | 2021-10-02 16:14:08 +0200 |
commit | a73c42cd662493e39441fa1b07ca97fda11f7f7b (patch) | |
tree | 9f29e96056a82276c8c5a63c356b2a71c9f01772 | |
parent | 5aefb97ffb5d920bc2b15fb7c0ea287ab6cc90e4 (diff) | |
download | aur-a73c42cd662493e39441fa1b07ca97fda11f7f7b.tar.gz |
Refactoring due to new ModemManager
-rw-r--r-- | .SRCINFO | 8 | ||||
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | PKGBUILD | 10 | ||||
-rw-r--r-- | mobile_mm | 271 | ||||
-rw-r--r-- | mobile_mm.profile | 4 |
5 files changed, 169 insertions, 126 deletions
@@ -1,15 +1,15 @@ pkgbase = netctl-mm pkgdesc = Mobile broadband support for netctl using ModemManager - pkgver = 0.0.11 + pkgver = 0.1.1 pkgrel = 1 arch = any license = GPL depends = netctl depends = modemmanager + depends = jq source = mobile_mm.profile source = mobile_mm - md5sums = 03d3c43f41396093c64348c89c9c6342 - md5sums = 0f19810092c4600a13ea0aa5c5994658 + md5sums = ccd14753d61a5439ebf4ee01d500b5c8 + md5sums = e90c30ee7b5e08408515099341779d19 pkgname = netctl-mm - diff --git a/.gitignore b/.gitignore index 0d32c7dcbd50..f3bae4043f09 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ TODO Makefile -*.pkg.tar.xz +*.pkg.tar.* @@ -1,14 +1,14 @@ -# Maintainer: Max Wölfing <ff0x@infr.cat> +# Maintainer: Max Bülte <ff0x@this-is-fine.io> pkgname=netctl-mm -pkgver=0.0.11 +pkgver=0.1.1 pkgrel=1 pkgdesc="Mobile broadband support for netctl using ModemManager" arch=(any) license=('GPL') -depends=(netctl modemmanager) +depends=(netctl modemmanager jq) source=(mobile_mm.profile mobile_mm) -md5sums=('03d3c43f41396093c64348c89c9c6342' - '0f19810092c4600a13ea0aa5c5994658') +md5sums=('ccd14753d61a5439ebf4ee01d500b5c8' + 'e90c30ee7b5e08408515099341779d19') package() { install -Dm644 "$srcdir/mobile_mm.profile" "$pkgdir/etc/netctl/examples/mobile_mm" diff --git a/mobile_mm b/mobile_mm index 05c8ad151380..3480c11b72a8 100644 --- a/mobile_mm +++ b/mobile_mm @@ -1,5 +1,6 @@ -# Contributed by Max Wölfing <ff0x@infr.cat> -# Version: 0.0.13 +# Contributed by Max Bülte <ff0x@this-is-fine.io> +# Version: 0.1.1 +# shellcheck disable=SC2148,SC2016,SC1091,SC2034 # KNOWN BUGS: # - After suspend/hibernate the mobile broadband connection is not going to reconnect automatically (that's probably ok) @@ -9,68 +10,22 @@ . "$SUBR_DIR/ip" . "$SUBR_DIR/rfkill" -if ! hash mmcli; then - report_error "'mmcli' not found. Please install 'modemmanager' first" - exit 1 -else - __MMCLI=$(command -v mmcli) -fi - -# Try to get the modem ID or start ModemManager if available -MODEM_ID="$($__MMCLI -L 2>/dev/null | awk '/\/Modem\// {print $1}' | cut -d/ -f 6)" -if [[ -z "$MODEM_ID" ]] || [[ ! "$MODEM_ID" =~ ^[0-9]+$ ]]; then - if ! systemctl is-active ModemManager.service &>/dev/null; then - systemctl start ModemManager.service +DEPENDENCIES=('mmcli' 'jq') - # Wait until ModemManager has initialised the modem - TIMEOUT_MODEM=${TimeoutModem:-5} - until [[ $($__MMCLI -L 2>/dev/null | awk '/\/Modem\// {print $1}' | cut -d/ -f 6) =~ ^[0-9]+$ ]] || [ "$TIMEOUT_MODEM" -eq 0 ]; do - sleep 1 - ((TIMEOUT_MODEM--)) - done - - # Finally get the modem ID - MODEM_ID="$($__MMCLI -L 2>/dev/null | awk '/\/Modem\// {print $1}' | cut -d/ -f 6)" - if [[ -z "$MODEM_ID" ]] || [[ ! "$MODEM_ID" =~ ^[0-9]+$ ]]; then - report_error "No modem found. Please ensure you have ModemManager installed and the service is started" - exit 1 - fi - fi -fi - -# Get the modem path -MODEM=$($__MMCLI -L 2>/dev/null | sed -n 's#.*\(/org/.*/Modem/[0-9]\+\).*#\1#p') -if [[ -z "$MODEM" ]]; then - report_error "No modem found. Please ensure you have ModemManager installed and the service is started" - exit 1 -fi +function check_deps() { + local _prog="$1" -# Get the modem status -MODEM_STATUS=$($__MMCLI -m "$MODEM" 2>/dev/null | awk '/Status/ {for(i=1; i<5; i++) {getline; if ($2=="state:") {gsub("\047","",$3); print $3}}}') -if [[ "$MODEM_STATUS" == 'locked' ]]; then - report_notice "Modem is locked. Trying to supply PIN, if provided in the connection profile.." - if [[ $Pin ]]; then - PUK=""; [[ $Puk ]] && PUK="--puk=${Puk}" - SIM_PATH=$($__MMCLI -m "$MODEM" 2>/dev/null | grep 'SIM' | awk '{print $4}' | sed "s/'//g") - if [[ -n "$SIM_PATH" ]]; then - $__MMCLI -m "$MODEM_ID" -i "$SIM_PATH" $PUK --pin="${Pin}" >/dev/null 2>&1 - MODEM_STATUS=$($__MMCLI -L 2>/dev/null | sed -n "s/.*state: '\([^ \t]\+\)'.*/\1/p") - if [[ "$MODEM_STATUS" == 'locked' ]]; then - report_error "Modem is still locked. Maybe the supplied PIN is wrong or the PUK is required" - exit 1 - fi - fi - else - report_error "Modem is locked. PIN (and maybe PUK) required. Please add correspondig options to the connection profile" - exit 1 + if ! command -v "$_prog" >/dev/null 2>&1; then + report_error "'$_prog' not found. Check required dependencies." + return 1 fi -fi +} function mobile_mm_up { - local mmcli_args=() + local _mmcli_args=() if ! is_interface "$Interface"; then - report_notice "Interface '$Interface' does not exist. Is this a problem?" + report_debug "Interface '$Interface' does not exist. Is this a problem?" fi if [[ $RFKill ]]; then @@ -81,33 +36,33 @@ function mobile_mm_up { report_error "Option 'AccessPointName' is required" return 1 else - mmcli_args+=("apn=${AccessPointName}") + _mmcli_args+=("apn=${AccessPointName}") fi - [[ $Pin ]] && mmcli_args+=("pin=${Pin}") + [[ $Pin ]] && _mmcli_args+=("pin=${Pin}") - local ip_type="ipv4" + local _ip_type="ipv4" if [[ $IP6 ]] && [[ ! "$IP6" =~ (dhcp|no) ]]; then report_notice "Currently only the following options are supported for 'IP6' ('dhcp', 'no'). Continueing with disabled IPv6" IP6="no" fi - [[ "$IP6" == 'dhcp' ]] && ip_type="ipv4v6" - mmcli_args+=("ip-type=${ip_type}") + [[ "$IP6" == 'dhcp' ]] && _ip_type="ipv4v6" + _mmcli_args+=("ip-type=${_ip_type}") if [[ $User ]] && [[ $Password ]]; then - mmcli_args+=("user=${User}") - mmcli_args+=("password=${Password}") + _mmcli_args+=("user=${User}") + _mmcli_args+=("password=${Password}") fi - local roaming=0 - is_yes "${Roaming:-0}" && roaming=1 - mmcli_args+=("allow-roaming=${roaming}") + local _roaming=0 + is_yes "${Roaming:-0}" && _roaming=1 + _mmcli_args+=("allow-roaming=${_roaming}") - mmcli_args+=("number=${PhoneNumber:-*99#}") + _mmcli_args+=("number=${PhoneNumber:-*99#}") - local connect_args - connect_args=$(printf ",%s" "${mmcli_args[@]}") - connect_args=${connect_args:1} + local _connect_args + _connect_args=$(printf ",%s" "${_mmcli_args[@]}") + _connect_args=${_connect_args:1} if [[ $Mode ]] && [[ ! "$Mode" =~ ^(ANY|2G|3G|4G)$ ]]; then report_notice "Mode must be one of (ANY, 2G, 3G, 4G). Selecting 4G as preferred mode" @@ -116,42 +71,47 @@ function mobile_mm_up { Mode="4G" fi - report_debug "Full connect string: $__MMCLI -m $MODEM --set-allowed-modes=ANY --set-preferred-mode=${Mode} --simple-connect=$connect_args" + report_debug "Full connect string: mmcli -m $MODEM --set-allowed-modes=ANY --set-preferred-mode=${Mode} --simple-connect=$_connect_args" # Trying to establish the broadband connection until the modem got its bearer (and the bearer_interface) or the timeout is reached - local bearer=''; bearer_interface=''; TIMEOUT_CONNECT=${TimeoutConnect:-30} - until [[ -n "$bearer_interface" ]] || [ "$TIMEOUT_CONNECT" -eq 0 ]; do - $__MMCLI -m "$MODEM" --set-allowed-modes=ANY --set-preferred-mode="${Mode}" --simple-connect="$connect_args" + local _bearer _bearer_interface + TIMEOUT_CONNECT=${TimeoutConnect:-30} + _bearer=''; _bearer_interface='' + + until [[ -n "$_bearer_interface" ]] || [ "$TIMEOUT_CONNECT" -eq 0 ]; do + mmcli -m "$MODEM" --set-allowed-modes=ANY --set-preferred-mode="${Mode}" --simple-connect="$_connect_args" - if [[ -n "$bearer" ]]; then + if [[ -n "$_bearer" ]]; then report_debug "Bearer found on modem" - until [[ $($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | awk '/Status/ {for(i=1; i<5; i++) {getline; if ($2=="interface:") {gsub("\047","",$3); print $3}}}') ]] || [ "$TIMEOUT_CONNECT" -eq 0 ]; do + + until mmcli -J -m "$MODEM" 2>/dev/null | jq -r '.[].generic.bearers[0]' 2>/dev/null || [ "$TIMEOUT_MODEM" -eq 0 ]; do sleep 1 ((TIMEOUT_CONNECT--)) done - bearer_interface=$($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | awk '/Status/ {for(i=1; i<5; i++) {getline; if ($2=="interface:") {gsub("\047","",$3); print $3}}}') + + _bearer_interface="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[].status.interface' 2>/dev/null)" else sleep 1 - bearer=$($__MMCLI -m "$MODEM" 2>/dev/null | sed -n 's#.*\(/org/.*/Bearer/[0-9]\+\).*#\1#p') + _bearer="$(mmcli -J -m "$MODEM" 2>/dev/null | jq -r '.[].generic.bearers[0]' 2>/dev/null)" ((TIMEOUT_CONNECT--)) fi done - if [[ -z "$bearer" ]]; then + if [[ -z "$_bearer" ]]; then report_error "No bearer found!" return 1 fi - if [[ -z "$bearer_interface" ]]; then + if [[ -z "$_bearer_interface" ]]; then report_error "No bearer interface found. Consider increasing \$TimeoutConnect a bit." return 1 fi report_debug "Interface found on modem bearer" - if [[ "$bearer_interface" != "$Interface" ]]; then - report_notice "Network interface used by the bearer is not the same as provided by your connection profile. Please update the profile using the right bearer interface: '$bearer_interface'" - Interface=$bearer_interface + if [[ "$_bearer_interface" != "$Interface" ]]; then + report_notice "Network interface used by the bearer is not the same as provided by your connection profile. Please update the profile using the right bearer interface: '$_bearer_interface'" + Interface=$_bearer_interface fi # Disable IPv6 before bringing the interface up to prevent SLAAC @@ -171,28 +131,37 @@ function mobile_mm_up { return 1 fi + local _interface_address _interface_prefix _interface_gateway _interface_dns + # Configuring IPv4 - if [[ $($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | sed -n "s/IPv4.*method: \(.*\)/\1/p") == *static* ]]; then + if [[ "$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".method')" == "static" ]]; then IP="static" - for bearer_config in $($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | awk '/IPv4/ {for(i=1; i<5; i++) {getline; print $2 $3 $4}}' | sed "s/'//g"); do - [[ $bearer_config == *address:* ]] && interface_address="${bearer_config#*:}" - [[ $bearer_config == *prefix:* ]] && interface_prefix="${bearer_config#*:}" - [[ $bearer_config == *gateway:* ]] && interface_gateway="${bearer_config#*:}" - [[ $bearer_config == *DNS:* ]] && interface_dns="${bearer_config#*:}" - done - - Address=("${interface_address}/${interface_prefix}") - Gateway="$interface_gateway" - [[ "${UsePeerDNS:-true}" == 'true' ]] && DNS=("$(echo $interface_dns | sed 's/,/ /g')") - else + _interface_address="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".address')" + _interface_prefix="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".prefix')" + _interface_gateway="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".gateway')" + _interface_dns="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".dns[0]')" + + Address=("${_interface_address}/${_interface_prefix}") + Gateway="$_interface_gateway" + [[ "${UsePeerDNS:-true}" == 'true' ]] && DNS=("$_interface_dns") + elif [[ "$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".method')" == "dhcp" ]]; then IP="dhcp" fi + # FIXME: IPv6 Support (requires testing) # Configuring IPv6 if [[ "$IP6" == 'dhcp' ]]; then - if [[ $($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | sed -n "s/IPv6.*method: \(.*\)/\1/p") != *dhcp* ]]; then - report_error "IPv6 (dhcp) not supported by modem. Skipping" - else + if [[ "$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".method')" == "static" ]]; then + IP="static" + _interface_address="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".address')" + _interface_prefix="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".prefix')" + _interface_gateway="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".gateway')" + _interface_dns="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".dns[0]')" + + Address=("${_interface_address}/${_interface_prefix}") + Gateway="$_interface_gateway" + [[ "${UsePeerDNS:-true}" == 'true' ]] && DNS=("$_interface_dns") + elif [[ "$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".method')" == "dhcp" ]]; then IP6="dhcp" fi fi @@ -204,24 +173,33 @@ function mobile_mm_up { } function mobile_mm_down { - local bearer_interface - bearer=$($__MMCLI -m "$MODEM" 2>/dev/null | sed -n 's#.*\(/org/.*/Bearer/[0-9]\+\).*#\1#p') - bearer_interface=$($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | sed -n "s/.*interface: '\([^ \t]\+\)'.*/\1/p") - - if [[ $($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | sed -n "s/IPv4.*method: '\([^ \t]\+\)'.*/\1/p") == *static* ]]; then - for bearer_config in $($__MMCLI -m "$MODEM" -b "$bearer" 2>/dev/null | awk '/IPv4/ {for(i=1; i<5; i++) {getline; print $2 $3 $4}}' | sed "s/'//g"); do - [[ $bearer_config == *address:* ]] && interface_address="${bearer_config#*:}" - [[ $bearer_config == *prefix:* ]] && interface_prefix="${bearer_config#*:}" - [[ $bearer_config == *gateway:* ]] && interface_gateway="${bearer_config#*:}" - [[ $bearer_config == *DNS:* ]] && interface_dns="${bearer_config#*:}" - done + local _bearer _bearer_interface + _bearer="$(mmcli -J -m "$MODEM" 2>/dev/null | jq -r '.[].generic.bearers[0]' 2>/dev/null)" + _bearer_interface="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[].status.interface')" + + if [[ "$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".method')" == "static" ]]; then + _interface_address="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".address')" + _interface_prefix="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".prefix')" + _interface_gateway="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".gateway')" + _interface_dns="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv4-config".dns[0]')" + + Address=("${_interface_address}/${_interface_prefix}") + Gateway="$_interface_gateway" + [[ "${UsePeerDNS:-true}" == 'true' ]] && DNS=("$_interface_dns") + fi - Address=("${interface_address}/${interface_prefix}") - Gateway="$interface_gateway" - [[ "${UsePeerDNS:-true}" == 'true' ]] && DNS=("$(echo $interface_dns | sed 's/,/ /g')") + if [[ "$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".method')" == "static" ]]; then + _interface_address="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".address')" + _interface_prefix="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".prefix')" + _interface_gateway="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".gateway')" + _interface_dns="$(mmcli -J -m "$MODEM" -b "$_bearer" 2>/dev/null | jq -r '.[]."ipv6-config".dns[0]')" + + Address=("${_interface_address}/${_interface_prefix}") + Gateway="$_interface_gateway" + [[ "${UsePeerDNS:-true}" == 'true' ]] && DNS=("$_interface_dns") fi - $__MMCLI -m "$MODEM" --simple-disconnect 2>/dev/null + mmcli -m "$MODEM" --simple-disconnect 2>/dev/null ip_unset interface_delete "$Interface" @@ -230,4 +208,69 @@ function mobile_mm_down { fi } +# Check that the dependencies are available +for PROGRAM in "${DEPENDENCIES[@]}"; do + check_deps "$PROGRAM" +done + +# Try getting the modem path +MODEM="$(mmcli -J -L 2>/dev/null | jq -r '.[][0]' 2>/dev/null)" + +if [[ -z "$MODEM" ]]; then + report_debug "No modem found yet." + + if ! systemctl is-active ModemManager.service &>/dev/null; then + report_notice "ModemManager service not running, trying to start it.." + systemctl start ModemManager.service + + # Wait until ModemManager has initialised the modem + report_debug "Sleeping until modem is available.." + TIMEOUT_MODEM=${TimeoutModem:-15} + until [[ "$(mmcli -J -L 2>/dev/null | jq -r '.[][0]' 2>/dev/null)" =~ ^/org/freedesktop/ModemManager[0-9]+/Modem/[0-9]+$ ]] || [ "$TIMEOUT_MODEM" -eq 0 ]; do + sleep 1 + ((TIMEOUT_MODEM--)) + done + + # Finally get the modem path + MODEM="$(mmcli -J -L 2>/dev/null | jq -r '.[][0]' 2>/dev/null)" + fi +fi + +MODEM_ID="$(mmcli -J -L 2>/dev/null | jq -r '.[][0] | [splits("/")] | (.[5] | tonumber)' 2>/dev/null)" +if [[ -z "$MODEM_ID" ]] || [[ ! "$MODEM_ID" =~ ^[0-9]+$ ]]; then + report_error "No modem found! Please ensure that ModemManager is capable of finding your modem." + exit 1 +fi + +# Get the modem status +MODEM_STATUS="$(mmcli -J -m "$MODEM" 2>/dev/null | jq -r '.[].generic.state')" + +if [[ "$MODEM_STATUS" == 'locked' ]]; then + report_notice "Modem is locked. Trying to supply PUK/PIN, if provided in the connection profile.." + + # Getting SIM for modem + SIM="$(mmcli -J -m "$MODEM" 2>/dev/null | jq -r '.[].generic.sim')" + + if [[ -n "$SIM" ]]; then + if [[ $Puk ]]; then + report_notice "Trying to unlock using the PUK.." + mmcli -m "$MODEM" -i "$SIM" --puk="${Pin}" >/dev/null 2>&1 + fi + + if [[ $Pin ]]; then + report_notice "Trying to unlock using the PIN.." + mmcli -m "$MODEM" -i "$SIM" --pin="${Pin}" >/dev/null 2>&1 + fi + + MODEM_STATUS="$(mmcli -J -m "$MODEM" 2>/dev/null | jq -r '.[].generic.state')" + if [[ "$MODEM_STATUS" == 'locked' ]]; then + report_error "Modem is still locked. Maybe the supplied PIN/PUK is wrong?" + exit 1 + fi + else + report_error "No SIM card found!" + exit 1 + fi +fi + # vim: ft=sh ts=2 et sw=2: diff --git a/mobile_mm.profile b/mobile_mm.profile index e0da3f977976..af71c1c3808f 100644 --- a/mobile_mm.profile +++ b/mobile_mm.profile @@ -38,8 +38,8 @@ AccessPointName=apn # Enable/Disable roaming (default: no) #Roaming=yes -# Amount of seconds, we will wait until initialisation of the modem will be interrupted (default: 5) -#TimeoutModem=10 +# Amount of seconds, we will wait until initialisation of the modem will be interrupted (default: 15) +#TimeoutModem=5 # Amount of seconds, we will wait for the connection is established (default: 30) #TimeoutConnect=35 |