Time-Zone Processing with Asterisk, Part I
Last year, I took a trip to Asia. To stay in touch, I carried a GSM world phone, capable of receiving telephone calls in the countries I was visiting. The capability to receive calls with the same mobile phone number I use at home while halfway across the world seemed incredibly cool—at least until the first call came in! Mobile phones hide the location of the phone, which cuts both ways. A colleague had decided to call me in the middle of the day on a Friday, which had awakened me very early on Saturday morning, because the phone “hid” my faraway location from him.
After returning home, I asked several people why my phone company could not simply play a message to warn callers when my time zone changes by more than four or five hours, letting them know the call might be inconvenient. Nobody could come up with a technical reason, but we all suspected it was because the mobile phone company to which I subscribed charged several dollars per minute to connect calls. As part of the process of attaching a GSM phone to a network, the home network needs to learn where the phone is visiting, and that information conceivably could include a time zone.
I returned to my idea once I started using Asterisk, because it provides an extensive toolkit for designing PBX-hosted services. Anything that can be coded in a computer can become an Asterisk service. After I understood the basics of Asterisk, I sat down to implement a feature that kept track of the time of day where I visited and prevented calls from coming in at inconvenient times.
The system I built on top of Asterisk to handle this feature has two major parts. The key to the system is maintaining a time-zone offset from the time in London. (My code implements offsets only of whole hours, though it could be extended to use either half or quarter hours.) When a device first connects to Asterisk, its IP address is used to guess the location and, therefore, the time offset. After the offset is programmed into the system, incoming calls are then checked against the time at the remote location. Before the phone is allowed to ring, the time at the remote location is checked, and callers can be warned if they are trying to complete a call at an inconvenient time.
Asterisk does not have a built-in method to estimate the time zone from an IP address, but it does have the next best thing—the Asterisk Gateway Interface (AGI). AGI programming allows an Asterisk extension to pass data to an external program, do computations in that program and return results as Asterisk channel variables.
I began the project by writing an AGI script that would take an IP address as input and return an estimated time zone. Several existing geolocation databases map IP addresses into geographic information. None of the free products or compilations I tried for this project could return a time zone directly from the database, so I estimated the time zone based on the longitude. (The earth's surface has 24 time zones, each of which is approximately 15 degrees of longitude.) After trying several databases, I settled on MaxMind's GeoLite City, a free-for-non-commercial-use version of the comprehensive GeoCity commercial database.
GeoCity has APIs available in several programming languages. I used Perl, because there is also an AGI library module for Perl that makes handling AGI scripts easier. As input, the program takes an IP address, and then it needs to return the time zone. I used the convention of returning the time zone as an offset of the number of hours from the time in London, which leads to some differences in daylight time handling.
The start of the program pulls in utility functions, including the Asterisk::AGI module, which decodes all the parameters passed to the program by Asterisk:
#!/usr/bin/perl -w # Asterisk AGI to estimate time zone from IP address use strict; use Asterisk::AGI; use Geo::IP::PurePerl; use POSIX qw(ceil floor); # California is GMT -8 my $HOME_OFFSET = -8; my $AGI = new Asterisk::AGI; my %input = $AGI->ReadParse();
(The full listing of programs from this article is available on the Linux Journal FTP site; see Resources.) The argument to the program is an IP address, which is given to us by Asterisk. The first check is to determine whether the IP address is on the local subnet of the Asterisk server, 192.168.1.0/24. Most location databases don't include RFC 1918 address space and won't return a lookup. The MaxMind API can accept a domain name as an argument, but we don't expect to pass it one:
my $addr = $ARGV[0];
my @octets = split(/\./,$addr);
if (($octets[0] eq "192") && ($octets[1] eq "168") &&
($octets[2] eq "1")) {
# Local IP addresses get the home offset
$AGI->set_variable("TZ_OFFSET",$HOME_OFFSET);
exit 0;
}The use of the database is straightforward. We create a new object, telling the API the location of the database on disk, and then call the get_city_record_as_hash function in MaxMind's API, which returns everything about the IP address as a hash. The item of interest is the longitude component of the hash. If there isn't one, we'll simply return -8 for California and let Asterisk deal with the problem:
my $gi = Geo::IP::PurePerl-> new(
"/usr/local/share/GeoIP/GeoLiteCity.dat",
GEOIP_STANDARD);
my $cityref = $gi->get_city_record_as_hash($addr);
if (!(defined ($cityref->{"longitude"}))) {
# Guess at the home time when longitude undefined
$AGI->set_variable("TZ_OFFSET",-8);
exit 1;
}
my $longitude=$cityref->{"longitude"};
A bit of math is required to deal with the fact that time-zone boundaries may be 15 degrees, but zero degrees is in the middle of a time zone. We can use two formulas, depending on whether the longitude is positive or negative. After computing the time zone, we pass it back to Asterisk in the TZ_OFFSET channel variable, where it is available for use in the dial plan:
my $numerator;
my $denominator=15;
if ($longitude>0) {
$numerator=$longitude+7.5;
$quotient=floor($numerator/$denominator);
} else {
$numerator=$longitude-7.5;
$quotient=ceil($numerator/$denominator);
}
$AGI->set_variable("TZ_OFFSET",$quotient);
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Sponsored by AMD
Built-in forensics, incident response, and security with Red Hat Enterprise Linux 6
Every security policy provides guidance and requirements for ensuring adequate protection of information and data, as well as high-level technical and administrative security requirements for a system in a given environment. Traditionally, providing security for a system focuses on the confidentiality of the information on it. However, protecting the data integrity and system and data availability is just as important. For example, when processing United States intelligence information, there are three attributes that require protection: confidentiality, integrity, and availability.
Learn more about catching the bad guy in this free white paper.
Sponsored by DLT Solutions
| Dynamic DNS—an Object Lesson in Problem Solving | May 21, 2013 |
| Using Salt Stack and Vagrant for Drupal Development | May 20, 2013 |
| Making Linux and Android Get Along (It's Not as Hard as It Sounds) | May 16, 2013 |
| Drupal Is a Framework: Why Everyone Needs to Understand This | May 15, 2013 |
| Home, My Backup Data Center | May 13, 2013 |
| Non-Linux FOSS: Seashore | May 10, 2013 |
- RSS Feeds
- Making Linux and Android Get Along (It's Not as Hard as It Sounds)
- Using Salt Stack and Vagrant for Drupal Development
- Dynamic DNS—an Object Lesson in Problem Solving
- New Products
- Validate an E-Mail Address with PHP, the Right Way
- Drupal Is a Framework: Why Everyone Needs to Understand This
- A Topic for Discussion - Open Source Feature-Richness?
- Download the Free Red Hat White Paper "Using an Open Source Framework to Catch the Bad Guy"
- Tech Tip: Really Simple HTTP Server with Python
- Roll your own dynamic dns
3 hours 57 min ago - Please correct the URL for Salt Stack's web site
7 hours 8 min ago - Android is Linux -- why no better inter-operation
9 hours 24 min ago - Connecting Android device to desktop Linux via USB
9 hours 52 min ago - Find new cell phone and tablet pc
10 hours 50 min ago - Epistle
12 hours 19 min ago - Automatically updating Guest Additions
13 hours 28 min ago - I like your topic on android
14 hours 14 min ago - This is the easiest tutorial
20 hours 50 min ago - Ahh, the Koolaid.
1 day 2 hours ago
Enter to Win an Adafruit Pi Cobbler Breakout Kit for Raspberry Pi

It's Raspberry Pi month at Linux Journal. Each week in May, Adafruit will be giving away a Pi-related prize to a lucky, randomly drawn LJ reader. Winners will be announced weekly.
Fill out the fields below to enter to win this week's prize-- a Pi Cobbler Breakout Kit for Raspberry Pi.
Congratulations to our winners so far:
- 5-8-13, Pi Starter Pack: Jack Davis
- 5-15-13, Pi Model B 512MB RAM: Patrick Dunn
- 5-21-13, Prototyping Pi Plate Kit: Philip Kirby
- Next winner announced on 5-27-13!
Free Webinar: Hadoop
How to Build an Optimal Hadoop Cluster to Store and Maintain Unlimited Amounts of Data Using Microservers
Realizing the promise of Apache® Hadoop® requires the effective deployment of compute, memory, storage and networking to achieve optimal results. With its flexibility and multitude of options, it is easy to over or under provision the server infrastructure, resulting in poor performance and high TCO. Join us for an in depth, technical discussion with industry experts from leading Hadoop and server companies who will provide insights into the key considerations for designing and deploying an optimal Hadoop cluster.
Some of key questions to be discussed are:
- What is the “typical” Hadoop cluster and what should be installed on the different machine types?
- Why should you consider the typical workload patterns when making your hardware decisions?
- Are all microservers created equal for Hadoop deployments?
- How do I plan for expansion if I require more compute, memory, storage or networking?




Comments
for accurate local time...
I'd recommend interfacing to the World Time Engine API.
You can check the timezone info that you're likely to get on the main website @ http://worldtimeengine.com.
It works a treat for one of our IVR services we've got running.
excellent article
Calling people across time zones might prove to be inconveniencing to the receiving party, especially if it’s late at night or very early in the morning. This is an excellent article on how to make Asterisk redirect inbound callers to a message informing them that they are calling at inconvenient hours.
Very well written
I find this article to be very useful and I think more articles like this can help us go deeper into Asterisk.
i think so too
my thoughts ... a little bit more informations and i will be an "asterix-magican" :-) ok i´m far away from that but i´m willing to learn and linuxjournal is allways a good resource.
i agree
i agree with you schnäpel - linuxjournal is for me the ultimative ressource i only find here the stuff if searched for. excellent website i love it.
linüx
I hope linüx come number one
Asterisk
evden, i hope too :)
To Bruce Byfield: good article, thanks!
linux is good but ..
i hope not! there far to less software development to be number one.
Yes, Great article, I agree
Yes, Great article, I agree with this feature of asterisk seem cool, but I don't think it is very necessary.
A simpler suggestion
Very cool use of Asterisk, but I might suggest a much simpler way of dealing with the problem:
Turn your cell phone off when you don't want people to call you on it. I recently went to Spain and took my GSM cell phone with me, but when I wasn't using it, I turned it off. That way no random calls waking me up in the middle of the night! Sure, it's not as cool as setting up Asterisk to tell callers you're in a different timezone, but for most people it makes a lot more sense.
not while traveling
I want my family to be able to contact me *anytime* while I'm not at home or work. I'll tolerate the occasional wrong number, or mis-calculated time zone difference, rather than cut myself off from my loved ones.
or 2 numbers
Another answer to that is to have 2 numbers, an unlisted one for family and other close people, and a listed one for everybody else. Have them both go through your Asterisk server, and through to your real phone. Disable accepting calls from the listed one when it's not convenient.
You are absolutely right !
I agree with you that two numbers it's very good solutions, btw are there any cell phones with cover two sim cards at time?
Greg
Time-Zone Processing
Whether or not you agree with the method used to solve the original problem this solution does a great job of exploring what can be achieved by exploiting the AGI. Hopefully other readers will create equally alternative uses engaging the AGI. After all the purpose here is surely to expand the general awareness of what Asterisk can be made to do. Let's not knock someone down just because we don't agree with their reasoning for a given implementation.