shill: Retry calls to proxy's GetIMSI

After unlocking a SIM, it takes some time for the SIM to be
ready to respond to the GetIMSI request.  The amount of time
is unknown.  This change adds retry logic to retry the GetIMSI
request every 200 ms up to 10 times.

BUG=chromium-os:31866
TEST=On a lumpy, unlock SIM and verify that modem becomes enabled.
Run all unit tests.

Change-Id: I7c9fea3f14e05aa9873d86eaf9221fd121ddb4ac
Reviewed-on: https://gerrit.chromium.org/gerrit/29120
Reviewed-by: mukesh agrawal <quiche@chromium.org>
Commit-Ready: Gary Morain <gmorain@chromium.org>
Tested-by: Gary Morain <gmorain@chromium.org>
diff --git a/cellular_capability_gsm.cc b/cellular_capability_gsm.cc
index 016e288..bb14966 100644
--- a/cellular_capability_gsm.cc
+++ b/cellular_capability_gsm.cc
@@ -47,6 +47,10 @@
 const char CellularCapabilityGSM::kPropertyUnlockRequired[] = "UnlockRequired";
 const char CellularCapabilityGSM::kPropertyUnlockRetries[] = "UnlockRetries";
 
+const int CellularCapabilityGSM::kGetIMSIRetryLimit = 10;
+const int64 CellularCapabilityGSM::kGetIMSIRetryDelayMilliseconds = 200;
+
+
 CellularCapabilityGSM::CellularCapabilityGSM(Cellular *cellular,
                                              ProxyFactory *proxy_factory)
     : CellularCapabilityClassic(cellular, proxy_factory),
@@ -54,6 +58,8 @@
       registration_state_(MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN),
       access_technology_(MM_MODEM_GSM_ACCESS_TECH_UNKNOWN),
       home_provider_(NULL),
+      get_imsi_retries_(0),
+      get_imsi_retry_delay_milliseconds_(kGetIMSIRetryDelayMilliseconds),
       scanning_(false),
       scan_interval_(0) {
   SLOG(Cellular, 2) << "Cellular capability constructed: GSM";
@@ -135,6 +141,7 @@
                           weak_ptr_factory_.GetWeakPtr(), cb));
   tasks->push_back(Bind(&CellularCapabilityGSM::GetIMEI,
                         weak_ptr_factory_.GetWeakPtr(), cb));
+  get_imsi_retries_ = 0;
   tasks->push_back(Bind(&CellularCapabilityGSM::GetIMSI,
                         weak_ptr_factory_.GetWeakPtr(), cb));
   tasks->push_back(Bind(&CellularCapabilityGSM::GetSPN,
@@ -865,10 +872,21 @@
     SLOG(Cellular, 2) << "IMSI: " << imsi;
     imsi_ = imsi;
     SetHomeProvider();
+    callback.Run(error);
   } else {
-    SLOG(Cellular, 2) << "GetIMSI failed - " << error;
+    if (get_imsi_retries_++ < kGetIMSIRetryLimit) {
+      SLOG(Cellular, 2) << "GetIMSI failed - " << error << ". Retrying";
+      base::Callback<void(void)> retry_get_imsi_cb =
+          Bind(&CellularCapabilityGSM::GetIMSI,
+               weak_ptr_factory_.GetWeakPtr(), callback);
+      cellular()->dispatcher()->PostDelayedTask(
+          retry_get_imsi_cb,
+          get_imsi_retry_delay_milliseconds_);
+    } else {
+      LOG(INFO) << "GetIMSI failed - " << error;
+      callback.Run(error);
+    }
   }
-  callback.Run(error);
 }
 
 void CellularCapabilityGSM::OnGetSPNReply(const ResultCallback &callback,