root/trunk/AMP2-UseAmportal/amp_conf/var/lib/asterisk/agi-bin/dialparties.agi

Revision 159, 7.2 kB (checked in by rcourtna, 8 years ago)

[ 1160168 ] [Patch] Ring Groups broken in Asterisk HEAD

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1 #!/usr/bin/perl -w
2 #
3 # Copyright (C) 2003 Zac Sprackett <zsprackett-asterisk@sprackett.com>
4 #
5 # This program is free software; you can redistribute it and/or
6 # modify it under the terms of the GNU General Public License
7 # as published by the Free Software Foundation; either version 2
8 # of the License, or (at your option) any later version.
9 #
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14 #
15 # Amended by Coalescent Systems Inc. Sept, 2004
16 # to include support for DND, Call Waiting, and CF to external trunk
17 # info@coalescentsystems.ca
18
19 use Asterisk::AGI;
20 use Net::Telnet ();
21
22 my $debug = 2;
23
24 my %ext;     # Hash that will contain our list of extensions to call
25 my $cidnum;  # Caller ID Number for this call
26 my $cidname; # Caller ID Name for this call
27 my $timer;   # Call timer for Dial command
28 my $dialopts;# options for dialing
29 my $rc;      # Catch return code
30 my $priority;# Next priority
31
32 my $AGI = new Asterisk::AGI;
33 my %input = $AGI->ReadParse();
34 $AGI->setcallback(\&mycallback);
35
36 if ($debug >= 2) {
37   foreach $key (keys %input) {
38     debug("$key = " . $input{$key},3);
39   }
40 }
41 $priority = $input{'priority'} + 1;
42
43 if ($input{'callerid'} =~  /^\"(.*)\"\s+\<(\d+)\>\s*$/) {
44   $cidname = $1;
45   $cidnum  = $2;
46   debug("Caller ID name is '$cidname' number is '$cidnum'", 1);
47 } else {
48   $cidname = undef;
49   $cidnum  = undef;
50   debug("Caller ID is not set", 1);
51 }
52
53 $timer = $AGI->get_variable('ARG1') || 0;
54 $dialopts = $AGI->get_variable('ARG2') || '';
55
56 # Start with Arg Count set to 3 as two args are used
57 my $arg_cnt = 3;
58 while(my $arg = $AGI->get_variable('ARG' . $arg_cnt)) {
59   if ($arg == 'noresponse') {  #not sure why, dialparties will get stuck in a loop if noresponse
60     debug("get_variable got a \"noresponse\"!  Exiting");
61     exit($arg_cnt);
62   }
63   @extarray=split(/-/,$arg);
64   foreach my $k (@extarray) {
65     $ext{$k} = $k;
66     debug("Added extension $k to extension map", 3);
67   }
68  
69   $arg_cnt++;
70 }
71
72 # Check for call forwarding first
73 # If call forward is enabled, we use chan_local
74 foreach my $k (keys %ext) {
75   my $cf  = $AGI->database_get('CF',$k);
76   if ($cf) {
77     $ext{$k} = $cf.'#';  # append a hash sign so we can send out on chan_local below.
78     debug("Extension $k has call forward set to $cf", 1);
79   } else {
80     debug("Extension $k cf is disabled", 3);
81   }
82 }
83
84 # Now check for DND
85 foreach my $k (keys %ext) {
86   if (!$ext{$k} =~ /\#/) {   #no point in doing if cf is enabled
87     my $dnd = $AGI->database_get('DND',$ext{$k});
88     if ($dnd) {
89       debug("Extension $ext{$k} has do not disturb enabled", 1);
90       delete $ext{$k};
91     } else {
92       debug("Extension $ext{$k} do not disturb is disabled", 3);
93     }
94   }
95 }
96
97 # Now check for call waiting
98 # first let's see which channels are on a call
99
100 $schannels=&get_active_sip; #get the active sip channels
101 @lines=split(/\n/,$schannels); #add each line of output into @lines array
102 shift(@lines); #shift first line off array, as it is useless
103
104 foreach $line(@lines){
105   $line=~/.* ([0-9]+) .*/;  #expecting sip user to be surrounded by (1) spaces
106   push(@sipusers,$1);  #push the sip user into @sipusers array
107 }
108
109 # Now let's cycle through all the extensions in sent to this agi
110 foreach my $k (keys %ext) {
111   if (!$ext{$k} =~ /\#/) {   #no point in doing if cf is enabled
112    
113     my $cw = $AGI->database_get('CW',$ext{$k});  #check the database for CW-enable
114     if ($cw) {
115       debug("Extension $ext{$k} has call waiting enabled", 1); #leave it in the dial string no matter what
116     } else {
117       debug("Extension $ext{$k} has call waiting disabled", 1);
118  
119     $inuse=grep(/^$ext{$k}$/,@sipusers); #check to see if this channel is on a call
120      
121       if ($inuse > 0) {
122         my $fwb = $AGI->database_get('CFB',$k);  # check for call-forward on busy.  Does not check to see if fwd-to exten is busy
123         if ($fwb) {
124             $ext{$k} = $fwb;
125             }
126         else {
127           debug("Max calls of 1 exceeded - deleting from dial", 1);
128           delete $ext{$k};  #this exten can't take another call, so delete it from dial string
129         }
130         if (%ext) {  # check if there any extensions left in the dial string
131           debug("Dial still has extensions - continuing",1);
132         } else { #there are no extensions left in the dial string, jump out of agi
133           debug("Dial string is empty - nothing to do",1);
134           $fromcontext = $AGI->get_variable('FROMCONTEXT');
135           if ($fromcontext eq 'exten-vm') {
136             debug("Was direct call, jumping to priority " . ($priority + 21),1);
137             $AGI->set_priority($priority + 21);
138           }
139         }
140       }
141     }
142    
143   }
144 }
145
146
147
148 # Update Caller ID for calltrace application
149 foreach my $k (keys %ext) {
150   if (!$ext{$k} =~ /\#/) {   #no point in doing if cf is enabled
151     if ($cidnum) {
152     $rc = $AGI->database_put('CALLTRACE', $ext{$k}, $cidnum);
153     if ($rc == 1) {
154       debug("DbSet CALLTRACE/$ext{$k} to $cidnum", 3);
155     } else {
156       debug("Failed to DbSet CALLTRACE/$ext{$k} to $cidnum ($rc)", 1);
157     }
158     } else {
159     # We don't care about retval, this key may not exist
160     $AGI->database_del('CALLTRACE', $ext{$k});
161     debug("DbDel CALLTRACE/$ext{$k} - Caller ID is not defined", 3);
162     }
163     }
164 }
165
166 my $ds = '';
167 foreach my $k (keys %ext) {
168   if ($ext{$k} =~ s/\#//) {                       # "#" used to identify external numbers in forwards and callgourps
169     $ds .= 'Local/'.$ext{$k}.'@from-internal&';
170   #} elsif (substr($ext{$k},0,1) == '3') {           # if ext starts with 3 it's a Zap interface
171   #  $ds .= 'Zap/' . substr($ext{$k},-1) . '&';      # and Zap channel is the last digit of ext
172   } else {
173     $tech = $AGI->get_variable('E'.$ext{$k}) || 'SIP'; # grab the global var that defines extension technology.  Assume SIP if empty.
174     if ($tech eq "ZAP") {
175       $zapchannel = $AGI->get_variable('ZAPCHAN_'.$ext{$k});
176       $ds .= $tech.'/' . $zapchannel . '&';
177     } else {
178       $ds .= $tech.'/' . $ext{$k} . '&';
179     }
180   }
181 }
182 chop $ds if length($ds);
183
184 if (!length($ds)) {
185   $AGI->exec('NoOp');
186 } else {
187   $ds .= '|';
188   $ds .= $timer if ($timer);
189   $ds .= '|' . $dialopts; # pound to transfer, provide ringing
190
191   debug("Dial string is $ds", 1);
192   $AGI->set_variable('ds',$ds);
193   $AGI->set_priority(10); #dial command is at priority 10
194 }
195
196 exit 0;
197
198 sub debug
199 {
200   my $string = shift;
201   my $level = shift || 3;
202
203   if ($debug) {
204     $AGI->verbose($string, $level);
205   }
206   return(0);
207 }
208
209 sub mycallback
210 {
211   my $rc = shift;
212   debug("User hung up. (rc=" . $rc . ")", 1);
213   exit ($rc)
214 }
215
216 sub get_active_sip{  #uses manager api to get output of sip show channels
217   #asterisk server manager interface information
218   $mgrUSERNAME='AMPMGRUSER';
219   $mgrSECRET='AMPMGRPASS';
220   $server_ip='127.0.0.1';
221  
222   $tn = new Net::Telnet (Port => 5038,
223         Prompt => '/.*[\$%#>] $/',
224         Output_record_separator => '',
225         Errmode    => 'return'
226         );
227  
228   #connect to manager and login     
229   $tn->open("$server_ip");
230   $tn->waitfor('/0\n$/');                   
231   $tn->print("Action: Login\nUsername: $mgrUSERNAME\nSecret: $mgrSECRET\n\n");
232   $tn->waitfor('/Authentication accepted\n\n/');
233
234   #issue command
235   $tn->print("Action: command\nCommand: sip show channels\n\n\n");
236   $tn->waitfor('/Response: Follows\n/');
237   ($schannels)=$tn->waitfor('/.*active SIP channel/') or die "Unable to get channels", $tn->lastline;    # wait for asterisk to process
238   $tn->print("Action: Logoff\n\n");
239   return $schannels;
240 }
Note: See TracBrowser for help on using the browser.