Update: Shortly after showing this to some asterisk people (the same ones I asked last night for assistance in this matter) they showed me an easier way Snippits / Channel Check 2.0
The code below still perfectly usefull if you want to check more then a few extensions.
I can’t belive that this isn’t built into Asterisk – I can’t possibly be the only person in the world that wants to be able to ring multipul extensions except when one is busy (not just off hook)
It took some hunting around, and a great deal of source searching but I’ve done it.
First I need to get a list of open channels in order to work out which ones are busy
This is a library file, I keep it in /var/lib/asterisk/perl/apps/lib
sub get_chanlist {
# Open a purely random file...
open(TMP, "+>", undef) or die($!);
# Fill it up with data
$meh = asterisk_chanlist(fileno(TMP));
# GO back to start of file
seek(TMP,0,0);
# I'm being slack here, load it all (No biggy, only 2 lines after all)
my @Returned = <TMP>;
close(TMP);
# Get the list of field names from the first record
my @Keys = ($Returned[0] =~ /^\s+(\S+)\s+\(\s*(\S+)\s+(\S+)\s+(\S+)\s*\)\s+(\S+)\s+(\S+).\s+(\S.+)\r?\n/);
shift(@Returned); pop(@Returned); # We don't want the first or last record
my @Records = ();
foreach $Record (@Returned) {
if (@Row = ($Record =~ /^\s+(\S+)\s+\(\s*(\S+)\s+(\S+)\s+(\S+)\s*\)\s+(\S+)\s+(\S+)\s+(\S.+)\r?\n/)) {
my %hash;
@hash{@Keys} = @Row;
push(@Records, \%hash);
}
}
return @Records;
}
1;
Then we have the res_perl application “chancheck.pl” (Yeh, I probably should renabe it to something more specific)
package Asterisk::Embed;
push(@INC,"/var/lib/asterisk/perl/apps/lib");
require("get_chanlist.pl");
sub {
my $chan_name = shift;
my $chan = asterisk_get_channel_by_name($chan_name);
my @chans = split(/\&/,shift);
asterisk_log("LOG_NOTICE","chancheck.pl: Checking for busy extensions (".join(', ',@chans).")\n");
my @Channels = &get_chanlist();
my $inUse = 0;
foreach $Chan (@Channels) {
foreach $CheckChan (@chans) {
if ($Chan->{Channel} =~ /^\Q$CheckChan\E/i) {
$inUse++;
}
}
}
if ($inUse > 0) {
asterisk_log("LOG_NOTICE","chancheck.pl: Found busy extensions\n");
asterisk_setvariable($chan,'CHANCHECK','BUSY');
} else {
asterisk_log("LOG_NOTICE","chancheck.pl: All extensions free\n");
asterisk_setvariable($chan,'CHANCHECK','AVAIL');
}
}
You call this function with the same params you call your dial() with
ie: tech/ext&tech/ext&tech/ext etc
Sample code:
IPDial=sip/9100&sip/9101
IPVoicemail=9100@default
; Tell our user to hold
exten => s,1,Playback(pls-wait-connect-call)
; Check our lines (sip/9100&sip/9101)
exten => s,2,Perl(LoadFile:chancheck.pl:${IPDial})
exten => s,3,Goto(${CHANCHECK},s,1);
[AVAIL] ; $CHANCHECK
; Dial the extensions - we use music on hold here
exten => s,1,Dial(${IPDial},30,tm(default)hH)
exten => s,2,goto(${DIALSTATUS},s,2)
[BUSY] ; $CHANCHECK & $DIALSTATUS
exten => s,1,Playback(the-party-you-are-calling)
exten => s,2,Playback(vm-isonphone)
exten => s,3,Goto(LEAVEAMSG,s,1)
[CHANUNAVAIL] ; $DIALSTATUS
exten => s,1,NoOp
exten => s,2,Playback(cannot-complete-temp-error)
exten => s,3,Goto(LEAVEAMSG,s,1)
[NOANSWER] ; $DIALSTATUS
exten => s,1,Playback(away-naughty-boy)
exten => s,2,Goto(LEAVEAMSG,s,1)
[LEAVEAMSG]
exten => s,1,DigitTimeout,5
exten => s,2,ResponseTimeout,10
exten => s,3,Background(T-to-leave-msg)
exten => s,4,Background(press-1)
; Press 1
exten => 1,1,Voicemail(${IPVoicemail})
; Timeout - If they take too long, give up
exten => t,1,Playback(thank-you-for-calling)
exten => t,2,Playback(goodbye)
exten => t,3,Wait(2) ; Sometimes goodbye gets cut off
exten => t,4,Hangup
exten => i,1,Playback(invalid) ; "That's not valid, try again"