Writing

Feed Software, technology, sysadmin war stories, and more.

Tuesday, January 10, 2012

One example of a project done in C++: my scanner

Today, my rant about C++ not being special made it onto Hacker News. As usual, it has generated some controversy spun off all over the place.

Adrian was disappointed and got a vibe of "language hipsterism and NIH syndrome" from my post instead of examples of interesting things which happen to run on top of C or C++. Am I a language hipster? Okay, if you say I am. I don't care either way.

But, he has a point: I should show off some of the things I've done with C++. My post from last week was about shutting up and actually doing stuff, so let's talk about what I've actually done with it in recent times.

My biggest project since quitting El Goog back in May and going to work for myself is called the Super Trunking Scanner. It's two big pieces.

One piece which I call "cscan" is linked to GNU Radio and listens to the actual radio hardware. GNU Radio itself happens to be C++ at the very bottom. My code (cscan) is also C++ all the way through. I was originally using some demo code written in Python as my base, but I got tired of dealing with the foibles of that code and rewrote it in C++ one night last summer.

cscan is responsible for tracking the control channel and running FM decoders to generate MP3 files. Those MP3 files are created through a special GNU Radio "sink" class I wrote which wraps around libmp3lame. That class is based on the stock WAV sink found in the GR tree. cscan also talks to MySQL to write the metadata for each call: when it started, when it ended, what frequency it was on, and which talkgroup it was for (police, fire, ...).

Incidentally, libmysqlclient is written in either C or C++. I'm not entirely sure right off the top of my head, and it doesn't really matter. It's there and it works, so I'm happy.

A lot of the glue in cscan is from a bunch of classes/libs I wrote to get things done. There's something which handles talking to libmysqlclient, for instance. Many of them were written for other projects and continue to be useful in this context.

The second big part of the scanner is the web side. There's a bit of static HTML and CSS and then a good bit of Javascript which runs on the client. It uses jQuery's $.ajax() and calls back to my server where a program called "listcalls" handles the request.

listcalls is just another C++ program which talks to MySQL using that same helper library of mine, and it looks up call data. Then it formats it nicely as JSON, spits it to stdout (for it is CGI under Apache) and shuts down. That's it.

Back on the client, it gets the incoming JSON message and builds a bunch of rows, appending them to the table. There's also a little loop which wakes up now and then and looks for new calls. If it finds them and you are in "autoplay" mode, then it will jump to the next and start playing it. The actual playing happens thanks to jPlayer.

Now for some links. Here are earlier posts about the creation, design and implementation of this project.

Building a better mousetrap

Feedback on the above

Dollars and cents of building it

The original idea

Buying the hardware and learning the software

Hardware assembly and initial software hacks

Early hurdles and weak CPUs

New Linux box equals success

Figuring out squelch and doing a demo


January 11, 2012: This post has an update.