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_gsm_unittest.cc b/cellular_capability_gsm_unittest.cc
index 5083736..c516ee9 100644
--- a/cellular_capability_gsm_unittest.cc
+++ b/cellular_capability_gsm_unittest.cc
@@ -18,6 +18,7 @@
#include "shill/mock_metrics.h"
#include "shill/mock_modem_gsm_card_proxy.h"
#include "shill/mock_modem_gsm_network_proxy.h"
+#include "shill/mock_profile.h"
#include "shill/nice_mock_control.h"
using base::Bind;
@@ -617,4 +618,71 @@
EXPECT_EQ(kRetries, capability_->sim_lock_status_.retries_left);
}
+TEST_F(CellularCapabilityGSMTest, SetupApnTryList) {
+ static const string kTmobileApn("epc.tmobile.com");
+ static const string kLastGoodApn("remembered.apn");
+ static const string kLastGoodUsername("remembered.user");
+ static const string kSuppliedApn("my.apn");
+
+ SetService();
+ capability_->imsi_ = "310240123456789";
+ InitProviderDB();
+ capability_->SetHomeProvider();
+ DBusPropertiesMap props;
+ capability_->SetupConnectProperties(&props);
+ EXPECT_FALSE(props.find(flimflam::kApnProperty) == props.end());
+ EXPECT_EQ(kTmobileApn, props[flimflam::kApnProperty].reader().get_string());
+
+ ProfileRefPtr profile(new NiceMock<MockProfile>(
+ &control_, reinterpret_cast<Manager *>(NULL)));
+ cellular_->service()->set_profile(profile);
+ Stringmap apn_info;
+ apn_info[flimflam::kApnProperty] = kLastGoodApn;
+ apn_info[flimflam::kApnUsernameProperty] = kLastGoodUsername;
+ cellular_->service()->SetLastGoodApn(apn_info);
+ props.clear();
+ EXPECT_TRUE(props.find(flimflam::kApnProperty) == props.end());
+ capability_->SetupConnectProperties(&props);
+ // We expect the list to contain the last good APN, plus
+ // the 4 APNs from the mobile provider info database.
+ EXPECT_EQ(5, capability_->apn_try_list_.size());
+ EXPECT_FALSE(props.find(flimflam::kApnProperty) == props.end());
+ EXPECT_EQ(kLastGoodApn, props[flimflam::kApnProperty].reader().get_string());
+ EXPECT_FALSE(props.find(flimflam::kApnUsernameProperty) == props.end());
+ EXPECT_EQ(kLastGoodUsername,
+ props[flimflam::kApnUsernameProperty].reader().get_string());
+
+ Error error;
+ apn_info.clear();
+ props.clear();
+ apn_info[flimflam::kApnProperty] = kSuppliedApn;
+ // Setting the APN has the side effect of clearing the LastGoodApn,
+ // so the try list will have 5 elements, with the first one being
+ // the supplied APN.
+ cellular_->service()->SetApn(apn_info, &error);
+ EXPECT_TRUE(props.find(flimflam::kApnProperty) == props.end());
+ capability_->SetupConnectProperties(&props);
+ EXPECT_EQ(5, capability_->apn_try_list_.size());
+ EXPECT_FALSE(props.find(flimflam::kApnProperty) == props.end());
+ EXPECT_EQ(kSuppliedApn, props[flimflam::kApnProperty].reader().get_string());
+
+ apn_info.clear();
+ props.clear();
+ apn_info[flimflam::kApnProperty] = kLastGoodApn;
+ apn_info[flimflam::kApnUsernameProperty] = kLastGoodUsername;
+ // Now when LastGoodAPN is set, it will be the one selected.
+ cellular_->service()->SetLastGoodApn(apn_info);
+ EXPECT_TRUE(props.find(flimflam::kApnProperty) == props.end());
+ capability_->SetupConnectProperties(&props);
+ // We expect the list to contain the last good APN, plus
+ // the user-supplied APN, plus the 4 APNs from the mobile
+ // provider info database.
+ EXPECT_EQ(6, capability_->apn_try_list_.size());
+ EXPECT_FALSE(props.find(flimflam::kApnProperty) == props.end());
+ EXPECT_EQ(kLastGoodApn, props[flimflam::kApnProperty].reader().get_string());
+ EXPECT_FALSE(props.find(flimflam::kApnUsernameProperty) == props.end());
+ EXPECT_EQ(kLastGoodUsername,
+ props[flimflam::kApnUsernameProperty].reader().get_string());
+}
+
} // namespace shill