|  |  |  | @@ -6,15 +6,16 @@ | 
		
	
		
			
				|  |  |  |  | # - 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 if hilink_host ip/name differs, set "hilink_host=192.168.178.1" before calling any function | 
		
	
		
			
				|  |  |  |  | #   o if the device is locked by a password, set hilink_user="admin"; hilink_password"1234secret" | 
		
	
		
			
				|  |  |  |  | #     _login is called automatically | 
		
	
		
			
				|  |  |  |  | #     only password type 4 is supported | 
		
	
		
			
				|  |  |  |  | #   o if the SIM is requiring a PIN, set "hilink_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 _getAllInformations: returns all available informations as key/value pairs (outputs text)  | 
		
	
		
			
				|  |  |  |  | #   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 | 
		
	
	
		
			
				
					
					|  |  |  | @@ -29,6 +30,7 @@ | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # required software: curl, base64, sha256sum, sed | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # ToDo: improve error handling | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # zbchristian 2021 | 
		
	
		
			
				|  |  |  |  | # | 
		
	
	
		
			
				
					
					|  |  |  | @@ -36,65 +38,73 @@ | 
		
	
		
			
				|  |  |  |  | # 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 | 
		
	
		
			
				|  |  |  |  | # hilink_host=192.168.8.1       # ip address of device | 
		
	
		
			
				|  |  |  |  | # hilink_user="admin"           # user name if locked (default admin) | 
		
	
		
			
				|  |  |  |  | # hilink_password="1234Secret"  # password if locked  | 
		
	
		
			
				|  |  |  |  | # hilink_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.) | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  | # BE AWARE, THAT THE API USES SOME GLOBAL VARIABLES : hilink_host, user, password, pin, response, status | 
		
	
		
			
				|  |  |  |  | # USE THESE ONLY TO COMMUNICATE WITH THE API. | 
		
	
		
			
				|  |  |  |  | # DO NOT USE THE VARIABLE PRE_FIX "hilink_" FOR YOUR OWN VARIABLES | 
		
	
		
			
				|  |  |  |  | # | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | host_default="192.168.8.1" | 
		
	
		
			
				|  |  |  |  | save_file="/tmp/hilink_api_saved.dat" | 
		
	
		
			
				|  |  |  |  | save_age=60 | 
		
	
		
			
				|  |  |  |  | header_file="/tmp/hilink_login_hdr.txt" | 
		
	
		
			
				|  |  |  |  | hilink_host_default="192.168.8.1" | 
		
	
		
			
				|  |  |  |  | hilink_save_file="/tmp/hilink_api_saved.dat" | 
		
	
		
			
				|  |  |  |  | hilink_save_age=60 | 
		
	
		
			
				|  |  |  |  | hilink_header_file="/tmp/hilink_login_hdr.txt" | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # initialize | 
		
	
		
			
				|  |  |  |  | function _initHilinkAPI() { | 
		
	
		
			
				|  |  |  |  |     if [ -z "$host" ]; then host=$host_default; fi | 
		
	
		
			
				|  |  |  |  |     local age | 
		
	
		
			
				|  |  |  |  |     if [ -z "$hilink_host" ]; then hilink_host=$hilink_host_default; fi | 
		
	
		
			
				|  |  |  |  |     if ! _hostReachable; then return 1; fi | 
		
	
		
			
				|  |  |  |  |     if [ -f $save_file ]; then # found file with saved data | 
		
	
		
			
				|  |  |  |  |     if [ -f $hilink_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 | 
		
	
		
			
				|  |  |  |  |         age=$(( $(date +%s) - $(stat $hilink_save_file  -c %Y) )) | 
		
	
		
			
				|  |  |  |  |         if [[ $age -gt $hilink_save_age ]]; then  | 
		
	
		
			
				|  |  |  |  |             rm -f $hilink_save_file | 
		
	
		
			
				|  |  |  |  |             _logout | 
		
	
		
			
				|  |  |  |  |             _sessToken | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |     if [ -z "$sessID" ] || [ -z "$token" ]; then _sessToken; fi | 
		
	
		
			
				|  |  |  |  |     if [ -z "$hilink_sessID" ] || [ -z "$hilink_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') ) | 
		
	
		
			
				|  |  |  |  |     local dat | 
		
	
		
			
				|  |  |  |  |     if [ -f $hilink_save_file ]; then  # restore saved session data | 
		
	
		
			
				|  |  |  |  |         dat=$(cat $hilink_save_file) | 
		
	
		
			
				|  |  |  |  |         hilink_sessID=$(echo "$dat" | sed -nr 's/sessionid: ([a-z0-9]*)/\1/ip') | 
		
	
		
			
				|  |  |  |  |         hilink_token=$(echo "$dat" | sed -nr 's/token: ([a-z0-9]*)/\1/ip') | 
		
	
		
			
				|  |  |  |  |         hilink_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 | 
		
	
		
			
				|  |  |  |  |     local opt | 
		
	
		
			
				|  |  |  |  |     if [ -z "$hilink_host" ]; then hilink_host=$hilink_host_default; fi | 
		
	
		
			
				|  |  |  |  |     if ! _hostReachable; then return 1; fi | 
		
	
		
			
				|  |  |  |  |     rm -f $save_file | 
		
	
		
			
				|  |  |  |  |     rm -f $hilink_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 | 
		
	
		
			
				|  |  |  |  |         echo "sessionid: $hilink_sessID" > $hilink_save_file | 
		
	
		
			
				|  |  |  |  |         echo "token: $hilink_token" >> $hilink_save_file | 
		
	
		
			
				|  |  |  |  |         echo "tokenlist: ${hilink_tokenlist[@]}" >> $hilink_save_file | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |     _logout | 
		
	
		
			
				|  |  |  |  |     tokenlist="" | 
		
	
		
			
				|  |  |  |  |     sessID="" | 
		
	
		
			
				|  |  |  |  |     token="" | 
		
	
		
			
				|  |  |  |  |     hilink_tokenlist="" | 
		
	
		
			
				|  |  |  |  |     hilink_sessID="" | 
		
	
		
			
				|  |  |  |  |     hilink_token="" | 
		
	
		
			
				|  |  |  |  |     return 0 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -111,6 +121,7 @@ function _getStatus() { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | function _isConnected() { | 
		
	
		
			
				|  |  |  |  |     local conn | 
		
	
		
			
				|  |  |  |  |     conn=$(_getStatus "connectionstatus") | 
		
	
		
			
				|  |  |  |  |     status="NO" | 
		
	
		
			
				|  |  |  |  |     if [ ! -z "$conn" ] && [ $conn -eq 901 ]; then | 
		
	
	
		
			
				
					
					|  |  |  | @@ -176,7 +187,7 @@ function _getMobileDataStatus() { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # PIN of SIM can be passed either as $pin, or as parameter | 
		
	
		
			
				|  |  |  |  | # PIN of SIM can be passed either as $hilink_pin, or as parameter | 
		
	
		
			
				|  |  |  |  | # parameter: PIN number of SIM card | 
		
	
		
			
				|  |  |  |  | function _enableSIM() { | 
		
	
		
			
				|  |  |  |  | #SimState: | 
		
	
	
		
			
				
					
					|  |  |  | @@ -187,14 +198,15 @@ function _enableSIM() { | 
		
	
		
			
				|  |  |  |  | #259 - check PIN, | 
		
	
		
			
				|  |  |  |  | #260 - PIN required, | 
		
	
		
			
				|  |  |  |  | #261 - PUK required | 
		
	
		
			
				|  |  |  |  |     if [ ! -z "$1" ]; then pin="$1"; fi | 
		
	
		
			
				|  |  |  |  |     local simstate | 
		
	
		
			
				|  |  |  |  |     if [ ! -z "$1" ]; then hilink_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'` | 
		
	
		
			
				|  |  |  |  |         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 | 
		
	
		
			
				|  |  |  |  |             status="PIN required" | 
		
	
		
			
				|  |  |  |  |             if [ ! -z "$hilink_pin" ]; then _setPIN "$hilink_pin"; fi | 
		
	
		
			
				|  |  |  |  |         return $? | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |         if [[ $simstate -eq 255  ]]; then status="NO SIM"; return 1; fi | 
		
	
	
		
			
				
					
					|  |  |  | @@ -202,20 +214,20 @@ function _enableSIM() { | 
		
	
		
			
				|  |  |  |  |     return 1 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # obtain session and verification token - stored in vars $sessID and $token  | 
		
	
		
			
				|  |  |  |  | # obtain session and verification token - stored in vars $hilink_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 | 
		
	
		
			
				|  |  |  |  |     hilink_tokenlist="" | 
		
	
		
			
				|  |  |  |  |     hilink_token="" | 
		
	
		
			
				|  |  |  |  |     hilink_sessID="" | 
		
	
		
			
				|  |  |  |  |     response=$(curl -s http://$hilink_host/api/webserver/SesTokInfo -m 5 2> /dev/null) | 
		
	
		
			
				|  |  |  |  |     if [ -z "$response" ]; then echo "No access to device at $hilink_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" | 
		
	
		
			
				|  |  |  |  |         hilink_token=$(echo $response | sed  -r 's/.*<TokInfo>(.*)<\/TokInfo>.*/\1/') | 
		
	
		
			
				|  |  |  |  |         hilink_sessID=$(echo $response | sed  -r 's/.*<SesInfo>(.*)<\/SesInfo>.*/\1/') | 
		
	
		
			
				|  |  |  |  |         if [ ! -z "$hilink_sessID" ] &&  [ ! -z "$hilink_token" ]; then  | 
		
	
		
			
				|  |  |  |  |             hilink_sessID="SessionID=$hilink_sessID" | 
		
	
		
			
				|  |  |  |  |             return 0 | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
	
		
			
				
					
					|  |  |  | @@ -223,38 +235,39 @@ function _sessToken() { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # unlock device (if locked) with user name and password | 
		
	
		
			
				|  |  |  |  | # requires stored user="admin"; pw="1234secret";host=$host_default  | 
		
	
		
			
				|  |  |  |  | # requires stored hilink_user="admin"; hilink_password"1234secret";hilink_host=$hilink_host_default  | 
		
	
		
			
				|  |  |  |  | # parameter: none | 
		
	
		
			
				|  |  |  |  | function _login() { | 
		
	
		
			
				|  |  |  |  |     local ret encpw pwtype pwtype3 hashedpw pwtype4  | 
		
	
		
			
				|  |  |  |  |     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 | 
		
	
		
			
				|  |  |  |  | 	ret=1 | 
		
	
		
			
				|  |  |  |  |     if [[ ! -z "$user" ]] && [[ ! -z "$pw" ]]; then | 
		
	
		
			
				|  |  |  |  |     ret=1 | 
		
	
		
			
				|  |  |  |  |     if [[ ! -z "$hilink_user" ]] && [[ ! -z "$hilink_password" ]]; 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' ) | 
		
	
		
			
				|  |  |  |  |         pwtype3=$(echo -n "$hilink_password" | base64 --wrap=0) | 
		
	
		
			
				|  |  |  |  |         hashedpw=$(echo -n "$hilink_password" | 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' ) | 
		
	
		
			
				|  |  |  |  |         pwtype4=$(echo -n "$hilink_user$hashedpw$hilink_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 | 
		
	
		
			
				|  |  |  |  |         hilink_xmldata="<?xml version='1.0' encoding='UTF-8'?><request><Username>$hilink_user</Username><Password>$encpw</Password><password_type>$pwtype</password_type></request>" | 
		
	
		
			
				|  |  |  |  |         hilink_xtraopts="--dump-header $hilink_header_file" | 
		
	
		
			
				|  |  |  |  |         rm -f $hilink_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') ) | 
		
	
		
			
				|  |  |  |  |             hilink_tokenlist=( $(cat $hilink_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 ret=0; fi | 
		
	
		
			
				|  |  |  |  |             hilink_sessID=$(cat $hilink_header_file  | grep -ioP 'SessionID=([a-z0-9]*)') | 
		
	
		
			
				|  |  |  |  |             if [ ! -z "$hilink_sessID" ] &&  [ ! -z "$hilink_token" ]; then ret=0; fi | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  |         rm -f $header_file		 | 
		
	
		
			
				|  |  |  |  |         rm -f $hilink_header_file | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |     return $ret | 
		
	
		
			
				|  |  |  |  | } | 
		
	
	
		
			
				
					
					|  |  |  | @@ -263,12 +276,12 @@ function _login() { | 
		
	
		
			
				|  |  |  |  | # parameter: none | 
		
	
		
			
				|  |  |  |  | function _logout() { | 
		
	
		
			
				|  |  |  |  |     if _loginState; then  | 
		
	
		
			
				|  |  |  |  |         xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><Logout>1</Logout></request>" | 
		
	
		
			
				|  |  |  |  |         hilink_xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><Logout>1</Logout></request>" | 
		
	
		
			
				|  |  |  |  |         if _sendRequest "api/user/logout"; then  | 
		
	
		
			
				|  |  |  |  |             tokenlist="" | 
		
	
		
			
				|  |  |  |  |             sessID="" | 
		
	
		
			
				|  |  |  |  |             token="" | 
		
	
		
			
				|  |  |  |  | 			login_enabled="" | 
		
	
		
			
				|  |  |  |  |             hilink_tokenlist="" | 
		
	
		
			
				|  |  |  |  |             hilink_sessID="" | 
		
	
		
			
				|  |  |  |  |             hilink_token="" | 
		
	
		
			
				|  |  |  |  |             hilink_login_enabled="" | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  |         return $? | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
	
		
			
				
					
					|  |  |  | @@ -277,41 +290,44 @@ function _logout() { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # 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 | 
		
	
		
			
				|  |  |  |  |     local state | 
		
	
		
			
				|  |  |  |  |     status="OK" | 
		
	
		
			
				|  |  |  |  |     if [ -z "$hilink_login_enabled" ]; then _checkLoginEnabled; fi | 
		
	
		
			
				|  |  |  |  |     if [ $hilink_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() { | 
		
	
		
			
				|  |  |  |  |     local state | 
		
	
		
			
				|  |  |  |  |     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 | 
		
	
		
			
				|  |  |  |  |         hilink_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 | 
		
	
		
			
				|  |  |  |  |             hilink_login_enabled=1 | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         hilink_login_enabled="" | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # switch mobile data on/off  1/0 | 
		
	
		
			
				|  |  |  |  | # if SIM is locked, $pin has to be set | 
		
	
		
			
				|  |  |  |  | # if SIM is locked, $hilink_pin has to be set | 
		
	
		
			
				|  |  |  |  | # parameter: state - ON/OFF or 1/0 | 
		
	
		
			
				|  |  |  |  | function _switchMobileData() { | 
		
	
		
			
				|  |  |  |  |     local mode | 
		
	
		
			
				|  |  |  |  |     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>" | 
		
	
		
			
				|  |  |  |  |         if _enableSIM "$hilink_pin"; then | 
		
	
		
			
				|  |  |  |  |             hilink_xmldata="<?xml version: '1.0' encoding='UTF-8'?><request><dataswitch>$mode</dataswitch></request>" | 
		
	
		
			
				|  |  |  |  |             _sendRequest "api/dialup/mobile-dataswitch" | 
		
	
		
			
				|  |  |  |  |             return $? | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
	
		
			
				
					
					|  |  |  | @@ -321,31 +337,33 @@ function _switchMobileData() { | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # parameter: PIN of SIM card | 
		
	
		
			
				|  |  |  |  | function _setPIN() { | 
		
	
		
			
				|  |  |  |  |     local pin | 
		
	
		
			
				|  |  |  |  |     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>" | 
		
	
		
			
				|  |  |  |  |     hilink_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 | 
		
	
		
			
				|  |  |  |  | # Send request to host at http://$hilink_host/$apiurl | 
		
	
		
			
				|  |  |  |  | # data in $hilink_xmldata and options in $hilink_xtraopts | 
		
	
		
			
				|  |  |  |  | # parameter: apiurl (e.g. "api/user/login") | 
		
	
		
			
				|  |  |  |  | function _sendRequest() { | 
		
	
		
			
				|  |  |  |  |     local ret apiurl | 
		
	
		
			
				|  |  |  |  |     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") | 
		
	
		
			
				|  |  |  |  |     if [ -z "$hilink_sessID" ] || [ -z "$hilink_token" ]; then _sessToken; fi  | 
		
	
		
			
				|  |  |  |  |     if [ -z "$hilink_xmldata" ];then | 
		
	
		
			
				|  |  |  |  |         response=$(curl -s http://$hilink_host/$apiurl -m 10 \ | 
		
	
		
			
				|  |  |  |  |                      -H "Cookie: $hilink_sessID") | 
		
	
		
			
				|  |  |  |  |     else  | 
		
	
		
			
				|  |  |  |  |         response=$(curl -s -X POST http://$host/$apiurl -m 10 \ | 
		
	
		
			
				|  |  |  |  |         response=$(curl -s -X POST http://$hilink_host/$apiurl -m 10 \ | 
		
	
		
			
				|  |  |  |  |                     -H "Content-Type: text/xml"  \ | 
		
	
		
			
				|  |  |  |  |                     -H "Cookie: $sessID" \ | 
		
	
		
			
				|  |  |  |  |                     -H "__RequestVerificationToken: $token" \ | 
		
	
		
			
				|  |  |  |  |                     -d "$xmldata" $xtraopts 2> /dev/null) | 
		
	
		
			
				|  |  |  |  |                     -H "Cookie: $hilink_sessID" \ | 
		
	
		
			
				|  |  |  |  |                     -H "__RequestVerificationToken: $hilink_token" \ | 
		
	
		
			
				|  |  |  |  |                     -d "$hilink_xmldata" $hilink_xtraopts 2> /dev/null) | 
		
	
		
			
				|  |  |  |  |         _getToken | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |     if [ ! -z "$response" ];then  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -363,28 +381,29 @@ function _sendRequest() { | 
		
	
		
			
				|  |  |  |  |         status="ERROR" | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |     if [[ "$status" =~ ERROR ]]; then _handleError; fi | 
		
	
		
			
				|  |  |  |  |     xtraopts="" | 
		
	
		
			
				|  |  |  |  |     xmldata="" | 
		
	
		
			
				|  |  |  |  |     hilink_xtraopts="" | 
		
	
		
			
				|  |  |  |  |     hilink_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 | 
		
	
		
			
				|  |  |  |  |     if [ ! -z "$hilink_tokenlist" ] && [ ${#hilink_tokenlist[@]} -gt 0 ]; then | 
		
	
		
			
				|  |  |  |  |         hilink_token=${hilink_tokenlist[0]}       # get first token in list | 
		
	
		
			
				|  |  |  |  |         hilink_tokenlist=("${hilink_tokenlist[@]:1}") # remove used token from list | 
		
	
		
			
				|  |  |  |  |         if [ ${#hilink_tokenlist[@]} -eq 0 ]; then | 
		
	
		
			
				|  |  |  |  |             _logout     # use the last token to logout | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  | 	else | 
		
	
		
			
				|  |  |  |  | 		_sessToken		# old token has been used - need new session | 
		
	
		
			
				|  |  |  |  |     else | 
		
	
		
			
				|  |  |  |  |         _sessToken      # old token has been used - need new session | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # Analyse $status for error code | 
		
	
		
			
				|  |  |  |  | # return error text in $status | 
		
	
		
			
				|  |  |  |  | function _handleError() { | 
		
	
		
			
				|  |  |  |  |     local ret txt | 
		
	
		
			
				|  |  |  |  |     txt=$(_getErrorText) | 
		
	
		
			
				|  |  |  |  |     if [ -z "$code" ]; then return 1; fi | 
		
	
		
			
				|  |  |  |  |     ret=0 | 
		
	
	
		
			
				
					
					|  |  |  | @@ -407,20 +426,21 @@ function _handleError() { | 
		
	
		
			
				|  |  |  |  |     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]} | 
		
	
		
			
				|  |  |  |  | declare -A hilink_err_api | 
		
	
		
			
				|  |  |  |  | hilink_err_api[101]="Unable to get session ID/token" | 
		
	
		
			
				|  |  |  |  | hilink_err_api[108001]="Invalid username/password" | 
		
	
		
			
				|  |  |  |  | hilink_err_api[108002]=${hilink_err_api[108001]} | 
		
	
		
			
				|  |  |  |  | hilink_err_api[108006]=${hilink_err_api[108001]} | 
		
	
		
			
				|  |  |  |  | hilink_err_api[108003]="User already logged in - need to wait a bit" | 
		
	
		
			
				|  |  |  |  | hilink_err_api[108007]="Too many login attempts - need to wait a bit" | 
		
	
		
			
				|  |  |  |  | hilink_err_api[125001]="Invalid session/request token" | 
		
	
		
			
				|  |  |  |  | hilink_err_api[125002]=${hilink_err_api[125001]} | 
		
	
		
			
				|  |  |  |  | hilink_err_api[125003]=${hilink_err_api[125001]} | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | # check error and return error text | 
		
	
		
			
				|  |  |  |  | # status passsed in $status, or $1 | 
		
	
		
			
				|  |  |  |  | function _getErrorText() { | 
		
	
		
			
				|  |  |  |  |     local err code errortext | 
		
	
		
			
				|  |  |  |  |     err="$status" | 
		
	
		
			
				|  |  |  |  |     code="0" | 
		
	
		
			
				|  |  |  |  |     if [ ! -z "$1" ]; then err="$1"; fi | 
		
	
	
		
			
				
					
					|  |  |  | @@ -428,8 +448,8 @@ function _getErrorText() { | 
		
	
		
			
				|  |  |  |  |     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]}" | 
		
	
		
			
				|  |  |  |  |         if [ ! -z "$code" ] && [ ! -z "${hilink_err_api[$code]}" ]; then  | 
		
	
		
			
				|  |  |  |  |             errortext="${hilink_err_api[$code]}" | 
		
	
		
			
				|  |  |  |  |         fi | 
		
	
		
			
				|  |  |  |  |     fi | 
		
	
		
			
				|  |  |  |  |     echo $errortext | 
		
	
	
		
			
				
					
					|  |  |  | @@ -437,8 +457,10 @@ function _getErrorText() { | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | function _hostReachable() { | 
		
	
		
			
				|  |  |  |  |     avail=`timeout 0.5 ping -c 1 $host | sed -rn 's/.*time=.*/1/p'` | 
		
	
		
			
				|  |  |  |  |     if [ -z "$avail" ]; then return 1; fi | 
		
	
		
			
				|  |  |  |  |     local avail | 
		
	
		
			
				|  |  |  |  |     avail=$( timeout 0.5 ping -c 1 $hilink_host | sed -rn 's/.*time=.*/1/p' ) | 
		
	
		
			
				|  |  |  |  |     if [ -z "$avail" ]; then status="ERROR: Not reachable"; return 1; fi | 
		
	
		
			
				|  |  |  |  |     status="OK" | 
		
	
		
			
				|  |  |  |  |     return 0; | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
	
		
			
				
					
					|  |  |  | @@ -446,6 +468,7 @@ function _hostReachable() { | 
		
	
		
			
				|  |  |  |  | # call another function first! | 
		
	
		
			
				|  |  |  |  | # parameter: tag-name | 
		
	
		
			
				|  |  |  |  | function _valueFromResponse() { | 
		
	
		
			
				|  |  |  |  |     local par value | 
		
	
		
			
				|  |  |  |  |     if [ -z "$response" ] || [ -z "$1" ]; then return 1; fi | 
		
	
		
			
				|  |  |  |  |     par="$1" | 
		
	
		
			
				|  |  |  |  |     value=$(echo $response | sed  -rn 's/.*<'$par'>(.*)<\/'$par'>.*/\1/pi') | 
		
	
	
		
			
				
					
					|  |  |  | @@ -468,15 +491,15 @@ function _keyValuePairs() { | 
		
	
		
			
				|  |  |  |  |     return 0 | 
		
	
		
			
				|  |  |  |  | } | 
		
	
		
			
				|  |  |  |  |  | 
		
	
		
			
				|  |  |  |  | host=$host_default | 
		
	
		
			
				|  |  |  |  | user="admin" | 
		
	
		
			
				|  |  |  |  | pw="" | 
		
	
		
			
				|  |  |  |  | token="" | 
		
	
		
			
				|  |  |  |  | tokenlist="" | 
		
	
		
			
				|  |  |  |  | sessID="" | 
		
	
		
			
				|  |  |  |  | xmldata="" | 
		
	
		
			
				|  |  |  |  | xtraopts="" | 
		
	
		
			
				|  |  |  |  | hilink_token="" | 
		
	
		
			
				|  |  |  |  | hilink_tokenlist="" | 
		
	
		
			
				|  |  |  |  | hilink_sessID="" | 
		
	
		
			
				|  |  |  |  | hilink_xmldata="" | 
		
	
		
			
				|  |  |  |  | hilink_xtraopts="" | 
		
	
		
			
				|  |  |  |  | hilink_host=$hilink_host_default | 
		
	
		
			
				|  |  |  |  | hilink_user="admin" | 
		
	
		
			
				|  |  |  |  | hilink_password="" | 
		
	
		
			
				|  |  |  |  | hilink_pin="" | 
		
	
		
			
				|  |  |  |  | response="" | 
		
	
		
			
				|  |  |  |  | status="" | 
		
	
		
			
				|  |  |  |  | pwtype=-1 | 
		
	
		
			
				|  |  |  |  |   | 
		
	
		
			
				|  |  |  |  |   |