Archive for the ‘Perl’ Category

Truncated e-mail attachments of recordings with the Asterisk Gateway Interface

Saturday, February 24th, 2007

I recently wrote what I’m referring to as a “private podcast” service for Asterisk. My friends are widely distributed throughout the world. While there are some who are quite convenient to call, like those who are on the West Coast with me, others are much farther away. It’s really not that convenient to arrange times to talk to people in London or Singapore when you are in Califoria.

My “pseudopodcast” is an extension on Asterisk that prompts to record a sound file, plays it back, and then e-mails the sound file to a receipient specified by the extension. It’s implemented as an AGI script that takes arguments for the sender and receiver. The dialplan has a two-digit receiver extension that specifies the recipient. Caller ID provides the sender identification.

It’s a neat idea, and it has helped me stay in touch with several of my friends. The only problem was that I initially was sending out e-mail with the recording truncated. It would sound fine, but it would only be a few hundred kilobytes. It wasn’t a big problem because I had the original and I could mail in the traditional manner, but it was a bit annoying to have written all this automation that didn’t work.

The first thing I checked was that the file was being recorded OK. That allowed me to trace the problem to the delivery of the e-mail. After reading the documentation for Perl’s MIME::Lite module, which I used to create the message with its attachment, I discovered that MIME::Lite doesn’t do the encoding on attached files until it’s necessary. My first troubleshooting step was to write out the e-mail message that I meant to send to disk. By checking the message on disk, I could see that it looked fine. However, receivers still told me about truncated messages.

As a next step, I sent the e-mail message on to my ISP’s mail server. (I only run sSMTP on my Asterisk server because I don’t need to receive mail from the Internet.) Even that seemed to work, which validated the SMTP route between my Asterisk server and at least one Internet e-mail host. So, the problem wasn’t my ISP arbitrarily truncating the attachment.

What I realized when sending the the message “by hand” from the command prompt is that it takes a long time to send more than a megabyte through base64 encoding and SMTP. The problem was in how my AGI script was implemented. I had assumed that when I called MIME::Lite’s $message->send() operation, it would fork a copy of sSMTP and deliver the message. Almost, but not quite. When I hung up, the AGI script would be hung up, and that would kill its child processes. The reason all the attachments were about 500 kB is that was about the limit of my patience.

There’s a two-fold fix. One was to have the script call Asterisk’s Playtones() application to give me an audio indication that it was still working on sending. The second, and more important part, is to have the AGI script ignore HUP until it’s done sending the message. Problem solved!

Perl POE programs (for the Asterisk manager?) hang Linux

Thursday, February 8th, 2007

I have recently been experimenting with the Perl Object Environment. It’s a neat event-driven framework that builds on top of Perl. I started using it for the Perl Asterisk manager interface.

I started using the Asterisk manager as a way to get information out of Asterisk and to display on the LCD on my system. The POE component is much easier than coding up something in Expect, and it’s a wondeful standardized layer for catching events. I’ve been experimenting with a POE program that displays the number of waiting voicemails on the LCD panel. Here’s the core of the program, which essentially says that when the manager indicates a new waiting voicemail, call the voicemail_state_handler procedure, and when there is a voicemail status report, call the voicemail_status_state_handler procedure.

POE::Component::Client::Asterisk::Manager->new(
Alias => ‘vm-monitor’,
Username => ‘user’, # not real!
Password => ‘secret’, # also not real!
CallBacks => {
input => ‘:all’,
voicemail => {
‘Event’ => ‘MessageWaiting’,
},
voicemail_status => {
‘Response’ => ‘Success’,
‘Message’ => ‘Mailbox Message Count’,
},
},
inline_states => {
input => \&input_state_handler,
voicemail => \&voicemail_state_handler,
voicemail_status => \&voicemail_status_state_handler,
},
);

POE::Kernel->run();

I’ve also experimented with programs that report other Asterisk data, or even programs that tick off a clock for display on an LCD. What they all have in common is that eventually, the system will lock up. Hard. Nothing responds, not even the attached monitor. I haven’t done any detailed diagnosis, but I can’t figure out what might cause the computer to just hang hard. The best I have for a working theory at this point is that the POE loop isn’t correctly freeing objects and is exhausting system memory to the point where a critical system task is interrupted, but that’s just a working theory.