The Palner Group, Inc.

Kamailio, Asterisk, VoIP, and IT Consulting

Use ENUM to Save Real MONey

Ok — it almost rhymed.

ENUM (read the wiki) refers to the mapping of telephone numbers to internet addresses. Think of it almost as reverse DNS for your phone number. Although there are many methods of integrating ENUM into your system, our current “favorite” is ENUMPlus.org.

From their website:

ENUM sources are very segregated and there was no global repository – until now. ENUMPlus queries all of the top ENUM lookup sources and returns the most accurate result with minimal overhead; meaning you only need to specify one source. ENUMPlus allows you to offload all of the query processing to our powerful servers so you don’t have to waste time and precious resources.

Integrating ENUMplus into Asterisk can be very quick and there’s a few choices/methods of going about it. You can choose to use their php scripts, go direct from the dialplan, or run your own lookup script. Here, we’ve chosen to write our own lookup script that basically does the following:

  1. Checks ENUMplus.org for a result (with a 2 second timeout)
  2. Sets a variable of ENUMRESULT and returns to dialplan
  3. The dialplan then evaluates that variable, and if a sip value is provided calls the number directly via SIP.

Here’s an example dialplan:

exten => _X.,1,Set(CALLTO=${EXTEN})
exten => _X.,n,Goto(out,1)
exten => out,1,AGI(enumcheck.pl,${CALLTO})
exten => out,n,GotoIf($["${ENUMRESULT}" = "FAIL"]?pstn)
exten => out,n,GotoIf($[${ISNULL(${ENUMRESULT})}]?pstn)
exten => out,n,Dial(${ENUMRESULT},55)
exten => out,n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?pstn)
exten => out,n,GotoIf($["${DIALSTATUS}" = "CONGESTION" ]?pstn)
exten => out,n,GotoIf($["${DIALSTATUS}" = "BUSY" ]?busy)
exten => out,n,Hangup()
exten => out,n(pstn),Dial(SIP/${CALLTO}@yourprovider); or DAHDI, etc.
exten => out,n,GotoIf($["${DIALSTATUS}" = "CHANUNAVAIL" ]?busy)
exten => out,n,GotoIf($["${DIALSTATUS}" = "CONGESTION" ]?busy)
exten => out,n,GotoIf($["${DIALSTATUS}" = "BUSY" ]?busy)
exten => out,n,Hangup()
exten => out,n(busy),Busy(5)
exten => out,n,Hangup()

And here’s the script:

#!/usr/bin/perl -w
use strict;
$|=1;
my ($phone, $url, $apikey, $result, @sip);

while(<STDIN>) {
	chomp;
	last unless length($_);
}

if ($ARGV[0]) {
	$phone = &URLEncode($ARGV[0]);
} else {
	&setvar("ENUMRESULT", "FAIL");
	&printverbose("enumlookup: No CALLTO received.",2);
	exit(0);
}

#Get via WEB
$apikey = "REPLACE WITH YOUR KEY";
$url = "http://enumplus.org/api";

$result = qx(curl -m 2 -s -d 'key=$apikey' $url/$phone);

if ($result) {
	if ($result =~ /SIP/i) {
		@sip = split(/\|/, $result);
		&setvar("ENUMRESULT", $sip[0]);
		&printverbose("enumlookup: $sip[0]",2);
	} else {
		&setvar("ENUMRESULT", "FAIL");
		&printverbose("enumlookup: No sip address found.",2);
	}
} else {
	&setvar("ENUMRESULT", "FAIL");
	&printverbose("enumlookup: Timeout or error",2);
}

sub URLEncode {
   my $theURL = $_[0];
   $theURL =~ s/([\W])/"%" . uc(sprintf("%2.2x",ord($1)))/eg;
   return $theURL;
}

sub setvar {
	my ($var, $val) = @_;
	print STDOUT "SET VARIABLE $var \"$val\" \n";
	while(<STDIN>) {
		m/200 result=1/ && last;
	}
	return;
}

sub printverbose {
	my ($var, $val) = @_;
	print STDOUT "VERBOSE \"$var\" $val\n";
	while(<STDIN>) {
		m/200 result=1/ && last;
	}
	return;
}

Happy Coding!

1 Comment

  1. Thanks for the fantastic script! I really should have RTFM (for cURL) and set the -m flag in the FreePBX module… looks like it’s time to get working on version 0.2.3.

Comments are closed.