Grandstream GXP1610 Reboot-o-matic

Standard

I wrote a nice little script to fix a problem I’ve been having with my work VOIP phone. It would lose connection but the screen wouldn’t let you know it had. I didn’t notice that it hadn’t been connected for *two* weeks until someone left a voicemail.

The phone did have a built in SSH interface, which had a reboot command, so I tried using ssh -i key admin@phone < commands.txt to feed it a bunch of commands. I had to pipe a text command to ssh because it doesn’t use a ‘real’ shell on the phone, just Grandstream’s proprietary command interface, which doesn’t accept commands directly when called from ssh.

This was okay, it restarted the phone but it would also reset the password back to ‘admin’. Not very secure really… So I looked for a way to reboot it using the web interface. I fired up Firefox’s network debugger and started to reverse engineer how commands were processed.

I worked out what I needed to do to login as an admin, and then issue the reboot command. It worked. Nice.

#!/bin/bash
sid=$(curl -k -s -c /tmp/cookies.txt -d"password=hunter2" https://192.168.1.50/cgi-bin/dologin --referer https://192.168.1.50 | sed -r 's|.*"sid": "([0-9a-z]+)".*|\1|' )
curl -k -s -b /tmp/cookies.txt -d"request=REBOOT&amp;sid=${sid}" https://192.168.1.50/cgi-bin/api-sys_operation --referer https://192.168.1.50
rm /tmp/cookies.txt

Really though, I wanted a better solution, sure I could reboot the phone every day to make sure it’s working but what would be awesome would be if my script could check to see if the phone was connected to my SIP account, and if it wasn’t, or there was some kind of error, it could reboot it or at least tell me there was an error.

So I wrote version 1 of my script and got it working, when the SIP connection isn’t registered, it will restart the phone.

#!/bin/bash
# Grandstream GXP1610 Reboot-o-matic v1
# Authored on 12/10/2020
# by jcx
# https://jcx.life
# Licence: GPLv3 (or at your option, any later version.)
# Usage: gsreboot [IP/Hostname]
sid=$(curl -k -s -c /tmp/cookies.txt -d"password=hunter2" https://${1}/cgi-bin/dologin --referer https://${1} | sed -r 's|.*"sid": "([0-9a-z]+)".*|\1|' )
status=$(curl -k -s -b /tmp/cookies.txt -d"request=vendor_fullname:P35:PAccountRegisteredServer1:PAccountRegistered1" https://${1}/cgi-bin/api.values.get --referer https://${1} | sed -r 's|.*"PAccountRegistered1": "([0-9a-z]+)".*|\1|' )
if [ ${status} != 1 ]
then
echo "Requesting reboot on ${1} ..."
date
curl -k -s -b /tmp/cookies.txt -d"request=REBOOT&amp;sid=${sid}" https://${1}/cgi-bin/api-sys_operation --referer https://${1}
fi
rm /tmp/cookies.txt

Now I just need some way to automate it, which is where cron comes in. Cron will run a command however often you like, so I just set it to every 5 minutes to do a check, and now I won’t miss any more important work phone calls.

*/5 * * * * /usr/local/bin/gsreboot.sh 192.168.1.50

Okay, so the first version of the script I wrote, while it works, it isn’t very elegant. It didn’t really report any error messages and wasn’t user-configurable so I’ve rewritten it (v2!) and now it supports some options, and has more sensible error messages.

#!/bin/bash
#################################
#
# Grandstream GXP1610 Reboot-o-matic v2
#
# Authored on 12/10/2020
# by jcx
# https://jcx.life
#
# Licence: GPLv3 (or at your option, any later version)
#
#################################
# Please edit the password below to be the admin account on your GXP1610.
# I defined it here so that you don't need to use it on the command line.
# You shouldn't need to make any other changes.
#################################
 
password="hunter2"
 
#### Begin Script
 
if [ -z ${1} ]
    then
    echo "----------------"
    echo "gsreboot2: GXP1610 Reboot-o-matic v2 by jcx (https://jcx.life) licenced under GPLv3"
    echo "Usage: gsreboot2.sh [IP/Hostname] [Protocol: http/https] [Ignore Certificate Errors: Y/N]"
    echo "Example: gsreboot2.sh 192.168.1.50 https Y"
    echo "----------------"
    echo "This will connect to the Grandstream phone on 192.168.1.50"
    echo "using https and will ignore any certificate errors."
    echo "Use with cron every 5 minutes, as it takes the phone about 3 minutes to boot."
    echo "Don't forget to change the password at the top of the script!"
    exit
fi
 
if [ -f "/tmp/gsreboot2.txt" ]
    then
    rm "/tmp/gsreboot2.txt"
fi
 
if [ -z ${2} ]
    then 
    proto="http"
fi
if [ "${2}" = "https" ]
    then
    proto="https"
fi
if [ "${2}" = "http" ]
    then
    proto="http"
fi
 
if [ -z ${3} ]
    then 
    certignore=""
fi
if [ "${3}" = "Y" ]
    then 
    certignore="-k "
fi
if [ "${3}" = "N" ]
    then
    certignore=""
fi
 
sid=$(curl ${certignore}-s --connect-timeout 10 -c /tmp/gsreboot2.txt -d"password=${password}" ${proto}://${1}/cgi-bin/dologin --referer ${proto}://${1} | sed -r 's|.*"sid": "([0-9a-z]+)".*|\1|' )
status=$(curl ${certignore}-s --connect-timeout 10 -b /tmp/gsreboot2.txt -d"request=vendor_fullname:P35:PAccountRegisteredServer1:PAccountRegistered1" ${proto}://${1}/cgi-bin/api.values.get --referer ${proto}://${1} | sed -r 's|.*"PAccountRegistered1": "([0-9a-z]+)".*|\1|' )
if [ "${status}" = "0" ]
    then
    echo "VOIP account not registered..."
    echo "Requesting reboot on ${1} ..."
    request=$(curl ${certignore}-s --connect-timeout 10 -b /tmp/gsreboot2.txt -d"request=REBOOT&amp;sid=${sid}" ${proto}://${1}/cgi-bin/api-sys_operation --referer ${proto}://${1} | sed -r 's|.*"body": "([0-9a-z]+)".*|\1|' )
    if [ "${request}" = "savereboot" ]
        then
        echo "Reboot request has been acknowledged."
    fi
    if [ -f "/tmp/gsreboot2.txt" ]
        then
        rm "/tmp/gsreboot2.txt"
    fi
    exit
fi
 
if [ "${status}" != "1" ]
    then
    echo "Error: Cannot determine status of VOIP account."
fi
 
###
# Enable this code if you want output on success... disabled by default because it works with cron.
###
 
#if [ "${status}" = "1" ]
#    then
#    echo "Success! Your VOIP account is active. No reboot required."
#fi
 
if [ -f "/tmp/gsreboot2.txt" ]
    then
    rm "/tmp/gsreboot2.txt"
fi

Its grown from 18 lines of code to 109(!). This isn’t bad, considering before I wrote these scripts, I’d never written anything in shell / bash script before. So I replaced the entry in my crontab to run the new script every 5 minutes.

*/5 * * * * /usr/local/bin/gsreboot2.sh 192.168.1.50 https Y

Below is what it looks like in my email client on my Linux box when the SIP account is not registered and it needs a reboot.

Date: Mon, 12 Oct 2020 00:10:07 +0100
From: Cron Daemon <root@localhost>
To: jcx@localhost
Subject: Cron <jcx@localhost> /usr/local/bin/gsreboot2.sh 192.168.1.50 https Y
VOIP account not registered...
Requesting reboot on 192.168.1.50 ...
Reboot request has been acknowledged.

If the script encounters an error, it will email an error response. This looks like the following:

Date: Mon, 12 Oct 2020 00:35:07 +0100
From: Cron Daemon <root@localhost>
To: jcx@localhost
Subject: Cron <jcx@localhost> /usr/local/bin/gsreboot2.sh 192.168.1.50 https Y
Error: Cannot determine status of VOIP account.

I hope this proves useful to you, it certainly has to me. Not only because my phone will always be connected but I also learnt how to do some basic shell scripting. Have a great day!

Leave a Reply

Your email address will not be published. Required fields are marked *