blob: 35bb40306ee7159b3cd639bc16acae129f4b7d7d [file] [log] [blame]
Thieu Le3426c8f2012-01-11 17:35:11 -08001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masoneb925cc82011-06-22 15:39:57 -07002// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "shill/cellular.h"
6
Darin Petkov0828f5f2011-08-11 10:18:52 -07007#include <sys/socket.h>
8#include <linux/if.h>
9#include <linux/netlink.h> // Needs typedefs from sys/socket.h.
10
Eric Shienbrood9a245532012-03-07 14:20:39 -050011#include <base/bind.h>
Chris Masoneb925cc82011-06-22 15:39:57 -070012#include <chromeos/dbus/service_constants.h>
Darin Petkovbec79a22011-08-01 14:47:17 -070013#include <mm/mm-modem.h>
Darin Petkov137884a2011-10-26 18:52:47 +020014#include <mobile_provider.h>
Chris Masoneb925cc82011-06-22 15:39:57 -070015
Darin Petkovae0c64e2011-11-15 15:50:27 +010016#include "shill/cellular_capability_cdma.h"
Jason Glasgow82f9ab32012-04-04 14:27:19 -040017#include "shill/cellular_capability_classic.h"
Darin Petkov184c54e2011-11-15 12:44:39 +010018#include "shill/cellular_capability_gsm.h"
Darin Petkovd9661952011-08-03 16:25:42 -070019#include "shill/cellular_service.h"
Darin Petkov4d6d9412011-08-24 13:19:54 -070020#include "shill/error.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070021#include "shill/event_dispatcher.h"
Thieu Le37b90032012-05-15 15:18:41 -070022#include "shill/mock_cellular_service.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070023#include "shill/mock_device_info.h"
Darin Petkov77cb6812011-08-15 16:19:41 -070024#include "shill/mock_dhcp_config.h"
25#include "shill/mock_dhcp_provider.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070026#include "shill/mock_manager.h"
Thieu Le3426c8f2012-01-11 17:35:11 -080027#include "shill/mock_metrics.h"
Darin Petkovbec79a22011-08-01 14:47:17 -070028#include "shill/mock_modem_cdma_proxy.h"
Darin Petkov975b5e72011-08-30 11:48:08 -070029#include "shill/mock_modem_gsm_card_proxy.h"
Darin Petkova1e0a1c2011-08-25 15:08:33 -070030#include "shill/mock_modem_gsm_network_proxy.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070031#include "shill/mock_modem_proxy.h"
Darin Petkove604f702011-07-28 15:51:17 -070032#include "shill/mock_modem_simple_proxy.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070033#include "shill/mock_rtnl_handler.h"
Darin Petkov3335b372011-08-22 11:05:32 -070034#include "shill/nice_mock_control.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070035#include "shill/property_store_unittest.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070036#include "shill/proxy_factory.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070037
Eric Shienbrood9a245532012-03-07 14:20:39 -050038using base::Bind;
39using base::Unretained;
Darin Petkovc0865312011-09-16 15:31:20 -070040using std::map;
Chris Masoneb925cc82011-06-22 15:39:57 -070041using std::string;
Eric Shienbrood7fce52c2012-04-13 19:11:02 -040042using std::vector;
Darin Petkovbec79a22011-08-01 14:47:17 -070043using testing::_;
Chris Masoneb9c00592011-10-06 13:10:39 -070044using testing::AnyNumber;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050045using testing::Invoke;
Darin Petkov0828f5f2011-08-11 10:18:52 -070046using testing::NiceMock;
Darin Petkove604f702011-07-28 15:51:17 -070047using testing::Return;
Darin Petkovbec79a22011-08-01 14:47:17 -070048using testing::SetArgumentPointee;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050049using testing::Unused;
Chris Masoneb925cc82011-06-22 15:39:57 -070050
51namespace shill {
52
Eric Shienbrood9a245532012-03-07 14:20:39 -050053MATCHER(IsSuccess, "") {
54 return arg.IsSuccess();
55}
56
Gary Morainbaeefdf2012-04-30 14:53:35 -070057MATCHER(IsFailure, "") {
58 return arg.IsFailure();
59}
60
Darin Petkov0828f5f2011-08-11 10:18:52 -070061class CellularPropertyTest : public PropertyStoreTest {
62 public:
63 CellularPropertyTest()
Chris Masone2176a882011-09-14 22:29:15 -070064 : device_(new Cellular(control_interface(),
Darin Petkov0828f5f2011-08-11 10:18:52 -070065 NULL,
66 NULL,
Thieu Le3426c8f2012-01-11 17:35:11 -080067 NULL,
Darin Petkove9d12e02011-07-27 15:09:37 -070068 "usb0",
Chris Masone626719f2011-08-18 16:58:48 -070069 "00:01:02:03:04:05",
Darin Petkove9d12e02011-07-27 15:09:37 -070070 3,
Ben Chan3ecdf822012-08-06 12:29:23 -070071 Cellular::kTypeCDMA,
Darin Petkov0828f5f2011-08-11 10:18:52 -070072 "",
Darin Petkov137884a2011-10-26 18:52:47 +020073 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040074 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070075 NULL,
76 ProxyFactory::GetInstance())) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -070077 virtual ~CellularPropertyTest() {}
Darin Petkove9d12e02011-07-27 15:09:37 -070078
Chris Masoneb925cc82011-06-22 15:39:57 -070079 protected:
Darin Petkov0828f5f2011-08-11 10:18:52 -070080 DeviceRefPtr device_;
Chris Masoneb925cc82011-06-22 15:39:57 -070081};
82
Darin Petkov0828f5f2011-08-11 10:18:52 -070083TEST_F(CellularPropertyTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -070084 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
85 EXPECT_FALSE(device_->store().Contains(""));
Chris Masoneb925cc82011-06-22 15:39:57 -070086}
87
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080088TEST_F(CellularPropertyTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -070089 {
90 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080091 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -070092 device_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -070093 flimflam::kCellularAllowRoamingProperty,
94 PropertyStoreTest::kBoolV,
95 &error));
96 }
Chris Masonea8a2c252011-06-27 22:16:30 -070097 // Ensure that attempting to write a R/O property returns InvalidArgs error.
98 {
99 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800100 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
101 flimflam::kAddressProperty,
102 PropertyStoreTest::kStringV,
103 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700104 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700105 }
106 {
107 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800108 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
109 flimflam::kCarrierProperty,
110 PropertyStoreTest::kStringV,
111 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700112 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700113 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700114}
115
Darin Petkov0828f5f2011-08-11 10:18:52 -0700116class CellularTest : public testing::Test {
117 public:
118 CellularTest()
Thieu Le3426c8f2012-01-11 17:35:11 -0800119 : manager_(&control_interface_, &dispatcher_, &metrics_, &glib_),
120 device_info_(&control_interface_, &dispatcher_, &metrics_, &manager_),
Darin Petkov77cb6812011-08-15 16:19:41 -0700121 dhcp_config_(new MockDHCPConfig(&control_interface_,
Paul Stewartd408fdf2012-05-07 17:15:57 -0700122 kTestDeviceName)),
Ben Chan3ecdf822012-08-06 12:29:23 -0700123 create_gsm_card_proxy_from_factory_(false),
124 proxy_(new MockModemProxy()),
125 simple_proxy_(new MockModemSimpleProxy()),
126 cdma_proxy_(new MockModemCDMAProxy()),
127 gsm_card_proxy_(new MockModemGSMCardProxy()),
128 gsm_network_proxy_(new MockModemGSMNetworkProxy()),
129 proxy_factory_(this),
130 provider_db_(NULL),
Darin Petkov0828f5f2011-08-11 10:18:52 -0700131 device_(new Cellular(&control_interface_,
132 &dispatcher_,
Thieu Le3426c8f2012-01-11 17:35:11 -0800133 &metrics_,
Darin Petkov0828f5f2011-08-11 10:18:52 -0700134 &manager_,
Darin Petkov77cb6812011-08-15 16:19:41 -0700135 kTestDeviceName,
Chris Masone626719f2011-08-18 16:58:48 -0700136 kTestDeviceAddress,
Darin Petkov0828f5f2011-08-11 10:18:52 -0700137 3,
138 Cellular::kTypeGSM,
139 kDBusOwner,
Jason Glasgowa585fc32012-06-06 11:04:09 -0400140 kDBusService,
Darin Petkov137884a2011-10-26 18:52:47 +0200141 kDBusPath,
Ben Chan3ecdf822012-08-06 12:29:23 -0700142 NULL,
143 &proxy_factory_)) {}
Darin Petkov137884a2011-10-26 18:52:47 +0200144
145 virtual ~CellularTest() {
146 mobile_provider_close_db(provider_db_);
147 provider_db_ = NULL;
148 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700149
150 virtual void SetUp() {
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700151 static_cast<Device *>(device_)->rtnl_handler_ = &rtnl_handler_;
Darin Petkov77cb6812011-08-15 16:19:41 -0700152 device_->set_dhcp_provider(&dhcp_provider_);
Chris Masone2ae797d2011-08-23 20:41:00 -0700153 EXPECT_CALL(manager_, device_info()).WillRepeatedly(Return(&device_info_));
Chris Masoneb9c00592011-10-06 13:10:39 -0700154 EXPECT_CALL(manager_, DeregisterService(_)).Times(AnyNumber());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700155 }
156
157 virtual void TearDown() {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500158 device_->DestroyIPConfig();
Darin Petkovfb0625e2012-01-16 13:05:56 +0100159 device_->state_ = Cellular::kStateDisabled;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500160 device_->capability_->ReleaseProxies();
Darin Petkov77cb6812011-08-15 16:19:41 -0700161 device_->set_dhcp_provider(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700162 }
163
Eric Shienbrood9a245532012-03-07 14:20:39 -0500164 void InvokeEnable(bool enable, Error *error,
165 const ResultCallback &callback, int timeout) {
166 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500167 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500168 void InvokeGetSignalQuality(Error *error,
169 const SignalQualityCallback &callback,
170 int timeout) {
171 callback.Run(kStrength, Error());
172 }
173 void InvokeGetModemStatus(Error *error,
174 const DBusPropertyMapCallback &callback,
175 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500176 DBusPropertiesMap props;
177 props["carrier"].writer().append_string(kTestCarrier);
178 props["unknown-property"].writer().append_string("irrelevant-value");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500179 callback.Run(props, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500180 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500181 void InvokeGetModemInfo(Error *error, const ModemInfoCallback &callback,
182 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500183 static const char kManufacturer[] = "Company";
184 static const char kModelID[] = "Gobi 2000";
185 static const char kHWRev[] = "A00B1234";
186 ModemHardwareInfo info;
187 info._1 = kManufacturer;
188 info._2 = kModelID;
189 info._3 = kHWRev;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500190 callback.Run(info, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500191 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500192 void InvokeGetRegistrationState1X(Error *error,
193 const RegistrationStateCallback &callback,
194 int timeout) {
195 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
196 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
197 Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500198 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500199 void InvokeGetIMEI(Error *error, const GSMIdentifierCallback &callback,
200 int timeout) {
201 callback.Run(kIMEI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500202 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500203 void InvokeGetIMSI(Error *error, const GSMIdentifierCallback &callback,
204 int timeout) {
205 callback.Run(kIMSI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500206 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500207 void InvokeGetMSISDN(Error *error, const GSMIdentifierCallback &callback,
208 int timeout) {
209 callback.Run(kMSISDN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500210 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500211 void InvokeGetSPN(Error *error, const GSMIdentifierCallback &callback,
212 int timeout) {
Darin Petkova4ca3c32012-08-17 16:05:24 +0200213 callback.Run(kTestCarrierSPN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500214 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500215 void InvokeGetRegistrationInfo(Error *error,
216 const RegistrationInfoCallback &callback,
217 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500218 static const char kNetworkID[] = "22803";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500219 callback.Run(MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING,
220 kNetworkID, kTestCarrier, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500221 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500222 void InvokeRegister(const string &network_id,
223 Error *error,
224 const ResultCallback &callback,
225 int timeout) {
226 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500227 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500228 void InvokeGetRegistrationState(Error *error,
229 const RegistrationStateCallback &callback,
230 int timeout) {
231 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
232 MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
233 Error());
234 }
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400235 void InvokeGetRegistrationStateUnregistered(
236 Error *error,
237 const RegistrationStateCallback &callback,
238 int timeout) {
239 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
240 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
241 Error());
Arman Uguray539c4232012-09-11 10:00:22 -0700242 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500243 void InvokeConnect(DBusPropertiesMap props, Error *error,
244 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400245 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500246 callback.Run(Error());
247 }
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400248 void InvokeConnectFail(DBusPropertiesMap props, Error *error,
Thieu Leb5954a22012-05-18 10:37:34 -0700249 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400250 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
251 callback.Run(Error(Error::kNotOnHomeNetwork));
252 }
Thieu Leb5954a22012-05-18 10:37:34 -0700253 void InvokeConnectFailNoService(DBusPropertiesMap props, Error *error,
254 const ResultCallback &callback, int timeout) {
255 device_->service_ = NULL;
256 callback.Run(Error(Error::kNotOnHomeNetwork));
257 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500258 void InvokeDisconnect(Error *error, const ResultCallback &callback,
259 int timeout) {
260 if (!callback.is_null())
261 callback.Run(Error());
262 }
Arman Uguray539c4232012-09-11 10:00:22 -0700263 void InvokeDisconnectFail(Error *error, const ResultCallback &callback,
264 int timeout) {
265 error->Populate(Error::kOperationFailed);
266 if (!callback.is_null())
267 callback.Run(*error);
268 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500269
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400270 void ExpectCdmaStartModem(string network_technology) {
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400271 if (!device_->IsUnderlyingDeviceEnabled())
272 EXPECT_CALL(*proxy_,
273 Enable(true, _, _, CellularCapability::kTimeoutEnable))
274 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400275 EXPECT_CALL(*simple_proxy_,
276 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
277 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
278 EXPECT_CALL(*proxy_,
279 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
280 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
281 if (network_technology == flimflam::kNetworkTechnology1Xrtt)
282 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400283 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState1X));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400284 else
285 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400286 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400287 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
288 .Times(2)
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400289 .WillRepeatedly(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400290 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400291 EXPECT_CALL(manager_, RegisterService(_));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400292 }
293
Eric Shienbrood9a245532012-03-07 14:20:39 -0500294 MOCK_METHOD1(TestCallback, void(const Error &error));
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500295
Darin Petkov0828f5f2011-08-11 10:18:52 -0700296 protected:
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500297 static const char kTestDeviceName[];
298 static const char kTestDeviceAddress[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500299 static const char kDBusOwner[];
Jason Glasgowa585fc32012-06-06 11:04:09 -0400300 static const char kDBusService[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500301 static const char kDBusPath[];
302 static const char kTestCarrier[];
Darin Petkova4ca3c32012-08-17 16:05:24 +0200303 static const char kTestCarrierSPN[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500304 static const char kMEID[];
305 static const char kIMEI[];
306 static const char kIMSI[];
307 static const char kMSISDN[];
308 static const char kTestMobileProviderDBPath[];
Eric Shienbrood9a245532012-03-07 14:20:39 -0500309 static const int kStrength;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500310
Darin Petkov0828f5f2011-08-11 10:18:52 -0700311 class TestProxyFactory : public ProxyFactory {
312 public:
Paul Stewart7355ce12011-09-02 10:47:01 -0700313 explicit TestProxyFactory(CellularTest *test) : test_(test) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -0700314
mukesh agrawal1830fa12011-09-26 14:31:40 -0700315 virtual ModemProxyInterface *CreateModemProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700316 const string &/*path*/,
317 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700318 return test_->proxy_.release();
319 }
320
321 virtual ModemSimpleProxyInterface *CreateModemSimpleProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700322 const string &/*path*/,
323 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700324 return test_->simple_proxy_.release();
325 }
326
327 virtual ModemCDMAProxyInterface *CreateModemCDMAProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700328 const string &/*path*/,
329 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700330 return test_->cdma_proxy_.release();
331 }
332
Darin Petkov975b5e72011-08-30 11:48:08 -0700333 virtual ModemGSMCardProxyInterface *CreateModemGSMCardProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700334 const string &/*path*/,
335 const string &/*service*/) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700336 // TODO(benchan): This code conditionally returns a NULL pointer to avoid
337 // CellularCapabilityGSM::InitProperties (and thus
338 // CellularCapabilityGSM::GetIMSI) from being called during the
339 // construction. Remove this workaround after refactoring the tests.
340 return test_->create_gsm_card_proxy_from_factory_ ?
341 test_->gsm_card_proxy_.release() : NULL;
Darin Petkov975b5e72011-08-30 11:48:08 -0700342 }
343
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700344 virtual ModemGSMNetworkProxyInterface *CreateModemGSMNetworkProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700345 const string &/*path*/,
346 const string &/*service*/) {
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700347 return test_->gsm_network_proxy_.release();
348 }
349
Darin Petkov0828f5f2011-08-11 10:18:52 -0700350 private:
351 CellularTest *test_;
352 };
Darin Petkov0828f5f2011-08-11 10:18:52 -0700353 void StartRTNLHandler();
354 void StopRTNLHandler();
355
Ben Chan3ecdf822012-08-06 12:29:23 -0700356 void AllowCreateGSMCardProxyFromFactory() {
357 create_gsm_card_proxy_from_factory_ = true;
358 }
359
Darin Petkov721ac932011-11-16 15:43:09 +0100360 void SetCellularType(Cellular::Type type) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700361 device_->InitCapability(type);
Darin Petkov721ac932011-11-16 15:43:09 +0100362 }
363
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400364 CellularCapabilityClassic *GetCapabilityClassic() {
365 return dynamic_cast<CellularCapabilityClassic *>(
366 device_->capability_.get());
367 }
368
Darin Petkovae0c64e2011-11-15 15:50:27 +0100369 CellularCapabilityCDMA *GetCapabilityCDMA() {
370 return dynamic_cast<CellularCapabilityCDMA *>(device_->capability_.get());
371 }
372
373 CellularCapabilityGSM *GetCapabilityGSM() {
374 return dynamic_cast<CellularCapabilityGSM *>(device_->capability_.get());
375 }
376
Darin Petkov3335b372011-08-22 11:05:32 -0700377 NiceMockControl control_interface_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700378 EventDispatcher dispatcher_;
Thieu Le3426c8f2012-01-11 17:35:11 -0800379 MockMetrics metrics_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700380 MockGLib glib_;
Chris Masone2ae797d2011-08-23 20:41:00 -0700381 MockManager manager_;
382 MockDeviceInfo device_info_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700383 NiceMock<MockRTNLHandler> rtnl_handler_;
384
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500385 MockDHCPProvider dhcp_provider_;
386 scoped_refptr<MockDHCPConfig> dhcp_config_;
387
Ben Chan3ecdf822012-08-06 12:29:23 -0700388 bool create_gsm_card_proxy_from_factory_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700389 scoped_ptr<MockModemProxy> proxy_;
390 scoped_ptr<MockModemSimpleProxy> simple_proxy_;
391 scoped_ptr<MockModemCDMAProxy> cdma_proxy_;
Darin Petkov975b5e72011-08-30 11:48:08 -0700392 scoped_ptr<MockModemGSMCardProxy> gsm_card_proxy_;
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700393 scoped_ptr<MockModemGSMNetworkProxy> gsm_network_proxy_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700394 TestProxyFactory proxy_factory_;
Darin Petkov137884a2011-10-26 18:52:47 +0200395 mobile_provider_db *provider_db_;
Ben Chan3ecdf822012-08-06 12:29:23 -0700396 CellularRefPtr device_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700397};
398
Darin Petkov77cb6812011-08-15 16:19:41 -0700399const char CellularTest::kTestDeviceName[] = "usb0";
Chris Masone626719f2011-08-18 16:58:48 -0700400const char CellularTest::kTestDeviceAddress[] = "00:01:02:03:04:05";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700401const char CellularTest::kDBusOwner[] = ":1.19";
Jason Glasgowa585fc32012-06-06 11:04:09 -0400402const char CellularTest::kDBusService[] = "org.chromium.ModemManager";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700403const char CellularTest::kDBusPath[] = "/org/chromium/ModemManager/Gobi/0";
Darin Petkov51489002011-08-18 13:13:20 -0700404const char CellularTest::kTestCarrier[] = "The Cellular Carrier";
Darin Petkova4ca3c32012-08-17 16:05:24 +0200405const char CellularTest::kTestCarrierSPN[] = "Home Provider";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500406const char CellularTest::kMEID[] = "01234567EF8901";
Darin Petkov975b5e72011-08-30 11:48:08 -0700407const char CellularTest::kIMEI[] = "987654321098765";
408const char CellularTest::kIMSI[] = "123456789012345";
409const char CellularTest::kMSISDN[] = "12345678901";
Darin Petkov137884a2011-10-26 18:52:47 +0200410const char CellularTest::kTestMobileProviderDBPath[] =
411 "provider_db_unittest.bfd";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500412const int CellularTest::kStrength = 90;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700413
Darin Petkove9d12e02011-07-27 15:09:37 -0700414TEST_F(CellularTest, GetStateString) {
Darin Petkovcc044422011-08-17 13:30:06 -0700415 EXPECT_EQ("CellularStateDisabled",
416 device_->GetStateString(Cellular::kStateDisabled));
417 EXPECT_EQ("CellularStateEnabled",
418 device_->GetStateString(Cellular::kStateEnabled));
419 EXPECT_EQ("CellularStateRegistered",
420 device_->GetStateString(Cellular::kStateRegistered));
421 EXPECT_EQ("CellularStateConnected",
422 device_->GetStateString(Cellular::kStateConnected));
423 EXPECT_EQ("CellularStateLinked",
424 device_->GetStateString(Cellular::kStateLinked));
Darin Petkove9d12e02011-07-27 15:09:37 -0700425}
426
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700427TEST_F(CellularTest, StartCDMARegister) {
Darin Petkov721ac932011-11-16 15:43:09 +0100428 SetCellularType(Cellular::kTypeCDMA);
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400429 ExpectCdmaStartModem(flimflam::kNetworkTechnology1Xrtt);
Darin Petkov975b5e72011-08-30 11:48:08 -0700430 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500431 Error error;
432 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
Darin Petkov0828f5f2011-08-11 10:18:52 -0700433 dispatcher_.DispatchPendingEvents();
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400434 EXPECT_EQ(kMEID, GetCapabilityClassic()->meid_);
435 EXPECT_EQ(kTestCarrier, GetCapabilityClassic()->carrier_);
Darin Petkovbac96002011-08-09 13:22:00 -0700436 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovd2045802011-08-23 11:09:25 -0700437 ASSERT_TRUE(device_->service_.get());
438 EXPECT_EQ(flimflam::kNetworkTechnology1Xrtt,
Darin Petkovb72cf402011-11-22 14:51:39 +0100439 device_->service_->network_technology());
Darin Petkov22b72bf2011-08-29 14:01:20 -0700440 EXPECT_EQ(kStrength, device_->service_->strength());
Darin Petkovd2045802011-08-23 11:09:25 -0700441 EXPECT_EQ(flimflam::kRoamingStateHome, device_->service_->roaming_state());
Darin Petkovbac96002011-08-09 13:22:00 -0700442}
443
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700444TEST_F(CellularTest, StartGSMRegister) {
Darin Petkov137884a2011-10-26 18:52:47 +0200445 provider_db_ = mobile_provider_open_db(kTestMobileProviderDBPath);
446 ASSERT_TRUE(provider_db_);
447 device_->provider_db_ = provider_db_;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500448 EXPECT_CALL(*proxy_, Enable(true, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500449 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500450 EXPECT_CALL(*gsm_card_proxy_,
451 GetIMEI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500452 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMEI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500453 EXPECT_CALL(*gsm_card_proxy_,
454 GetIMSI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500455 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMSI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500456 EXPECT_CALL(*gsm_card_proxy_,
457 GetSPN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500458 .WillOnce(Invoke(this, &CellularTest::InvokeGetSPN));
459 EXPECT_CALL(*gsm_card_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500460 GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500461 .WillOnce(Invoke(this, &CellularTest::InvokeGetMSISDN));
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700462 EXPECT_CALL(*gsm_network_proxy_, AccessTechnology())
463 .WillOnce(Return(MM_MODEM_GSM_ACCESS_TECH_EDGE));
Darin Petkov63138a92012-02-06 14:09:15 +0100464 EXPECT_CALL(*gsm_card_proxy_, EnabledFacilityLocks())
465 .WillOnce(Return(MM_MODEM_GSM_FACILITY_SIM));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500466 EXPECT_CALL(*proxy_, GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500467 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
Darin Petkov137884a2011-10-26 18:52:47 +0200468 static const char kNetworkID[] = "22803";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500469 EXPECT_CALL(*gsm_network_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500470 GetRegistrationInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500471 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationInfo));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500472 EXPECT_CALL(*gsm_network_proxy_, GetSignalQuality(NULL, _, _))
473 .Times(2)
474 .WillRepeatedly(Invoke(this,
475 &CellularTest::InvokeGetSignalQuality));
476 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400477 EXPECT_CALL(manager_, RegisterService(_));
Ben Chan3ecdf822012-08-06 12:29:23 -0700478 AllowCreateGSMCardProxyFromFactory();
479
Eric Shienbrood9a245532012-03-07 14:20:39 -0500480 Error error;
481 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
482 EXPECT_TRUE(error.IsSuccess());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700483 dispatcher_.DispatchPendingEvents();
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400484 EXPECT_EQ(kIMEI, GetCapabilityGSM()->imei_);
485 EXPECT_EQ(kIMSI, GetCapabilityGSM()->imsi_);
Darin Petkova4ca3c32012-08-17 16:05:24 +0200486 EXPECT_EQ(kTestCarrierSPN, GetCapabilityGSM()->spn_);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400487 EXPECT_EQ(kMSISDN, GetCapabilityGSM()->mdn_);
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700488 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
489 ASSERT_TRUE(device_->service_.get());
490 EXPECT_EQ(flimflam::kNetworkTechnologyEdge,
Darin Petkovb72cf402011-11-22 14:51:39 +0100491 device_->service_->network_technology());
Darin Petkov63138a92012-02-06 14:09:15 +0100492 EXPECT_TRUE(GetCapabilityGSM()->sim_lock_status_.enabled);
Darin Petkov22b72bf2011-08-29 14:01:20 -0700493 EXPECT_EQ(kStrength, device_->service_->strength());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700494 EXPECT_EQ(flimflam::kRoamingStateRoaming, device_->service_->roaming_state());
Darin Petkov137884a2011-10-26 18:52:47 +0200495 EXPECT_EQ(kNetworkID, device_->service_->serving_operator().GetCode());
Darin Petkova4ca3c32012-08-17 16:05:24 +0200496 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Darin Petkov137884a2011-10-26 18:52:47 +0200497 EXPECT_EQ("ch", device_->service_->serving_operator().GetCountry());
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700498}
499
Darin Petkovbac96002011-08-09 13:22:00 -0700500TEST_F(CellularTest, StartConnected) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700501 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
502 .WillOnce(Return(true));
Darin Petkov721ac932011-11-16 15:43:09 +0100503 SetCellularType(Cellular::kTypeCDMA);
Darin Petkovbac96002011-08-09 13:22:00 -0700504 device_->set_modem_state(Cellular::kModemStateConnected);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400505 GetCapabilityClassic()->meid_ = kMEID;
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400506 ExpectCdmaStartModem(flimflam::kNetworkTechnologyEvdo);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500507 Error error;
508 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
509 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700510 dispatcher_.DispatchPendingEvents();
Darin Petkovbac96002011-08-09 13:22:00 -0700511 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
512}
513
Darin Petkov0828f5f2011-08-11 10:18:52 -0700514TEST_F(CellularTest, StartLinked) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700515 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
516 .WillOnce(DoAll(SetArgumentPointee<1>(IFF_UP), Return(true)));
Darin Petkov721ac932011-11-16 15:43:09 +0100517 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700518 device_->set_modem_state(Cellular::kModemStateConnected);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400519 GetCapabilityClassic()->meid_ = kMEID;
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400520 ExpectCdmaStartModem(flimflam::kNetworkTechnologyEvdo);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700521 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _))
Darin Petkov77cb6812011-08-15 16:19:41 -0700522 .WillOnce(Return(dhcp_config_));
523 EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(true));
Darin Petkov60b8c3b2011-08-25 11:03:20 -0700524 EXPECT_CALL(manager_, UpdateService(_)).Times(2);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500525 Error error;
526 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
527 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700528 dispatcher_.DispatchPendingEvents();
529 EXPECT_EQ(Cellular::kStateLinked, device_->state_);
Darin Petkov60b8c3b2011-08-25 11:03:20 -0700530 EXPECT_EQ(Service::kStateConfiguring, device_->service_->state());
531 device_->SelectService(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700532}
533
Darin Petkov3335b372011-08-22 11:05:32 -0700534TEST_F(CellularTest, CreateService) {
Darin Petkov721ac932011-11-16 15:43:09 +0100535 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov3335b372011-08-22 11:05:32 -0700536 static const char kPaymentURL[] = "https://payment.url";
537 static const char kUsageURL[] = "https://usage.url";
Darin Petkov3335b372011-08-22 11:05:32 -0700538 device_->home_provider_.SetName(kTestCarrier);
Darin Petkov381928f2012-02-02 23:00:12 +0100539 GetCapabilityCDMA()->olp_.SetURL(kPaymentURL);
Darin Petkovae0c64e2011-11-15 15:50:27 +0100540 GetCapabilityCDMA()->usage_url_ = kUsageURL;
Darin Petkov3335b372011-08-22 11:05:32 -0700541 device_->CreateService();
542 ASSERT_TRUE(device_->service_.get());
Darin Petkov381928f2012-02-02 23:00:12 +0100543 EXPECT_EQ(kPaymentURL, device_->service_->olp().GetURL());
Darin Petkov3335b372011-08-22 11:05:32 -0700544 EXPECT_EQ(kUsageURL, device_->service_->usage_url());
545 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
546}
547
Darin Petkovc5f56562011-08-06 16:40:05 -0700548namespace {
549
550MATCHER(ContainsPhoneNumber, "") {
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400551 return ContainsKey(arg,
552 CellularCapabilityClassic::kConnectPropertyPhoneNumber);
Darin Petkovc5f56562011-08-06 16:40:05 -0700553}
554
Eric Shienbrood9a245532012-03-07 14:20:39 -0500555} // namespace
Darin Petkovc5f56562011-08-06 16:40:05 -0700556
557TEST_F(CellularTest, Connect) {
Darin Petkov4d6d9412011-08-24 13:19:54 -0700558 Error error;
Chris Masone2ae797d2011-08-23 20:41:00 -0700559 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700560 .Times(2)
561 .WillRepeatedly(Return(true));
Darin Petkovc5f56562011-08-06 16:40:05 -0700562 device_->state_ = Cellular::kStateConnected;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700563 device_->Connect(&error);
564 EXPECT_EQ(Error::kAlreadyConnected, error.type());
565 error.Populate(Error::kSuccess);
Darin Petkovc5f56562011-08-06 16:40:05 -0700566
Darin Petkov0828f5f2011-08-11 10:18:52 -0700567 device_->state_ = Cellular::kStateLinked;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700568 device_->Connect(&error);
569 EXPECT_EQ(Error::kAlreadyConnected, error.type());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700570
Darin Petkovc5f56562011-08-06 16:40:05 -0700571 device_->state_ = Cellular::kStateRegistered;
Darin Petkovd2045802011-08-23 11:09:25 -0700572 device_->service_ = new CellularService(
Thieu Le3426c8f2012-01-11 17:35:11 -0800573 &control_interface_, &dispatcher_, &metrics_, &manager_, device_);
Darin Petkovd2045802011-08-23 11:09:25 -0700574
Jason Glasgow7b461df2012-05-01 16:38:45 -0400575 device_->allow_roaming_ = false;
Darin Petkovb72cf402011-11-22 14:51:39 +0100576 device_->service_->roaming_state_ = flimflam::kRoamingStateRoaming;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700577 device_->Connect(&error);
Darin Petkov4d6d9412011-08-24 13:19:54 -0700578 EXPECT_EQ(Error::kNotOnHomeNetwork, error.type());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500579
Darin Petkov4d6d9412011-08-24 13:19:54 -0700580 error.Populate(Error::kSuccess);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500581 EXPECT_CALL(*simple_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500582 Connect(ContainsPhoneNumber(), _, _,
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500583 CellularCapability::kTimeoutConnect))
584 .Times(2)
585 .WillRepeatedly(Invoke(this, &CellularTest::InvokeConnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400586 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Darin Petkovb72cf402011-11-22 14:51:39 +0100587 device_->service_->roaming_state_ = flimflam::kRoamingStateHome;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500588 device_->state_ = Cellular::kStateRegistered;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700589 device_->Connect(&error);
590 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc5f56562011-08-06 16:40:05 -0700591 dispatcher_.DispatchPendingEvents();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500592 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
593
Jason Glasgow7b461df2012-05-01 16:38:45 -0400594 device_->allow_roaming_ = true;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500595 device_->service_->roaming_state_ = flimflam::kRoamingStateRoaming;
596 device_->state_ = Cellular::kStateRegistered;
597 device_->Connect(&error);
598 EXPECT_TRUE(error.IsSuccess());
599 dispatcher_.DispatchPendingEvents();
600 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
Darin Petkovc5f56562011-08-06 16:40:05 -0700601}
602
Eric Shienbrood9a245532012-03-07 14:20:39 -0500603TEST_F(CellularTest, Disconnect) {
604 Error error;
605 device_->state_ = Cellular::kStateRegistered;
606 device_->Disconnect(&error);
607 EXPECT_EQ(Error::kNotConnected, error.type());
608 error.Reset();
609
Darin Petkovfb0625e2012-01-16 13:05:56 +0100610 device_->state_ = Cellular::kStateConnected;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500611 EXPECT_CALL(*proxy_,
612 Disconnect(_, _, CellularCapability::kTimeoutDefault))
613 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400614 GetCapabilityClassic()->proxy_.reset(proxy_.release());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500615 device_->Disconnect(&error);
616 EXPECT_TRUE(error.IsSuccess());
617 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100618}
619
Arman Uguray539c4232012-09-11 10:00:22 -0700620TEST_F(CellularTest, DisconnectFailure) {
621 // Test the case where the underlying modem state is set
622 // to disconnecting, but shill thinks it's still connected
623 Error error;
624 device_->state_ = Cellular::kStateConnected;
625 EXPECT_CALL(*proxy_,
626 Disconnect(_, _, CellularCapability::kTimeoutDefault))
627 .Times(2)
628 .WillRepeatedly(Invoke(this, &CellularTest::InvokeDisconnectFail));
629 GetCapabilityClassic()->proxy_.reset(proxy_.release());
630 device_->modem_state_ = Cellular::kModemStateDisconnecting;
631 device_->Disconnect(&error);
632 EXPECT_TRUE(error.IsFailure());
633 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
634
635 device_->modem_state_ = Cellular::kModemStateConnected;
636 device_->Disconnect(&error);
637 EXPECT_TRUE(error.IsFailure());
638 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
639}
640
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400641TEST_F(CellularTest, ConnectFailure) {
642 SetCellularType(Cellular::kTypeCDMA);
643 device_->state_ = Cellular::kStateRegistered;
644 device_->service_ = new CellularService(
645 &control_interface_, &dispatcher_, &metrics_, &manager_, device_);
646 ASSERT_EQ(Service::kStateIdle, device_->service_->state());
647 EXPECT_CALL(*simple_proxy_,
648 Connect(_, _, _, CellularCapability::kTimeoutConnect))
649 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFail));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400650 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400651 Error error;
652 device_->Connect(&error);
653 EXPECT_EQ(Service::kStateFailure, device_->service_->state());
654}
655
Thieu Leb5954a22012-05-18 10:37:34 -0700656TEST_F(CellularTest, ConnectFailureNoService) {
657 // Make sure we don't crash if the connect failed and there is no
658 // CellularService object. This can happen if the modem is enabled and
659 // then quick disabled.
660 SetCellularType(Cellular::kTypeCDMA);
661 device_->state_ = Cellular::kStateRegistered;
662 device_->service_ = new CellularService(
663 &control_interface_, &dispatcher_, &metrics_, &manager_, device_);
664 EXPECT_CALL(
665 *simple_proxy_,
666 Connect(_, _, _, CellularCapability::kTimeoutConnect))
667 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFailNoService));
668 EXPECT_CALL(manager_, UpdateService(_));
669 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
670 Error error;
671 device_->Connect(&error);
672}
673
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400674TEST_F(CellularTest, ModemStateChangeEnable) {
675 EXPECT_CALL(*simple_proxy_,
676 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
677 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
678 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
679 EXPECT_CALL(*proxy_,
680 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
681 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
682 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
683 .WillOnce(Invoke(this,
684 &CellularTest::InvokeGetRegistrationStateUnregistered));
685 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
686 .WillOnce(Invoke(this, &CellularTest::InvokeGetSignalQuality));
687 EXPECT_CALL(manager_, UpdateEnabledTechnologies());
688 device_->state_ = Cellular::kStateDisabled;
689 device_->set_modem_state(Cellular::kModemStateDisabled);
690 SetCellularType(Cellular::kTypeCDMA);
691
692 DBusPropertiesMap props;
693 props[CellularCapabilityClassic::kModemPropertyEnabled].writer().
694 append_bool(true);
695 device_->OnDBusPropertiesChanged(MM_MODEM_INTERFACE, props, vector<string>());
696 dispatcher_.DispatchPendingEvents();
697
698 EXPECT_EQ(Cellular::kModemStateEnabled, device_->modem_state());
699 EXPECT_EQ(Cellular::kStateEnabled, device_->state());
700 EXPECT_TRUE(device_->enabled());
701}
702
703TEST_F(CellularTest, ModemStateChangeDisable) {
704 EXPECT_CALL(*proxy_,
705 Disconnect(_, _, CellularCapability::kTimeoutDefault))
706 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
707 EXPECT_CALL(*proxy_,
Thieu Lec8d2d962012-05-15 14:31:18 -0700708 Enable(false, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400709 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
710 EXPECT_CALL(manager_, UpdateEnabledTechnologies());
711 device_->enabled_ = true;
712 device_->enabled_pending_ = true;
713 device_->state_ = Cellular::kStateEnabled;
714 device_->set_modem_state(Cellular::kModemStateEnabled);
715 SetCellularType(Cellular::kTypeCDMA);
716 GetCapabilityClassic()->InitProxies();
717
718 GetCapabilityClassic()->OnModemStateChangedSignal(kModemClassicStateEnabled,
719 kModemClassicStateDisabled,
720 0);
721 dispatcher_.DispatchPendingEvents();
722
723 EXPECT_EQ(Cellular::kModemStateDisabled, device_->modem_state());
724 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
725 EXPECT_FALSE(device_->enabled());
726}
727
Thieu Led0012052012-07-25 16:09:09 -0700728TEST_F(CellularTest, ModemStateChangeStaleConnected) {
729 // Test to make sure that we ignore stale modem Connected state transitions.
730 // When a modem is asked to connect and before the connect completes, the
731 // modem is disabled, it may send a stale Connected state transition after
732 // it has been disabled.
733 device_->state_ = Cellular::kStateDisabled;
734 device_->OnModemStateChanged(Cellular::kModemStateEnabling,
735 Cellular::kModemStateConnected,
736 0);
737 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
738}
739
740TEST_F(CellularTest, ModemStateChangeValidConnected) {
741 device_->state_ = Cellular::kStateEnabled;
742 device_->service_ = new CellularService(
743 &control_interface_, &dispatcher_, &metrics_, &manager_, device_);
744 device_->OnModemStateChanged(Cellular::kModemStateConnecting,
745 Cellular::kModemStateConnected,
746 0);
747 EXPECT_EQ(Cellular::kStateConnected, device_->state());
748}
749
Thieu Le37b90032012-05-15 15:18:41 -0700750TEST_F(CellularTest, StartModemCallback) {
Gary Morainbaeefdf2012-04-30 14:53:35 -0700751 EXPECT_CALL(*this, TestCallback(IsSuccess()));
752 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -0700753 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
754 Unretained(this)),
755 Error(Error::kSuccess));
Gary Morainbaeefdf2012-04-30 14:53:35 -0700756 EXPECT_EQ(device_->state_, Cellular::kStateEnabled);
757}
758
Thieu Le37b90032012-05-15 15:18:41 -0700759TEST_F(CellularTest, StartModemCallbackFail) {
Gary Morainbaeefdf2012-04-30 14:53:35 -0700760 EXPECT_CALL(*this, TestCallback(IsFailure()));
761 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -0700762 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
763 Unretained(this)),
764 Error(Error::kOperationFailed));
Gary Morainbaeefdf2012-04-30 14:53:35 -0700765 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
766}
767
Thieu Le37b90032012-05-15 15:18:41 -0700768TEST_F(CellularTest, StopModemCallback) {
769 EXPECT_CALL(*this, TestCallback(IsSuccess()));
770 device_->service_ = new MockCellularService(&control_interface_,
771 &dispatcher_,
772 &metrics_,
773 &manager_,
774 device_);
775 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
776 Unretained(this)),
777 Error(Error::kSuccess));
778 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
779 EXPECT_FALSE(device_->service_.get());
780}
781
782TEST_F(CellularTest, StopModemCallbackFail) {
783 EXPECT_CALL(*this, TestCallback(IsFailure()));
784 device_->service_ = new MockCellularService(&control_interface_,
785 &dispatcher_,
786 &metrics_,
787 &manager_,
788 device_);
789 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
790 Unretained(this)),
791 Error(Error::kOperationFailed));
792 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
793 EXPECT_FALSE(device_->service_.get());
794}
795
Gary Moraina9fb3252012-05-31 12:05:31 -0700796TEST_F(CellularTest, ConnectAddsTerminationAction) {
797 Error error;
798 EXPECT_CALL(*simple_proxy_,
799 Connect(ContainsPhoneNumber(), _, _,
800 CellularCapability::kTimeoutConnect))
801 .WillRepeatedly(Invoke(this, &CellularTest::InvokeConnect));
802 EXPECT_CALL(*proxy_,
803 Disconnect(_, _, CellularCapability::kTimeoutDefault))
804 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
805
806 // TestCallback() will be called when the termination actions complete. This
807 // verifies that the actions were registered, invoked, and report their
808 // status.
809 EXPECT_CALL(*this, TestCallback(IsSuccess())).Times(2);
810
811 device_->service_ = new CellularService(
812 &control_interface_, &dispatcher_, &metrics_, &manager_, device_);
813 GetCapabilityClassic()->proxy_.reset(proxy_.release());
814 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
815 device_->state_ = Cellular::kStateRegistered;
816 device_->Connect(&error);
817 EXPECT_TRUE(error.IsSuccess());
818 dispatcher_.DispatchPendingEvents();
819 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
820
821 // If the action of establishing a connection registered a termination action
822 // with the manager, then running the termination action will result in a
823 // disconnect.
824 manager_.RunTerminationActions(
Darin Petkov3ec55342012-09-28 14:04:44 +0200825 Bind(&CellularTest::TestCallback, Unretained(this)));
Gary Moraina9fb3252012-05-31 12:05:31 -0700826 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
827 dispatcher_.DispatchPendingEvents();
828
829 // Verify that the termination action has been removed from the manager.
830 // Running the registered termination actions again should result in
831 // TestCallback being called with success because there are no registered
832 // termination actions.. If the termination action is not removed, then
833 // TestCallback will be called with kOperationTimeout.
834 manager_.RunTerminationActions(
Darin Petkov3ec55342012-09-28 14:04:44 +0200835 Bind(&CellularTest::TestCallback, Unretained(this)));
Gary Moraina9fb3252012-05-31 12:05:31 -0700836 dispatcher_.DispatchPendingEvents();
837}
838
Darin Petkove7c6ad32012-06-29 10:22:09 +0200839TEST_F(CellularTest, SetAllowRoaming) {
840 EXPECT_FALSE(device_->allow_roaming_);
841 EXPECT_CALL(manager_, UpdateDevice(_));
842 Error error;
843 device_->SetAllowRoaming(true, &error);
844 EXPECT_TRUE(error.IsSuccess());
845 EXPECT_TRUE(device_->allow_roaming_);
846}
847
Chris Masoneb925cc82011-06-22 15:39:57 -0700848} // namespace shill