#!/usr/local/bin/perl # set volume on Cisco 7940G IP Phones # script assumes that the extension of the phone is also # the fourth octet of the ip address. # Copyright 2010 Jeremy Kister # Released under Perl's Artistic License # v2010081701 # Usage: # -d debug # -s silent, but slow # -x xtns # -r ringtone # -v volume # -x can take multiple extensions in the form of # SIP/141&SIP/140&SIP/111 or 101&102&103&104 # if you have custom ring tones on the 7940G, the first # custom ringtone starts at 3 use strict; use Net::Telnet; use Getopt::Std; use Time::HiRes qw(sleep); use File::TinyLock; my %opt; getopts('dsx:r:v:', \%opt); my $NET = '10.9.1'; # the first three octets of your subnet my $PW = 'cisco'; # the password to telnet into your phone die "cannot use both -v and -r\n" if($opt{v} && $opt{r}); if(defined($opt{r})){ die "invalid -r" unless($opt{r} eq int($opt{r})); }elsif(defined($opt{v})){ die "invalid -v" unless($opt{v} eq int($opt{v})); }else{ die "must specify -r or -v\n"; } my $who = ( $opt{r} + 2 ); my @children; for my $xtn (split /\&/, $opt{x}){ next if($xtn =~ /\@/); $xtn =~ s/^SIP\///; next if($xtn =~ /^19/); my $pid = fork(); if($pid){ push @children, $pid; }elsif($pid == 0){ my $lock = "/tmp/ringer.$xtn"; my $locksmith = File::TinyLock->new(lock => $lock, retries => 0); unless( $locksmith->lock() ){ die "could not get lock on $xtn\n"; } my $addr = "$net.$xtn"; my %log; if($opt{d}){ my($y,$m,$d,$min,$sec) = ( localtime(time) )[5,4,3,2,1,0]; $y += 1900; $m++; $m = sprintf('%02d', $m); $d = sprintf('%02d', $d); $min = sprintf('%02d', $min); $sec = sprintf('%02d', $sec); my $file = "/tmp/ringer.$y$m$d.$min:$sec.$xtn"; %log = ( dump => "$file.dump", input => "$file.input", output => "$file.output", ); } my $t = Net::Telnet->new(Timeout => 2, Dump_log => $log{dump}, Input_log => $log{input}, Output_log => $log{output} ); unless( $t->open($addr) ){ warn "[$$] couldnt telnet to $addr\n"; exit; } $t->waitfor('/Password :.*$/'); $t->print($PW); my @a = ('open', 'offhook', 'onhook'); push @a, ('key set', 'key 2') if($opt{r}); if($opt{v}){ push @a, map { 'key voldn' } (1 .. 30); push @a, map { 'key volup' } (1 .. $opt{v}); }elsif($opt{s}){ my $down = ($who - 1); push @a, map { 'key navdn' } (1 .. $down); }else{ while($who > 10){ push @a, map { 'key navdn' } (1 .. 10); $who -= 10; } push @a, "key $who"; } push @a, ('key soft1', 'key soft3', 'key set') if($opt{r}); push @a, 'close'; my $sleep = $opt{r} ? '0.30' : '0.05'; foreach my $key (@a){ debug( $key ); $t->waitfor('/SIP Phone>\s+$/'); $t->print("test ".$key); sleep($sleep); sleep($sleep) if($key eq 'key soft3' || $key eq 'key set'); } $t->waitfor('/SIP Phone>\s+$/'); $t->print("exit"); $locksmith->unlock(); exit; }else{ warn "couldnt fork: $!\n"; } } foreach(@children){ waitpid($_,0); } sub debug { my ($msg) = join(' ', @_); warn "$msg\n" if($opt{d}); }