shill: Transition Cellular's state to Registered when the modem is registered.
Also, process GSM network technology types and roaming states and update the
Cellular service appropriately.
BUG=chromium-os:19676
TEST=unit tests, tested on device
Change-Id: I6606a01a07cf635cb344aef95c3145eaf2290fba
Reviewed-on: http://gerrit.chromium.org/gerrit/6768
Reviewed-by: Darin Petkov <petkov@chromium.org>
Tested-by: Darin Petkov <petkov@chromium.org>
diff --git a/cellular.cc b/cellular.cc
index 272f863..22dc67c 100644
--- a/cellular.cc
+++ b/cellular.cc
@@ -139,6 +139,10 @@
activation_state(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
prl_version(0) {}
+Cellular::GSM::GSM()
+ : registration_state(MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN),
+ access_technology(MM_MODEM_GSM_ACCESS_TECH_UNKNOWN) {}
+
Cellular::Cellular(ControlInterface *control_interface,
EventDispatcher *dispatcher,
Manager *manager,
@@ -227,8 +231,29 @@
string Cellular::GetNetworkTechnologyString() const {
switch (type_) {
case kTypeGSM:
- // TODO(petkov): Implement this.
- NOTIMPLEMENTED();
+ if (gsm_.registration_state == MM_MODEM_GSM_NETWORK_REG_STATUS_HOME ||
+ gsm_.registration_state == MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING) {
+ switch (gsm_.access_technology) {
+ case MM_MODEM_GSM_ACCESS_TECH_GSM:
+ case MM_MODEM_GSM_ACCESS_TECH_GSM_COMPACT:
+ // TODO(petkov): Add "GSM" to system_api:service_constants.h.
+ return "GSM";
+ case MM_MODEM_GSM_ACCESS_TECH_GPRS:
+ return flimflam::kNetworkTechnologyGprs;
+ case MM_MODEM_GSM_ACCESS_TECH_EDGE:
+ return flimflam::kNetworkTechnologyEdge;
+ case MM_MODEM_GSM_ACCESS_TECH_UMTS:
+ return flimflam::kNetworkTechnologyUmts;
+ case MM_MODEM_GSM_ACCESS_TECH_HSDPA:
+ case MM_MODEM_GSM_ACCESS_TECH_HSUPA:
+ case MM_MODEM_GSM_ACCESS_TECH_HSPA:
+ return flimflam::kNetworkTechnologyHspa;
+ case MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS:
+ return flimflam::kNetworkTechnologyHspaPlus;
+ default:
+ NOTREACHED();
+ }
+ }
break;
case kTypeCDMA:
if (cdma_.registration_state_evdo !=
@@ -249,8 +274,14 @@
string Cellular::GetRoamingStateString() const {
switch (type_) {
case kTypeGSM:
- // TODO(petkov): Implement this.
- NOTIMPLEMENTED();
+ switch (gsm_.registration_state) {
+ case MM_MODEM_GSM_NETWORK_REG_STATUS_HOME:
+ return flimflam::kRoamingStateHome;
+ case MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING:
+ return flimflam::kRoamingStateRoaming;
+ default:
+ break;
+ }
break;
case kTypeCDMA: {
uint32 state = cdma_.registration_state_evdo;
@@ -419,8 +450,9 @@
}
void Cellular::GetGSMProperties() {
- // TODO(petkov): Implement this.
- NOTIMPLEMENTED();
+ // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
+ gsm_.access_technology = gsm_network_proxy_->AccessTechnology();
+ VLOG(2) << "GSM AccessTechnology: " << gsm_.access_technology;
}
void Cellular::RegisterGSMModem() {
@@ -463,8 +495,15 @@
}
void Cellular::GetGSMRegistrationState() {
- // TODO(petkov): Implement this.
- NOTIMPLEMENTED();
+ CHECK_EQ(kTypeGSM, type_);
+ // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
+ ModemGSMNetworkProxyInterface::RegistrationInfo info =
+ gsm_network_proxy_->GetRegistrationInfo();
+ gsm_.registration_state = info._1;
+ gsm_.network_id = info._2;
+ gsm_.operator_name = info._3;
+ VLOG(2) << "GSM Registration: " << gsm_.registration_state << ", "
+ << gsm_.network_id << ", " << gsm_.operator_name;
}
void Cellular::HandleNewRegistrationState() {
@@ -502,6 +541,8 @@
}
service_->set_network_tech(network_tech);
service_->set_roaming_state(GetRoamingStateString());
+ // TODO(petkov): For GSM, update the serving operator based on the network id
+ // and the mobile provider database.
}
void Cellular::GetModemSignalQuality() {
@@ -727,8 +768,11 @@
void Cellular::OnGSMRegistrationInfoChanged(uint32 status,
const string &operator_code,
const string &operator_name) {
- // TODO(petkov): Implement this.
- NOTIMPLEMENTED();
+ CHECK_EQ(kTypeGSM, type_);
+ gsm_.registration_state = status;
+ gsm_.network_id = operator_code;
+ gsm_.operator_name = operator_name;
+ HandleNewRegistrationState();
}
void Cellular::OnGSMSignalQualityChanged(uint32 quality) {
diff --git a/cellular.h b/cellular.h
index da5d5f8..6d1fa1d 100644
--- a/cellular.h
+++ b/cellular.h
@@ -117,18 +117,6 @@
DISALLOW_COPY_AND_ASSIGN(Network);
};
- struct CDMA {
- CDMA();
-
- uint32 registration_state_evdo;
- uint32 registration_state_1x;
- uint32 activation_state;
-
- uint16 prl_version;
- std::string payment_url;
- std::string usage_url;
- };
-
struct SimLockStatus {
public:
SimLockStatus() : retries_left(0) {}
@@ -177,21 +165,44 @@
FRIEND_TEST(CellularTest, Connect);
FRIEND_TEST(CellularTest, GetCDMAActivationStateString);
FRIEND_TEST(CellularTest, GetCDMAActivationErrorString);
+ FRIEND_TEST(CellularTest, GetCDMANetworkTechnologyString);
FRIEND_TEST(CellularTest, GetCDMARegistrationState);
+ FRIEND_TEST(CellularTest, GetCDMARoamingStateString);
FRIEND_TEST(CellularTest, GetCDMASignalQuality);
+ FRIEND_TEST(CellularTest, GetGSMNetworkTechnologyString);
+ FRIEND_TEST(CellularTest, GetGSMRoamingStateString);
FRIEND_TEST(CellularTest, GetModemInfo);
FRIEND_TEST(CellularTest, GetModemStatus);
- FRIEND_TEST(CellularTest, GetNetworkTechnologyString);
- FRIEND_TEST(CellularTest, GetRoamingStateString);
FRIEND_TEST(CellularTest, GetStateString);
FRIEND_TEST(CellularTest, GetTypeString);
FRIEND_TEST(CellularTest, InitProxiesCDMA);
FRIEND_TEST(CellularTest, InitProxiesGSM);
FRIEND_TEST(CellularTest, StartConnected);
FRIEND_TEST(CellularTest, StartCDMARegister);
- FRIEND_TEST(CellularTest, StartGSM);
+ FRIEND_TEST(CellularTest, StartGSMRegister);
FRIEND_TEST(CellularTest, StartLinked);
+ struct CDMA {
+ CDMA();
+
+ uint32 registration_state_evdo;
+ uint32 registration_state_1x;
+ uint32 activation_state;
+
+ uint16 prl_version;
+ std::string payment_url;
+ std::string usage_url;
+ };
+
+ struct GSM {
+ GSM();
+
+ uint32 registration_state;
+ uint32 access_technology;
+ std::string network_id;
+ std::string operator_name;
+ };
+
static const char kPhoneNumberCDMA[];
static const char kPhoneNumberGSM[];
@@ -290,6 +301,7 @@
scoped_ptr<ModemGSMNetworkProxyInterface> gsm_network_proxy_;
CDMA cdma_;
+ GSM gsm_;
CellularServiceRefPtr service_;
diff --git a/cellular_unittest.cc b/cellular_unittest.cc
index ba84506..043acbf 100644
--- a/cellular_unittest.cc
+++ b/cellular_unittest.cc
@@ -239,7 +239,7 @@
EXPECT_EQ("CellularTypeCDMA", device_->GetTypeString());
}
-TEST_F(CellularTest, GetNetworkTechnologyString) {
+TEST_F(CellularTest, GetCDMANetworkTechnologyString) {
device_->type_ = Cellular::kTypeCDMA;
EXPECT_EQ("", device_->GetNetworkTechnologyString());
device_->cdma_.registration_state_evdo =
@@ -254,7 +254,41 @@
device_->GetNetworkTechnologyString());
}
-TEST_F(CellularTest, GetRoamingStateString) {
+TEST_F(CellularTest, GetGSMNetworkTechnologyString) {
+ device_->type_ = Cellular::kTypeGSM;
+ EXPECT_EQ("", device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_GSM;
+ EXPECT_EQ("", device_->GetNetworkTechnologyString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_HOME;
+ // TODO(petkov): Define "GSM" in system_api:service_constants.h.
+ EXPECT_EQ("GSM", device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_GSM_COMPACT;
+ EXPECT_EQ("GSM", device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_GPRS;
+ EXPECT_EQ(flimflam::kNetworkTechnologyGprs,
+ device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_EDGE;
+ EXPECT_EQ(flimflam::kNetworkTechnologyEdge,
+ device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_UMTS;
+ EXPECT_EQ(flimflam::kNetworkTechnologyUmts,
+ device_->GetNetworkTechnologyString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_HSDPA;
+ EXPECT_EQ(flimflam::kNetworkTechnologyHspa,
+ device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_HSUPA;
+ EXPECT_EQ(flimflam::kNetworkTechnologyHspa,
+ device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_HSPA;
+ EXPECT_EQ(flimflam::kNetworkTechnologyHspa,
+ device_->GetNetworkTechnologyString());
+ device_->gsm_.access_technology = MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS;
+ EXPECT_EQ(flimflam::kNetworkTechnologyHspaPlus,
+ device_->GetNetworkTechnologyString());
+}
+
+TEST_F(CellularTest, GetCDMARoamingStateString) {
device_->type_ = Cellular::kTypeCDMA;
EXPECT_EQ(flimflam::kRoamingStateUnknown, device_->GetRoamingStateString());
device_->cdma_.registration_state_evdo =
@@ -279,6 +313,21 @@
EXPECT_EQ(flimflam::kRoamingStateRoaming, device_->GetRoamingStateString());
}
+TEST_F(CellularTest, GetGSMRoamingStateString) {
+ device_->type_ = Cellular::kTypeGSM;
+ EXPECT_EQ(flimflam::kRoamingStateUnknown, device_->GetRoamingStateString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_HOME;
+ EXPECT_EQ(flimflam::kRoamingStateHome, device_->GetRoamingStateString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
+ EXPECT_EQ(flimflam::kRoamingStateRoaming, device_->GetRoamingStateString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING;
+ EXPECT_EQ(flimflam::kRoamingStateUnknown, device_->GetRoamingStateString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED;
+ EXPECT_EQ(flimflam::kRoamingStateUnknown, device_->GetRoamingStateString());
+ device_->gsm_.registration_state = MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE;
+ EXPECT_EQ(flimflam::kRoamingStateUnknown, device_->GetRoamingStateString());
+}
+
TEST_F(CellularTest, GetStateString) {
EXPECT_EQ("CellularStateDisabled",
device_->GetStateString(Cellular::kStateDisabled));
@@ -355,7 +404,7 @@
EXPECT_EQ(flimflam::kRoamingStateHome, device_->service_->roaming_state());
}
-TEST_F(CellularTest, StartGSM) {
+TEST_F(CellularTest, StartGSMRegister) {
device_->type_ = Cellular::kTypeGSM;
static const char kNetwork[] = "My Favorite GSM Network";
device_->selected_network_ = kNetwork;
@@ -363,9 +412,20 @@
EXPECT_CALL(*gsm_network_proxy_, Register(kNetwork)).Times(1);
EXPECT_CALL(*simple_proxy_, GetStatus())
.WillOnce(Return(DBusPropertiesMap()));
+ EXPECT_CALL(*gsm_network_proxy_, AccessTechnology())
+ .WillOnce(Return(MM_MODEM_GSM_ACCESS_TECH_EDGE));
EXPECT_CALL(*proxy_, GetInfo()).WillOnce(Return(ModemProxyInterface::Info()));
+ ModemGSMNetworkProxyInterface::RegistrationInfo reg_info;
+ reg_info._1 = MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING;
+ EXPECT_CALL(*gsm_network_proxy_, GetRegistrationInfo())
+ .WillOnce(Return(reg_info));
device_->Start();
- EXPECT_EQ(Cellular::kStateEnabled, device_->state_);
+ dispatcher_.DispatchPendingEvents();
+ EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
+ ASSERT_TRUE(device_->service_.get());
+ EXPECT_EQ(flimflam::kNetworkTechnologyEdge,
+ device_->service_->network_tech());
+ EXPECT_EQ(flimflam::kRoamingStateRoaming, device_->service_->roaming_state());
}
TEST_F(CellularTest, StartConnected) {
@@ -522,8 +582,8 @@
TEST_F(CellularTest, Connect) {
Error error;
EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
- .WillOnce(Return(true))
- .WillOnce(Return(true));
+ .Times(2)
+ .WillRepeatedly(Return(true));
device_->state_ = Cellular::kStateConnected;
device_->Connect(&error);
EXPECT_EQ(Error::kAlreadyConnected, error.type());
diff --git a/mock_modem_gsm_network_proxy.h b/mock_modem_gsm_network_proxy.h
index 633f25f..ebf6bd6 100644
--- a/mock_modem_gsm_network_proxy.h
+++ b/mock_modem_gsm_network_proxy.h
@@ -18,6 +18,8 @@
virtual ~MockModemGSMNetworkProxy();
MOCK_METHOD1(Register, void(const std::string &network_id));
+ MOCK_METHOD0(GetRegistrationInfo, RegistrationInfo());
+ MOCK_METHOD0(AccessTechnology, uint32());
private:
DISALLOW_COPY_AND_ASSIGN(MockModemGSMNetworkProxy);
diff --git a/modem_gsm_network_proxy.cc b/modem_gsm_network_proxy.cc
index 587cc0b..abbe710 100644
--- a/modem_gsm_network_proxy.cc
+++ b/modem_gsm_network_proxy.cc
@@ -23,6 +23,15 @@
proxy_.Register(network_id);
}
+ModemGSMNetworkProxyInterface::RegistrationInfo
+ModemGSMNetworkProxy::GetRegistrationInfo() {
+ return proxy_.GetRegistrationInfo();
+}
+
+uint32 ModemGSMNetworkProxy::AccessTechnology() {
+ return proxy_.AccessTechnology();
+}
+
ModemGSMNetworkProxy::Proxy::Proxy(ModemGSMNetworkProxyListener *listener,
DBus::Connection *connection,
const string &path,
diff --git a/modem_gsm_network_proxy.h b/modem_gsm_network_proxy.h
index 816ec7c..2a8df41 100644
--- a/modem_gsm_network_proxy.h
+++ b/modem_gsm_network_proxy.h
@@ -22,6 +22,8 @@
// Inherited from ModemGSMNetworkProxyInterface.
virtual void Register(const std::string &network_id);
+ virtual RegistrationInfo GetRegistrationInfo();
+ virtual uint32 AccessTechnology();
private:
class Proxy
diff --git a/modem_gsm_network_proxy_interface.h b/modem_gsm_network_proxy_interface.h
index 414042f..a461d46 100644
--- a/modem_gsm_network_proxy_interface.h
+++ b/modem_gsm_network_proxy_interface.h
@@ -8,6 +8,7 @@
#include <string>
#include <base/basictypes.h>
+#include <dbus-c++/types.h>
namespace shill {
@@ -15,9 +16,15 @@
// support. The interface is provided so that it can be mocked in tests.
class ModemGSMNetworkProxyInterface {
public:
+ typedef DBus::Struct<uint32, std::string, std::string> RegistrationInfo;
+
virtual ~ModemGSMNetworkProxyInterface() {}
virtual void Register(const std::string &network_id) = 0;
+ virtual RegistrationInfo GetRegistrationInfo() = 0;
+
+ // Properties.
+ virtual uint32 AccessTechnology() = 0;
};
// ModemManager.Modem.Gsm.Network signal listener to be associated with the