mirror of
https://github.com/billz/raspap-webgui.git
synced 2023-10-10 13:37:24 +02:00
Add Huawei Hilink API
Cleanup mobile data scripts
This commit is contained in:
parent
a94337342b
commit
613cd6bae8
482
config/client_config/huawei_hilink_api.sh
Normal file
482
config/client_config/huawei_hilink_api.sh
Normal file
@ -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/.*<simstate>([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/.*<code>([0-9]*)<\/code>.*/\1/ip')
|
||||||
|
if [ -z "$status" ]; then
|
||||||
|
token=`echo $response | sed -r 's/.*<TokInfo>(.*)<\/TokInfo>.*/\1/'`
|
||||||
|
sessID=`echo $response | sed -r 's/.*<SesInfo>(.*)<\/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/.*<password_type>([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="<?xml version='1.0' encoding='UTF-8'?><request><Username>$user</Username><Password>$encpw</Password><password_type>$pwtype</password_type></request>"
|
||||||
|
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="<?xml version: '1.0' encoding='UTF-8'?><request><Logout>1</Logout></request>"
|
||||||
|
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>(.*)<\/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>(.*)<\/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="<?xml version: '1.0' encoding='UTF-8'?><request><dataswitch>$mode</dataswitch></request>"
|
||||||
|
_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="<?xml version: '1.0' encoding='UTF-8'?><request><OperateType>0</OperateType><CurrentPin>$pin</CurrentPin><NewPin></NewPin><PukCode></PukCode></request>"
|
||||||
|
_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/.*<code>([0-9]*)<\/code>.*/\1/ip') # check for error code
|
||||||
|
if [ -z "$status" ]; then
|
||||||
|
status="OK"
|
||||||
|
response=$(echo "$response" | sed -nr 's/.*<response>(.*)<\/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
|
||||||
|
|
@ -12,43 +12,43 @@
|
|||||||
# zbchristian 2020
|
# zbchristian 2020
|
||||||
#
|
#
|
||||||
opt="device"
|
opt="device"
|
||||||
if [ ! -z $1 ]; then opt=${1,,}; fi
|
if [ ! -z "$1" ]; then opt=${1,,}; fi
|
||||||
type="hilink"
|
type="hilink"
|
||||||
if [ ! -z $2 ]; then type=${2,,}; fi
|
if [ ! -z "$2" ]; then type=${2,,}; fi
|
||||||
|
|
||||||
path=`dirname $0`
|
path=$(dirname "$0")
|
||||||
if [[ $type == "hilink" ]]; then
|
if [ "$type" = "hilink" ]; then
|
||||||
connect="192.168.8.1"
|
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"
|
script="$path/info_huawei_hilink.sh"
|
||||||
else
|
else
|
||||||
connect="/dev/ttyUSB2"
|
connect="/dev/ttyUSB2"
|
||||||
if [ ! -z $3 ]; then connect=$3; fi
|
if [ ! -z "$3" ]; then connect=$3; fi
|
||||||
script="$path/info_huawei_modem.sh"
|
script="$path/info_huawei_modem.sh"
|
||||||
fi
|
fi
|
||||||
res=`$script $opt $connect`
|
res=$($script $opt $connect)
|
||||||
|
|
||||||
# some results require special treatment
|
# some results require special treatment
|
||||||
case $opt in
|
case $opt in
|
||||||
|
|
||||||
# manufacturer)
|
# manufacturer)
|
||||||
# if [[ $res == "none" ]]; then res="Huawei"; fi
|
# if [ "$res" = "none" ]; then res="Huawei"; fi
|
||||||
# ;;
|
# ;;
|
||||||
|
|
||||||
# device)
|
# device)
|
||||||
# if [[ ! $res == "none" ]]; then res="Huawei $res";
|
# if [ ! "$res" = "none" ]; then res="Huawei $res";
|
||||||
# else res="Huawei"; fi
|
# else res="Huawei"; fi
|
||||||
# ;;
|
# ;;
|
||||||
|
|
||||||
mode)
|
mode)
|
||||||
if [[ ! $res == "none" ]]; then
|
if [ ! "$res" = "none" ]; then
|
||||||
if [[ $type == "hilink" ]]; then
|
if [ "$type" = "hilink" ]; then
|
||||||
if [[ $res == "LTE" ]]; then res="4G"
|
if [ "$res" = "LTE" ]; then res="4G"
|
||||||
elif [[ $res == "WCDMA" ]]; then res="3G";
|
elif [ "$res" = "WCDMA" ]]; then res="3G";
|
||||||
else res="2G"; fi
|
else res="2G"; fi
|
||||||
else
|
else
|
||||||
if [[ $res == 7 ]]; then res="4G"
|
if [ $res -eq 7 ]; then res="4G"
|
||||||
elif [[ $res < 7 ]] && [[ $res > 2 ]] ; then res="3G";
|
elif [ $res -lt 7 ] && [ $res -gt 2 ] ; then res="3G";
|
||||||
else res="2G"; fi
|
else res="2G"; fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
@ -56,36 +56,36 @@ case $opt in
|
|||||||
|
|
||||||
signal)
|
signal)
|
||||||
# return signal strength/quality in %
|
# return signal strength/quality in %
|
||||||
if [[ $type == "hilink" ]]; then
|
if [ "$type" = "hilink" ]; then
|
||||||
# signal request tries to get RSRQ value
|
# signal request tries to get RSRQ value
|
||||||
# try to get RSRQ (4G), EC/IO (3G) or RSSI (2G) 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 res=$($script "ecio"); fi
|
||||||
if [[ ! $res == "none" ]]; then
|
if [ ! "$res" = "none" ]; then
|
||||||
# for rsrq and ecio assume: -3dB (100%) downto -20dB (0%)
|
# for rsrq and ecio assume: -3dB (100%) downto -20dB (0%)
|
||||||
qual=${res//dB/}
|
qual=${res//dB/}
|
||||||
if [[ ! "$qual" =~ [-0-9\.]* ]]; then qual=-100; fi
|
if [[ ! "$qual" =~ [-0-9\.]* ]]; then qual=-100; fi
|
||||||
qual=$(bc <<< "scale=0;res=$qual-0.5;res/1") # just round to next integer
|
qual=$(bc <<< "scale=0;res=$qual-0.5;res/1") # just round to next integer
|
||||||
if [[ $qual -le -20 ]]; then qual=0;
|
if [ $qual -le -20 ]; then qual=0;
|
||||||
elif [[ $qual -ge -3 ]]; then qual=100;
|
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 qual=$(bc <<< "scale=0;res=100.0/17.0*$qual+2000.0/17.0;res/1"); fi
|
||||||
else
|
else
|
||||||
# try rssi: >-70dBm (100%) downto -100dBm (0%)
|
# try rssi: >-70dBm (100%) downto -100dBm (0%)
|
||||||
res=`$script "rssi"`;
|
res=$($script "rssi");
|
||||||
if [[ ! $res == "none" ]]; then
|
if [ ! "$res" = "none" ]; then
|
||||||
if [[ $res =~ [-0-9\.]* ]]; then res="-120 dBm"; fi
|
if [[ ! $res =~ [-0-9\.]* ]]; then res="-120 dBm"; fi
|
||||||
qual=${res//dBm/}
|
qual=${res//dBm/}
|
||||||
qual=$(bc <<< "scale=0;res=$qual+0.5;res/1") # just round to next integer
|
qual=$(bc <<< "scale=0;res=$qual+0.5;res/1") # just round to next integer
|
||||||
if [[ $qual -le -110 ]]; then qual=0;
|
if [ $qual -le -110 ]; then qual=0;
|
||||||
elif [[ $qual -ge -70 ]]; then qual=100;
|
elif [ $qual -ge -70 ]; then qual=100;
|
||||||
else qual=$(bc <<< "scale=0;res=2.5*$qual+275;res/1"); fi
|
else qual=$(bc <<< "scale=0;res=2.5*$qual+275;res/1"); fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
else
|
else
|
||||||
# modem returns RSSI as number 0-31 - 0 = -113dB (0%), 1 = -111dB, 31 = >=51dB (100%)
|
# 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")
|
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
|
fi
|
||||||
if [[ ! "$res" == "none" ]]; then res="$res (${qual}%)"; fi
|
if [ ! "$res" = "none" ]; then res="$res (${qual}%)"; fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
operator)
|
operator)
|
||||||
@ -94,7 +94,7 @@ case $opt in
|
|||||||
mcc=${res:0:3}
|
mcc=${res:0:3}
|
||||||
mnc=${res:3:2}
|
mnc=${res:3:2}
|
||||||
op=$(cat $path/mcc-mnc-table.csv | sed -rn 's/^'$mcc'\,[0-9]*\,'$mnc'\,(.*\,){4}(.*)$/\2/p')
|
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
|
fi
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
@ -1,49 +1,75 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Infosramtion about HUAWEI hilink (router) modem
|
# Information about HUAWEI hilink (router) modem
|
||||||
# -----------------------------------------------
|
# ----------------------------------------------
|
||||||
# get info about the device and signal
|
# get info about the device and signal
|
||||||
# parameter: $1 - see opts list below
|
# parameter: $1 - see opts list below
|
||||||
# $2 - host ip address for API calls (optional)
|
# $2 - host ip address for API calls (optional)
|
||||||
# returns the value of the parameter, or "none" if not found or empty
|
# 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
|
# zbchristian 2020
|
||||||
|
|
||||||
opts=("device" "imei" "imsi" "telnumber" "ipaddress" "mode" "signal" "rssi" "rsrq" "rsrp" "sinr" "ecio" "operator")
|
if [ -z "$1" ]; then echo "none"; exit; fi
|
||||||
|
|
||||||
# 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")
|
|
||||||
|
|
||||||
host="192.168.8.1"
|
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'`
|
status="no option given"
|
||||||
if [[ -z $avail ]]; then echo "none"; exit; fi
|
if [ ! -z "$2" ]; then host="$2"; fi
|
||||||
|
|
||||||
idx=-1
|
opt="${1,,}"
|
||||||
opt=${opts[0]}
|
result="none"
|
||||||
if [ ! -z $1 ]; then opt=$1; fi
|
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 [ -f "$info_file" ]; then
|
||||||
if [[ ${opts[$i]} == $opt ]]; then idx=$i; fi
|
infos=$(cat $info_file)
|
||||||
done
|
else
|
||||||
if [[ $idx == -1 ]];then echo "none"; exit; fi
|
source /usr/local/sbin/huawei_hilink_api.sh
|
||||||
|
if ! _initHilinkAPI; then echo "none"; exit; fi
|
||||||
par=${tags[$idx]}
|
infos=$(_getAllInformations)
|
||||||
iu=${iurl[$idx]}
|
_closeHilinkAPI
|
||||||
|
if [ ! -z "$infos" ]; then echo "$infos" > /tmp/huawei_infos_$host.dat; fi
|
||||||
url="http://$host/${urls[$iu]}"
|
fi
|
||||||
# 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'`
|
|
||||||
|
|
||||||
|
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
|
if [ -z "$result" ]; then result="none"; fi
|
||||||
|
fi
|
||||||
echo $result
|
echo -n "$result"
|
||||||
|
|
||||||
|
@ -8,89 +8,12 @@
|
|||||||
# -h 192.168.8.1 - host ip address
|
# -h 192.168.8.1 - host ip address
|
||||||
# -p 1234 - PIN of SIM card
|
# -p 1234 - PIN of SIM card
|
||||||
# -c 0/1 - connect - set datamode off/on
|
# -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 2021
|
||||||
#
|
|
||||||
# zbchristian 2020
|
|
||||||
|
|
||||||
# obtain session and verification token
|
# include the hilink API
|
||||||
function _SessToken() {
|
source /usr/local/sbin/huawei_hilink_api.sh
|
||||||
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>(.*)<\/TokInfo>.*/\1/'`
|
|
||||||
sesinfo=`echo $SesTok | sed -r 's/.*<SesInfo>(.*)<\/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="<?xml version='1.0' encoding='UTF-8'?><request><Username>$user</Username><Password>$pwtype4</Password><password_type>4</password_type></request>"
|
|
||||||
# xmldata="<?xml version='1.0' encoding='UTF-8'?><request><Username>$user</Username><Password>$pwtype3</Password><password_type>3</password_type></request>"
|
|
||||||
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="<?xml version: '1.0' encoding='UTF-8'?><request><dataswitch>$datamode</dataswitch></request>"
|
|
||||||
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>(.*)<\/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="<?xml version: '1.0' encoding='UTF-8'?><request><OperateType>0</OperateType><CurrentPin>$pin</CurrentPin><NewPin></NewPin><PukCode></PukCode></request>"
|
|
||||||
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=""
|
|
||||||
}
|
|
||||||
|
|
||||||
# handle options
|
# handle options
|
||||||
|
|
||||||
@ -98,8 +21,8 @@ host="192.168.8.1"
|
|||||||
pin=""
|
pin=""
|
||||||
user=""
|
user=""
|
||||||
pw=""
|
pw=""
|
||||||
datamode=-1
|
datamode=""
|
||||||
connect=-1
|
|
||||||
while getopts ":c:h:l:m:p:" opt; do
|
while getopts ":c:h:l:m:p:" opt; do
|
||||||
case $opt in
|
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
|
h) if [[ $OPTARG =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then host="$OPTARG"; fi
|
||||||
@ -118,21 +41,11 @@ done
|
|||||||
|
|
||||||
echo "Hilink: switch device at $host to mode $datamode" | systemd-cat
|
echo "Hilink: switch device at $host to mode $datamode" | systemd-cat
|
||||||
|
|
||||||
# check if device is reachable
|
status="usage: -c 1/0 to disconnect/disconnect"
|
||||||
avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'`
|
if [ -z "$datamode" ] || [ ! _initHilinkAPI ]; then echo "Hilink: failed - return status: $status"; exit; fi
|
||||||
if [[ -z $avail ]]; then
|
|
||||||
echo "Hilink: no link to host" | systemd-cat
|
|
||||||
exit
|
|
||||||
fi
|
|
||||||
|
|
||||||
token=""
|
if ! _switchMobileData "$datamode"; then echo "Hilink: could not switch the data mode on/off . Error: ";_getErrorText; fi
|
||||||
Sesinfo=""
|
|
||||||
xmldata=""
|
|
||||||
xtraopts=""
|
|
||||||
result=""
|
|
||||||
|
|
||||||
_SessToken
|
if ! _closeHilinkAPI; then echo -n "Hilink: failed - return status: $status . Error: ";_getErrorText; fi
|
||||||
_enableSIM
|
|
||||||
_switchMobileData # check and perform enable/disable mobile data connection
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user