RSS Feeds
Posts
Comments
Photos
Twitter
technmsg

In the past I’ve avoided location-aware services, opting instead to conceal my location to all but my ISP, cellular provider, and whoever else might be capable and willing to find out.

2012 marks a departure from that stance.

Armed with a Nexus One, I’ve started using a few new services.

I’ve started to use foursquare to track my outings. The service automatically characterizes both the nature and locale of the places I visit, which is interesting to me even before adding the social aspects and friendly competition. I spent a lot of time last semester on my living room couch, allowing my brain to recover from the mental anguish of Modern Cryptography; I’m hopeful that foursquare might motivate me to try some new places, maybe just around the corner from my usual haunts.

Google Latitude allows you to see where your friends are, overlaid on top of the familiar Google Maps interface. When they move, their position is updated in near-real-time. It also keeps a visual historical record of where you’ve been and when, which is more informational and appealing to the statistician in me. Latitude is handy when you’re trying to meet up and someone hasn’t arrived yet; one peek and you can see that they’re a few minutes out without having to bug them while they’re driving. But mostly, it’s a neat little toy. I’ve gotten a kick out of seeing my buddies jet set around the country (or county, depending).

Admittedly the privacy aspect is still a little chilling, but I’m warming up little by little. I’m trying to live more openly, but I definitely wasn’t ready to go public with everything. For now my location-specific data should — in theory — only be visible to friends, family, and people with whom I don’t mind sharing my whereabouts.

Here we go.

This past weekend I tagged along with the crew of Sterling Volunteer Fire Company’s Engine 611 on a thirteen hour shift. I was free to observe, with no responsibilities other than to stay out of the way. I learned quite a bit. I’m still processing a few things, and no doubt I’ve forgotten some of it already. But overall it was a great experience, one that I’d recommend to anyone who has the opportunity.

IMG_3546

Lesson #1 - Fire trucks are cool.

No matter how old you are, there’s something amazing about fire trucks. Those in the business refer to them as apparatus, but I can’t bring myself to do that. I’m an amateur fan. But seriously, why shouldn’t we continue to be amazed? These things are large diesel-powered monsters, decked out in a lot of chrome and stainless steel, with lots of buttons and knobs and switches, flashing lights, sirens, lights bright enough to turn night into day, and electronics. And that doesn’t even begin to talk about the water features…

IMG_5511

Lesson #2 - Arriving early is important.

Time is critical to first responders. Minutes can — in many cases — equate to lives saved or lost. Firefighter are no exception, and this notion was stressed both verbally and in the crew’s actions throughout the shift. If a crew’s shift is from 6pm until 7am, that means that they need to be ready to go at 6pm. Not getting dressed. Not checking our their safety gear. Ready to go.

We arrived at Station 11 plenty early. After dropping personal gear at our bunks, I was given a quick tour of the fire station. Bunk rooms, with lights that come on automatically when there’s a call. Radio room, where all the dispatcher’s calls are received and the valid ones are rebroadcast around the station. Lounge, complete with sofas and big screen. Kitchen, with gas range and two refrigerators. Very humble and functional surroundings, nothing too out of the ordinary. Bathrooms, too. Firefighters tend to relieve themselves whenever they have the opportunity, not necessarily when they have to.

At 5:42 PM we headed down to the garage. Normally home to an engine, a ladder tower, a quint (which can serve the role of both engine and ladder truck, plus other functions), and few specialty vehicles (brush unit, canteen), the space appeared pretty packed to me; the 611 ladder tower was out of service due to a mechanical issue and so a quint from another station (Quint 618) was standing in that night. The inbound crew was busy checking out the equipment, getting notes from the outbound crew (e.g. the left rear spotlight is still not working, it’s going to have to be replaced). I was given the quick overview of where I’d be seated if we got a call (back seat, center, facing forward), what to do in that case (get in quickly, buckle up), how to use the headphones, and what to do once we were on scene (generally, stay in the truck unless told otherwise).

Engine 611 is considered “in service” when the equipment is functional and it’s ready to be manned by an officer, a driver, and at least one firefighter. I think the last part depends on the county/state, but in general there’s a set number of individuals filling specific roles that need to be present. If you’ve got a flat tire, no go. If you’re missing any of the key personnel, no go. Once in service, the county dispatcher knows that the unit is available to be dispatched to a scene if necessary.

Lesson #3 - Like most industries, there’s a specific dialect.

Firefighters tend to talk in numbers and geography. They’ll say that they were headed over to 11 or 18, when they’re talking about specific fire stations. There’s a lot of radio jargon that differs from the 10-codes used by law enforcement, but it sounds similar to my untrained ear. They know which hydrant out of a thousand is a pain in the ass to open. They appear to have an encyclopedic knowledge of street addresses and direction; punching in an address to a GPS-assisted navigation system seems abysmally slow by comparison to a seasoned firefighter.

There are speakers installed throughout the fire station, many of which broadcast continual updates from the dispatcher, all in the background. Status of current calls, call-backs from dispatched units, etc. There are also display monitors posted throughout, which list the last couple calls and the status of all the equipment. Both audio and visual methods are somewhat cryptic to me, but after a while you can start to understand some of it. Not all the updates are applicable to our specific crew, as the station house hosts both the fire company and the rescue squad, but everyone there appears to be accustomed to listening to that stream of audio and carrying on conversation simultaneously. Mid-conversation some tones were dropped, some updates relayed by the dispatcher, and I’m told we’ve got a call.

Lesson #4 - Riding on a truck fire is more cool.

At 6:15 PM, Engine 611 and Engine 618 were dispatched to the scene of a car accident. I wasn’t sure what to expect, but everyone quickly and calmly boarded the truck, got strapped in, and donned their headset. The garage door rolled up and we were out the door, siren blazing and lights flashing.

As the firefighters in the compartment were busy changing out of their shoes and getting into their protective gear, the driver was busy weaving through traffic, running red lights, and sharing my sheer amazement at other drivers who just do not seem to understand that they’re in the way and that a truck that size won’t stop on a dime.

Public Service Announcement: when you see or hear an engine, move out of the way. Aside from the fact that you’re impeding a crew from reaching their destination in a timely matter, you do not want to be hit by one of these things, even at slow speed. They’re big, they don’t corner well, and they weigh a lot; from the seat of a fire truck, every other vehicle looks miniscule. Put it this way, the 750+ gallons of water onboard Engine 611 alone weighs more than most vehicles on the road today. Newton’s laws of motion should be suitable reading, here.

I never felt like the rig was out of control or that we were going excessively fast, that being said I have no idea how fast we were going. I do know that it’s pretty amazing to see such a large vehicle navigate through traffic. I’m told that the trucks are geared for acceleration, not top speed; I believe it, these things can pick up and move when they have to, which is incredible given their weight. On the headset I can hear the others in the truck over the intercom, speaking normally. In the same headset but overlaid louder are updates to/from the dispatcher, units en route, and our officer asking for updated location information.

As it turns out, the car accident was on a ramp to the highway. Direction wasn’t provided as to whether it was an on-ramp or an off-ramp, so there was a lot of looking out the window to locate it. Emergency responders can only respond if they can find you. Mile markers are good I guess, but I’d think that basic directions would be better. If the caller had reported that they were on the on-ramp to highway 123 northbound, we wouldn’t have had to go looking around for two stopped cars. Granted, some folks don’t know where they’re going in general and it’s not uncommon to be disoriented after a collision. Eventually the accident scene was located, requiring our driver to reverse up the on-ramp (with assistance from the firefighters-turned-backers).

From my seat in the cab, it looked like a standard rear-end collision. The rear end of the lead car was in decent condition. The front end of the following car, very much accordion-like. The humans involved appeared to be undamaged, if not a bit shaken. Police and EMS were on the scene too, taking statements and writing reports. The crew deployed cat litter to soak up leaked fluids, the Engine stood in place blocking traffic and keeping passing cars away from all those involved.

Lesson #5 - When you eat, it’s always to-go.

At 7:00 PM we backed into the refuse/loading area at Dulles Town Center to grab dinner. Food courts provide a lot of options, so everyone can get what they want. There are fire exits and passages everywhere, and the crew uses them expertly to navigate quickly and efficiently through the back corridors of the mall. I also learned that it’s difficult to try to buy a firefighter dinner, but I’d encourage you to try. After finishing up, it was decided to go top off the tank.

Lesson #6 - You can never had enough fuel in the tank.

At 7:38 PM we arrived at Station 18, the northern fire station of Sterling. Engine 611 took on 8 gallons of diesel. According to the odometer Engine 611 might only get a mile to the gallon, which sounds pretty awful. But the engine isn’t just responsible for propulsion, so that measure is prone to inaccuracy. At the scene of a fire the transmission is placed in neutral, but the engine runs continuously and spools up to pump water as necessary. An engine might only power the transmission for 10 minutes to get to the scene, but then run for 3-4 hours. Similar to nature’s calling, you fill up when you can.

Lesson #7 - There’s a lot of water feeding the hydrant.

At 8:21 PM we arrived at Park View High School for training, play time, drills, or whatever else you want to call it. The other three trucks from the station were already present. The chief assembled the crews and explained the various drills that he wanted to see, after which each truck deployed to a space in the back parking lot. Our truck would not be involved in any drill and was moved into position for quick departure. It’s standard procedure to keep engine running (in pump gear) when the temperature is below freezing, to keep the water circulating (and as a bonus the cab is kept nice and warm).

Engine 611

One team was hooked up to a hydrant and was practicing dousing a trailer from a handheld hose. One team set forth with a pair of roof ladders (ladders with a pair of hooks on the end), working their way onto the various roof structures of the high school, taking the ladders with them as they moved.

One team deployed a 105-foot ladder into the sky, the instructions being that everyone had to climb up and down once.

Quint 618

The last team practiced what I’d call a pit-stop maneuver. The truck would drive up to a hydrant and stop. A firefighter would hop out and lash a four-inch line to the hydrant, then motion the driver to advance, thus deploying the hose out from the back of the truck. Let the truck do the heavy lifting: smart.

IMG_5513

Once stopped, the firefighter would work to attach the hose to the hydrant, the hose to the truck, pressurize the system by opening the valve on the hydrant. Once pressurized, those hoses are hard as concrete, yet I was told that the slightest kink in the hose could drastically reduce pressure.

IMG_5518

Then the driver (who also operates the engine-mounted pumps) would open one of the valves on the engine to flow some water (video). A firefighter’s notion of some water is vastly different than mine; the amount of water flowed in each one of these 30-60 second tests far exceeded what I use at home in a month.

IMG_5519

After everyone is satisfied, the whole operation has to be undone in the reverse order.

IMG_5515

This was done three or four times that I saw, then each hose had to be purged of water, rolled up (you can see some of the rolled up coils laying on the sidewalk in the photos above), then stowed in the back of the truck properly. This particular truck has a retractable housing to store hoses.

IMG_5524

All of this in 20° weather, not counting the wind chill.

At 9:04 PM Engine 611 was dispatched to assist with an EMS call. We climbed aboard and left the other crews behind. I’ll exclude the details due to potential HIPAA issues, but suffice to say it would have been a call where the crew would be there to provide manpower, perhaps a little extra muscle with the stretcher on the staircase, etc. An individual was loaded into the ambulance at less-than-emergency speed (read: cause for EMS was non-life-threatening, not that the crews were acting slowly). Once the ambulance departed, we headed back to the high school.

Most of the crews had finished their drills, but one was still working with a monitor. It it usually attached to the truck, but can be removed and placed anywhere. It can be fixed to direct water at particular area to keep an area wet, so that firefighters can focus their attention elsewhere (instead of having to man a hose).

IMG_5523

Lesson #8 - Everyone needs rest.

Upon our return to the station, we set up our bunks and headed back downstairs. I picked up my stocking cap and gloves and put them into the cab with my jacket so that I’d have them for the next call. Some of the crew started watching a movie, others went to sleep, others stuck around and talked. I hung around to listen. Company politics. War stories. Eventually I started to tire, having been up for 20 hours or so. I found myself dozing off in my chair.

At 1:15 AM, we called it a night and headed upstairs to our bunks, flipped off the lights and tucked into our sleeping bags.

At some point, probably around 2:00 AM, I was awaken by tones and the voice of the dispatcher. The lights snapped on. I rolled out of bed and started getting my boots on, when I was informed that the call didn’t include us. Okay, maybe EMS only. The lights snapped out on their own in a minute or two and I went back to sleep.

Lesson #9 - Being woken up at 3:00 AM is disorienting.

At 3:03 AM Engine 611 was dispatched for reasons unknown. The tones dropped. The lights flicked on. I heard 611-something spoken. I rolled out of bed, put my boots on, tied ‘em up, put my wallet and phone in my pockets and shuffled down the stairs to Engine 611. I found the garage door open and everyone else already inside the cab. As I got in and sat down my host informed me, “you were about 3 seconds from being left behind.” Shoelaces. Now I know why his boots have zippers instead of laces.

As we bolted through now-empty streets to the destination, the officer on-board requested an update from the dispatcher. It was a self-reported 911 call from an injured person. The call had been lost. Attempts to re-dial the cell phone had gone unanswered, so GPS was being used to attempt to locate the caller. We arrived shortly after the police, so we parked a block or two away and waited for further information. Over the intercom more war stories were swapped, along with shop talk, and speculation about the accuracy of GPS devices.

At 3:50 AM we headed back to the station, the sheriff apparently having settled the matter, whatever it happened to be. Never found out. Sometimes that’s how it happens.

At 6:50 AM I got up, packed up my bunk and headed downstairs. I picked up my jacket and personal effects from the cab. Just in case the next crew were to be called at 7:01 AM, no telling when they’d be back. I fixed a cup of hot chocolate and listened to the exchange of information from the evening crew to the morning crew. Shortly thereafter, I walked out to my car and headed for home.

It was a quick 13 hours, but I don’t know how those crews do it. Two or three hours sleep in 26 hours time simply isn’t enough for me; the following day I found myself napping sporadically and uncontrollably. Riding along was a rush, no doubt about it, but also very humbling. These volunteers are from all walks of life: engineers, HVAC repair, computer geeks, community college, white collar, blue collar, you name it. Once they commit to the service of their community, they put on the uniform and work together as a single professional unit, calm and collected. It was a privilege to witness it, even without seeing a single flame. Tired but feeling good, even though I was just along for the ride.

Health insurance is convoluted. It’s hard to understand when you don’t utilize it; it’s easier to understand when you do utilize it, but there are still plenty of weird things about it. One example from the past year.

I saw a physician in April. The bill was submitted to my insurance company a week later. I didn’t receive a bill from the physician for several months, but once I did I sent payment off promptly. A few months after that, I got another bill for the same visit for a much smaller amount, the result of the insurance company quietly renegotiating the rate they were willing to pay for my visit, changing what I owed after the fact.

Using very rounded numbers…

  • 04/01/11 - Physician date of service
  • 04/08/11 - Bill submitted to insurer for $500
    • Negotiated down to $200
  • 04/21/11 - EOB shows my responsibility as $200
  • 09/17/11 - Physician’s bill received for $200
  • 09/22/11 - Physician’s bill paid
  • 12/19/11 - Insurer quietly renegotiates allowable rate as $250
  • 01/07/12 - Physician’s bill received for $50

There are two few odd things going on here.

The physician’s office waited five months before sending me a bill. That simply can’t be good for cash flow. As much as I appreciated having the dough in the bank, in the grand scheme this makes things harder on the medical profession and contributes to higher costs.

The insurance company opted to renegotiated a higher rate for the billed services eight months after they had been paid for at a lower rate (and three months after I had paid my end). This seems dishonest, particularly to the patient. Depending on the reason for medical care, billing can be an emotional matter. We need closure. We just want to pay the bills and move on; receiving yet another bill in the mail for something that we would love to have forgotten about seems cruel.

Once a service has been bought and paid for, that’s should be it. The kid mowing your lawn doesn’t pop over and say “hey, everyone’s giving me $30 a lawn this year instead of $20, so you owe me $10 for last year.” He could, but you’d probably scoff at the idea and tell him to take a hike.

Maybe the physician’s office was arguing with the insurance company about the rate, contributing to the super-late bill. If so, that’s a lot time to be negotiating. Time is money. Maybe they got sick of arguing with the insurance company and figured they could get something in the meantime, then work out the details later. Nobody knows.

This is not the way to run a business.

Violation of Expectation

As I tweeted, change may violate design of a program, but changes to implementation that violate our expectations are worse.

In software development, the design becomes useless if the user elects not to use the application. You might have the most amazing and thorough design, but if it doesn’t attract and entice users to use the thing, what’s the point?

In configuration management, process can help cover all the documentation needs, but if it’s so much that a developer strays from the process entirely, what’s the point?

But these are often just academic exercises…

Suppose a meteor landed on your house. Assurance from your neighbor that everything will be alright — while correct in emotional terms — isn’t as good as their offer to pitch in and help clear the wreckage and salvage whatever precious goods may have survived.

But that’s just a hypothetical…

In employee relations, consistency is key when working with employees. People in general, really. If you tell someone that they matter, actions that suggest that they don’t will breed skepticism and distrust. An employee may be fine in the knowledge that they’re an entry in a profit/loss ledger so long as their financial needs are being met, but once expectations are raised and the employee feels valued, actions that make them feel undervalued are a violation of expectation.

In a labor-based economy, employee knowledge and expertise are considered precious goods, but more important is what the employee is going to be capable of in the future. When policies that affect employees change in ways that could be construed as inequitable, pleasantries won’t be enough of a consolation to mend that tear in trust.

That isn’t to say that design isn’t important, but design for the sake of design is foolish.

Home of the Garbage Plate

In college, we’d often end a night of revelry by heading over to Lyle Avenue for plates. A greasy and starch-laden meal whose mystical powers could quell a hangover before it had a chance to develop, but more importantly a delicious tradition of upstate New York.

Nick Tahou Hots, “Home of the Garbage Plate” and a Rochester institution, was founded in 1918. Nicolaos Tahou, a Greek immigrant, formulated the Garbage Plate, originally called “Hots and Potatoes,” during the Depression era to offer a large amount of food to his customers for a reasonable price. The dish is built on a base of home fries and macaroni salad, then topped with a choice of meats and dressed to one’s liking. Today, it is a signature dish of the Rochester region.

A garbage plate is a concept where the sum of the parts don’t look all that appealing at first, but has to experienced first-hand to be understood and appreciated fully. And despite the many restaurants and bars in the area that attempt to emulate the dish, there’s simply no substitute for the original.

Nick Tahou Hots Exterior

In college after-hours at Lyle Avenue there was much time spend standing in line, wherein bouncers would only allow a reasonable number of people into the place (where reasonable was defined as a number exceeding the number of seats and/or fire code but below that which would constitute a riotous hungry mob), unless your previous tips to the order-taker were noticed in which case you might be whisked to the front of the line like a VIP much to the dismay and verbal ire of those behind you. While the rapid-fire process of late-night ordering tended to be chaotic at best, the weekday lunch time method downtown is considerably more subdued.

There are a multitude of options: you must choose one meat and two sides. Meats include hots, hamburger, cheeseburger, sausage, chicken, fried ham, fish, grilled cheese, veggie burger, or egg. Sides include home fries, french fries, macaroni salad, or beans. I’m a fan of one of the standards, and thus I order the following: “cheeseburger plate, mac home fries, everything.”

Roughly translated and visualized, this means two cheeseburgers set atop cold macaroni salad and warm home fries, with mustard and raw onions, then covered with a seasoned meat sauce. Two pieces of fresh baked Italian bread are served on the side.

Cheeseburger Plate at Nick Tahou Hots

Realistically speaking, a ladle of meat sauce probably represents another half a burger plus an untold amount of griddle scrapings. In that, every plate tastes a little bit different. Sometimes there’s a little kick to the sauce, other times it’s more savory. It all depends on what’s been on the grill that day and how much seasoning went into the original batch.

After it’s all assembled to-order and you pay, there’s some preparations to be made. First, the application of liberal amounts of ketchup and hot sauce. At Lyle Avenue you’d easily apply a third- or half-bottle of ketchup from a restaurant-sized bottle. Smartly, Main Street has switched over to the pump model… less mess, no glass to break or dispose of, etc. I’ve cut down on the sauce lately, preferring not to mask the flavor of over ingredients.

Getting Sauced

Once you’re all sauced up, you’ve got to prepare the dish. Everyone I know cuts their burgers up and mixes to some extent, since you want a combination of all the components with every bite. Recommend that you do the same.

Thus you have a garbage plate from Nick Tahou Hots, ready to eat. The take-out version tends to be large to the point of filling the container, however if you eat in everything fits onto a plate so it’s not an intolerable amount of food.

Mixed and Ready to Eat

In college, it was all about putting down some food at the end of the night. Regardless of its appearance, everything tasted amazing. At times my perception may have been a tad fuzzy, so I’m happy to report that uninhibited the garbage plate tastes just as good as I remember. Better, actually. There’s a nice juxtaposition between the warm potato and the cold pasta, the meat and cheese adding some grease and coarseness, the raw onions giving it a little crunch here and there. It’s a culinary experience that everyone ought to try at least once; if you’re in Rochester, don’t miss out.

For the curious or those who want a mild trip down memory lane, there are more pictures from my recent trip to Nick Tahou Hots.

Nick Tahou Hots on Urbanspoon

I haven’t had land-line phone service in more than a decade, but that doesn’t mean that I haven’t missed it. If I’m on a two hour conference call I don’t want to be burning up the minutes and battery on my cell phone (or be tethered to the wall where the charger is plugged in), or hunched in front of the computer using Google Voice. I miss having a decent speakerphone, too.

So when I read that Asterisk 1.8 supported Google Voice, I was excited. It only costs about $8 a month to run a small tower PC. That’s already several times cheaper than a land-line phone, moreso if you consider that long distance is included. Plus you can do some neat things with an in-home PBX.

Unfortunately, support for the Cisco 7940G handset has been broken as of Asterisk 1.8.4. There’s a bug — documented in ASTERISK-17830 and ASTERISK-17535 –wherein the handsets can’t complete SIP registration. Basically the SIP registration includes an IP address and port in a Via header, and this pair needs to be correct in order for the registration to succeed… and the IP address is wrong. The handsets can speak to the PBX but two-way communications are problematic, which makes most of the fun stuff impossible. What follows is what I went through to get this all working.

I figured I’d get Asterisk up and running first using soft phones (software that runs on your computer and interacts with the PBX just as a SIP handset would), then worry about getting the Cisco handsets working.

Building Asterisk

On a fairly bland CentOS install, I had to install a few things just to configure the build. I’ve gotten used to having a stocked development system, so I felt pretty dumb about some of these.

configure: error: C++ preprocessor "/lib/cpp" fails sanity check

The Asterisk Common Compiling Issues recommends installing gcc-c++ … duh. I’ll spare you the details, but configure also complained about libxml2.

box# yum install gcc-c++ libxml2-devel

Try again, and… nice.

configure: Menuselect build configuration successfully completed

               .$$$$$$$$$$$$$$$=..
            .$7$7..          .7$$7:.
          .$$:.                 ,$7.7
        .$7.     7$$$$           .$$77
     ..$$.       $$$$$            .$$$7
    ..7$   .?.   $$$$$   .?.       7$$$.
   $.$.   .$$$7. $$$$7 .7$$$.      .$$$.
 .777.   .$$$$$$77$$$77$$$$$7.      $$$,
 $$$~      .7$$$$$$$$$$$$$7.       .$$$.
.$$7          .7$$$$$$$7:          ?$$$.
$$$          ?7$$$$$$$$$$I        .$$$7
$$$       .7$$$$$$$$$$$$$$$$      :$$$.
$$$       $$$$$$7$$$$$$$$$$$$    .$$$.
$$$        $$$   7$$$7  .$$$    .$$$.
$$$$             $$$$7         .$$$.
7$$$7            7$$$$        7$$$
 $$$$$                        $$$
  $$$$7.                       $$  (TM)
   $$$$$$$.           .7$$$$$$  $$
     $$$$$$$$$$$$7$$$$$$$$$.$$$$$$
       $$$$$$$$$$$$$$$$.                

configure: Package configured for:
configure: OS type  : linux-gnu
configure: Host CPU : i686
configure: build-cpu:vendor:os: i686 : pc : linux-gnu :
configure: host-cpu:vendor:os: i686 : pc : linux-gnu :

Now I did some pre-reading and knew that Google Voice would require a few other dependencies, notably iksemel (an XML parsing for XMPP) and libgnutls (for securing communications back to Google).

box# wget http://iksemel.googlecode.com/files/iksemel-1.4.tar.gz
box# tar -zxvf iksemel-1.4.tar.gz
box# cd iksemel-1.4
box# ./configure --with-gnutls
.
.
checking for libgnutls - version >= 0.1.0... no
*** The libgnutls-config script installed by LIBGNUTLS could not be found
*** If LIBGNUTLS was installed in PREFIX, make sure PREFIX/bin is in
*** your path, or set the LIBGNUTLS_CONFIG environment variable to the
*** full path to libgnutls-config.

I tried this workaround, which didn’t work. I rolled back and installed gnutls-devel package and then everything built fine, plain vanilla. Some of these fixes are dated, clearly.

box# yum install gnutls-devel
box# cd iksemel-1.4
box# ./configure
box# make
box# make check
box# make install

Back to Asterisk, dependencies satisfied we begin to build.

Building Documentation For: channels pbx apps codecs formats cdr cel bridges funcs tests main res addons
 +--------- Asterisk Build Complete ---------+
 + Asterisk has successfully been built, and +
 + can be installed by running:              +
 +                                           +
 +                make install               +
 +-------------------------------------------+

real	20m33.595s
user	19m2.208s
sys	1m15.730s

Oh, single 750Mhz processor on legacy hardware… ouch.

Configuring Google Voice

I started out with the Calling using Google guide, which I found didn’t work. Not exactly, but not entirely the fault of the configuration shown there.

After starting Asterisk up using the dialplan defined in the Asterisk documentation, outbound calls were failing.

== Using SIP RTP CoS mark 5
  -- Executing [14105551234@users:1] Dial("SIP/gv-00000000", "gtalk/asterisk/+14105551234@voice.google.com") in new stack
[Aug 20 13:24:03] WARNING[23196]: channel.c:5503 ast_request: No channel type registered for 'gtalk'
[Aug 20 13:24:03] WARNING[23196]: app_dial.c:2197 dial_exec_full: Unable to create channel of type 'gtalk' (cause 66 - Channel not implemented)
== Everyone is busy/congested at this time (1:0/0/1)
  -- Auto fallthrough, channel 'SIP/gv-00000000' status is 'CHANUNAVAIL'

It turns out that the res_gtalk.so resource libraries weren’t being loaded. Since this was a from-source build and not a pretty pre-build, Asterisk had no concept of where there crypto libraries were. Will fix this later (as well as running as root), but for now we’ll just start the PBX like so…

box# export LD_LIBRARY_PATH=/usr/local/lib ; asterisk -vvvvc

Outbound calls were still failing…

== Using SIP RTP CoS mark 5
  -- Executing [14105551234@users:1] Dial("SIP/gv-00000000", "gtalk/asterisk/+14105551234@voice.google.com") in new stack
  -- Called gtalk/asterisk/+14105551234@voice.google.com
  -- Gtalk/+14105551234@voice.google.com-f411 is ringing
== Spawn extension (users, 14105551234, 1) exited non-zero on 'SIP/gv-00000000'

I knew that we were talking to Google, since there’s an endless stream of presence message flying by on the console; the more buddies you have the worse it is. Enabling debug mode for Jabber (jabber set debug on) outputs every XMPP stanza to the Asterisk console, even more verbose. And therein was a clue.

JABBER: google_voice INCOMING:
<iq type="error" to="ACCOUNTNAME@gmail.com/1234567890" from="14105551234@voice.google.com" id="aaaaa">
  <ses:session type="initiate" initiator="ACCOUNTNAME@gmail.com/1234567890" id="abcdefghijklmop" xmlns:ses="http://www.google.com/session">
    <pho:description xml:lang="en" xmlns:pho="http://www.google.com/session/phone">
    <pho:payload-type id="0" name="PCMU" clockrate="8000" bitrate="64000"/>
    <pho:payload-type id="100" name="EG711U" clockrate="8000" bitrate="64000"/>
    <pho:payload-type id="101" name="telephone-event" clockrate="8000"/></pho:description>
  </ses:session>
  <error code="302" type="modify">
    <sta:redirect xmlns:sta="urn:ietf:params:xml:ns:xmpp-stanzas">xmpp:14105551234@voice.google.com/srvres-abc123abc123</sta:redirect>
    <ses:redirect xmlns:ses="http://www.google.com/session">xmpp:14105551234@voice.google.com/srvres-abc123abc123</ses:redirect>
  </error>
</iq>

So Google is redirecting us to a new resource, but res_gtalk.so isn’t picking it up. As it turns out, a bug report had been filed a few hours prior along with a simple patch.

Index: channels/chan_gtalk.c
===================================================================
--- channels/chan_gtalk.c	(revision 332695)
+++ channels/chan_gtalk.c	(working copy)
@@ -496,7 +496,7 @@
 				break;
 			}
 			if (!strcasecmp(name, "error") &&
-				(redirect = iks_find_cdata(traversenodes, "redirect")) &&
+				(redirect = iks_find_cdata(traversenodes, "sta:redirect")) &&
 				(redirect = strstr(redirect, "xmpp:"))) {
 				redirect += 5;
 				ast_debug(1, "redirect %s\n", redirect);

It seems Google altered the name of their redirect stanza to be “sta:redirect” instead of “redirect”. After a quick recompile, outbound calls were working but inbound were failing.

Update: Naturally, it appears that Google has flipped back to the “redirect” version. No idea if they’ll stick with it or not, so perhaps I’ll apply this patch so that I can accept both.

== Starting Gtalk/+17607058888-d417 at google-in,ACCOUNTNAME@gmail.com,1 failed so falling back to exten 's'
  -- Executing [s@google-in:1] Answer("Gtalk/+17607058888-d417", "") in new stack
  -- Executing [s@google-in:2] Wait("Gtalk/+17607058888-d417", "2") in new stack
  -- Executing [s@google-in:3] SendDTMF("Gtalk/+17607058888-d417", "1") in new stack
  -- Executing [s@google-in:4] Dial("Gtalk/+17607058888-d417", "SIP/101,20,D(:1)") in new stack
== Using SIP RTP CoS mark 5
[Aug 20 20:36:41] WARNING[27059]: acl.c:708 ast_ouraddrfor: Cannot connect
[Aug 20 20:36:41] WARNING[27059]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
  -- Called SIP/101
[Aug 20 20:36:41] WARNING[27034]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
[Aug 20 20:36:42] WARNING[27034]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
[Aug 20 20:36:44] WARNING[27034]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
== Spawn extension (google-in, s, 4) exited non-zero on 'Gtalk/+17607058888-d417'
[Aug 20 20:36:48] WARNING[27034]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
[Aug 20 20:36:56] WARNING[27034]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
[Aug 20 20:37:12] WARNING[27034]: chan_sip.c:3349 __sip_xmit: sip_xmit of 0x9b3bb20 (len 892) to 0.0.0.101:5060 returned -1: Invalid argument
[Aug 20 20:37:13] WARNING[27034]: chan_sip.c:3620 retrans_pkt: Retransmission timeout reached on transmission 7b0e2ef22c3e8660699c921c665c1c93@127.0.0.1:5060 for seqno 102 (Critical Request) -- See https://wiki.asterisk.org/wiki/display/AST/SIP+Retransmissions
Packet timed out after 32000ms with no response

I could see the XMPP stanzas arriving, and it turned out to be a dialplan problem. Rather, I had specified a SIP address in my dialplan that didn’t exist. As I’m re-discovering after 9 years away from Asterisk, most of the problems are with your dialplan.

So now that inbound and outbound works via my Google Voice number (which itself is pretty fucking cool), back to the SIP registration problem.

Getting Cisco 7940G Working as a SIP Device

Supposedly, Asterisk 1.8.6.0-rc1 contains the following patch, to insert the proper IP in the Via header. But that didn’t work right away. I tried a bunch of other patches, none of which did the trick. So I decided to upgrade the firmware on the phones.

Before:

Cisco Systems, Inc. Copyright 2000-2004
Cisco IP phone  MAC: 0000:0000:0000
Loadid:  SW: P0S3-06-3-00  ARM: PAS3ARM1  Boot: PC030301  DSP: PS03AT38

After:

Cisco Systems, Inc. Copyright 2000-2005
Cisco IP phone  MAC: 0000:0000:0000
Loadid:  SW: P0S3-8-12-00  ARM: PAS3ARM1  Boot: PC030301  DSP: 4.0(5.0)[A0]

And there’s a lot of bullshit written out there about what files the phone will try to retrieve via TFTP, most of which appears to be incorrect. After the flash to v8 here’s what the 7940G retrieved, where the string of zeros represents the hardware address of the handset.

Aug 21 00:29:59 box in.tftpd[28275]: RRQ from 192.168.1.6 filename CTLSEP000000000000.tlv
Aug 21 00:29:59 box in.tftpd[28276]: RRQ from 192.168.1.6 filename SEP000000000000.cnf.xml
Aug 21 00:30:00 box in.tftpd[28277]: RRQ from 192.168.1.6 filename P0S3-8-12-00.loads
Aug 21 00:30:21 box in.tftpd[28278]: RRQ from 192.168.1.6 filename SIPDefault.cnf
Aug 21 00:30:21 box in.tftpd[28279]: RRQ from 192.168.1.6 filename ./SIP000000000000.cnf

After the upgrade to v8, SIP registration succeeded. Believe me, that’s a lot easier that the rigamarole that I went through…

Asterisk Configuration Files

All of the relevant configuration files follow, half from the Asterisk documentation and half from Mario’s Adventures in Geekery. I especially like how numbers are dialed automatically after a pause, similar to a land-line phone… compared to many VOIP phones where you have to explicitly tell them to dial. Options in all CAPS have been sanitized and should be tailored to your specific install; note that while the configuration lists @gmail.com as the account name, you can use your Google Apps account without any problem.

sip.conf

[office]
type=friend
host=dynamic
secret=PASSWORD
callerid="Office <104>"
context=outbound

[alex]
type=friend
host=dynamic
secret=PASSWORD
callerid="Alex <102>"
context=outbound

[soft1]
type=friend
host=dynamic
secret=PASSWORD
callerid="Soft Phone 1 <101>"
context=outbound

jabber.conf

[general]
autoregister=yes

[google_apps_alex]
type=client
serverhost=talk.google.com
username=ACCOUNTNAME@gmail.com/RESOURCE_NAME
secret=PASSWORD
port=5222
status=xaway
statusmessage="Danger, Will Robinson..."
usetls=yes
usesasl=yes
timeout=100

gtalk.conf

[general]
context=google-in
bindaddr=0.0.0.0
allowguests=yes
externip=EXTERNAL_IP
allowguest=yes

[gtalk-alex]
username=ACCOUNTNAME@gmail.com
disallow=all
allow=ulaw
context=google-in
connection=google_apps_alex

[guest]
disallow=all
allow=ulaw

extensions.conf

[general]
static=yes
writeprotect=no
clearglobalvars=no

[globals]
CONSOLE=Console/dsp                             ; Console interface for demo
IAXINFO=guest                                   ; IAXtel username/password
TRUNK=DAHDI/G2                                  ; Trunk interface
TRUNKMSD=1                                      ; MSD digits to strip (usually 1 or 0)

[ani]
exten => _X.,40000(ani),NoOp(ANI: ${EXTEN})
exten => _X.,n,Wait(0.25)
exten => _X.,n,Answer()
exten => _X.,n,Playback(vm-from)
exten => _X.,n,SayDigits(${CALLERID(ani)})
exten => _X.,n,Wait(1.25)
exten => _X.,n,SayDigits(${CALLERID(ani)})      ; playback again in case of missed digit
exten => _X.,n,Return()

[default]
exten => s,1,Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})})
exten => s,n,Dial(SIP/soft1,10)
exten => s,n, Hangup
exten => 101, 1, Dial(SIP/soft1, 10)
exten => 102, 1, Dial(SIP/alex, 10)
exten => 104, 1, Dial(SIP/office, 10)
include => ani
exten => 778,1,Gosub(ani)
exten => 778,n,Hangup()

[google-in]
exten => ACCOUNTNAME@gmail.com, 1, GotoIf(${DB_EXISTS(gv_dialout/channel)}?bridged)
exten => ACCOUNTNAME@gmail.com, n, NoOp(Callerid  ${CALLERID(name)})
exten => ACCOUNTNAME@gmail.com, n, Set(CALLERID(num)=${SHIFT(CALLERID(name),@)})
exten => ACCOUNTNAME@gmail.com, n, Set(CALLERID(name)=${DB(cidname/${CALLERID(num)})})
exten => ACCOUNTNAME@gmail.com, n, Dial(SIP/alex&SIP/office, 180, D(:1))
exten => ACCOUNTNAME@gmail.com, n(bridged),Bridge(${DB_DELETE(gv_dialout/channel)}, p)

[outbound]
include => seven-digit
include => local-devices
include => tollfree
include => talk-gmail-outbound
include => talk-numeric-outbound
include => dial-uri

[local-devices]
exten => _2, 1, Dial(SIP/alex,10)
exten => 102, 1, Dial(SIP/alex,10)
exten => _4, 1, Dial(SIP/office,10)
exten => 104, 1, Dial(SIP/office,10)

[tollfree]
exten => _1800NXXXXXX,1,Dial(Gtalk/gtalk_alex/${EXTEN}@voice.google.com)
exten => _1888NXXXXXX,1,Dial(Gtalk/gtalk_alex/${EXTEN}@voice.google.com)
exten => _1877NXXXXXX,1,Dial(Gtalk/gtalk_alex/${EXTEN}@voice.google.com)
exten => _1866NXXXXXX,1,Dial(Gtalk/gtalk_alex/${EXTEN}@voice.google.com)

[seven-digit]
exten => _NXXXXXX,1,Set(CALLERID(dnid)=1410${CALLERID(dnid)})
exten => _NXXXXXX,n,Goto(1410${EXTEN},1)
exten => _NXXNXXXXXX,1,Set(CALLERID(dnid)=1${CALLERID(dnid)})
exten => _NXXNXXXXXX,n,Goto(1${EXTEN},1)

[talk-gmail-outbound]
exten => _[a-z].@gmail.com,1,Dial(Gtalk/gtalk_alex/${EXTEN}@gmail.com)
exten => _[A-Z].@gmail.com,1,Dial(Gtalk/gtalk_alex/${EXTEN}@gmail.com)

[talk-numeric-outbound]
exten => _1NXXNXXXXXX,1,Dial(Gtalk/gtalk_alex/${EXTEN}@voice.google.com)
exten => _+1NXXNXXXXXX,1,Dial(Gtalk/gtalk_alex/${EXTEN}@voice.google.com)

[gv-agi-outbound]
exten => _1NXXNXXXXXX,1,AGI(google-voice-dialout.agi)
exten => _+1NXXNXXXXXX,1,AGI(google-voice-dialout.agi)

[dial-uri]
exten => _[a-z].,1,Dial(SIP/${EXTEN}@${SIPDOMAIN},120,tr)
exten => _[A-Z].,1,Dial(SIP/${EXTEN}@${SIPDOMAIN},120,tr)
exten => _X.,1,Dial(SIP/${EXTEN}@${SIPDOMAIN},120,tr)

This dialplan technically allows you to call Google Talk users by dialing user@gmail.com, although I haven’t had time to play with it.

What Remains

The end result is that outbound calls are routed through Google Voice with correct ANI (verified with MCI’s 1-800-444-4444 service). Inbound calls to my Google Voice number are routed to two handsets, with proper caller ID being displayed.

In the future, we’ll be adding another Google Voice trunk for my roommate. Outbound calls from a third handset will be routed through their account, since Asterisk has no troubles connecting to numerous Jabber XMPP streams simultaneously. Inbound calls from that account’s telephone number will be routed solely to the roommate’s handset.

There are some other fun things that I discovered, to be documented soon.

In which life can be both a comedy and tragedy at the same time…

Just because things happen slow doesn’t mean you’ll be ready for them. If they happened fast, you’d be alert for all kinds of suddenness, aware that speed was trump. “Slow” works on an altogether different principle, on the deceptive impression that there’s plenty of time to prepare, which conceals the central fact, that no matter how slow things go, you’ll always be slower.

– Richard Russo, Empire Falls

Quote #20 - Good Qualities

Like most things, it takes time and careful feeding.

All good qualities must be sown and cultivated. We can’t expect to change overnight from an ordinary person into one with high realizations.

– Dalai Lama, via Twitter

Quote #19 - Research

Useful stuff, research…

Research tells us that fourteen out of any ten individuals like chocolate.

– Sandra Boynton

Recovery Time

It’s been a month. It feels strange, not because I haven’t been blogging, but because I haven’t written anything in that time.

To say I’ve been distracted lately wouldn’t be completely accurate. I haven’t been busy all the time, either. One of those periods where what the hell am I doing frequently crosses your mind; not dwelling on how things could have been, but an honest reflection upon life priorities. Between a few personal matters, some paper pushing, extra bills, clashing with company management, June has been a different sort of month.

That being said, I’m healthy. Fit, even. Still running and swimming on a regular basis, tracking both with dailymile. Expanding my social circle a little bit, with all the conversations and good meals that that entails.

There have been some crappy times, but I’m making an effort to get out there and do things. Keep moving, I think that’s the key.

Memorial Weekend Eats

This past weekend was non-stop rush of social events, good company, and amazing food. I love it when a bunch of people get together in a shared kitchen and cook for the group. No one sits idle for too long, everyone pitches in. It’s a good time, a great way to get to know people better, and of course the outcome is a happy stomach full of homemade food.

We made a medium-sized batch of MegaTots, which for the uninitiated is a casserole composed of tater tots, molten and shredded cheese, diced bacon, and ranch dressing.

MegaTots with Ranch Drizzle

Then there were the hand-formed beef/pork burgers, topped with shredded cheddar, bacon, and a homemade Memphis-style BBQ sauce.

Memphis BBQ Bacon Cheeseburger

Then there were hand-formed falafel patties, pan-fried in olive oil and served in a pita with hummus, cucumbers, and freshly made Tzatziki sauce.

Falafel Patties

And for the health-conscious there was roasted asparagus too!

Asparagus

And that was just last Sunday night…

I jumped out of this plane last Saturday afternoon.

The Plane

Include the pilot, the thing seats five. For my run, it was still fairly cramped with just me and my instructor. After a brief taxiing we took off, climbing quickly from the runway at Ridgely Airpark and into the clouds.

Taking Off Into Clouds

It took about ten minutes to get up to altitude, past the clouds, about 11,000 feet according to my altimeter. Last minute positioning and rigging complete, I wasn’t nervous. Just about the time I realized that we’d be falling through clouds and how cool that would be, the door opened. Go time.

My right leg out the door and my foot on the ledge above the landing gear, I wasn’t nervous. My right knee hanging over the open threshold, still wasn’t nervous. Arching my back and rolling out the door, there’s a brief period where the tiny little voice in the back of your head is thinking “oh shit, we’re falling.”

Surprisingly, panic doesn’t set in. The rush of adrenaline does. The ground becomes your sky. By the time you realize you’re falling, you’ve accelerated to near 120mph, but it doesn’t feel like falling. It isn’t like a roller coaster where you feel like your stomach was left on the 3rd loop. Despite the clouds disappearing as you pass, a frame of reference for your rate of descent just isn’t there (unless you watch your altimeter). The amount of wind and pressure on your body is similar to motorcycling, except that your entire body is affected at once, unprotected. It’s noisy. I don’t know if I was screaming or not, but I know was thinking “this is amazing” the whole time.

And then there’s a gentle tug like you’re being slowed a little and then you rotate forward into a seated position like you’re swinging on a swing at the playground. It wasn’t nearly as jerky as I expected. You look up and there’s a deployed parachute. Excellent.

A few minutes of deep carving turns and you descend to the ground at a much slower pace (about 10-15 feet/second), watching the horizon and sights below.

Why do it?

To get over your fear for starters, but more importantly for the experience itself. Skydiving is a singularly unique experience that can’t be duplicated on the ground, especially the free-fall. Arms out and gazing down at the Earth getting closer, free-fall is a beautiful thing; an amazing way to look at the world below.

After I completed the 2011 Warrior Dash in Maryland, I saw a guy with a head-mounted video camera. As it turns out, he filmed his entire run through the Mechanicsville course. He sped it up a little bit in post, so the video is less than 15 minutes (per YouTube’s rule). No sound, but all of the obstacles and dirty mud are there.

The nastiest point for me was probably around 6:30 on his video, the under-the-room mud crawl.

Also, another cut-together video of course highlights. Not the whole thing, but a little less bumpy.

Thanks for sharing, guys!

The mud at Budds Creek smells like crap. Literally. It’s nauseating and when you take a dive and end up covered in the stuff from the neck down, the only thing to do is flail your arms and keep running.

I’ve got to hand it to the designers, the 2011 Warrior Dash in Maryland was the hardest 5K that I’ve ever run. Now granted the course was a little different than advertised; there was no rappelling line, drifting logs, or a scrap yard, but amazing nevertheless. It may not seem like a lot of obstacles, but the map doesn’t show how much of the time you’re running through water or mud. Now I knew there would be mud, but I had no idea how hilly the course was. I like hills. I do well on hills. But man, there were a lot of hills.

Downhill to the Finish

Backing up a bit, the Warrior Dash is a 5K race. Actually an entire series of races, held across the country, where not a single step is taken on pavement. In additional to the varied natural terrain which could include woods, water, and mud, the organizers add man-made obstacles for participants to navigate, like cargo nets…

Cargo Net

…and even some made-made natural obstacles, like fire.

Over the Fire

And it’s supposed to be messy. Very messy.

Under the Barbed Wire

So messy, in fact, that most people elect to get hosed down afterwards.

Getting Clean

And since most of our shoes are completely unusable for anything after the event, we donate them to GreenSneakers.

A Big Pile of Shoes

Afterwards, we hung out for a bit on the field. There’s beer, turkey legs, as well as a surprisingly good band called Whitehouse Effect. We couldn’t have asked for a more perfect day, sunny and upper 70’s, with a light breeze from time to time.

One note, this event was extremely well organized. Parking was a snap. There wasn’t a race packet mailed to us beforehand, but packet pickup took less than three minutes. Less the first couple hundred yards, the staggered waves made for short waits at most of the obstacles. Plenty of room on the field. No lines for food or beer. Plenty of toilets, too. Bottom line, the people at Red Frog Events have got this thing down to a science; it shows and it was much appreciated.

Next time around I’d be sure to bring a few things to better enjoy the post-race festivities: a picnic blanket, extra towels, a cooler full of Gatorade and water, some collapsible camp chairs, sunscreen, clean sunglasses, a better camera, and maybe one of those little pop-up gazebo/canopy things.

As neat as the post-race festival is, I think the most fun is checking out other people’s costumes; a saw a good selection of kilts, tutus, tuxedo shirts, and luau skirts, but the best I saw was the pack of Waldos. I think I’m going to wear a pin-stripe suit and jacket next year. Or perhaps organize a Pac-Man theme with a group, thinking about cherries, ghosts, a big yellow suit, and a lot of people making wuh-uh wuh-uh wuh-uh noises while they run around the course.

I’m still smiling thinking about the day.

To be honest, it wouldn’t surprise me if the organizers collected a bunch of the cow turds from the farm next door and mixed it in with that mud. It was that pungent.

Amazon recently started using LaserShip to deliver DVDs to customers, resulting in absurdly fast delivery to Prime members. Electing for standard two-day shipping, I received my last order 19 hours after placing it.

On Thursday I placed an order around 10pm. Around 2am Friday I received a notification from Amazon saying that my order had been shipped. By 5pm the package was delivered to my door.

This is the second or third time in the past month or two that I’ve noticed the use of LaserShip for movies. As Andrew Tanenbaum said, “never underestimate the bandwidth of a station wagon full of tapes hurtling down the highway.” The same is true for Blu-ray discs, hurtling toward you from a nearby Amazon distribution facility.

Older Posts »