Sample perl script and/or SIP NOTIFY commands to reboot Cisco 89xx and 99xx phones

Hi,

Some folks with Cisco 89xx and 99xx series phones floating around may find the following “reboot” perl script useful. I’ve adapted this from a script written a few years ago by Matt Klein which used the telnet protocol.

This script logs into the phone using SSH, then enters the debug shell where either the ‘reset hard|soft|factory’ command is executed before closing the connection.

Here are the steps to get this working:

[List=1]
[*] Install the Net::SSH::Expect perl module

At a system prompt type:

then at the CPAN prompt type

[*] Edit the variables and addresses in the script to suit your environment and place script in /var/www/cgi-bin

[*] chmod 755 reboot.pl to make it executable

[/List]
The script can be called from the command prompt giving the IP address of the phone to be reboot as an argument. Alternatively use the ‘all’ argument to reboot all phones (as defined inside the script)

Not that I’m a huge perl guru (so far from it really) but I’ve read in a few perl blogs that the reliability of Net::SSH::Expect module has been called into question, due in part to the way it detects the completion of remote commands. A more solid alternative may be to re-write the script to use Net::OpenSSH or Net::SSH2 modules, but for now it seems to be working fine for me…

Please feel free to modify and use as you wish.

#!/usr/bin/perl 
# Sean Simpson 2012 Please feel free to distribute
# 
# perl script using SSH to reboot Cisco 4th Gen (89xx and 99xx series) phones
# 
# Adapted from Matt Klein's 2004 perl script to reboot Cisco 79xx series phones
# 
# Please ensure that you can manually SSH to your phone, first.
#
use Net::SSH::Expect;

$phone_ip = shift; 

# Your phone SSH Username, as set in the phone SEP<mac address>.cnf.xml file
$sshusername = "admin";

# Your phone SSH Password, as set in the phone SEP<mac address>.cnf.xml file
$sshpassword = "cisco";

# The phone Debug shell login prompt, should not need to be changed
$debuglogin = "(none) login: ";

# The phone Debug shell username, should not need to be changed
$debugusername = "debug";

# The phone Debug shell password, should not need to be changed
$debugpassword = "debug";

# The Cisco CP-9971 Debug shell prompt, should not need to be changed
$debugprompt = "DEBUG> ";

# Cisco Reset Command
# Use either "reset hard", "reset soft" or "reset factory"
$command = "reset hard";

# Timeout for the SSH login
# My phone takes around 15 seconds to provide the SSH password prompt, ensure the timeout value below is set accordingly
# An insufficient timeout value will cause a script error such as, "SSHAuthenticationError Login timed out" to be displayed
# A too long timeout will also cause SSHProcessErrors, I would recommend the default setting of 15 is maintained for stability
$timeoutvalue = "15";

if ($phone_ip eq "all")
{
	reboot("192.168.0.80",$sshpassword,$sshusername,$debuglogin,$debugusername,$debugpassword,$debugprompt,$command); 
	reboot("192.168.0.85",$sshpassword,$sshusername,$debuglogin,$debugusername,$debugpassword,$debugprompt,$command); 
	reboot("192.168.0.90",$sshpassword,$sshusername,$debuglogin,$debugusername,$debugpassword,$debugprompt,$command); 
} elsif ($phone_ip eq "") {
	print "\n*WARNING* No IP address provided.\n";
	print "\nPlease enter a valid Cisco phone IP Address or enter 'all' (to reboot all phones) as an argument.\n\n";
} else {
	reboot($phone_ip,$sshpassword,$sshusername,$debuglogin,$debugusername,$debugpassword,$debugprompt,$command); 
}

exit;

sub reboot{ 

    my ($ip,$sshpassword,$sshusername,$debuglogin,$debugusername,$debugpassword,$debugprompt,$command) = @_;

    print "\nPlease be patient whilst Cisco phone at address $ip is reboot. This may take up to 90 seconds to complete...\n";  

    my $ssh = Net::SSH::Expect->new (
	host => $ip, 
	password=> $sshpassword, 
	user => $sshusername, 
        timeout => $timeoutvalue,
	raw_pty => 1
        );

    my $login_output = $ssh->login();

    $ssh->waitfor('/'.$debuglogin.'>.*$/');
    $ssh->send($debugusername);

    $ssh->waitfor('/Password :.*$/');
    $ssh->send($debugpassword);

    $ssh->waitfor('/'.$debugprompt.'>.*$/');
    $ssh->exec($command);

    $ssh->close();

    print "\n*SUCCESS* Cisco phone at address $ip has been sucessfully reboot using command '$command'\n\n";
    
}
1 Like

Although it is possible to write a php or perl script (as described above) to remotely restart or reset Cisco 89xx and 99xx phones, by far the simplest and quickest method is to use the SIP NOTIFY command. By applying the Presence Subscription on Cisco Phones Asterisk patch, it is possible to use the following commands from the Asterisk CLI to restart (reloads line keys, dial-plan and soft keys) or reset these Cisco phones:

CLI> sip notify cisco-restart ${PEERNAME}
or
CLI> sip notify cisco-reset ${PEERNAME}

Also I’ve just noticed (although it was probably there all along) that the MWI indicator can be manually cleared using the following command:

CLI> sip notify clear-mwi ${PEERNAME}

The following variables and functions should be included in sip_notify_custom.conf settings:

[clear-mwi]
Event=>message-summary
Content-type=>application/simple-message-summary
Content=>Messages-Waiting: no
Content=>Message-Account: sip:[email protected]
Content=>Voice-Message: 0/0 (0/0)
Content=>

; Cisco

[cisco-restart]
Event=>service-control
Subscription-State=>active
Content-Type=>text/plain
Content=>action=restart
Content=>RegisterCallId={${SIPPEER(${PEERNAME},regcallid)}}
Content=>ConfigVersionStamp={0000000000000000}
Content=>DialplanVersionStamp={0000000000000000}
Content=>SoftkeyVersionStamp={0000000000000000}

[cisco-reset]
Event=>service-control
Subscription-State=>active
Content-Type=>text/plain
Content=>action=reset
Content=>RegisterCallId={${SIPPEER(${PEERNAME},regcallid)}}
Content=>ConfigVersionStamp={0000000000000000}
Content=>DialplanVersionStamp={0000000000000000}
Content=>SoftkeyVersionStamp={0000000000000000}
1 Like

I tried the php route but couldn’t get it to work. This worked fine though, thanks.

I’ve found these SIP NOTIFY commands to work really well too.

I’m less inclined to recommend the perl script method as its SO much more difficult to get working and also much, much slower to run.

One other comment, the sip-notify is the preferred method. PHP expect is a very tedious and error prone method, it involves multiple text based protocols with no handshake and is not clean.

I do not recommend the telnet/expect route.