Monday, November 19, 2012

Mobile VoIP

The Nexus 4 is on backorder. But just because I have to stick with my iPhone 4 for the time being (#FirstWorldProblems) doesn't mean I have to stick with the $100/month AT&T bill. Described below is my journey transitioning my iPhone from AT&T to a combination of Google Voice and a low-priced T-Mobile monthly/no-contract plan.

Unlocking the iPhone 4

In order to use my iPhone with a carrier other than AT&T, I'd have to get it unlocked so that it wasn't tied to AT&T's network. It doesn't matter that it's a GSM/SIM-based phone. If you don't unlock it, trying to use another carrier's SIM will do nothing but get you a "this SIM is unsupported" nasty-gram from the phone. Unlocking is easy enough, with a few caveats:
  • AT&T won't unlock the phone unless you meet several requirements such as being a current AT&T customer and being off-contract.
  • You can use an online request form, but it can take up to 7 days to process. Why the delay? Who knows.
  • After you get the request approval notification, you'll have to plug the iPhone into iTunes and do a full Restore of iOS, at the end of which will be a sort of "Congratulations" message indicating a successful unlock. If you have a nearly full 16GB, the file coping alone will take forever. <Sigh> They can't just flip a setting somewhere?
  • Although you should be able to restore the phone settings (apps and otherwise) from a backup, it's been my experience that these restores never work quite right (app setting deleted here, another app missing there), so be sure to backup all important phone data before the restore wipes the phone.

Porting from AT&T to Google Voice

This was easy enough to perform online using guided forms on the Google Voice website. It can take up to 24 hours to complete the port, and text messages may not work for the ported number for a few days. Also, porting will close your AT&T account, so make sure you unlock your iPhone before porting. There is a one-time fee of $20 to port--plus another $20 if you want to keep your existing Google Voice number.

New T-Mobile Account

I ordered a SIM-only activation package from T-Mobile. Price shipped was 99-cents. Took about a week to arrive in the mail. Once it did, I gathered all the important numbers (activation code, SIM barcode, iPhone IMEI number, etc) and used the T-Mobile online activation process to create an account and choose a Monthly 4G plan. Pretty easy.

Google Voice

I had to add my new T-Mobile line to Google Voice as a forwarding phone. Not a problem, however, prepaid T-Mobile plans do not include call forwarding, that makes it impossible to forward T-Mobile voicemail to Google Voice voicemail. The only solution for this is to call (or online chat) T-Mo customer support and get them to completely deactivate voicemail forwarding. This will prevent unanswered calls from being routed to T-Mo voicemail, which is okay because Google Voice voicemail will catch it (eventually). As long as no one calls the T-Mo directly, there's no issue with this approach.


The Google Voice iOS app has an option in the settings called Call2Click. When active, it means that when dialing out, GV will call one of your forward numbers first, and then after you answer it will dial the outgoing number. This is what makes all the following options possible.

Option 1: Linphone + SIP + IPKall

T-Mobile has a $30/month, no-contract plan for 100 minutes/unlimited text/unlimited data (up to 5GB at 4G) that seems to be pretty popular among the hacker crowd. If you can live with VoIP, you do all your talking over wifi or cell data, and no minutes are used. One method of accomplishing this is to get

  • a SIP account
  • a SIP client application
  • a US phone number which routes to the SIP
There are many options for all the above, plenty of them free. It works like this... First, you get an SIP account (from, say, Then you get a phone number which routes to that account (from, say, Then you add the number as a forwarding phone in GV.

Then, install any of a number of SIP client applications (MicroSIP, linphone on iOS/Windows/Mac, etc). When your GV number is called, it routes all the way to your SIP client. To make an outgoing call, use the Google Voice callback feature (Call2Click) to ring your SIP number first and then connect to the dialed number.

Once it's all setup, it's simple to use. The downside to this setup is the call quality is highly variable, and--if poor--it can be near impossible to fix it. But you can't beat the price (free).

Option 2: Skype with Skype-In/Skype Number

If call quality with the SIP/IPKall option is subpar for your liking, consider using Skype. This ain't no mother's-basement telephony company; it's a big time player with teams of software gurus supporting it. However, that level of quality isn't free. Skype will run you $30/year for your own phone number (they say $60, but it's usually on sale) and $3/month for unlimited US calling. Hook the Skype number to GV and you've got the same solution as above.

Option 3: Cell Plan with More Minutes

If any of the above gets too funky, T-Mo has a $50/month unlimited voice/text/data plan (4G up to 2GB). No contract required, still fits nicely with GV integrations, still relatively cheap. However, also consider that overages on the $30 plan are $0.10 per minute, which still makes it a cheaper option than the $50/month plan if you can keep it under 300 minutes.

Sunday, October 7, 2012

Raspberry Pi Setup Notes

Finally took my Raspberry Pi out of the box:

Time to start messing around with it...
  • Going to start with the recommended Raspbian "Wheezy" build, though I'll probably give XBMC.
  • For OS storage, I picked-up a Microcenter-branded Adata 16 GB microSDHD class 10 for $11. (I went with microSD cause it's only a few bucks more and you get compatibility with cell phones/cameras/etc.)
  • Keyboard: check. Mouse: check. Monitor + HDMI: check. But after SSH and VNC servers are set-up, I'm booting the keyboard and mouse and reclaiming the USB ports for hard drives.
  • Probably going to skip adding a USB wifi-adapter and just keep it on the shelf next to the router.
  • I've got 3 mini-USB cables, but no micro-USB. So it looks like I'm off to Microcenter again.
  • All my legos are in a box in the bottom of a closet at my parent's house, so I guess I'll need to find my own case. Including tax and shipping from the UK: $15.47. Takes 5-12 business days, but until then...
  • The microSD card was a dud. Cheap electronics, why you so cheap? I'm going to return it to Microcenter, maybe trade it in for an actual name-brand SD card.
  • In the meantime, I had a 2GB mircoSD class 4 sitting in the bottom of my "wires & batteries" drawer just collecting dust. Turns out it works just fine with my RPi, though I'm only left with a few hundred MB of free space on the OS. Time will tell if that's enough...
  • Got a USB to micro-USB cord (3-ft., $10) that--when paired with a spare iPhone charger--works just fine to power the unit.
  • After a bit of reading, I think I'll give Raspbmc a try (as opposed to Xian or OpenELEC) because it maintains a relatively standard Debian base that will allow me to still use the RPi for other functions (NAS, iTunes server, backup scripts, etc.).

Sunday, September 16, 2012

Google Drive for iOS

Even with its latest update, Google Drive for iOS is still missing some essential features:
- I appreciate it took this long even to get one-at-a-time uploads, but it's really not a usable feature until you can select more than one at a time.
- You can share but you can't unshare? Seems like an oversight to me.
- There's still no "gallery" view of image thumbnails for folders containing images/photos.
- There is no apparent way to sort a folder by file size, date modified, etc.

Some of these features may actually be there, but the fact I can't find them still constitutes a need for improvement.

I'm optimistic Google will address these drawbacks. They always do.

Friday, August 3, 2012

Plugging the Holes in Linq-to-Entities

If you can do it in SQL, you should be able to do it with Linq-to-Entities, right? Trouble is, not everything in a Linq expression is directly translatable into SQL by Entity Framework. Well, not without some help...
Between the above techniques (especially the last one), you should be able to get entity to run just about anything.

Thursday, June 21, 2012

Custom Telerik MVC Grid Ajax Binding

Here's a code block demonstrating the manual sort/filter/paging of an ajax-bound Telerik MVC Grid request--it's handy for hook-ins of various flavors.

public ActionResult CustomBindingResult(IEnumerable items)
    int page = int.Parse(Request["page"]);
    int size = int.Parse(Request["size"]);
    string orderBy = Request["orderBy"];
    string groupBy = Request["groupBy"];
    string filter = Request["filter"];

    var list = items.ToList();
    var filtered = (IEnumerable)list.AsQueryable().ToGridModel(1, int.MaxValue, null, null, filter).Data;
    var results = (IEnumerable)filtered.AsQueryable().ToGridModel(page, size, orderBy, groupBy, null).Data;
    var data = results.Select(result => Activator.CreateInstance(typeof(TDestination), result));
    var model = new GridModel { Data = data, Total = filtered.Count() };
    return View(model);

Will need the Telerik.Web.Mvc.Extensions namespace.

Wednesday, June 13, 2012

Storing State in the Url Hash

It can be done. We have the technology.
function settingsToStorage(settings) {
    var s = [];
    $.each(settings, function (key, value) {
        s.push(key + "=" + encodeURIComponent(value));
    return s.join("&");

function settingsFromStorage(storage) {
    var settings = {};
    storage.replace(/[#&]+([^=&]+)=([^&]*)/gi, function (m, key, value) { settings[key] = decodeURIComponent(value); });
    return settings;

Thursday, June 7, 2012

HTTP Error 403.14 in IIS 7.5

I get this error the first time I try to set up IIS for local development on a new 64-bit Windows install.
Turns out, ASP.NET 4 isn't yet properly registered with IIS. To do so, run the following from an administrator-level command prompt:

%windir%\Microsoft.NET\Framework64\v4.0.30319\aspnet_regiis.exe -ir

Do the same for a 32-bit Windows install except with s/Framework64/Framework/.