blob: 0a652a6b41ac5d97e36be251550aeecf347d0a6d [file] [log] [blame]
#!/bin/sh
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, either version 2 of the License, or (at your option) any later
# version.
#
# This program is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
# FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
# details.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 51
# Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# Copyright (C) 2012-2013 Aleksander Morgado <aleksander@gnu.org>
print_usage ()
{
echo "usage: $0 [OPTIONS] [DEVICE] [COMMAND]"
}
help ()
{
echo "Usage: qmi-network [OPTIONS] [DEVICE] [COMMAND]"
echo
echo "Simple network management of QMI devices"
echo
echo "Commands:"
echo " start Start network connection"
echo " stop Stop network connection"
echo " status Query network connection status"
echo
echo "Options:"
echo " --help 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 qmi-network script requires a profile to be available"
echo " in the following path:"
echo " /etc/qmi-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) If you want to instruct the qmi-network script to use the"
echo " qmi-proxy setup, you can do so by configuring the following line"
echo " in the profile:"
echo " PROXY=yes"
echo
echo " 5) Once the qmi-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 "qmi-network @VERSION@"
echo "Copyright (2013-2015) 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
}
if [ $# -ne 2 ]; then
if [ "$1" = "--help" ]; then
help
exit 0
elif [ "$1" = "--version" ]; then
version
exit 0
fi
echo "error: missing arguments" 1>&2
print_usage
exit 255
fi
DEVICE=$1
COMMAND=$2
STATE_FILE=/tmp/qmi-network-state
PROFILE_FILE=/etc/qmi-network.conf
load_profile ()
{
if [ -f $PROFILE_FILE ]; then
echo "Loading profile..."
. $PROFILE_FILE
if [ "x$APN" != "x" ]; then
echo " APN: $APN"
else
echo " APN: unset"
fi
if [ "x$PROXY" = "xyes" ]; then
echo " qmi-proxy: $PROXY"
PROXY_OPT='--device-open-proxy'
else
echo " qmi-proxy: no"
fi
else
echo "Profile at '$PROFILE_FILE' not found..."
fi
}
save_state ()
{
KEY=$1
VAL=$2
echo "Saving state... ($KEY: $VAL)"
if [ -f $STATE_FILE ]; then
PREVIOUS=`cat $STATE_FILE`
PREVIOUS=`echo "$PREVIOUS" | grep -v $KEY`
if [ "x$PREVIOUS" != "x" ]; then
echo $PREVIOUS > $STATE_FILE
else
rm $STATE_FILE
fi
fi
if [ "x$VAL" != "x" ]; then
echo "$KEY=\"$VAL\"" >> $STATE_FILE
fi
}
load_state ()
{
if [ -f $STATE_FILE ]; then
echo "Loading previous state..."
. $STATE_FILE
if [ "x$CID" != "x" ]; then
echo " Previous CID: $CID"
fi
if [ "x$PDH" != "x" ]; then
echo " Previous PDH: $PDH"
fi
fi
}
clear_state ()
{
echo "Clearing state..."
rm -f $STATE_FILE
}
# qmicli -d /dev/cdc-wdm0 --wds-start-network --client-no-release-cid
# [/dev/cdc-wdm0] Network started
# Packet data handle: 3634026241
# [/dev/cdc-wdm0] Client ID not released:
# Service: 'wds'
# CID: '80'
start_network ()
{
if [ "x$CID" != "x" ]; then
USE_PREVIOUS_CID="--client-cid=$CID"
fi
if [ "x$PDH" != "x" ]; then
echo "error: cannot re-start network, PDH already exists" 1>&2
exit 3
fi
# Read link layer protocol
DATA_FORMAT_CMD="qmicli -d $DEVICE --wda-get-data-format $PROXY_OPT"
echo "Checking data format with '$DATA_FORMAT_CMD'..."
if [ "x$QMIDEBUG" != "x" ]; then
DATA_FORMAT_OUT="\
[/dev/cdc-wdm1] Successfully got data format
QoS flow header: no
Link layer protocol: '802-3'
Uplink data aggregation protocol: 'disabled'
Downlink data aggregation protocol: 'disabled'
NDP signature: '0'
Uplink data aggregation max size: '0'
Downlink data aggregation max size: '0'"
else
DATA_FORMAT_OUT=`$DATA_FORMAT_CMD`
fi
LLP=`echo "$DATA_FORMAT_OUT" | sed -n "s/.*Link layer protocol:.*'\(.*\)'.*/\1/p"`
if [ "x$LLP" = "x" ]; then
echo "Link layer protocol not retrieved" 1>&2
else
echo "Link layer protocol retrieved: $LLP" 1>&2
if [ "x$LLP" != "x802-3" ]; then
DATA_FORMAT_SET_CMD="qmicli -d $DEVICE --wda-set-data-format=802-3 $PROXY_OPT"
echo "Updating data format with '$DATA_FORMAT_SET_CMD'..."
if [ "x$QMIDEBUG" != "x" ]; then
DATA_FORMAT_SET_OUT="\
[/dev/cdc-wdm1] Successfully set data format
QoS flow header: no
Link layer protocol: '802-3'
Uplink data aggregation protocol: 'disabled'
Downlink data aggregation protocol: 'disabled'
NDP signature: '0'
Downlink data aggregation max datagrams: '0'
Downlink data aggregation max size: '0'"
else
DATA_FORMAT_SET_OUT=`$DATA_FORMAT_SET_CMD`
fi
LLP=`echo "$DATA_FORMAT_SET_OUT" | sed -n "s/.*Link layer protocol:.*'\(.*\)'.*/\1/p"`
if [ "x$LLP" = "x" ]; then
echo "Link layer protocol not retrieved after update" 1>&2
else
echo "New link layer protocol retrieved: $LLP" 1>&2
fi
fi
fi
START_NETWORK_CMD="qmicli -d $DEVICE --wds-start-network=$APN $USE_PREVIOUS_CID --client-no-release-cid $PROXY_OPT"
echo "Starting network with '$START_NETWORK_CMD'..."
if [ "x$QMIDEBUG" != "x" ]; then
START_NETWORK_OUT="\
[/dev/cdc-wdm0] Network started
Packet data handle: '3634026241'
[/dev/cdc-wdm0] Client ID not released:
Service: 'wds'
CID: '80'"
else
START_NETWORK_OUT=`$START_NETWORK_CMD`
fi
# Save the new CID if we didn't use any before
if [ "x$CID" = "x" ]; then
CID=`echo "$START_NETWORK_OUT" | sed -n "s/.*CID.*'\(.*\)'.*/\1/p"`
if [ "x$CID" = "x" ]; then
echo "error: network start failed, client not allocated" 1>&2
exit 1
else
save_state "CID" $CID
fi
fi
PDH=`echo "$START_NETWORK_OUT" | sed -n "s/.*handle.*'\(.*\)'.*/\1/p"`
if [ "x$PDH" = "x" ]; then
echo "error: network start failed, no packet data handle" 1>&2
# Cleanup the client
qmicli -d "$DEVICE" --wds-noop --client-cid="$CID" $PROXY_OPT
clear_state
exit 2
else
save_state "PDH" $PDH
fi
echo "Network started successfully"
}
# qmicli -d /dev/cdc-wdm0 --wds-stop-network
stop_network ()
{
if [ "x$CID" = "x" ]; then
echo "Network already stopped"
elif [ "x$PDH" = "x" ]; then
echo "Network already stopped; need to cleanup CID $CID"
# Cleanup the client
qmicli -d "$DEVICE" --wds-noop --client-cid="$CID" $PROXY_OPT
else
STOP_NETWORK_CMD="qmicli -d $DEVICE --wds-stop-network=$PDH --client-cid=$CID $PROXY_OPT"
echo "Stopping network with '$STOP_NETWORK_CMD'..."
if [ "x$QMIDEBUG" != "x" ]; then
STOP_NETWORK_OUT="\
[/dev/cdc-wdm0] Network stopped
"
else
STOP_NETWORK_OUT=`$STOP_NETWORK_CMD`
fi
echo "Network stopped successfully"
fi
clear_state
}
# qmicli -d /dev/cdc-wdm0 --wds-get-packet-service-status
packet_service_status ()
{
if [ "x$CID" != "x" ]; then
USE_PREVIOUS_CID="--client-cid=$CID --client-no-release-cid"
fi
STATUS_CMD="qmicli -d $DEVICE --wds-get-packet-service-status $USE_PREVIOUS_CID $PROXY_OPT"
echo "Getting status with '$STATUS_CMD'..."
if [ "x$QMIDEBUG" != "x" ]; then
STATUS_OUT="\
[/dev/cdc-wdm0] Connection status: 'disconnected'
"
else
STATUS_OUT=`$STATUS_CMD`
fi
CONN=`echo "$STATUS_OUT" | sed -n "s/.*Connection status:.*'\(.*\)'.*/\1/p"`
if [ "x$CONN" = "x" ]; then
echo "error: couldn't get packet service status" 1>&2
exit 2
else
echo "Status: $CONN"
if [ "x$CONN" != "xconnected" ]; 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")
start_network
;;
"stop")
stop_network
;;
"status")
packet_service_status
;;
*)
echo "error: unexpected command '$COMMAND'" 1>&2
print_usage
exit 255
;;
esac
exit 0