iDevelopSoftware

Simplicity and Clarity by Design

App Definition Statement for Count’em UP

Toward the end of March I am teaching an introductory class in iOS development. Unlike lots of classes that focus on one API after another, my approach is to walk the students through the creation of a meaningful (dare I say real) application over the course of 2 1/2 days. As we go step-by-step through the process of creating the application the students will be developing skills that will serve as a foundation for further independant learning. As a bonus, by the end of the course the students will have a fully working application on their phone to show their friends.

For the class I needed a meaningful example application. My idea was to build an application that manages one or more counters. The first things I needed were a description for the idea and a graphic designer to assist with turning that idea into something interesting and fun to build. I wrote up an App Definition Statement to describe the application and searched on behance.net to hire a graphic designer for the project.

What is an App Definition Statement?

Apple recommends that you create what they refer to as an App Definition Statement to describe each new app you want to build. As described in the iOS Human Interface Guidelines, “An app definition statement is a concise, concrete declaration of an app’s main purpose and its intended audience. Create an app definition statement early in your development effort to help you turn an idea and a list of features into a coherent product that people want to own. Throughout development, use the definition statement to decide if potential features and behaviors make sense.”

Count’em UP App Definition Statement

The application will let the user easily perform manual counting of many different things. There are apps like this in the store already so its not an original idea. The idea is easy for developers to understand and most of their focus will be on learning iOS development.

The goal is to teach the students to work through the whole process of building an iOS application. They will be exposed to the process of building something that follows the graphical and interaction design as spec’d by a professional designer. I’m not just trying to teach the students to build “programmer interfaces” in iOS applications. I want to show them how to build beautiful and functional applications. By the end of the class the students will have an app that they can show their friends and be proud of having built.

The application will have an overview screen where you can see all of your counters in a colorful display. Perhaps something similar to Static or StatNut. Counters could be grouped together and assigned a group name. Each group could have a separate overview screen where the individual counter names and values are summarized. Swipe left/right on overview screens to get at different sets of counters. Tap on a counter’s “tile” to open up the details of that counter.

Counters would have a name, type and be assigned a color. Depending on the type there might be other properties too.

Counting up or down might be done using a gesture (swipe up/down) and also by tapping on a + or - button. Switching between counters might be handled by swiping left/ right. It might be fun to include some sound effects that play on increment, decrement, reset and when a major boundary is crosses (every 10 counts, for example). The counters are all stored in the user’s iCloud account so they sync between iOS devices.

Counter Type: Simple

This is an integer counter. It has a starting value and a step increment. The counter can be reset manually.

Counter Type: Target / Goal

This is an integer counter, like the simple counter. The difference is you also set a goal and the counter displays how close to the goal you are. It might be used to track how many times you went to the gym this month. This counter type might auto-reset on a specific date, or might reset manually.

Counter Type: Elapsed Time

This counter tracks how much time has elapsed. It is basically a stop watch with a name. The timer can only be started, stopped and reset. When stopped the timer can be started again to continue measuring time. This might be used to measure the number of minutes a player is on the field in a youth soccer game. One counter can be setup for each of the players on the team.

Example Use Case

Youth soccer coach could setup counters to track game play. - One elapsed time counter for each player on the team. - One simple counter for team goal count. - One simple counter for opponent goal count. - A way to reset the group of counters should be provided to make it easy to “zero out” before a game. - When a player is on the field start his/her elapsed time counter. - When a player is taken off the field stop his/her elapsed time counter. - When a goal is scored increment the team goal count for the scoring team

Announcing iOS Weekend - Introduction to iOS Development

Join me Friday, March 22, 2013 as we kick off the first iOS Weekend of 2013. (http://www.iosweekend.com)

The focus is on helping you develop practical skills building mobile applications for iOS by building a real application over a weekend. At iOS Weekend you won’t get bogged down in mindless study of API calls or every little detail of Objective-C. What you will do is build a real application from start to finish. By the time you leave Sunday evening you will have an app running on your phone that you can be proud of.

This course is an introduction to iOS development. You will learn how to build applications using Xcode, iOS and the UIKit framework. You will have a better appreciation of how developers build iOS applications, having built one yourself once you complete the class. The full process for turning ideas into mobile applications sold through the Apple iTunes Store will be discussed.

You will build an iPhone application called “Count’em UP” over the course of 2 1/2 days. The class is 100% hands-on development with class size kept to a minimum so there will be plenty of one-on-one assistance as you work through the class exercises. Using guided demonstrations and a mix of follow-along exercises and hands-on experimentation you will see “Count’em UP” come to life.

You will receive a complete design specification for the application on the first day of the class. This will include some user stories, wireframe models from a graphic designer, pixel-perfect Photoshop files, all design elements (icons, font, color and animation specifications) and an object-model diagram to get you started. Here’s a short video illustrating what you can expect. (http://files.iosweekend.com/movies/Counters_revisions.mp4)

This course will be valuable if you are a …

  • Professional developer wishing to transition from desktop or web development to mobile development.
  • Graphic designer wishing to get a better understanding of mobile application development for iOS.
  • Product managers responsible for delivering iOS applications and wishing to understand what it takes to go live in the Apple iTunes Store.
  • Entreprenuar with and idea who is planning to build a minimally viable product (MVP).
  • Hobbyist curious about how to build applications for iOS.

Hope to see you there!

Comcast Support Problems - SURFboard SBG6580 - Intermittent Connection Loss

Last night I finally got fed up with the frequent momentary disconnects that I was experiencing with Comcast. The cable modem/gateway device I have is a Motorola SURFboard SBG6580. I purchased this modem from Amazon after researching which models were supported by Comcast using the information on this page. Device details are available here. It is important to note that this is a currently supported option for connecting to the Comcast network.

Here is some information about the modem, as reported by accessing the web interface to the modem.

Standard Specification Compliant   DOCSIS 3.0
Hardware Version    1
Software Version    SBG6580-3.1.0.0-GA-07-180-NOSH
Cable Modem MAC Address ff:ff:ff:ff:ff:ff
Cable Modem Serial Number   324369118008466559530006
CM certificate  Installed

Looking in the logs of my gateway device I noticed a number of critical error messages. Below is an excerpt of the logs currently on my device. One of the errors that comes up repeatedly is a T3 time-out. If you run google searches on this you will learn that many Comcast subscribers (and other cable providers too) see this error in conjunction with intermittent disconnects from their service.

I have reproduced the log of errors from the modem at the bottom of this post.

After a lot of reading of forum posts on http://forums.comcast.com I have learned that many people have similar issues.

What all of these have in common is that after repeated suggestions from Comcast that it was a modem issue or an in-house wiring issue, and after customers in some cases spent money to swap out hardware, none of that helped to resolve the issue. The issue is most likely something upstream of the house, but other possibilities exist too.

Some have suggested that the firmware on this model is very old (and riddled with bugs) and that Motorola has made a number of updates to the firmware. You can read an interesting thread about trying to get the firmware upgraded here.

I found references to the following firmware versions being available from Motorola to the carriers.

  • SBG6580-3.2.1.0-GA-02-249-NOSH
  • SBG6580-3.3.0.0-GA-06-022-NOSH

Every networking device except a basic switch or hub has firmware in it that can be field upgraded. Most knowledgable customers are aware of this and have probably done at least one firmware upgrade of a networking device. The Motorola SURFboard 6580 is no different. The firmware can be upgraded. The problem is, Motorola will not provide the firmware to end consumers. Here is a support document from Motorola about their cable modems and the policies about firmware upgrades. To quote,

We apologize about the inconvenience, but your Motorola modem does not support manual upgrades. Motorola is not allowed to control the upgrades of DOCSIS devices, per the standards specification. Any firmware or software changes must be implemented via the cable network. Your cable provider can update the firmware based on what they have approved for their network distribution. Because of that Motorola is not capable of installing firmware for cable modems. Please contact the cable operator to obtain information on upgrading firmware on the cable modem.

Repeated calls to Comcast Customer Service (1-800-XFINITY / 1-800-934-6489) got me no where. I spent approximately two hours on the phone with them. I was disconnected three times, had it suggested to me that the problem was the modem multiple times and was offered the option of paying them for Signature Support, but at no time were they able to actually provide me with updated firmware for the modem.

  • They were able to remotely reset the modem.
  • They studied the connection history and noted that indeed the line had been failing intermittently.
  • They were not at all interested in the content of the log messages I shared below.
  • They could not offer any explanation for the log messages.

In summary, they were no help what so ever.

After reading about lack of firmware upgrades and my experience with their customer service folks I began to question whether Comcast Cares(™) about subscribers at all.

I wonder how many Comcast subscribers have similar problems with intermittent connection loss and just live with it. A survey of forum posts on their own site seems to indicate that the issues are wide spread.

This is truly a terrible situation. Customers purchase devices that Comcast recommends and then when something goes wrong with the service they place all of the blame on the in-house equipment and offer no support what so ever. The cable service providers have things structured such that consumers cannot get support for the devices from the manufacturers because that is the “service agreement” between the manufacturers and cable providers. Customers get squeezed in the middle without any recourse.

According to another site there are known problems with the Motorola SURFboard, especially with VOIP. I suspect these problems could be addressed with a firmware update, but we have already established that Comcast is in no mood to provide the necessary updates.

As a last-ditch effort I am now going to place the SURFboard SBG6580 into bridge mode and use a separate router. I found instructions for doing this on Anthony Volodkin’s blog, here. I will use my Apple AirPort Extreme (which Apple happily provides firmware updates for) as my router.

In a few days/weeks I will post a follow-up to let people know if this solved the intermittent connection loss problems.


 TLV-11 - unrecognized OID;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Resetting the cable modem due to docsDevResetNow 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 No Ranging Response received - T3 time-out  
 REG RSP not received;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; 
 No Ranging Response received - T3 time-out
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; 
 No Ranging Response received - T3 time-out  
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; 
 No Ranging Response received - T3 time-out  
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; 
 No Ranging Response received - T3 time-out  
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire QAM/QPSK symbol timing;;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to acquire FEC framing;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:00:00:00:00:00;CM-QOS=1.0;CM-VER=3.0; 
 Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 SYNC Timing Synchronization failure - Failed to receive MAC SYNC frame within time-out period;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Started Unicast Maintenance Ranging - No Response received - T3 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 Received Response to Broadcast Maintenance Request, But no Unicast Maintenance opportunities received - T4 time out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.1;CM-VER=3.0; 
 No Ranging Response received - T3 time-out  
 No Ranging Response received - T3 time-out  
 No Maintenance Broadcasts for Ranging opportunities received - T2 time-out;CM-MAC=ff:ff:ff:ff:ff:ff;CMTS-MAC=00:01:5c:24:f1:45;CM-QOS=1.0;CM-VER=3.0; 
 No Ranging Response received - T3 time-out    

Capturing AirPort Extreme Log With Lion Server Syslog

Mac OS X Lion Server can be used as a syslog server to capture the log messages from an Apple AirPort Extreme wireless router. The instructions below walk you through setting this up.

Syslog is controlled by a plist file found in the launch daemons directory. The full path to the file is:

/System/Library/LaunchDaemons/com.apple.syslogd.plist

You need to edit this file to add a network listener. The plist is stored in a binary format so you need to use the plutil to convert it to XML using this command:

$ pushd /System/Library/LaunchDaemons
$ sudo plutil -convert xml1 /System/Library/LaunchDaemons/com.apple.syslogd.plist
$ sudo vim /System/Library/LaunchDaemons/com.apple.syslogd.plist
$ sudo plutil -convert binary1 /System/Library/LaunchDaemons/com.apple.syslogd.plist
$ sudo launchctl unload /System/Library/LaunchDaemons/com.apple.syslogd.plist
$ sudo launchctl load /System/Library/LaunchDaemons/com.apple.syslogd.plist

Here is a complete example of the modified plist file. The new key is the NetworkListener. Be sure you add it nested inside the Sockets key or it will not work.

Once you have updated the plist the next step is to update the configuration of your AirPort Extreme. Under Applications => Utilities open the AirPort Utility and connect to your AirPort Extreme. On the Advanced tab select the “Logging & Statistics” panel. Enter the IP address of your Mac OS X Lion Server in “Syslog Destination Address:” and select “6 – Informational” for the “Syslog Level:”. You can see a screenshot of the AirPort Utility settings below. Update the settings on the AirPort Extreme.

AirPort Extreme Advanced Configuration

Now, you probably want to verify that the logging is actually happening. Open Console.app on your server and look at “All Messages”. While looking at the logs go to another machine (I used my MacBook Air with a wireless connection to the AirPort Extreme) and open System Preferences and then Network. Select your network adapter and ask for it to renew the DHCP lease. You should see some activity in the log.

Another way to verify the logging is to turn wifi off on your laptop. You should see a message like this:

8/9/11 8:43:09.000 AM 80211: Disassociated with station 60:33:4b:2c:de:c0

When you turn wifi back on you will see something similar to this:

8/9/11 8:43:10.000 AM 80211: Rotated TKIP group key.
8/9/11 8:43:21.000 AM 80211: Associated with station 60:33:4b:2c:de:c0
8/9/11 8:43:21.000 AM 80211: Authenticating station 60:33:4b:2c:de:c0 to RADIUS.
8/9/11 8:43:21.000 AM 80211: Installed unicast CCMP key for supplicant 60:33:4b:2c:de:c0
8/9/11 8:43:21.000 AM natpmp: Binding added for udp, 173.164.164.17:32770 to 10.0.1.104:4500 with lifetime 7200
8/9/11 8:43:21.000 AM natpmp: Binding added for udp, 173.164.164.17:32771 to 10.0.1.104:5353 with lifetime 7200

That’s it. You now have syslog data being captured on your Mac OS X Lion server from your AirPort Extreme base station!

Cookbook: Snow Leopard, RVM, Ruby on Rails

Recently I decided to clear out my RVM environments and start fresh. I’m running on a Snow Leopard MacBook Air. Here are the steps I went through.

$ curl -O ftp://ftp.cwru.edu/pub/bash/readline-6.0.tar.gz
$ tar xvf readline-6.0.tar.gz
$ cd readline-6.0
$ ./config && make && sudo make install
$ cd ..
$ rm -rf $HOME/.rvm
$ bash < <(curl -s https://rvm.beginrescueend.com/install/rvm)
$ rvm install 1.8.7 -C --with-arch=x86_64, --with-readline-dir=/usr/local
$ rvm system
$ rvm gemset export system.gems
$ rvm 1.8.7
$ rvm gemset import system
$ rvm --default 1.8.7

The following pages were helpful in figuring this out.

How I Setup Ubuntu 11.04 Server Using VirtualBox on a MacBook Air

Download and install the latest version of VirtualBox from http://www.virtualbox.org. As I write this article the current version is 4.1.

Download the Ubuntu 11.04 Server .ISO file from http://www.ubuntu.com. I first tried the 64-bit version but it seems that VirtualBox has trouble with it. The 32-bit version worked just fine, and for the sort of development tasks I am planning it will be okay so I didn’t look any further into why the 64-bit version failed to install.

Create a new virtual machine. I called mine “ubuntu-11.04″. This one will be used as a basis for other machines I clone.  I went with 512MB of RAM and 40GB of hard drive space, making sure that the hard drive was configured to grow dynamically.  I accepted all of the default settings during the installation process. I did not install any additional packages at this stage.  Since I plan on using Vagrant (http://vagrantup.com) to manage my virtual machines I chose to name this machine ubuntu and gave it a user name of “Vagrant Manager” with a login of “vagrant” and a password of “vagrant”.

Shutdown the virtual machine and then create a snapshot (I called mine “Fresh Install”).

You are now ready to create a clone of this machine and start playing around.  Right-click on the virtual machine you just created and select “Clone…” from the context menu.  Give your new virtual machine a unique name and be sure to check the “Reinitialize the MAC address of all network cards” option. I assigned the name “vagrant-ubuntu-natty” since that is in keeping with the conventions mentioned on the Vagrant site. I choose to only clone the current machine state.

Boot up the new virtual machine once the clone operation completes.  Log in using vagrant/vagrant.  You will now need to correct issues with the ethernet drivers.  Basically, when you asked VirtualBox to reinitialize the MAC addresses it caused the operating system to no longer recognize the virtual ethernet adapter hardware.  The steps to correct this are:

sudo rm /etc/udev/rules.d/70-persistent-net.rules
sudo service udev restart
sudo shutdown -r now

By running these three commands your virtual machine will be reconfigured to now recognize the new virtual ethernet adapters with their reinitialized MAC addresses.

Now you can proceed to install the VirtualBox Guest Additions software.  Start by updating the Ubuntu software using these commands:

sudo apt-get update
sudo apt-get -y upgrade
sudo apt-get -y install linux-headers-$(uname -r)
sudo apt-get -y install dkms
sudo shutdown -r now

At this point you are actually ready to do the installation of the Guest Additions. From the Devices menu in VirtualBox select the “Install Guest Additions…” menu item. This will “insert” the CD containing the guest additions software into the virtual machine.Now, from your virtual machine run the following commands.

sudo mkdir /tmp/cdrom
sudo mount /dev/cdrom /tmp/cdrom
cd /tmp/cdrom
sudo ./VBoxLinuxAdditions.run

Note, the installation of the Window System drivers will fail. This is okay; remember, we are running the server variant of Ubuntu and don’t have any of the windowing system components installed.

Now change the hostname for the system so it can be used as a Vagrant base box.

sudo hostname vagrant-ubuntu-natty.vagrantup.com

Edit the /etc/hosts file and change the second line where localhost is defined. Set the fully qualified domain name for the host and the short name for the host.

Edit the /etc/hostname file and replace “ubuntu” with “vagrant-ubuntu-natty”.

Edit the /etc/resolv.conf file and replace the domain and search values with “vagrantup.com”.

Reboot the machine once more using

sudo shutdown -r now

It is now time to setup the rest of the required software on the guest in order for it to be used as a Vagrant base box.

Start by editing /etc/sudoers using

sudo vim /etc/sudoers

Add or change the line giving sudo access to administrators to read as follows:

%admin ALL=NOPASSWD: ALL

Add the following line right after the “Defaults env_reset” line:

Defaults env_keep="SSH_AUTH_SOCK"

Run the command:

sudo /etc/init.d/sudo restart

Now setup the software Vagrant relies upon to provide all it’s goodness.

sudo apt-get install -y ruby-dev
sudo apt-get install -y rubygems
sudo apt-get install -y puppet
sudo apt-get install -y chef
sudo gem install chef
sudo apt-get install -y openssh-server openssh-client

When installing the chef package (above) you will be prompted for the URL of the Chef server. Just press enter here and ignore that step. We are only interested in chef-solo, and this URL is only used by chef-client. The package installer will go ahead and configure the chef client to run automatically. We now need to disable this by running the following command:

sudo /usr/sbin/update-rc.d chef-client disable

Edit the file /etc/ssh/sshd_config and add the following line (case matters here):

UseDNS no

Configure a secure key pair for our new Vagrant base box by running the following command on the host system.

ssh-keygen -P "" -t rsa -C "Some meaningful comment" -f ./vagrant-id_rsa

This command will create two files in the local directory called vagrant-id_rsa and vagrant-id_rsa.pub.  You will need to copy vagrant-id_rsa.pub into the ~/.ssh/authorized_keys file on the guest system. To do this you will need to setup port forwarding between the host and guest. The first step is to learn what the IP address of the host and guest systems are.  Use the following command to view the network adapters that are configured on each system:

ifconfig

Run this on both the host and guest. Once you know both IP addresses you need to add a port forwarding rule in Virtual Box for the SSH port. This is done by selecting the “Settings…” menu item from the “Machine” menu.  Once you have the settings dialog box open select the “Network” button and then open the “Advanced” section.  You will see a button labeled “Port Forwarding”. Press it to open the port forwarding rule editor. Here you need to create a rule as follows:

Name: SSH
Protocol: TCP
Host IP: <fill in host IP address from ifconfig>
Host Port: 9999
Guest IP: <fill in guest IP address from ifconfig>
Guest Port: 22

Close the panel and dismiss the settings dialog box. You should now have a port open between the host and the guest for SSH/SCP.  To verify this, enter the following command in a terminal window on the host system.

ssh -p 9999 vagrant@<host ip address>

When prompted for a password enter “vagrant”. You should now be in an ssh session on the guest system. If this worked you are ready to propogate the public key generated earlier. You can exit out of the SSH session now by typing exit in the guest. Back on the host type the following command to copy the public key.

cat vagrant-id_rsa.pub | ssh -p 9999 vagrant@<host ip address> 'sh -c "cat - >>~/.ssh/authorized_keys"'

You will be prompted for the guest password. Type “vagrant” again. You will now want to test that the key propogated successfully. On the host system enter the following commands.

ssh-add ./vagrant-id_rsa
ssh -p 9999 vagrant@<host ip address>

If everything worked in the earlier steps you should be in an SSH session on the guest without the need to enter your password!

As a final step before packaging a vagrant base box you should clean things up in the guest by running the following commands:

sudo apt-get clean
sudo apt-get autoclean

You are now ready to package the vagrant base box. Back on the host system in a terminal window first create a Vagrantfile that points to the SSH private key. Here is an example of what it might look like if you decide to copy your key (generated earlier). Call this file Vagrantfile.pkg.

Vagrant::Config.run do |config|
  config.ssh.private_key_path = "lcl-vagrant-id_rsa"
end

Now invoke this command in the terminal window to create the package.

vagrant package --base vagrant-ubuntu-natty --include lcl-vagrant-id_rsa --vagrantfile Vagrantfile.pkg

The packaging takes a little while. Once it completes you should test the base box using these steps:

mv package.box vagrant-ubuntu-natty.box
vagrant box add lclbase32 vagrant-ubuntu-natty.box
mkdir test_environment
cd test_environment
vagrant init lclbase32
vagrant up
vagrant ssh

If all went well you are now finished with building a Vagrant base box. Congratulations!