From 613cd6bae8ede03ec41e1c13fe3ebfc51498e3dd Mon Sep 17 00:00:00 2001 From: Christian Zeitnitz Date: Wed, 19 May 2021 21:04:31 +0200 Subject: [PATCH] Add Huawei Hilink API Cleanup mobile data scripts --- config/client_config/huawei_hilink_api.sh | 482 ++++++++++++++++++++ config/client_config/info_huawei.sh | 58 +-- config/client_config/info_huawei_hilink.sh | 94 ++-- config/client_config/onoff_huawei_hilink.sh | 109 +---- 4 files changed, 582 insertions(+), 161 deletions(-) create mode 100644 config/client_config/huawei_hilink_api.sh diff --git a/config/client_config/huawei_hilink_api.sh b/config/client_config/huawei_hilink_api.sh new file mode 100644 index 00000000..c4402a6e --- /dev/null +++ b/config/client_config/huawei_hilink_api.sh @@ -0,0 +1,482 @@ +#!/bin/bash +# +# Huawei Hilink API +# ================= +# - communication with Hilink devices via HTTP +# - send a standard http request with a xml formatted string to the device (default IP 192.169.8.1) +# - Howto: +# o "source" this script in your own script from the command line +# o if host ip/name differs, set "host=192.168.178.1" before calling any function +# o if the device is locked by a password, set user="admin"; pw="1234secret" +# _login is called automaticallcall +# Password types 3 and 4 are supported +# o if the SIM is requiring a PIN, set "pin=1234" +# o connect device to network: _switchMobileData ON ( or 1 ) +# o disconnect device: _switchMobileData OFF ( or 0 ) +# o get informations about the device: _getDeviceInformation and _getStatus and _getNetProvider +# all functions return XML formatted data in $response. +# o Check if device is connected: "if _isConnected; then .... fi" +# o $response can be parsed by calling _valueFromResponse +# e.g "_valueFromResponse msisdn" to get the phone number after a call to _getDeviceInformation +# +# +# Usage of functions +# - call the function with parameters (if required) +# - return code: 0 - success; 1 - failed +# - $status: status information (OK, ERROR) +# - $response: xml response to be parsed for the required information +# +# +# required software: curl, base64, sha256sum, sed +# +# +# zbchristian 2021 +# + +# Initialization procedure +# ======================== +# +# host=$host_default # ip address of device +# user="admin" # user name if locked (default admin) +# pw="1234Secret" # password if locked +# pin="1234" # PIN of SIM +# _initHilinkAPI # initialize the API +# +# Termination +# =========== +# cleanup the API before quitting the shell +# _closeHilinkAPI (optional: add parameter "save" to save the session/token data for subsequent calls. Valid for a few minutes.) + +host_default="192.168.8.1" +save_file="/tmp/hilink_api_saved.dat" +save_age=60 +header_file="/tmp/hilink_login_hdr.txt" + +# initialize +function _initHilinkAPI() { + if [ -z "$host" ]; then host=$host_default; fi + if ! _hostReachable; then return 1; fi + if [ -f $save_file ]; then # found file with saved data + _getSavedData + age=$(( $(date +%s) - $(stat $save_file -c %Y) )) + if [[ $age -gt $save_age ]]; then + rm -f $save_file + _logout + _sessToken + fi + fi + if [ -z "$sessID" ] || [ -z "$token" ]; then _sessToken; fi + _login + return $? +} + +function _getSavedData() { + if [ -f $save_file ]; then # restore saved session data + dat=$(cat $save_file) + sessID=$(echo "$dat" | sed -nr 's/sessionid: ([a-z0-9]*)/\1/ip') + token=$(echo "$dat" | sed -nr 's/token: ([a-z0-9]*)/\1/ip') + tokenlist=( $(echo "$dat" | sed -nr 's/tokenlist: ([a-z0-9 ]*)/\1/ip') ) + fi +} + +# Cleanup +# parameter: "save" - will store sessionid and tokens in file +function _closeHilinkAPI() { + if [ -z "$host" ]; then host=$host_default; fi + if ! _hostReachable; then return 1; fi + rm -f $save_file + [ ! -z "$1" ] && opt="${1,,}" + if [ ! -z "$opt" ] && [ "$opt" = "save" ]; then + echo "sessionid: $sessID" > $save_file + echo "token: $token" >> $save_file + echo "tokenlist: ${tokenlist[@]}" >> $save_file + fi + _logout + tokenlist="" + sessID="" + token="" + return 0 +} + +# get status (connection status, DNS, ) +# parameter: none +function _getStatus() { + if _login; then + if _sendRequest "api/monitoring/status"; then + if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi + fi + return $? + fi + return 1 +} + +function _isConnected() { + conn=$(_getStatus "connectionstatus") + status="NO" + if [ ! -z "$conn" ] && [ $conn -eq 901 ]; then + status="YES" + return 0 + fi + return 1 +} + +# get device information (device name, imei, imsi, msisdn-phone number, MAC, WAN IP ...) +# parameter: name of parameter to return +function _getDeviceInformation() { + if _login; then + if _sendRequest "api/device/information"; then + if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi + fi + return $? + fi + return 1 +} + +# get net provider information +# parameter: name of parameter to return +function _getNetProvider() { + if _login; then + if _sendRequest "api/net/current-plmn"; then + if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi + fi + return $? + fi + return 1 +} + +# get signal level +# parameter: name of parameter to return +function _getSignal() { + if _login; then + if _sendRequest "api/device/signal"; then + if [ ! -z "$1" ]; then _valueFromResponse "$1"; fi + fi + return $? + fi + return 1 +} + +function _getAllInformations() { + if _getDeviceInformation; then _keyValuePairs; fi + if _getSignal; then _keyValuePairs; fi + if _getNetProvider; then _keyValuePairs; fi +} + +# get status of mobile data connection +# parameter: none +function _getMobileDataStatus() { + if _login; then + if _sendRequest "api/dialup/mobile-dataswitch"; then + status=$(_valueFromResponse "dataswitch") + if [ $? -eq 0 ] && [ ! -z "$status" ]; then echo "$status"; fi + fi + return $? + fi + return 1 +} + + +# PIN of SIM can be passed either as $pin, or as parameter +# parameter: PIN number of SIM card +function _enableSIM() { +#SimState: +#255 - no SIM, +#256 - error CPIN, +#257 - ready, +#258 - PIN disabled, +#259 - check PIN, +#260 - PIN required, +#261 - PUK required + if [ ! -z "$1" ]; then pin="$1"; fi + if ! _login; then return 1; fi + if _sendRequest "api/pin/status"; then + simstate=`echo $response | sed -rn 's/.*([0-9]*)<\/simstate>.*/\1/pi'` + if [[ $simstate -eq 257 ]]; then status="SIM ready"; return 0; fi + if [[ $simstate -eq 260 ]]; then + status="PIN required" + if [ ! -z "$pin" ]; then _setPIN "$pin"; fi + return $? + fi + if [[ $simstate -eq 255 ]]; then status="NO SIM"; return 1; fi + fi + return 1 +} + +# obtain session and verification token - stored in vars $sessID and $token +# parameter: none +function _sessToken() { + tokenlist="" + token="" + sessID="" + response=$(curl -s http://$host/api/webserver/SesTokInfo -m 5 2> /dev/null) + if [ -z "$response" ]; then echo "No access to device at $host"; return 1; fi + status=$(echo "$response" | sed -nr 's/.*([0-9]*)<\/code>.*/\1/ip') + if [ -z "$status" ]; then + token=`echo $response | sed -r 's/.*(.*)<\/TokInfo>.*/\1/'` + sessID=`echo $response | sed -r 's/.*(.*)<\/SesInfo>.*/\1/'` + if [ ! -z "$sessID" ] && [ ! -z "$token" ]; then + sessID="SessionID=$sessID" + return 0 + fi + fi + return 1 +} + +# unlock device (if locked) with user name and password +# requires stored user="admin"; pw="1234secret";host=$host_default +# parameter: none +function _login() { + if _loginState; then return 0; fi # login not required, or already done + _sessToken + # get password type + if ! _sendRequest "api/user/state-login"; then return 1; fi + pwtype=$(echo "$response" | sed -rn 's/.*([0-9])<\/password_type>.*/\1/pi') + if [ -z "$pwtype" ];then pwtype=4; fi # fallback is type 4 + if [[ ! -z "$user" ]] && [[ ! -z "$pw" ]]; then + # password encoding + # type 3 : base64(pw) encoded + # type 4 : base64(sha256sum(user + base64(sha256sum(pw)) + token)) + pwtype3=$(echo -n "$pw" | base64 --wrap=0) + hashedpw=$(echo -n "$pw" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' ) + hashedpw=$(echo -n "$hashedpw" | base64 --wrap=0) + pwtype4=$(echo -n "$user$hashedpw$token" | sha256sum -b | sed -nr 's/^([0-9a-z]*).*$/\1/ip' ) + encpw=$(echo -n "$pwtype4" | base64 --wrap=0) + if [ $pwtype -ne 4 ]; then encpw=$pwtype3; fi + xmldata="$user$encpw$pwtype" + xtraopts="--dump-header $header_file" + rm -f $header_file + _sendRequest "api/user/login" + if [ ! -z "$status" ] && [ "$status" = "OK" ]; then + # store the list of 30 tokens. Each token is valid for a single request + tokenlist=( $(cat $header_file | sed -rn 's/^__RequestVerificationToken:\s*([0-9a-z#]*).*$/\1/pi' | sed 's/#/ /g') ) + _getToken + sessID=$(cat $header_file | grep -ioP 'SessionID=([a-z0-9]*)') + if [ ! -z "$sessID" ] && [ ! -z "$token" ]; then + return 0 + fi + fi + fi + return 1 +} + +# logout of hilink device +# parameter: none +function _logout() { + if _loginState; then + xmldata="1" + if _sendRequest "api/user/logout"; then + tokenlist="" + sessID="" + token="" + login_enabled="" + fi + return $? + fi + return 1 +} + +# parameter: none +function _loginState() { + status="OK" + if [ -z "$login_enabled" ]; then _checkLoginEnabled; fi + if [ $login_enabled -eq 1 ]; then return 0; fi # login is disabled + _sendRequest "api/user/state-login" + state=`echo "$response" | sed -rn 's/.*(.*)<\/state>.*/\1/pi'` + if [ ! -z "$state" ] && [ $state -eq 0 ]; then # already logged in + return 0 + fi + return 1 +} + +function _checkLoginEnabled() { + if _sendRequest "api/user/hilink_login"; then + login_enabled=0 + state=$(echo $response | sed -rn 's/.*(.*)<\/hilink_login>.*/\1/pi') + if [ ! -z "$state" ] && [ $state -eq 0 ]; then # no login enabled + login_enabled=1 + fi + else + login_enabled="" + fi +} + +# switch mobile data on/off 1/0 +# if SIM is locked, $pin has to be set +# parameter: state - ON/OFF or 1/0 +function _switchMobileData() { + if [ -z "$1" ]; then return 1; fi + _login + mode="${1,,}" + [ "$mode" = "on" ] && mode=1 + [ "$mode" = "off" ] && mode=0 + if [[ $mode -ge 0 ]]; then + if _enableSIM "$pin"; then + xmldata="$mode" + _sendRequest "api/dialup/mobile-dataswitch" + return $? + fi + fi + return 1 +} + +# parameter: PIN of SIM card +function _setPIN() { + if [ -z "$1" ]; then return 1; fi + pin="$1" + xmldata="0$pin" + _sendRequest "api/pin/operate" + return $? +} + +# Send request to host at http://$host/$apiurl +# data in $xmldata and options in $xtraopts +# parameter: apiurl (e.g. "api/user/login") +function _sendRequest() { + status="ERROR" + if [ -z "$1" ]; then return 1; fi + apiurl="$1" + ret=1 + if [ -z "$sessID" ] || [ -z "$token" ]; then _sessToken; fi + if [ -z "$xmldata" ];then + response=$(curl -s http://$host/$apiurl -m 10 \ + -H "Cookie: $sessID") + else + response=$(curl -s -X POST http://$host/$apiurl -m 10 \ + -H "Content-Type: text/xml" \ + -H "Cookie: $sessID" \ + -H "__RequestVerificationToken: $token" \ + -d "$xmldata" $xtraopts 2> /dev/null) + _getToken + fi + if [ ! -z "$response" ];then + response=$(echo $response | tr -d '\012\015') # delete newline chars + status=$(echo "$response" | sed -nr 's/.*([0-9]*)<\/code>.*/\1/ip') # check for error code + if [ -z "$status" ]; then + status="OK" + response=$(echo "$response" | sed -nr 's/.*(.*)<\/response>.*/\1/ip') + [ -z "$response" ] && response="none" + ret=0 + else + status="ERROR $status" + fi + else + status="ERROR" + fi + if [[ "$status" =~ ERROR ]]; then _handleError; fi + xtraopts="" + xmldata="" + return $ret +} + +# handle the list of tokens available after login +# parameter: none +function _getToken() { + if [ ! -z "$tokenlist" ] && [ ${#tokenlist[@]} -gt 0 ]; then + token=${tokenlist[0]} # get first token in list + tokenlist=("${tokenlist[@]:1}") # remove used token from list + if [ ${#tokenlist[@]} -eq 0 ]; then + _logout # use the last token to logout + fi + else + _sessToken # old token has been used - need new session + fi +} + +# Analyse $status for error code +# return error text in $status +function _handleError() { + txt=$(_getErrorText) + if [ -z "$code" ]; then return 1; fi + ret=0 + case "$code" in + 101|108003|108007) + ret=1 + status="$txt" + ;; + 108001|108002|108006) + ret=1 + status="$txt" + ;; + 125001|125002|125003) + _sessToken + ret=0 + ;; + *) + ;; + esac + return "$ret" +} + +declare -A err_hilink_api +err_hilink_api[101]="Unable to get session ID/token" +err_hilink_api[108001]="Invalid username/password" +err_hilink_api[108002]=${errors[108001]} +err_hilink_api[108006]=${errors[108001]} +err_hilink_api[108003]="User already logged in - need to wait a bit" +err_hilink_api[108007]="Too many login attempts - need to wait a bit" +err_hilink_api[125001]="Invalid session/request token" +err_hilink_api[125002]=${errors[125001]} +err_hilink_api[125003]=${errors[125001]} + +# check error and return error text +# status passsed in $status, or $1 +function _getErrorText() { + err="$status" + code="0" + if [ ! -z "$1" ]; then err="$1"; fi + if [ -z "$err" ]; then return 1; fi + errortext="$err" + if [[ "$err" =~ ERROR\ *([0-9]*) ]] && [ ! -z "${BASH_REMATCH[1]}" ]; then + code=${BASH_REMATCH[1]} + if [ ! -z "$code" ] && [ ! -z "${err_hilink_api[$code]}" ]; then + errortext="${err_hilink_api[$code]}" + fi + fi + echo $errortext + return 0 +} + +function _hostReachable() { + avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'` + if [ -z "$avail" ]; then return 1; fi + return 0; +} + +# helper function to parse $response (xml format) for a value +# call another function first! +# parameter: tag-name +function _valueFromResponse() { + if [ -z "$response" ] || [ -z "$1" ]; then return 1; fi + par="$1" + value=$(echo $response | sed -rn 's/.*<'$par'>(.*)<\/'$par'>.*/\1/pi') + if [ -z "$value" ]; then return 1; fi + echo "$value" + return 0 +} + +# list all keys of the current xml response +function _keysFromResponse() { + if [ -z "$response" ]; then return 1; fi + echo $response | grep -oiP "(?<=<)[a-z_-]*(?=>)" + return 0 +} + +# return all key=value pairs of the current xml response +function _keyValuePairs() { + if [ -z "$response" ]; then return 1; fi + echo $response | sed -n 's/<\([^>]*\)>\(.*\)<\/\1>[^<]*/\1=\"\2\"\n/gpi' + return 0 +} + +host=$host_default +user="admin" +pw="" +token="" +tokenlist="" +sessID="" +xmldata="" +xtraopts="" +response="" +status="" +pwtype=-1 + diff --git a/config/client_config/info_huawei.sh b/config/client_config/info_huawei.sh index bcdf8e37..475767fe 100644 --- a/config/client_config/info_huawei.sh +++ b/config/client_config/info_huawei.sh @@ -12,43 +12,43 @@ # zbchristian 2020 # opt="device" -if [ ! -z $1 ]; then opt=${1,,}; fi +if [ ! -z "$1" ]; then opt=${1,,}; fi type="hilink" -if [ ! -z $2 ]; then type=${2,,}; fi +if [ ! -z "$2" ]; then type=${2,,}; fi -path=`dirname $0` -if [[ $type == "hilink" ]]; then +path=$(dirname "$0") +if [ "$type" = "hilink" ]; then connect="192.168.8.1" - if [ ! -z $3 ]; then connect=$3; fi + if [ ! -z "$3" ]; then connect=$3; fi script="$path/info_huawei_hilink.sh" else connect="/dev/ttyUSB2" - if [ ! -z $3 ]; then connect=$3; fi + if [ ! -z "$3" ]; then connect=$3; fi script="$path/info_huawei_modem.sh" fi -res=`$script $opt $connect` +res=$($script $opt $connect) # some results require special treatment case $opt in # manufacturer) -# if [[ $res == "none" ]]; then res="Huawei"; fi +# if [ "$res" = "none" ]; then res="Huawei"; fi # ;; # device) -# if [[ ! $res == "none" ]]; then res="Huawei $res"; +# if [ ! "$res" = "none" ]; then res="Huawei $res"; # else res="Huawei"; fi # ;; mode) - if [[ ! $res == "none" ]]; then - if [[ $type == "hilink" ]]; then - if [[ $res == "LTE" ]]; then res="4G" - elif [[ $res == "WCDMA" ]]; then res="3G"; + if [ ! "$res" = "none" ]; then + if [ "$type" = "hilink" ]; then + if [ "$res" = "LTE" ]; then res="4G" + elif [ "$res" = "WCDMA" ]]; then res="3G"; else res="2G"; fi else - if [[ $res == 7 ]]; then res="4G" - elif [[ $res < 7 ]] && [[ $res > 2 ]] ; then res="3G"; + if [ $res -eq 7 ]; then res="4G" + elif [ $res -lt 7 ] && [ $res -gt 2 ] ; then res="3G"; else res="2G"; fi fi fi @@ -56,45 +56,45 @@ case $opt in signal) # return signal strength/quality in % - if [[ $type == "hilink" ]]; then + if [ "$type" = "hilink" ]; then # signal request tries to get RSRQ value # try to get RSRQ (4G), EC/IO (3G) or RSSI (2G) value - if [[ $res == "none" ]]; then res=`$script "ecio"`; fi - if [[ ! $res == "none" ]]; then + if [ "$res" = "none" ]; then res=$($script "ecio"); fi + if [ ! "$res" = "none" ]; then # for rsrq and ecio assume: -3dB (100%) downto -20dB (0%) qual=${res//dB/} if [[ ! "$qual" =~ [-0-9\.]* ]]; then qual=-100; fi qual=$(bc <<< "scale=0;res=$qual-0.5;res/1") # just round to next integer - if [[ $qual -le -20 ]]; then qual=0; - elif [[ $qual -ge -3 ]]; then qual=100; + if [ $qual -le -20 ]; then qual=0; + elif [ $qual -ge -3 ]; then qual=100; else qual=$(bc <<< "scale=0;res=100.0/17.0*$qual+2000.0/17.0;res/1"); fi else # try rssi: >-70dBm (100%) downto -100dBm (0%) - res=`$script "rssi"`; - if [[ ! $res == "none" ]]; then - if [[ $res =~ [-0-9\.]* ]]; then res="-120 dBm"; fi + res=$($script "rssi"); + if [ ! "$res" = "none" ]; then + if [[ ! $res =~ [-0-9\.]* ]]; then res="-120 dBm"; fi qual=${res//dBm/} qual=$(bc <<< "scale=0;res=$qual+0.5;res/1") # just round to next integer - if [[ $qual -le -110 ]]; then qual=0; - elif [[ $qual -ge -70 ]]; then qual=100; + if [ $qual -le -110 ]; then qual=0; + elif [ $qual -ge -70 ]; then qual=100; else qual=$(bc <<< "scale=0;res=2.5*$qual+275;res/1"); fi fi fi else # modem returns RSSI as number 0-31 - 0 = -113dB (0%), 1 = -111dB, 31 = >=51dB (100%) qual=$(bc <<< "scale=0;res=$res*3.5+0.5;res/1") - if [[ $qual -gt 100 ]]; then res=100; fi + if [ $qual -gt 100 ]; then res=100; fi fi - if [[ ! "$res" == "none" ]]; then res="$res (${qual}%)"; fi + if [ ! "$res" = "none" ]; then res="$res (${qual}%)"; fi ;; - + operator) # check if operator/network is just a 5 digit number -> extract network name from table if [[ $res =~ ^[0-9]{5}$ ]]; then mcc=${res:0:3} mnc=${res:3:2} op=$(cat $path/mcc-mnc-table.csv | sed -rn 's/^'$mcc'\,[0-9]*\,'$mnc'\,(.*\,){4}(.*)$/\2/p') - if [[ ! -z $op ]]; then res="$op ($res)"; fi + if [ ! -z "$op" ]; then res="$op ($res)"; fi fi ;; diff --git a/config/client_config/info_huawei_hilink.sh b/config/client_config/info_huawei_hilink.sh index 0bae3ecf..d3b20541 100644 --- a/config/client_config/info_huawei_hilink.sh +++ b/config/client_config/info_huawei_hilink.sh @@ -1,49 +1,75 @@ #!/bin/bash -# Infosramtion about HUAWEI hilink (router) modem -# ----------------------------------------------- +# Information about HUAWEI hilink (router) modem +# ---------------------------------------------- # get info about the device and signal # parameter: $1 - see opts list below # $2 - host ip address for API calls (optional) # returns the value of the parameter, or "none" if not found or empty # +# All device informations are buffered for 5 secs to speed up subsequent calls +# # zbchristian 2020 -opts=("device" "imei" "imsi" "telnumber" "ipaddress" "mode" "signal" "rssi" "rsrq" "rsrp" "sinr" "ecio" "operator") - -# xml tags to extract information from -tags=("devicename" "imei" "imsi" "msisdn" "wanipaddress" "workmode" "rsrq" "rssi" "rsrq" "rsrp" "sinr" "ecio" "fullname") -iurl=( 0 0 0 0 0 0 1 1 1 1 1 1 2) -# api urls -urls=("api/device/information" "api/device/signal" "api/net/current-plmn") +if [ -z "$1" ]; then echo "none"; exit; fi host="192.168.8.1" -if [ ! -z $2 ]; then host=$2; fi -avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'` -if [[ -z $avail ]]; then echo "none"; exit; fi +status="no option given" +if [ ! -z "$2" ]; then host="$2"; fi -idx=-1 -opt=${opts[0]} -if [ ! -z $1 ]; then opt=$1; fi +opt="${1,,}" +result="none" +if [ "$opt" = "connected" ]; then + source /usr/local/sbin/huawei_hilink_api.sh + if ! _initHilinkAPI; then echo "none"; exit; fi + result=$(_getMobileDataStatus) + _closeHilinkAPI +else + info_file="/tmp/huawei_infos_$host.dat" + if [ -f "$info_file" ]; then + age=$(( $(date +%s) - $(stat $info_file -c %Y) )) + if [[ $age -gt 5 ]]; then rm -f $info_file; fi + fi -for i in "${!opts[@]}"; do - if [[ ${opts[$i]} == $opt ]]; then idx=$i; fi -done -if [[ $idx == -1 ]];then echo "none"; exit; fi + if [ -f "$info_file" ]; then + infos=$(cat $info_file) + else + source /usr/local/sbin/huawei_hilink_api.sh + if ! _initHilinkAPI; then echo "none"; exit; fi + infos=$(_getAllInformations) + _closeHilinkAPI + if [ ! -z "$infos" ]; then echo "$infos" > /tmp/huawei_infos_$host.dat; fi + fi -par=${tags[$idx]} -iu=${iurl[$idx]} - -url="http://$host/${urls[$iu]}" -# echo "Found option $opt at index $idx - tag $par url $url " - - -info="" -if [ ! -z $url ]; then info=`curl -s $url`; fi - -result=`echo $info | sed -rn 's/.*<'"$par"'>(.*)<\/'"$par"'>.*/\1/pi'` - -if [ -z "$result" ]; then result="none"; fi - -echo $result + case "$opt" in + device|devicename) + key="devicename" + ;; + ipaddress|wanipaddress) + key="wanipaddress" + ;; + mode) + key="workmode" + ;; + telnumber) + key="msisdn" + ;; + imei|imsi|rssi|rsrq|rsrp|sinr|ecio) + key="$opt" + ;; + signal) + key="rsrq" + ;; + operator|fullname) + key="fullname" + ;; + *) + key="" + ;; + esac + if [ -z "$key" ]; then result="none"; fi + result=$(echo "$infos" | sed -rn 's/'$key'=\"([^ \s]*)\"/\1/ip') + if [ -z "$result" ]; then result="none"; fi +fi +echo -n "$result" diff --git a/config/client_config/onoff_huawei_hilink.sh b/config/client_config/onoff_huawei_hilink.sh index 18b1a016..65587d01 100644 --- a/config/client_config/onoff_huawei_hilink.sh +++ b/config/client_config/onoff_huawei_hilink.sh @@ -8,89 +8,12 @@ # -h 192.168.8.1 - host ip address # -p 1234 - PIN of SIM card # -c 0/1 - connect - set datamode off/on -# required software: curl, base64 +# required software: curl, base64, sha256sum # -# TODO: implement login into API - currently the login has to be disabled! -# -# zbchristian 2020 +# zbchristian 2021 -# obtain session and verification token -function _SessToken() { - SesTok=`sudo curl -s http://$host/api/webserver/SesTokInfo -m 5 2> /dev/null` - if [ -z "$SesTok" ]; then exit; fi - - token=`echo $SesTok | sed -r 's/.*(.*)<\/TokInfo>.*/\1/'` - sesinfo=`echo $SesTok | sed -r 's/.*(.*)<\/SesInfo>.*/\1/'` -} - -function _login() { -# ----------------------- THIS DOES NOT WORK ------------------------------------------ -# login to web api - _SessToken - - if [[ ! -z $user ]] && [[ ! -z $pw ]]; then - # password encoding - # type 3 : base64(pw) encoded - # type 4 : base64(sha256sum(user + base64(sha256sum(pw)) + token)) - pwtype3=$(echo $pw | base64 --wrap=0) - hashedpw=$(echo -n "$pw" | sha256sum -b | cut -d " " -f1 | base64 --wrap=0) - pwtype4=$(echo -n "$user$hashedpw$token" | sha256sum -b | cut -d " " -f1 | base64 --wrap=0) - apiurl="api/user/login" - xmldata="$user$pwtype44" -# xmldata="$user$pwtype33" - xtraopts="--dump-header /tmp/hilink_login_hdr.txt" - _sendRequest - # get updated session cookie - sesinfo=$(grep "SessionID=" /tmp/hilink_login_hdr.txt | cut -d ':' -f2 | cut -d ';' -f1) - token=$(grep "__RequestVerificationTokenone" /tmp/hilink_login_hdr.txt | cut -d ':' -f2) -echo "Login Cookie $sesinfo" -echo "Login Token $token" - fi -# ------------------------------ DO NOT USE THE LOGIN CODE ---------------------------------- -} - -function _switchMobileData() { -# switch mobile data on/off - if [[ $datamode -ge 0 ]]; then - xmldata="$datamode" - apiurl="api/dialup/mobile-dataswitch" - _sendRequest - fi -} - -function _enableSIM() { -#SimState: -#255 - no SIM, -#256 - error CPIN, -#257 - ready, -#258 - PIN disabled, -#259 - check PIN, -#260 - PIN required, -#261 - PUK required - status=`curl -s http://$host/api/pin/status -m 10` - state=`echo $status | sed -rn 's/.*(.*)<\/simstate>.*/\1/pi'` - if [[ $state -eq 257 ]]; then echo "Hilink: SIM ready"|systemd-cat; return; fi - if [[ $state -eq 260 ]]; then echo "Hilink: Set PIN"|systemd-cat; _setPIN; fi -} - -function _setPIN() { - if [[ ! -z $pin ]]; then - xmldata="0$pin" - apiurl="api/pin/operate" - _sendRequest - fi -} - -function _sendRequest() { - result="" - if [[ -z $xmldata ]]; then return; fi - result=`curl -s http://$host/$apiurl -m 10 \ - -H "Content-Type: application/xml" \ - -H "Cookie: $sesinfo" \ - -H "__RequestVerificationToken: $token" \ - -d "$xmldata" $xtraopts 2> /dev/null` - xtraopts="" -} +# include the hilink API +source /usr/local/sbin/huawei_hilink_api.sh # handle options @@ -98,8 +21,8 @@ host="192.168.8.1" pin="" user="" pw="" -datamode=-1 -connect=-1 +datamode="" + while getopts ":c:h:l:m:p:" opt; do case $opt in h) if [[ $OPTARG =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then host="$OPTARG"; fi @@ -109,7 +32,7 @@ while getopts ":c:h:l:m:p:" opt; do l) if [[ $OPTARG =~ ^[0-9a-zA-Z]*:.*$ ]]; then user=$(echo "$OPTARG" | cut -d':' -f1); pw=$(echo "$OPTARG" | cut -d':' -f2); - fi + fi ;; c) if [[ $OPTARG == "1" ]]; then datamode=1; else datamode=0; fi ;; @@ -118,21 +41,11 @@ done echo "Hilink: switch device at $host to mode $datamode" | systemd-cat -# check if device is reachable -avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'` -if [[ -z $avail ]]; then - echo "Hilink: no link to host" | systemd-cat - exit -fi +status="usage: -c 1/0 to disconnect/disconnect" +if [ -z "$datamode" ] || [ ! _initHilinkAPI ]; then echo "Hilink: failed - return status: $status"; exit; fi -token="" -Sesinfo="" -xmldata="" -xtraopts="" -result="" +if ! _switchMobileData "$datamode"; then echo "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi -_SessToken -_enableSIM -_switchMobileData # check and perform enable/disable mobile data connection +if ! _closeHilinkAPI; then echo -n "Hilink: failed - return status: $status . Error: ";_getErrorText; fi