Archive for November, 2010

Automated recording with Asterisk

Saturday, November 20th, 2010

So I decided to write a recipe for recording conference calls with Asterisk. Let’s say you have a dialin bridge number and a bridge passcode and you want your server to connect at certain times, announce that you are going to record (and periodically remind that you are doing so), and then do so. Optionally, you might ask the moderator to confirm this by pressing a key. You might spend many hours figuring this out, which is why I’m going to show you how.

First, you need some canned audio files. I use the following in my example (which I record using a studio microphone and then convert into sln files with the sox command: sox jcm-beep.wav -t raw -r 8000 -s -c 1 jcm-beep.sln):

  • jcm-beep – a tone indicating recording is ongoing
  • jcm-record_question – ask the moderator if they want to record
  • jcm-record_confirm – confirm that you will begin recording
  • jcm-record_cancel – announce that you have not made a recording
  • jcm-record_reminder – reminder that you are recording
  • jcm-record_limit – announce that recording time has been exceeded
  • jcm-record_timeout – announce that the limit for a response was exceeded

With those recordings in place (/usr/share/asterisk/sounds for example), add the following subroutine “context” to your /etc/asterisk/extensions.conf:


exten => h,1,Set(GOSUB_RESULT=ABORT)
exten => h,2,Return()

exten => s,1,Answer()
exten => s,2,Wait(2)
exten => s,3,Set(STARTSTAMP=${EPOCH})
exten => s,4,Set(TIMEOUTSECS=30)                                                ; 30 second timeout
exten => s,5,SendDTMF(00${CONFCALLPWD},200)
exten => s,6,Wait(15)
exten => s,7,Set(WAITSTART=${EPOCH})
exten => s,8,GotoIf($[${ASKTORECORD} == 1]?100)
exten => s,9,Goto(9,1)

exten => s,100,Set(WAITTIME=$[${EPOCH}-${WAITSTART}])
exten => s,101,BackGround(jcm-record_question)
exten => s,102,WaitExten(5)
exten => s,103,GotoIf($[${WAITTIME} <= ${TIMEOUTSECS}]?100)
exten => s,104,PlayBack(jcm-record_timeout)
exten => s,105,Set(GOSUB_RESULT=ABORT)
exten => s,106,Return()

exten => 6,1,Answer()
exten => 6,2,PlayBack(nothing-recorded)
exten => 6,3,PlayBack(goodbye)
exten => 6,4,Set(GOSUB_RESULT=ABORT)
exten => 6,5,Return()

exten => 9,1,Answer()
exten => 9,2,Set(MAXRECORDSECS=4000)                                            ; just over 1 hour
exten => 9,3,GotoIf($["${CONFCALLNAME}" != ""]?100)
exten => 9,4,Set(CONFCALLNAME=conf-call-${STRFTIME(,,%Y%m%d-%H%M%S)})
exten => 9,5,Goto(100)

exten => 9,100,Set(CALLREMINDBEEPINT=180) ; time in secs between beeps
; every 3 minutes
exten => 9,101,Set(CALLREMINDMSGMULT=5) ; number of beeps before message        ; every 15 minutes
exten => 9,102,Set(CALLREMINDBEEPCNT=0) ; current number of beeps
exten => 9,103,Set(CALLFILENAME=${CONFCALLNAME}-${STRFTIME(,,%Y%m%d-%H%M%S)})
exten => 9,104,Monitor(wav,${CALLFILENAME},m)
exten => 9,105,Set(RECORDSTART=${EPOCH})
exten => 9,106,PlayBack(jcm-beep)
exten => 9,107,PlayBack(jcm-record_reminder)
exten => 9,108,Goto(200)

exten => 9,200,Set(RECORDTIME=$[${EPOCH}-${RECORDSTART}])
exten => 9,201,Wait(${CALLREMINDBEEPINT})
exten => 9,202,PlayBack(jcm-beep)
exten => 9,204,GotoIf($[${CALLREMINDBEEPCNT} < ${CALLREMINDMSGMULT}]?210)
exten => 9,205,PlayBack(jcm-record_reminder)
exten => 9,206,Set(CALLREMINDBEEPCNT=0)
exten => 9,207,Goto(210)
exten => 9,210,GotoIf($[${RECORDTIME} <= ${MAXRECORDSECS}]?200)
exten => 9,211,PlayBack(jcm-record_limit)
exten => 9,212,Set(GOSUB_RESULT=ABORT)
exten => 9,213,Return()

Notice that there are still a few hard-coded variables in there, and that the bridge password is always prefixed with a “00″ since these first digits are generally lost in my case). There are two good ways to use this. The first is to add a test extension on your local server, which you can do using the Dial command with an option including U(conf-record). Since there’s a bug in the version of Asterisk I am running (now fixed upstream), I also append S(1) to force the call to hangup on successful connection. A more useful way to use this is with a call file. Create something like the following file (I prefix variables with double underscores to ensure they are always inherited with call properties):

Channel:	SIP_OR_IAX_TRUNK_HERE/19783038021
WaitTime:	60
Context:	conf-record
Extension:	s
Priority:	1
SetVar:		__CONFCALLNAME=fedora-talk-testcall
SetVar:		__CONFCALLPWD=2014

This is configured to connect to Fedora Talk conference room 2014 (general purpose room), announce itself, ask if it is ok to record, and then begin the recording (some conferenece systems don’t pass through DTMF, so you might need to explicitly disable ASKTORECORD in those cases – especially if you have permission anyway). If you copy this file into your /var/spool/asterisk/outgoing directory with correct ownership (for example, using vixie cron) then Asterisk will detect it and begin the recording. Those on the call will hear (for example): “beep…just a reminder that this call is being recorded”. Then every 3 minutes they will hear a (gentle!) sound, and every 15 they will hear an audible reminder that the call is being recorded like at the beginning. After recording, the call will be placed in the usual monitor directory. Have fun!


Android and Linux

Thursday, November 18th, 2010

So I went to the BLU – Boston Linux User Group – meeting tonight. I hadn’t been in a long time, but the talk was by a guy (Greg Milette) writing actual Android apps that have sold in the app. Market, so I thought it might be fun. It certainly was interesting to hear about practical app. development, not just listening to the same folks bitching again about how Google might or might not have modified the kernel and other bits to provide their desired user experience. Greg demonstrated writing an app, building, and testing, it, and I certainly got the feeling that my intention to have a small app that updates my GPS location on a server periodically (in order to allow me to have my Asterisk and IRC servers automatically route calls/set me away, etc.) would not be too tricky to pull off in a reasonable amount of time. I upgraded my Nexus One to CyanogenMod 6.0 recently and think I’ll find some time to play sometime.

Linux User Groups used to be very hard core affairs, where you’d have some pretty meaty stuff. These days, I generally avoid them because they’re catering to a different audience – not a wrong audience, but just not my cup of coffee. These days it’s often about pretty GUI stuff I don’t care about, and very “high level” discussion. And everyone has a laptop or netbook open and is reading email rather than paying attention. Tonight wasn’t too bad, although there was a guy in front who had discovered a “cow” application that could be run on the command line and would display a picture of a cow with a speech bubble full of whatever text he passed to it. That guy sat there for about 20 minutes (at least) playing with this, typing in various text, laughing to himself, and reminding me why I stopped going to LUGs at least 5 years ago (or maybe that was when he was on YouTube and found a video of dancing cows to complete the theme for his evening). Of course, all of this was on a laptop running Ubuntu. As was everyone else. Nobody there was running anything other than Ubuntu. Not a Fedora in sight. I have opinions on pragmatism that I believe explain precisely why nobody was running Fedora, but nobody is interested in hearing those anyway.


Rant: Linux Wars

Sunday, November 14th, 2010

So, I got into Linux almost 15 years ago now. Back in the day, Linux was about having a cheap and convenient UNIX-like system for those who couldn’t afford expensive Sun hardware at home or who wanted to get more involved with understanding and hacking on the internals. Linux benefited enormously from the fallout of the “UNIX Wars”, which had seen different UNIX vendors attacking one another, huge amounts of fragmentation etc., before a re-unification effort centered around common standards, like POSIX (and later, SUS). Yes, these standards are not perfect, but they send a strong message of intent.

Because we had common standards for low-level pieces, for interoperability, etc. we could at least make an effort to have portable software between very different systems. The reality wasn’t always rosy, but the intent was there. Everything from networked filesystems (NFS) to graphical desktop (X) was centered around understanding that there were “others” out there you needed to play nicely with. You could go implement some shiny new feature in a silo, or make your version do things in a radically new way, but the implosion of the UNIX market had demonstrated the futility of doing that in a vacuum without putting some effort into common solutions that others were going to get behind. Or at least not intentionally doing things differently in a way that couldn’t be easily integrated with other systems later on.

And then Linux grew up and became all sexy. Those involved started changing, not necessarily in bad ways, but just different. Suddenly not everyone enjoyed using terminals, typing commands, or having various daemons and services around. They wanted something for “mainstream” users that had all the fluff and shine of other Operating Systems. And so various projects spawned up over the last decade, seemingly out of a necessity, following the “Bazaar is always best” philosophy (which typically also comes with a hefty dose of libertarian-like laissez-faire thinking). New protocols, new interfaces, whole new approaches just kind of happened on us without any real co-ordinated thinking at a much higher level. So now we have many difference folks pulling in different directions. And each year one “Linux” becomes more different than the next “Linux”. Some want compatibility and standards based development (even if it’s lousy at times). Others want “OMG, not some lame standard, pah! we’re the best! just do it!” and for Linux to do its own thing entirely. Neither approach is entirely correct, nor entirely wrong. But we’re not learning from UNIX either.

Anyway. Now would be a very great time for us to take a deep breath and ask ourselves if we want to have the next ten years be like the last. Do we want to continue along a path that is going to increasingly see two, three, or more “solutions” to common Linux issues, with vendors getting behind one or another, and folks criticizing projects for NIH mentality? Or do we want to have a moment of Zen where we realize we’d be better off playing nicely together on a more comprehensive approach to world domination? I personally would like to see industry standards bodies like the Linux Foundation drive a few years of stabilization and standardization wherein we get behind common Linux ways to do things so we don’t turn into the next incarnation of UNIX.

I speak only for myself, etc.


More fun with Asterisk (video)

Tuesday, November 9th, 2010

So tonight I added some more database directories to my Asterisk server. For example, it now knows the numbers of most of my colleagues and will give them a special message (including internal contact information, etc.), has several databases for unwanted callers, specific greetings for others, and additional logic to handle various other fun. Here’s a video:


Some more fun with Asterisk

Monday, November 8th, 2010

So I moved to the US a while back. When I did that, I retained a mobile number in the UK that many people already had in their address books, and for those occasions when I might visit. For the longest time, I had it setup on permanent divert to a SIP trunk in the UK, that connected to an Asterisk server in Texas and then a SIP trunk in the US, out to my US cellphone. Callers never even realized that they were actually speaking to me on my US cellphone when calling my “UK” one. A nice hack for cheap roaming (I wrote an article on this some years ago now), and a great way to say “screw you” (but slightly more strongly) to the phone carriers who still overcharge for roaming. But we can do better.

Recently, I learned that A&A have started a UK mobile service that uses SIP extensions exclusively, basically giving you a SIP trunk into a cellphone handset. No more call forwarding. The phone is the SIP extension and can be configured just like any other (when will US carriers wake up? ever?). I’m hoping to get one the moment they can port my existing number (they’re still working on number porting), so that I can just have a UK SIP extension for when I am in the country. In the interim, I got another SIP trunk for playing around and forwarded my old mobile number to that one, with a customized message that will still forward to me after a delay. The message informs the caller that I am in a different timezone and since it now knows that calls to that number can only have come from the mobile, it can do some other nice things too. Ultimately, the call still winds up hitting my US cellphone, unless it’s from sales or marketing folks.

Anyway. While I was at it, I used what is commonly known as “ex-girlfriend logic” (someone once had to solve the “problem” of handling calls from their ex, so it became known as this, but it’s used for many different purposes!) to add special rules for all kinds of numbers. For example, I recorded special messages for organizations that routinely call to harass me and added rules to catch their calls through their caller ID (fakeable, but most organizations don’t do this today). These messages say things such as: “Organization A, your number has been recognized as belonging to Organization A. I have previously requested that you stop calling me with sales or marketing calls. If your call is not for sales or marketing reasons, please leave a message. If you are calling to sell me something, please also leave a message, explaining that you have heard this, have added me to a do not call list, and won’t be calling me again”. The messages vary, but the gist is clear. Then the call goes to voicemail and my phone never even rings.

A similar process happens when callers to my UK trunk need to be informed that I am not “Iceland Express”, the airline which has a number very similar to my own. Calls still reach me, but after a message explaining that I am not the airline they might be trying to reach. In due course, I would like to have the system record numbers that have already heard this message and don’t need to hear it again (if they aren’t exchange numbers – need a way to detect that also, maybe in the signalling data somewhere?). Conversely, the phone system recognizes my family and girlfriend and saves them from listening to my greeting every time, making their calls reach me a few seconds faster than some others, though with a funny message for fun.

At this point, I have a growing number of Cisco 7940 series IP phones around my apartment, as well as soft phones, and a number of trunks and mobiles that are all hooked together. When you call me, your call has all of the rich features of Asterisk. For example, you will (and have for years now) hear music on hold while the system rings all of my phones in unison, have a menu with various options, etc. I can easily record calls, transfer them between phones or countries, and I have speed dials configured for popular numbers that I need to reach (some of which will also setup pre-agreed recording, if it’s a conference). Oh, and I’ve been hooked into Fedora VoIP for a while now too, so that just gets handled like any other incoming call. My phone has a special dialplan prefix for Fedora, the same as how it also recognizes UK numbers and automatically dials the international bit and routes cheaply through the UK trunk without any need to do anything special.

What I would like to do next is to have a DNS service (perhaps RFC2916 compliant) that I could use my Asterisk server against in order to do anti-spam filtering of the form that I do already with spam-assassin. I would love to know if such a service exists, and if not, why not? I would love to be able to add wildcard rules to my Asterisk server to match on specific names of organizations, whose exact number might vary (but can be looked up in the database to find their name), in order that they will always get the special handling that I have deemed appropriate for them. With such a service, you could also easily and automatically exclude all known telemarketing numbers with a single command. Anyone point me to such a setup?


Playing with EDID and rawhide

Monday, November 8th, 2010

Photo: Modesetting problems with 2.6.37-rc1 and the i915 driver.

So there was an innocuous patch to i915 EDID code (in the intel_lvds setup code) that introduced cacheing of the EDID data, but in the process stopped reading panel data correctly on boot, which would result in all kinds of weird modesetting problems on these Intel parts. Like my ASUS Eee PC 1015PEM, where the screen was moved down an inch or so such that there was blank space at the top and the bottom inch of the screen was “missing”. You can see a photo above (and my upstream posting had a video). A lot of bisecting over the weekend tracked this down, and I very much enjoyed working briefly with the excellent Chris Wilson to test fixes. It should be that 2.6.37-rc1+the posted fix on LKML works well on various random panels again, such as this netbook.

Meanwhile, I’ve been actually using rawhide on the netbook, in the spirit of dogfooding (which is why I bought that netbook – to have a controlled and safe environment for playing with unstable software). It’s been tough though. A small list of the many issues currently includes: Lots of the conversion from GNOME2 to GNOME3 is hitting me. I’m unable to run rhythmbox (hasn’t worked in ages), the volume control applet won’t start, and ABRT frequently generates traces that are unusable (so I removed ABRT). Also, the screensaver won’t ever exit (without killing gnome-screensaver on the command line), and recently my sound stopped working completely. I fixed the latter by completely removing pulseaudio from the system (and filing several bugs – including one to have gnome-bluetooth not depend on PA). But it’s not all bad. The desktop mostly works, the browser has been fine, and evolution is able to send email now that the annoying “crash on sending mail” bug has gone away for me.

Nonetheless, at this point, my “exclude” yum configuration grows larger daily. The system is, at this point, usable for poking and playing around with experimental kernels, but I simply could not use rawhide on a daily basis as my main desktop environment, without a lot of deep meditative breathing. In my own personal opinion (of which all of this is personal opinion), the lack of any stability in rawhide is counter-productive. Sure, yea, it means you can shove anything you like in the distribution. But it also means you can shove anything you like into the distribution. I know there is a updates testing staging area, but part of me pines for the old days of Debian testing, where you knew you’d get cutting edge stuff, but you’d also know it had baked for a week or two first. I personally would like a direct equivalent in the rawhide space, which isn’t the same as the branching we have now. I like the branching, and I think it’s a far better system, but I’d also like a two-stage rawhide. And a pony, let’s not forget about the pony before people think I don’t realize how not trivial this stuff can be to implement.

UPDATE: I tried a combination of pulseaudio and gnome-shell. This results in sound, but the mixer in gnome-shell doesn’t control the PA output (just slides up and down with no effect), sound settings crashes, contol center won’t start, etc. I suspect I will go back to GNOME2 again tomorrow with PA removed again.

UPDATE2: Yup. Removed PA again and went back to GNOME2.