Mahlon's initial version.
authorMahlon E. Smith <mahlon@martini.nu>
Tue, 13 Jan 2009 07:56:11 +0000 (20:56 +1300)
committerAndrew Ruthven <andrew@etc.gen.nz>
Tue, 13 Jan 2009 07:56:11 +0000 (20:56 +1300)
enum.agi [new file with mode: 0644]

diff --git a/enum.agi b/enum.agi
new file mode 100644 (file)
index 0000000..35e7dff
--- /dev/null
+++ b/enum.agi
@@ -0,0 +1,96 @@
+#!/usr/bin/env perl
+#
+# Make outgoing calls via enum NAPTR records.
+# 
+# Add to your extensions.conf like so:
+#       exten => _*164X.,n,AGI(enum.agi, +${EXTEN:4})
+#
+# Requires Net::DNS and Asterisk::AGI perl modules.
+#
+# Mahlon E. Smith <mahlon@martini.nu>
+#
+# ---------------------------------------------------------
+
+use strict;
+use warnings;
+
+use Net::DNS;
+use Asterisk::AGI;
+
+my (
+    @resolvers,
+    $A,
+    %AGI,
+    $num,
+    $resources
+);
+
+# in order of preference
+@resolvers = qw/ e164.org e164.arpa /;
+
+# setup AGI environment
+$A = Asterisk::AGI->new();
+%AGI = $A->ReadParse;
+
+unless ( $num = $ARGV[0] ) {
+    $A->verbose( "No number to parse!  Exiting.", 4 );
+    exit;
+}
+$ARGV[0] =~ s/\s+//g;
+$num =~ s/[^\d]//g;
+$num = join '.', split //, reverse $num;
+
+foreach ( @resolvers ) {
+    last if $resources;
+    $A->verbose("Finding resource at $_ for $ARGV[0]...", 4);
+    $resources = get_resources( $num, $_ );
+}
+unless ( $resources ) {
+    $A->verbose( "No valid resources found for $ARGV[0].", 4 );
+    exit;
+}
+
+foreach ( sort { $resources->{$a}->{'preference'} <=> $resources->{$b}->{'preference'} }
+            keys %$resources ) {
+    my $resource = $resources->{$_}->{'resource'};
+    if ( $A->exec( 'Dial', "$resource|60|r" ) ) {
+        last;
+        $A->hangup;
+    }
+}
+
+exit;
+
+sub get_resources
+{
+    my ( $num, $resolver ) = @_;
+    my $resource;
+
+    my $res = Net::DNS::Resolver->new;
+    my $query = $res->query( "$num.$_", 'NAPTR' );
+
+    unless ( $query ) {
+        $A->verbose("ENUM query failed at $_ for $ARGV[0]: " . $res->errorstring, 4);
+        return;
+    }
+
+    # build hash of potential resources to use
+    my %records;
+    my $count = 0;
+    foreach my $rr ( $query->answer ) {
+        next unless $rr->type eq 'NAPTR';
+        next unless $rr->service =~ /(sip|iax)/i;
+        $count++;
+
+        $resource = $ARGV[0];
+        my ( $pattern, $replacement ) = (split '!', $rr->regexp)[1,2];
+        print "$pattern, $replacement\n";
+        unless ( $resource =~ s/$pattern/$replacement/ ) {
+            $A->verbose("Unable to apply regexp to $ARGV[0]", 4);
+        }
+        $resource =~ s/^(\w+):/\U$1\//;
+        $records{$count} = { preference => $rr->preference, resource => $resource };
+    }
+
+    return \%records;
+}