443 lines
11 KiB
Bash
Executable File
443 lines
11 KiB
Bash
Executable File
#!/bin/sh
|
|
|
|
# SPDX-License-Identifier: GPL-2.0-or-later
|
|
#
|
|
# Copyright (C) 2013-2016 Aleksander Morgado <aleksander@aleksander.es>
|
|
#
|
|
# Based on libqmi's qmi-network script
|
|
#
|
|
|
|
print_usage ()
|
|
{
|
|
echo "usage: $0 [OPTIONS] [DEVICE] [COMMAND]"
|
|
}
|
|
|
|
help ()
|
|
{
|
|
echo "Usage: mbim-network [OPTIONS] [DEVICE] [COMMAND]"
|
|
echo
|
|
echo "Simple network management of MBIM devices"
|
|
echo
|
|
echo "Commands:"
|
|
echo " start Start network connection"
|
|
echo " stop Stop network connection"
|
|
echo " status Query network connection status"
|
|
echo
|
|
echo "Options:"
|
|
echo " --profile=[PATH] Use the profile in the specified path"
|
|
echo " --help, -h Show help options"
|
|
echo " --version Show version"
|
|
echo
|
|
echo "Notes:"
|
|
echo
|
|
echo " 1) [DEVICE] is given as the full path to the cdc-wdm character"
|
|
echo " device, e.g.:"
|
|
echo " /dev/cdc-wdm0"
|
|
echo
|
|
echo " 2) The mbim-network script requires a profile to work. Unless"
|
|
echo " explicitly specified with \`--profile', the file is assumed to"
|
|
echo " be available in the following path:"
|
|
echo " /etc/mbim-network.conf"
|
|
echo
|
|
echo " 3) The APN to use should be configured in the profile, in the"
|
|
echo " following way (e.g. assuming APN is called 'internet'):"
|
|
echo " APN=internet"
|
|
echo
|
|
echo " 4) Optional APN user/password strings may be given in the"
|
|
echo " following way:"
|
|
echo " APN_USER=user"
|
|
echo " APN_PASS=password"
|
|
echo
|
|
echo " 5) If APN user/password is specified, the authentication protocol"
|
|
echo " to use (one of PAP, CHAP or MSCHAPV2) must also be specified in"
|
|
echo " the following way:"
|
|
echo " APN_AUTH=protocol"
|
|
echo
|
|
echo " 6) If you want to instruct the mbim-network script to use the"
|
|
echo " mbim-proxy setup, you can do so by configuring the following line"
|
|
echo " in the profile:"
|
|
echo " PROXY=yes"
|
|
echo
|
|
echo " 7) Once the mbim-network script reports a successful connection"
|
|
echo " you still need to run a DHCP client on the associated WWAN network"
|
|
echo " interface."
|
|
echo
|
|
}
|
|
|
|
version ()
|
|
{
|
|
echo "mbim-network 1.31.2"
|
|
echo "Copyright (C) 2013-2021 Aleksander Morgado"
|
|
echo "License GPLv2+: GNU GPL version 2 or later <http://gnu.org/licenses/gpl-2.0.html>"
|
|
echo "This is free software: you are free to change and redistribute it."
|
|
echo "There is NO WARRANTY, to the extent permitted by law."
|
|
echo
|
|
}
|
|
|
|
# Basic options
|
|
if [ $# -lt 2 ]; then
|
|
if [ "$1" = "--help" ] || [ "$1" = "-h" ]; then
|
|
help
|
|
exit 0
|
|
elif [ "$1" = "--version" ]; then
|
|
version
|
|
exit 0
|
|
fi
|
|
|
|
echo "error: missing arguments" 1>&2
|
|
print_usage
|
|
exit 255
|
|
fi
|
|
|
|
# Defaults
|
|
PROFILE_FILE=/etc/mbim-network.conf
|
|
|
|
# Device + Command with options; options given first
|
|
while [ $# -gt 2 ]; do
|
|
OPT="$1"
|
|
shift
|
|
|
|
case "$OPT" in
|
|
"--")
|
|
break 2;;
|
|
"--profile")
|
|
if [ $# -gt 2 ]; then
|
|
PROFILE_FILE="$1"
|
|
shift
|
|
else
|
|
PROFILE_FILE=""
|
|
fi
|
|
;;
|
|
"--profile="*)
|
|
PROFILE_FILE="${OPT#*=}";;
|
|
*)
|
|
echo >&2 "Invalid option: $OPT"
|
|
print_usage
|
|
exit 255;;
|
|
esac
|
|
done
|
|
|
|
if [ -z "$PROFILE_FILE" ]; then
|
|
echo "error: empty profile path given" 1>&2
|
|
print_usage
|
|
exit 255
|
|
fi
|
|
|
|
if [ $# -ne 2 ] || [ "$1" = "--*" ] || [ "$2" = "--*" ]; then
|
|
echo "error: missing arguments" 1>&2
|
|
print_usage
|
|
exit 255
|
|
fi
|
|
|
|
DEVICE=$1
|
|
COMMAND=$2
|
|
|
|
STATE_FILE=/tmp/mbim-network-state-`basename $DEVICE`
|
|
|
|
load_profile ()
|
|
{
|
|
if [ -f "$PROFILE_FILE" ]; then
|
|
echo "Loading profile at ${PROFILE_FILE}..."
|
|
. $PROFILE_FILE
|
|
|
|
if [ -n "$APN" ]; then
|
|
echo " APN: $APN"
|
|
else
|
|
echo " APN: unset"
|
|
fi
|
|
|
|
if [ -n "$APN_AUTH" ]; then
|
|
echo " APN auth protocol: $APN_AUTH"
|
|
else
|
|
echo " APN auth protocol: unset"
|
|
fi
|
|
|
|
if [ -n "$APN_USER" ]; then
|
|
echo " APN user: $APN_USER"
|
|
if [ -z "$APN_AUTH" ]; then
|
|
echo "error: APN_USER in the profile requires APN_AUTH" 1>&2
|
|
exit 32
|
|
fi
|
|
else
|
|
echo " APN user: unset"
|
|
fi
|
|
|
|
if [ -n "$APN_PASS" ]; then
|
|
echo " APN password: $APN_PASS"
|
|
if [ -z "$APN_USER" ]; then
|
|
echo "error: APN_PASS in the profile requires APN_USER" 1>&2
|
|
exit 32
|
|
fi
|
|
else
|
|
echo " APN password: unset"
|
|
fi
|
|
|
|
if [ "$PROXY" = "yes" ]; then
|
|
echo " mbim-proxy: $PROXY"
|
|
PROXY_OPT='--device-open-proxy'
|
|
else
|
|
echo " mbim-proxy: no"
|
|
fi
|
|
else
|
|
echo "Profile at '$PROFILE_FILE' not found..."
|
|
fi
|
|
}
|
|
|
|
save_state ()
|
|
{
|
|
KEY=$1
|
|
VAL=$2
|
|
|
|
if [ -n "${PROXY_OPT}" ]; then
|
|
return
|
|
fi
|
|
|
|
echo "Saving state at ${STATE_FILE}... ($KEY: $VAL)"
|
|
|
|
if [ -f "$STATE_FILE" ]; then
|
|
PREVIOUS=`cat $STATE_FILE`
|
|
PREVIOUS=`echo "$PREVIOUS" | grep -v $KEY`
|
|
if [ -n "$PREVIOUS" ]; then
|
|
echo $PREVIOUS > $STATE_FILE
|
|
else
|
|
rm $STATE_FILE
|
|
fi
|
|
fi
|
|
|
|
if [ -n "$VAL" ]; then
|
|
echo "$KEY=\"$VAL\"" >> $STATE_FILE
|
|
fi
|
|
}
|
|
|
|
load_state ()
|
|
{
|
|
if [ -n "${PROXY_OPT}" ]; then
|
|
return
|
|
fi
|
|
|
|
if [ -f "$STATE_FILE" ]; then
|
|
echo "Loading previous state from ${STATE_FILE}..."
|
|
. $STATE_FILE
|
|
if [ -n "$TRID" ]; then
|
|
echo " Previous Transaction ID: $TRID"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
clear_state ()
|
|
{
|
|
if [ -n "${PROXY_OPT}" ]; then
|
|
return
|
|
fi
|
|
|
|
echo "Clearing state at ${STATE_FILE}..."
|
|
rm -f $STATE_FILE
|
|
}
|
|
|
|
#
|
|
# $ sudo mbimcli -d /dev/cdc-wdm0 --connect="Internet" --no-close
|
|
# [/dev/cdc-wdm0] Successfully connected
|
|
# [/dev/cdc-wdm0] Connection status:
|
|
# Session ID: '0'
|
|
# Activation state: 'activated'
|
|
# Voice call state: 'none'
|
|
# IP type: 'ipv4'
|
|
# Context type: 'internet'
|
|
# Network error: 'unknown'
|
|
#
|
|
connect ()
|
|
{
|
|
# Always try to connect using a fresh session
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
if [ -n "$TRID" ]; then
|
|
# This will implicitly close the previous session
|
|
mbimcli -d $DEVICE --no-open=$TRID
|
|
clear_state
|
|
fi
|
|
fi
|
|
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
EXTRA_OPT="--no-close"
|
|
else
|
|
EXTRA_OPT="${PROXY_OPT}"
|
|
fi
|
|
|
|
SUBSCRIBER_READY_CMD="mbimcli -d $DEVICE --query-subscriber-ready-status ${EXTRA_OPT}"
|
|
echo "Querying subscriber ready status '$SUBSCRIBER_READY_CMD'..."
|
|
|
|
SUBSCRIBER_READY_OUT=`$SUBSCRIBER_READY_CMD`
|
|
echo $SUBSCRIBER_READY_OUT
|
|
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
TRID=`echo "$SUBSCRIBER_READY_OUT" | sed -n "s/.*TRID.*'\(.*\)'.*/\1/p"`
|
|
EXTRA_OPT="--no-open=$TRID --no-close"
|
|
else
|
|
EXTRA_OPT="${PROXY_OPT}"
|
|
fi
|
|
|
|
REGISTRATION_STATE_CMD="mbimcli -d $DEVICE --query-registration-state ${EXTRA_OPT}"
|
|
echo "Querying registration state '$REGISTRATION_STATE_CMD'..."
|
|
|
|
REGISTRATION_STATE_OUT=`$REGISTRATION_STATE_CMD`
|
|
echo $REGISTRATION_STATE_OUT
|
|
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
TRID=`echo "$REGISTRATION_STATE_OUT" | sed -n "s/.*TRID.*'\(.*\)'.*/\1/p"`
|
|
EXTRA_OPT="--no-open=$TRID --no-close"
|
|
else
|
|
EXTRA_OPT="${PROXY_OPT}"
|
|
fi
|
|
|
|
ATTACH_CMD="mbimcli -d $DEVICE --attach-packet-service ${EXTRA_OPT}"
|
|
echo "Attaching to packet service with '$ATTACH_CMD'..."
|
|
|
|
ATTACH_OUT=`$ATTACH_CMD`
|
|
echo $ATTACH_OUT
|
|
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
TRID=`echo "$ATTACH_OUT" | sed -n "s/.*TRID.*'\(.*\)'.*/\1/p"`
|
|
EXTRA_OPT="--no-open=$TRID --no-close"
|
|
else
|
|
EXTRA_OPT="${PROXY_OPT}"
|
|
fi
|
|
|
|
CONNECT_ARGS="apn='$APN'"
|
|
if [ -n "$APN_AUTH" ]; then
|
|
CONNECT_ARGS="${CONNECT_ARGS},auth='$APN_AUTH'"
|
|
if [ -n "$APN_USER" ]; then
|
|
CONNECT_ARGS="${CONNECT_ARGS},username='$APN_USER'"
|
|
if [ -n "$APN_PASS" ]; then
|
|
CONNECT_ARGS="${CONNECT_ARGS},password='$APN_PASS'"
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
CONNECT_CMD="mbimcli -d $DEVICE --connect=$CONNECT_ARGS ${EXTRA_OPT}"
|
|
echo "Starting network with '$CONNECT_CMD'..."
|
|
|
|
CONNECT_OUT=`$CONNECT_CMD`
|
|
if [ $? -eq 0 ]; then
|
|
echo "Network started successfully"
|
|
else
|
|
echo "Network start failed"
|
|
echo $CONNECT_OUT
|
|
fi
|
|
|
|
# Save the new TRID
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
TRID=`echo "$CONNECT_OUT" | sed -n "s/.*TRID.*'\(.*\)'.*/\1/p"`
|
|
if [ -n "$TRID" ]; then
|
|
save_state "TRID" $TRID
|
|
fi
|
|
fi
|
|
}
|
|
|
|
#
|
|
# $ sudo mbimcli -d /dev/cdc-wdm0 --disconnect="0"
|
|
# [/dev/cdc-wdm0] Successfully disconnected
|
|
# [/dev/cdc-wdm0] Connection status:
|
|
# Session ID: '0'
|
|
# Activation state: 'deactivated'
|
|
# Voice call state: 'none'
|
|
# IP type: 'default'
|
|
# Context type: 'internet'
|
|
# Network error: 'unknown'
|
|
#
|
|
disconnect ()
|
|
{
|
|
# Always close the session when disconnecting
|
|
if [ -n "${PROXY_OPT}" ]; then
|
|
EXTRA_OPT="${PROXY_OPT}"
|
|
elif [ -n "$TRID" ]; then
|
|
EXTRA_OPT="--no-open=$TRID"
|
|
else
|
|
EXTRA_OPT=""
|
|
fi
|
|
DISCONNECT_CMD="mbimcli -d $DEVICE --disconnect ${EXTRA_OPT}"
|
|
|
|
echo "Stopping network with '$DISCONNECT_CMD'..."
|
|
|
|
DISCONNECT_OUT=`$DISCONNECT_CMD`
|
|
if [ $? -eq 0 ]; then
|
|
echo "Network stopped successfully"
|
|
else
|
|
echo "Network stop failed"
|
|
echo $DISCONNECT_OUT
|
|
fi
|
|
|
|
clear_state
|
|
}
|
|
|
|
#
|
|
# $ sudo mbimcli -d /dev/cdc-wdm0 --query-connection-state --no-close
|
|
# [/dev/cdc-wdm0] Connection status:
|
|
# Session ID: '0'
|
|
# Activation state: 'deactivated'
|
|
# Voice call state: 'none'
|
|
# IP type: 'default'
|
|
# Context type: 'none'
|
|
# Network error: 'unknown'
|
|
#
|
|
status ()
|
|
{
|
|
if [ -n "${PROXY_OPT}" ]; then
|
|
EXTRA_OPT="${PROXY_OPT}"
|
|
elif [ -n "$TRID" ]; then
|
|
EXTRA_OPT="--no-open=$TRID --no-close"
|
|
else
|
|
EXTRA_OPT=""
|
|
fi
|
|
|
|
STATUS_CMD="mbimcli -d $DEVICE --query-connection-state ${EXTRA_OPT}"
|
|
echo "Getting status with '$STATUS_CMD'..."
|
|
|
|
STATUS_OUT=`$STATUS_CMD`
|
|
|
|
# Save the new TRID
|
|
if [ -z "${PROXY_OPT}" ]; then
|
|
TRID=`echo "$STATUS_OUT" | sed -n "s/.*TRID.*'\(.*\)'.*/\1/p"`
|
|
if [ -n "$TRID" ]; then
|
|
save_state "TRID" $TRID
|
|
fi
|
|
fi
|
|
|
|
CONN=`echo "$STATUS_OUT" | sed -n "s/.*Activation state:.*'\(.*\)'.*/\1/p"`
|
|
if [ -z "$CONN" ]; then
|
|
echo "error: couldn't get connection status" 1>&2
|
|
exit 2
|
|
else
|
|
echo "Status: $CONN"
|
|
if [ "$CONN" != "connected" ]; then
|
|
exit 64
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Main
|
|
|
|
# Load profile, if any
|
|
load_profile
|
|
|
|
# Load previous state, if any
|
|
load_state
|
|
|
|
# Process commands
|
|
case $COMMAND in
|
|
"start")
|
|
connect
|
|
;;
|
|
"stop")
|
|
disconnect
|
|
;;
|
|
"status")
|
|
status
|
|
;;
|
|
*)
|
|
echo "error: unexpected command '$COMMAND'" 1>&2
|
|
print_usage
|
|
exit 255
|
|
;;
|
|
esac
|
|
|
|
exit 0
|