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_capability.h b/cellular_capability.h
index cde66eb..105e119 100644
--- a/cellular_capability.h
+++ b/cellular_capability.h
@@ -38,6 +38,10 @@
   static const int kTimeoutRegister;
   static const int kTimeoutScan;
 
+  static const char kConnectPropertyApn[];
+  static const char kConnectPropertyApnUsername[];
+  static const char kConnectPropertyApnPassword[];
+  static const char kConnectPropertyHomeOnly[];
   static const char kConnectPropertyPhoneNumber[];
   static const char kPropertyIMSI[];
 
@@ -134,6 +138,8 @@
 
   static void OnUnsupportedOperation(const char *operation, Error *error);
 
+  virtual void OnConnectReply(const ResultCallback &callback,
+                              const Error &error);
   // Run the next task in a list.
   // Precondition: |tasks| is not empty.
   void RunNextStep(CellularTaskList *tasks);
@@ -165,6 +171,7 @@
   FRIEND_TEST(CellularCapabilityTest, FinishEnable);
   FRIEND_TEST(CellularCapabilityTest, GetModemInfo);
   FRIEND_TEST(CellularCapabilityTest, GetModemStatus);
+  FRIEND_TEST(CellularCapabilityTest, TryApns);
   FRIEND_TEST(CellularServiceTest, FriendlyName);
   FRIEND_TEST(CellularTest, StartCDMARegister);
   FRIEND_TEST(CellularTest, StartConnected);
@@ -192,8 +199,6 @@
   virtual void OnGetModemStatusReply(const ResultCallback &callback,
                                      const DBusPropertiesMap &props,
                                      const Error &error);
-  virtual void OnConnectReply(const ResultCallback &callback,
-                              const Error &error);
   virtual void OnDisconnectReply(const ResultCallback &callback,
                                  const Error &error);