shill: Make cellular Connect work for GSM networks.

Add the APN to the properties map passed to Connect.
Set up the list of APNs to try, and step through it when
a connect attempt fails with the InvalidApn error. The
order in which APNs are tried is

  - APN which most recently resulted in a successful
    connection on the current network
  - a user-specified APN, specified by setting the Cellular.APN
    property on the service
  - the list of APNs found for the home network provider in the
    mobile broadband provider database
  - if all those fail, a null APN

BUG=chromium-os:23259
TEST=manual testing, some of which involved modifying the
mobile provider DB to create invalid APN entries. Created
two new unit tests as well, and ran all unit tests.

Change-Id: I38c869228fe1aaf7421de8a826c54e7b62c209b2
Reviewed-on: https://gerrit.chromium.org/gerrit/19122
Tested-by: Eric Shienbrood <ers@chromium.org>
Reviewed-by: Jason Glasgow <jglasgow@chromium.org>
Commit-Ready: Eric Shienbrood <ers@chromium.org>
diff --git a/cellular_error.cc b/cellular_error.cc
index 2e3818a..ca404e3 100644
--- a/cellular_error.cc
+++ b/cellular_error.cc
@@ -20,6 +20,8 @@
     MM_MOBILE_ERROR(MM_ERROR_MODEM_GSM_SIMPINREQUIRED);
 static const char *kErrorSimPukRequired =
     MM_MOBILE_ERROR(MM_ERROR_MODEM_GSM_SIMPUKREQUIRED);
+static const char *kErrorGprsNotSubscribed =
+    MM_MOBILE_ERROR(MM_ERROR_MODEM_GSM_GPRSNOTSUBSCRIBED);
 
 // static
 void CellularError::FromDBusError(const DBus::Error &dbus_error,
@@ -42,6 +44,8 @@
     type = Error::kPinRequired;
   else if (name == kErrorSimPukRequired)
     type = Error::kPinBlocked;
+  else if (name == kErrorGprsNotSubscribed)
+    type = Error::kInvalidApn;
   else
     type = Error::kOperationFailed;