[index] [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] [11] [12] [13] [14] [15]
Upgrading to Asterisk 1.4.0 (15-Jan-2007)
It's been quite some time since I updated this project log and the past half year or so have been largely uneventful. I've been plodding along with Asterisk, not really doing much to the configuration and mostly just using the phone. My work Asterisk server fell into disuse as the users migrated to using Skype and stopped relying on the Asterisk server. I eventually decommissioned the server entirely. I did set up another Asterisk server for a different project I'm involved with, though, so I still have two servers -- one for home and one for work. They're both Linux now, so I'm no longer running Asterisk on FreeBSD or OS X for production. I do keep Asterisk installed on my MacBook Pro just to futz with.
At Joshua Colp's urging I upgraded my home server to 1.4.0-beta3 and then to 1.4.0 when Digium cut an official release. I'm quite pleased with 1.4.0 over 1.2.x and upgraded my work server as well shortly after. So far I've had no issues with either machine since the upgrade. I took the opportunity in both cases to start fresh with a "make samples" and then apply my local configurations to the new base configuration sample files. In hindsight I think this may have been excesively cautious, but I feel better knowing that there's no deprecated cruft in my configs. 1.0 - 1.4.0 has seen some pretty dramatic changes in the configs and I wasn't entirely confident I'd catch it all trying to clean it up "by hand."
None of that nutty extensions.ael stuff for me, I'm still using extensions.conf.
The changes mandated by 1.4.0 are minimal (mostly an
issue of converting variables like ${CALLERIDNUM} to the new
${CALLERID(number)} function form). Mostly painless.
PostgreSQL support Hurrah!
WIth native PostgreSQL CDR support I also migrated my CDR logging to a PostgreSQL server. This is tremendously useful for integration with my website and work web-based admin controls. I hacked up a perl script to convert the old Master.csv into SQL suitable for the pgsql CDR stuff in Asterisk.
I wanted to link asterisk up with with the website to allow agents to annotate calls in progress and link CDR call records up with our customer records. This is a bit tricky because Asterisk doesn't create a CDR row until the call is concluded, which can be a bit of a challenge if you want to tie other data into the call record based on the call's unique ID. Thankfully I was able to hack up the behavior I wanted with a few clever database triggers. It's a nice hack that's not nearly as ugly in practice as it appears at first glance. Here's what I did:
New Call (Incoming or Outgoing)
When a new call takes place, the first thing I do is launch new-call.agi. This AGI takes the call's CDR(uniqueid) and inserts a row into a staging table "cdr_live" in my asterisk database. It basically just runs my add_call stored procedure and passes in the call's uniqueid and callerid information. Most of these calls are then sent into an Asterisk Queue().
Agent grabs call from the Queue
This was a lot more complicated than it ought to have been. I wanted to automatically
tag the call's record in cdr_live with the identity of the agent who picked up the call
from the queue. At first it looked like I'd be able to hang an AGI off the Queue using
the new(ish) Queue() application feature where you can launch an AGI when an agent takes
a call. Sadly, though, I discovered that this doesn't actually work in reality. The
AGI appears to be launched before Asterisk actually connects the queued call with the
agent. I wrote fancy code to parse /var/log/asterisk/queue_log/ but when
I tested it I was dismayed to discover that the line I was lookin for wasn't actually
written to the log until after I was looking for it.
Google to the rescue, I stumbled across this clever technique devised by William Lloyd of converting the queue_log file into a named pipe. I made a few minor tweaks to his code to support pgsql and it all came together beautifully. Now, a few seconds after the agent grabs the call asterisk pumps some log lines into queue_log which are parsed by queue_log_pgsql.pl and that turns into a database stored procedure call which properly tags the cdr_live record with the appropriate agent ID. Thanks, William!
Call in progress
While the call is in progress the agent is able to annotate the cdr_live record with notes, or attach a customer id number (where appropriate) and add other metadata to the call.
Call concluded
I added a "before insert" trigger to the main cdr table that grabs any agent-supplied information from the cdr_live table and incorporates it into the data which comes from Asterisk as it writes out the final CDR record. Then it deletes the transient record from cdr_live.
Quite pleased overall
It'd be a lot cooler if Asterisk wrote CDR records when a call began and then updated the relevant fields accordingly but until that's feasible this solution is quite workable (albeit a bit overcomplicated). It would be a lot messier if my database didn't support stored procedures and flexible triggers, too. I thought about putting all my code up here for review but there wasn't really a good way to sanitize the code so that it didn't divulge internal schema details that my employer would prefer to keep private. If you're thinking about doing something similar please feel free to contact me privately and I'll be happy to assist if I can.
© Copyright 1995-2010 David McNett. All Rights Reserved.
