Time-Zone Processing with Asterisk, Part II
Last month, I wrote about a system for handling telephone calls with Asterisk that automatically handled the call depending on the time of day at a remote location. Use of the system, however, depended on the user performing the critical task of setting up the remote location's time with a telephone call. Rather than rely on the user to initiate the telephone call manually, it would be easier if the call occurred automatically.
If the setup call occurs automatically, the user won't forget to do it. The initial SIP registration may occur at a very strange hour in the home location, but the SIP registration occurs because a user has plugged something in. Therefore, we know the user is awake and can take a short call. Asterisk provides a management interface that reports when SIP registrations occur and can be used to take action based on it. With a bit of additional processing, a script talking to the manager can initiate calls only when the SIP registration is “new”.
The Asterisk Manager reports events processed by Asterisk and accepts commands over the interface. The form of the interface is a text-based protocol that separates event reports and commands into clusters of lines with a key: value format. For example, the registration of extension 300 using the SIP protocol looks like this:
Event: PeerStatus PeerStatus: Registered Peer: SIP/300
Before gaining access to the Asterisk manager, clients must authenticate against the list of administrative users stored in /etc/asterisk/manager.conf. Once logged in, a client can issue commands or query the value of variables with a set of lines that starts with a first line of Action:, followed by a command. Responses to commands typically start with Response: Success.
Because the protocol is text-based, it can be scripted in a language like Expect. A component is also available for the Perl Object Environment (POE), a framework that builds event-driven programs in Perl. The freely available component provides the base-level response parsing that would need to be written in Expect, so it is a much more extensible foundation for programs controlling the Asterisk manager.
The main code for the program is simple. POE sets up a system where state handlers are called in response to program states. A state can be defined by the programmer or by an external event. The typical flow through the program is to notice a SIP registration, check to see whether it has an active time-zone registration and if not, to initiate a configuration call.
To execute code in response to an event, the POE framework uses a hash called CallBacks. Every entry in CallBacks defines a state based on the event received from the manager. When an event matches a callback, the handler defined for the state is triggered. To set up a trigger with the CallBacks clause, identify every line in the event and set up a hash so that the left-hand side of each line of the event is the key value for a line of the hash. As an example, consider the callback definition for the SIP registration event earlier:
Event: PeerStatus register => { 'Event' => 'PeerStatus',
PeerStatus: Registered 'PeerStatus' => 'Registered', }
Peer: SIP/300
To link the callback to a handler, the inline_states hash has a list of states and references to the corresponding code to call. Although it is possible to inline event-handler code, for readability I have separated the code out into external procedures. Code called in response to a CallBack cannot be passed arguments:
123456789*123456789*123456789*123456789*123456789*12
inline_states => {
register => \®ister_state_handler,
},
Based on the flow of the program, three events are of interest. First, SIP registration events are used to start the entire process. SIP registrations typically occur hourly, so it is important to initiate the call only when a registration is the “first” registration. To prevent duplicate telephone calls from being initiated, the program will request data from both the Asterisk internal database AstDB as well as the SIP peer information. The second and third events will handle responses to commands and database queries, respectively. A fourth event will handle initiating the telephone call after receiving data back from the queries. The code I am currently using also has a state defined for unregister events, though it is a stub for an event that I am not currently using.
The core of the program is only 35 lines, most of which defines the program event states and shows what code will be used in response to those states. Note that the state of call is defined by the program and not by a callback, so the call state can be entered only by the program itself and not in response to an event from the manager. (A full listing of the program is available on the Linux Journal FTP site; see Resources.)
POE::Component::Client::Asterisk::Manager->new(
Alias => 'monitor',
RemoteHost => 'localhost',
RemotePort => 5038,
Username => 'autotzcaller',
Password => 'secretpassword',
CallBacks => {
input => ':all',
response => {
'Response' => 'Success',
},
dbresponse => {
'Event' => 'DBGetResponse',
},
register => {
'Event' => 'PeerStatus',
'PeerStatus' => 'Registered',
},
unregister => {
'Event' => 'PeerStatus',
'PeerStatus' => 'Unregistered',
},
},
inline_states => {
input => \&input_state_handler,
response => \&response_state_handler,
dbresponse => \&db_response_state_handler,
register => \®ister_state_handler,
call => \&call_state_handler,
unregister => \&unregister_state_handler,
},
);
POE::Kernel->run();
exit(0);
Two of the state handlers are only stubs. The input state handler prints out whatever it gets if a debug flag is set, and it is there for development purposes. It catches any unrecognized events that come from the manager, and it can be useful when testing that callbacks are catching the important events. The unregister state handler currently doesn't do anything, but it is there as a hook to expand if I choose in the future to take any action based on that.
With the core of the program in place, let's look at each of the states in the order they will be called through a typical program execution flow.
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
If you already use virtualized infrastructure, you are well on your way to leveraging the power of the cloud. Virtualization offers the promise of limitless resources, but how do you manage that scalability when your DevOps team doesn’t scale? In today’s hypercompetitive markets, fast results can make a difference between leading the pack vs. obsolescence. Organizations need more benefits from cloud computing than just raw resources. They need agility, flexibility, convenience, ROI, and control.
Stackato private Platform-as-a-Service technology from ActiveState extends your private cloud infrastructure by creating a private PaaS to provide on-demand availability, flexibility, control, and ultimately, faster time-to-market for your enterprise.
Sponsored by ActiveState
| Non-Linux FOSS: libnotify, OS X Style | Jun 18, 2013 |
| Containers—Not Virtual Machines—Are the Future Cloud | Jun 17, 2013 |
| Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer | Jun 12, 2013 |
| Weechat, Irssi's Little Brother | Jun 11, 2013 |
| One Tail Just Isn't Enough | Jun 07, 2013 |
| Introduction to MapReduce with Hadoop on Linux | Jun 05, 2013 |
- Containers—Not Virtual Machines—Are the Future Cloud
- Non-Linux FOSS: libnotify, OS X Style
- Linux Systems Administrator
- Validate an E-Mail Address with PHP, the Right Way
- Lock-Free Multi-Producer Multi-Consumer Queue on Ring Buffer
- Senior Perl Developer
- Technical Support Rep
- UX Designer
- Introduction to MapReduce with Hadoop on Linux
- RSS Feeds
Featured Jobs
| Linux Systems Administrator | Houston and Austin, Texas | Host Gator |
| Senior Perl Developer | Austin, Texas | Host Gator |
| Technical Support Rep | Houston and Austin, Texas | Host Gator |
| UX Designer | Austin, Texas | Host Gator |
| Web & UI Developer (JavaScript & j Query) | Austin, Texas | Host Gator |
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?




1 hour 34 min ago
3 hours 5 sec ago
7 hours 10 min ago
7 hours 55 min ago
8 hours 6 min ago
8 hours 11 min ago
10 hours 21 min ago
10 hours 22 min ago
11 hours 7 min ago
11 hours 55 min ago