Code

Sending SMS from Huawei LTE B593 Routeur (and possibly others)

We got a LTE routeur from Telus at work and I wanted to use it as a backup plan for sending SMS from our Nagios server.

Figured it would be REALLY easy using cURL. Turns out it is, once you’ve figured out all that is wrong with the system.

So here it is, the lines I used to send SMS using cURL on a Huawei LTE B593.

First thing first, you need a cookie file. Called mines cookies.txt.


# Netscape HTTP Cookie File

# http://curl.haxx.se/rfc/cookie_spec.html

# This file was generated by libcurl! Edit at your own risk.

huawei.smarthub    FALSE    /    FALSE    0    SessionID_R3    0

.huawei.smarthub    TRUE    /    FALSE    0    Language    en

.huawei.smarthub    TRUE    /    FALSE    0    FirstMenu    Admin_0

.huawei.smarthub    TRUE    /    FALSE    0    SecondMenu    Admin_0_0

.huawei.smarthub    TRUE    /    FALSE    0    ThirdMenu    Admin_0_0_0

Next part is a bit « Black box magic. » In order to actually correctly send a SMS you need to first login, then fetch a page THEN send the message. If you don’t fetch the page, it won’t work — Go figure.

Note that you need to Base64 encode your password.

Ok let’s login:


curl --cookie-jar cookies.txt --data "Username=admin&Password=Base64EncodedPassword" http://huawei.smarthub/index/login.cgi --cookie cookies.txt

Note that when you login the SessionID_R3 cookie must have a value of 0 otherwise it will fail. Since login in changes this value to give you a session ID, you need to reset it to 0 for every connection.

Now that you’re loged in we need, for some obscure reason, to fetch the message page, so let’s do that.


curl --cookie-jar cookies.txt http://huawei.smarthub/html/sms/message.asp --cookie cookies.txt

Now, we can  send an actual message


curl --data "Receivers=5555555555&SmsContent=Test SMS&EncodeType=7bit&LengthList=8,0,0,0&CurrentTime=5/14/2013 2:29:59 PM" http://huawei.smarthub/html/sms/sendSms.cgi?RequestFile=/html/sms/message.asp --cookie cookies.txt

This will send the message Test SMS to 555 555-5555. Not you can split the Recievers with ; to add (AFAIK) as many as you want.

Note you need to change the first number in the LengthList to the number of character in your message (the 8 in 8,0,0).

And that’s it!

One of my collegue packaged it all up in a nice, Nagios ready, sendsms.sh.


# ./sendsms.sh

Usage: ./sendsms.sh -t number [-H hostname] [-p password] [-m "message"] [-v]

Arguments:

-h : show this help

-H : hostname (or IP) for the SMS gateway

-p : password for admin

-t : destination (SMS number) (required)

-m : message (will be converted to 7-bit)

-v : verbose; show the curl output

Link seems to be broken so here’s the code

#! /bin/bash

#
# Send SMSes using a Huawei gateway, via cURL.
#
# kevin.lamontagne@libeo.com 2013-05-15

set -e
set -u

function usage(){
 /bin/cat <<EOF
Usage: $0 -t number [-H hostname] [-p password] [-m "message"] [-v]
Arguments:
-h : show this help
-H : hostname (or IP) for the SMS gateway
-p : password for admin
-t : destination (SMS number) (required)
-m : message (will be converted to 7-bit)
-v : verbose; show the curl output
EOF
 exit -1;
}

verbose=""
myhost="huawei.smarthub"
password="MTExMTEx" #111111 en b64
message="Test SMS"
mlen="${#message}"
destination=""

# Parse args
OPTERR=0
#only "-t" requires a value
while getopts ":hH:p:t::m:v" opt
do
case $opt
 in
 t)
 destination="$OPTARG"
 ;;
 m)
 message="$OPTARG"
 ;;
 H)
 myhost="$OPTARG"
 ;;
 v)
 verbose="--verbose"
 ;;
 d)
 dry=yes
 verbose=yes
 ;;
 h)
 usage
 ;;
 \?)
 echo "Invalid option: $OPTARG"
 usage
 ;;
 🙂
 echo "-${OPTARG}: Argument required"
 usage
 ;;
 esac
done
if [ "$OPTERR" != "0" -o -z "$destination" ]
then
 usage
fi

# http://stackoverflow.com/questions/296536
rawurlencode() {
 local string="${1}"
 local strlen=${#string}
 local encoded=""

 for (( pos=0 ; pos<strlen ; pos++ )); do
 c=${string:$pos:1}
 case "$c" in
 [-_.~a-zA-Z0-9] ) o="${c}" ;;
 * ) printf -v o '%%%02x' "'$c"
 esac
 encoded+="${o}"
 done
 echo "${encoded}"
}

#Convertir en ASCII 7-bit
message="$(echo "$message" | /usr/bin/iconv -c --to-code="ASCII")"
#Couper a 154 chars
message="$(echo "$message" | cut -c1-154)"
#Encoder pour le GET
message="$(rawurlencode "$message")"

#Create a temporary cookiejar
cookiejar="$(mktemp)"
cat /etc/icinga/huawei_default_cookie.txt > "$cookiejar"

#Login with a default cookiejar
curl -s $verbose --cookie-jar "$cookiejar" --cookie "$cookiejar" --data "Username=admin&Password=${password}" "http://${myhost}/index/login.cgi" >/dev/null

#Need to retrieve this page before sending a SMS...
curl -s $verbose --cookie-jar "$cookiejar" --cookie "$cookiejar" "http://${myhost}/html/sms/message.asp" >/dev/null

#HTTP POST the SMS
url_send="http://${myhost}/html/sms/sendSms.cgi?RequestFile=/html/sms/message.asp"
data_send="Receivers=${destination}&SmsContent=${message}&EncodeType=7bit&LengthList=${mlen},0,0,0&CurrentTime=$(date '+%D %r' | sed 's/ $//')"
command_send='LC_TIME="en_US.UTF-8" curl -s --data "$data_send" "$url_send" --cookie "$cookiejar"'
if ! eval $command_send | grep "gVarSendStateOK" -c
then
 echo "Erreur dans l'envoi de sms"
 exit 2
fi

rm -f "$cookiejar"
Standard