Hello Everyone, I've been playing with an agi script for paging sip phones. page.agi will take all available sip extensions and assign them to the global variable PAGE_GROUP. Allowing the phones to be paged from the dialplan with the new Page cmd. Extensions to be excluded are presented as arguments to the agi. Each time a page is made this agi refreshes the global variable. This works with both my aastra and polycom phones. It should be easily modified for other sip phones. The agi itself is a compliation of allpage.agi & allcall.agi, with a few changes. Copy this script to your agi-bin: #!/usr/bin/perl # # page.agi - Original file was allpage.agi by Rob Thomas 2005. # With parts of allcall.agi Original file by John Baker # Modified by Jeremy Betts 2006 # # # # This program is free software; you can redistribute it and/or # modify it under the terms of Version 2 of the GNU General # Public License as published by the Free Software Foundation # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # page.agi will take all available sip extensions and assign them to the # global variable PAGE_GROUP. Allowing the phones to be paged from the # # dialplan with the new Page cmd. # Each time a page is made this agi refreshes the global variable. # This works with both my aastra and polycom phones. # It should be easily modified for other sip phones # # # #Check for Telnet if (eval "require Net::Telnet;") { use Net::Telnet; } else { print "VERBOSE \"Net::Telnet NOT INSTALLED - this is required\" 0\n"; exit 0; } # You need to configure this: Your manager API username and password. This # is the information from /etc/asterisk/manager.conf. You need something like # this in it: # [admin] # secret = amp111 # deny=0.0.0.0/0.0.0.0 # permit=127.0.0.0/255.0.0.0 # read = system,call,log,verbose,command,agent,user # write = system,call,log,verbose,command,agent,user # IF that's what you have in your conf file, this is what you should have here: my $mgruser = "admin"; my $mgrpass = "amp111"; my $mgrport = 5038; # set our array of phones that we will NOT be paging @bypass = @ARGV; # Get our needed info for idle sip phones @sips = grep(/^\s+\d+\s.*/, `asterisk -rx "show hints"`); # Now check each sip phone to see if it's in use and also # against our exclude list. If it passes both, it's # added to our array of calls to make foreach $sipline (@sips) { my ($junk0, $exten, $junk1, $chan, $state, $junk2) = split(/ +/, $sipline,6); unless (($state ne "State:Idle") || (grep(/$exten/i, @bypass))) { push (@mypage, "$exten"); } } $page= join ("&SIP/", @mypage); print "$page";{ # Open connection to AGI and set Global Variable PAGE_GROUP # to our completed array of sip phones my $tn = new Net::Telnet ( Port => $mgrport, Prompt => '/.*[\$%#>] $/', Output_record_separator => '', Input_Log=> "/tmp/input.log", Output_Log=> "/tmp/output.log", Errmode => 'return', ); $tn->open("127.0.0.1"); $tn->waitfor('/0\n$/'); $tn->print("Action: Login\n"); $tn->print("Username: $mgruser\n"); $tn->print("Secret: $mgrpass\n"); $tn->print("Events: off\n\n"); my ($pm, $m) = $tn->waitfor('/Authentication (.+)\n\n/'); if ($m =~ /Authentication failed/) { print "VERBOSE \"Incorrect MGRUSER or MGRPASS - unable to connect to manager interface\" 0\n"; exit; } $tn->print("Action: Setvar\n"); $tn->print("Variable: PAGE_GROUP\n"); $tn->print("Value: $page\n\n"); $tn->print("Action: Logoff\n\n"); $tn->close; } Then add the following to your dialplan: exten => *61,1,Set(TIMEOUT(absolute) = 15) exten => *61,n,AGI(page.agi|<arg>|<arg>) exten => *61,n,SetCallerID("Page:${CALLERIDNAME}" <${CALLERIDNUM}>) exten => *61,n,Set(_ALERT_INFO="Ring Answer") exten => *61,n,SIPAddHeader(Call-Info: answer-after=0) exten => *61,n,Page(SIP/${PAGE_GROUP}) exten => *61,n,Hangup() Hope this is helpfull for others. Works great for me, no more waiting for page to hang up! As soon as the paging phone is hung up all paged phones hang up.
Hi Some petty notes notes regarding the perl: On Thu, Jan 26, 2006 at 11:23:27PM -0800, Jeremy wrote: 1. you didn't use strict and -w. Debugging will be a whole lot tougher 2. Consider using the nagging -T (taint mode), to explicitly know when you trust the input. 3. Consider the latency this cases. Note that this script is run at the startup of every call. Let's see what it does:> # > #Check for Telnet > if (eval "require Net::Telnet;") { > use Net::Telnet; > } else { > print "VERBOSE \"Net::Telnet NOT INSTALLED - this is required\" > 0\n"; > exit 0; > }Just use: use Net::Telnet; This will generate a compile-time (perl -c) check which is easy to test automatically. BTW: why not use an existing perl module to talk to> > # You need to configure this: Your manager API username and password. This > # is the information from /etc/asterisk/manager.conf. You need something > like > # this in it: > # [admin] > # secret = amp111 > # deny=0.0.0.0/0.0.0.0 > # permit=127.0.0.0/255.0.0.0 > # read = system,call,log,verbose,command,agent,user > # write = system,call,log,verbose,command,agent,userNow, why generate entries to talk to the the manager interface on localhost with full the permissions? Are all of those permissions necessary? Wouldn't it make more sense to send commands directly to the unix domain socket of Asterisk? Basically you connect there and send separate commands in separate writes.> # IF that's what you have in your conf file, this is what you should have > here: > > my $mgruser = "admin"; > my $mgrpass = "amp111"; > my $mgrport = 5038; > # set our array of phones that we will NOT be paging > @bypass = @ARGV; > # Get our needed info for idle sip phones > @sips = grep(/^\s+\d+\s.*/, `asterisk -rx "show hints"`);ah, but you do use it, indirectly. Why not get that information from the manager interface?> > # Now check each sip phone to see if it's in use and also > # against our exclude list. If it passes both, it's > # added to our array of calls to make > > foreach $sipline (@sips) { > my ($junk0, $exten, $junk1, $chan, $state, $junk2) = split(/ +/, > $sipline,6); > > unless (($state ne "State:Idle") || (grep(/$exten/i, @bypass))) { > push (@mypage, "$exten"); > > } > } > $page= join ("&SIP/", @mypage); > print "$page";{ > > # Open connection to AGI and set Global Variable PAGE_GROUP > # to our completed array of sip phones > my $tn = new Net::Telnet ( Port => $mgrport, > Prompt => '/.*[\$%#>] $/', > Output_record_separator => '', > Input_Log=> "/tmp/input.log", > Output_Log=> "/tmp/output.log", > Errmode => 'return', ); > > $tn->open("127.0.0.1"); > $tn->waitfor('/0\n$/'); > $tn->print("Action: Login\n"); > $tn->print("Username: $mgruser\n"); > $tn->print("Secret: $mgrpass\n"); > $tn->print("Events: off\n\n"); > my ($pm, $m) = $tn->waitfor('/Authentication (.+)\n\n/'); > if ($m =~ /Authentication failed/) { > print "VERBOSE \"Incorrect MGRUSER or MGRPASS - unable to connect to > manager interface\" 0\n"; > exit; > } > $tn->print("Action: Setvar\n"); > $tn->print("Variable: PAGE_GROUP\n"); > $tn->print("Value: $page\n\n"); > $tn->print("Action: Logoff\n\n"); > $tn->close; > } > > Then add the following to your dialplan: > > exten => *61,1,Set(TIMEOUT(absolute) = 15) > exten => *61,n,AGI(page.agi|<arg>|<arg>) > exten => *61,n,SetCallerID("Page:${CALLERIDNAME}" <${CALLERIDNUM}>) > exten => *61,n,Set(_ALERT_INFO="Ring Answer") > exten => *61,n,SIPAddHeader(Call-Info: answer-after=0) > exten => *61,n,Page(SIP/${PAGE_GROUP}) > exten => *61,n,Hangup()I really don't see why you need to connect to the manager just to set a global variable. You can easily do that from the dialplan or from the AGI itself. Or am I missing anything? -- Tzafrir Cohen | tzafrir@jbr.cohens.org.il | VIM is http://tzafrir.org.il | | a Mutt's tzafrir@cohens.org.il | | best ICQ# 16849755 | | friend
Hello, I'm trying to catch channel hangup in DeadAgi script. For example, A calls to DeadAgi script which connects (Dial) to B. After Dial command exits I need to identify where hangup came from: A or B. CHANNEL STATUS returns 6 (Line is Up) regardless of who hungup. In CLI "show channels" states that channel A to DeadAgi is UP even if A and B hungup. If A stays on the line after conversation with B (hangup from B), then DeadAgi would continue (with prompts and etc.), if A is off then DeadAgi should exit gracefully (not killed as Agi). Does anyone know how to do it? Thanks in advance. -- Grigoriy Puzankin
> -----Original Message----- > From: asterisk-users-bounces@lists.digium.com [mailto:asterisk-users- > bounces@lists.digium.com] On Behalf Of Tzafrir Cohen > Sent: 27 January 2006 08:21 > To: asterisk-users@lists.digium.com > Subject: Re: [Asterisk-Users] paging agi > > Hi > > Some petty notes notes regarding the perl: ><SNIPPED>> > I really don't see why you need to connect to the manager just to seta> global variable. You can easily do that from the dialplan or from the > AGI itself. Or am I missing anything? >Hi all, I'm not sure if this helps but I had a bit of a bash at fixing some issues with the new Page() function. The problem was the phone that initiates the Page was getting called itself and I think because the Snom360 had a bit of a race condition it wasn't returning "486 Busy Here" as it should of and thus causing a feedback loop that killed the phone and required a reboot to fix. My solution was the following (advice is more than welcome as this is the first EVER bash script I have written and maybe GROUP function would have been an option): Dialplan: [macro-page] exten => s,1,SIPAddHeader(Call-Info: <sip:192.168.10.16>\;answer-after=0) ;;;Strip out calling channel exten => s,n,Cut(caller=CHANNEL,-,1) ;exten => s,n,Cut(caller=caller,/,2) exten => s,n,AGI(strremove|${ARG1}|${caller}) exten => s,n,NoOp(dialstring: ${dialstring}) ;exten => s,n,Cut(dialstr=ARG1,caller,1) ;exten => s,n,NoOp(dialstr: ${dialstr}) exten => s,n,Page(${dialstring}) /var/lib/asterisk/agi-bin/strremove: #!/bin/sh dialarg=` echo $1 | sed -e 's/"//g'` channelarg=` echo $2 | sed -e 's/"//g'` echo arg: $1 echo arg: $unqarg OUT="test1 $string test2" OUT ="${dialarg//$channelarg/}" echo SET VARIABLE dialstring $OUT (I have tidied up the script a little to remove old debug but it should still work fine.) Notes: - The AGI script finds and removes a string from the target string. - The macro takes ARG1 as input which is the list of devices you wish to use as intercom phones: exten => 200,1,Macro(page,SIP/snom1&SIP/snom2&SIP/snom3) ;Pager / Intercom I still have issues with intercom breaking the odd snom that is currently on the phone so I dare say that Jeremy's script will fix that. However it would seem to me that the page function should be doing this itself. I hope this is of use to someone. Alex Information contained in this e-mail and any attachments are intended for the use of the addressee only, and may contain confidential information of Ubiquity Software Corporation. All unauthorized use, disclosure or distribution is strictly prohibited. If you are not the addressee, please notify the sender immediately and destroy all copies of this email. Unless otherwise expressly agreed in writing signed by an officer of Ubiquity Software Corporation, nothing in this communication shall be deemed to be legally binding. Thank you.