blob: c71ac128a41a73fb94d1fa7e8f78dd5ebbf8a9ed [file] [log] [blame]
Arman Ugurayf4c61812013-01-10 18:58:39 -08001// Copyright (c) 2013 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>
Chris Masoneb925cc82011-06-22 15:39:57 -070013
Darin Petkovae0c64e2011-11-15 15:50:27 +010014#include "shill/cellular_capability_cdma.h"
Jason Glasgow82f9ab32012-04-04 14:27:19 -040015#include "shill/cellular_capability_classic.h"
Darin Petkov184c54e2011-11-15 12:44:39 +010016#include "shill/cellular_capability_gsm.h"
Ben Chan09fa2a02012-11-07 22:09:09 -080017#include "shill/cellular_capability_universal.h"
Darin Petkovd9661952011-08-03 16:25:42 -070018#include "shill/cellular_service.h"
Darin Petkov4d6d9412011-08-24 13:19:54 -070019#include "shill/error.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070020#include "shill/event_dispatcher.h"
Thieu Le37b90032012-05-15 15:18:41 -070021#include "shill/mock_cellular_service.h"
Chris Masone2ae797d2011-08-23 20:41:00 -070022#include "shill/mock_device_info.h"
Darin Petkov77cb6812011-08-15 16:19:41 -070023#include "shill/mock_dhcp_config.h"
24#include "shill/mock_dhcp_provider.h"
Darin Petkovbec79a22011-08-01 14:47:17 -070025#include "shill/mock_modem_cdma_proxy.h"
Darin Petkov975b5e72011-08-30 11:48:08 -070026#include "shill/mock_modem_gsm_card_proxy.h"
Darin Petkova1e0a1c2011-08-25 15:08:33 -070027#include "shill/mock_modem_gsm_network_proxy.h"
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070028#include "shill/mock_modem_info.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070029#include "shill/mock_modem_proxy.h"
Darin Petkove604f702011-07-28 15:51:17 -070030#include "shill/mock_modem_simple_proxy.h"
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -070031#include "shill/mock_rtnl_handler.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070032#include "shill/property_store_unittest.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070033#include "shill/proxy_factory.h"
Chris Masoneb925cc82011-06-22 15:39:57 -070034
Ben Chan09fa2a02012-11-07 22:09:09 -080035// mm/mm-modem.h must be included after cellular_capability_universal.h
36// in order to allow MM_MODEM_CDMA_* to be defined properly.
37#include <mm/mm-modem.h>
38
Eric Shienbrood9a245532012-03-07 14:20:39 -050039using base::Bind;
40using base::Unretained;
Darin Petkovc0865312011-09-16 15:31:20 -070041using std::map;
Chris Masoneb925cc82011-06-22 15:39:57 -070042using std::string;
Eric Shienbrood7fce52c2012-04-13 19:11:02 -040043using std::vector;
Darin Petkovbec79a22011-08-01 14:47:17 -070044using testing::_;
Chris Masoneb9c00592011-10-06 13:10:39 -070045using testing::AnyNumber;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050046using testing::Invoke;
Arman Ugurayf84a4242013-04-09 20:01:07 -070047using testing::Mock;
Darin Petkov0828f5f2011-08-11 10:18:52 -070048using testing::NiceMock;
Darin Petkove604f702011-07-28 15:51:17 -070049using testing::Return;
Darin Petkovbec79a22011-08-01 14:47:17 -070050using testing::SetArgumentPointee;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050051using testing::Unused;
Chris Masoneb925cc82011-06-22 15:39:57 -070052
53namespace shill {
54
Eric Shienbrood9a245532012-03-07 14:20:39 -050055MATCHER(IsSuccess, "") {
56 return arg.IsSuccess();
57}
58
Gary Morainbaeefdf2012-04-30 14:53:35 -070059MATCHER(IsFailure, "") {
60 return arg.IsFailure();
61}
62
Darin Petkov0828f5f2011-08-11 10:18:52 -070063class CellularPropertyTest : public PropertyStoreTest {
64 public:
65 CellularPropertyTest()
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070066 : modem_info_(control_interface(),
67 dispatcher(),
68 metrics(),
69 manager(),
70 glib()),
71 device_(new Cellular(&modem_info_,
Darin Petkove9d12e02011-07-27 15:09:37 -070072 "usb0",
Chris Masone626719f2011-08-18 16:58:48 -070073 "00:01:02:03:04:05",
Darin Petkove9d12e02011-07-27 15:09:37 -070074 3,
Ben Chan3ecdf822012-08-06 12:29:23 -070075 Cellular::kTypeCDMA,
Darin Petkov0828f5f2011-08-11 10:18:52 -070076 "",
Darin Petkov137884a2011-10-26 18:52:47 +020077 "",
Jason Glasgowa585fc32012-06-06 11:04:09 -040078 "",
Ben Chan3ecdf822012-08-06 12:29:23 -070079 ProxyFactory::GetInstance())) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -070080 virtual ~CellularPropertyTest() {}
Darin Petkove9d12e02011-07-27 15:09:37 -070081
Chris Masoneb925cc82011-06-22 15:39:57 -070082 protected:
Prathmesh Prabhu27526f12013-03-25 19:42:18 -070083 MockModemInfo modem_info_;
Darin Petkov0828f5f2011-08-11 10:18:52 -070084 DeviceRefPtr device_;
Chris Masoneb925cc82011-06-22 15:39:57 -070085};
86
Darin Petkov0828f5f2011-08-11 10:18:52 -070087TEST_F(CellularPropertyTest, Contains) {
mukesh agrawalde29fa82011-09-16 16:16:36 -070088 EXPECT_TRUE(device_->store().Contains(flimflam::kNameProperty));
89 EXPECT_FALSE(device_->store().Contains(""));
Chris Masoneb925cc82011-06-22 15:39:57 -070090}
91
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080092TEST_F(CellularPropertyTest, SetProperty) {
Chris Masonea8a2c252011-06-27 22:16:30 -070093 {
94 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -080095 EXPECT_TRUE(DBusAdaptor::SetProperty(
mukesh agrawalde29fa82011-09-16 16:16:36 -070096 device_->mutable_store(),
Chris Masonea8a2c252011-06-27 22:16:30 -070097 flimflam::kCellularAllowRoamingProperty,
98 PropertyStoreTest::kBoolV,
99 &error));
100 }
Chris Masonea8a2c252011-06-27 22:16:30 -0700101 // Ensure that attempting to write a R/O property returns InvalidArgs error.
102 {
103 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800104 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
105 flimflam::kAddressProperty,
106 PropertyStoreTest::kStringV,
107 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700108 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700109 }
110 {
111 ::DBus::Error error;
mukesh agrawal6bb9e7c2012-01-30 14:57:54 -0800112 EXPECT_FALSE(DBusAdaptor::SetProperty(device_->mutable_store(),
113 flimflam::kCarrierProperty,
114 PropertyStoreTest::kStringV,
115 &error));
Chris Masone9d779932011-08-25 16:33:41 -0700116 EXPECT_EQ(invalid_args(), error.name());
Chris Masonea8a2c252011-06-27 22:16:30 -0700117 }
Chris Masoneb925cc82011-06-22 15:39:57 -0700118}
119
Darin Petkov0828f5f2011-08-11 10:18:52 -0700120class CellularTest : public testing::Test {
121 public:
122 CellularTest()
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700123 : modem_info_(NULL, &dispatcher_, NULL, NULL, NULL),
124 device_info_(modem_info_.control_interface(), &dispatcher_,
125 modem_info_.metrics(), modem_info_.manager()),
126 dhcp_config_(new MockDHCPConfig(modem_info_.control_interface(),
Paul Stewartd408fdf2012-05-07 17:15:57 -0700127 kTestDeviceName)),
Ben Chan3ecdf822012-08-06 12:29:23 -0700128 create_gsm_card_proxy_from_factory_(false),
129 proxy_(new MockModemProxy()),
130 simple_proxy_(new MockModemSimpleProxy()),
131 cdma_proxy_(new MockModemCDMAProxy()),
132 gsm_card_proxy_(new MockModemGSMCardProxy()),
133 gsm_network_proxy_(new MockModemGSMNetworkProxy()),
134 proxy_factory_(this),
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700135 device_(new Cellular(&modem_info_,
Darin Petkov77cb6812011-08-15 16:19:41 -0700136 kTestDeviceName,
Chris Masone626719f2011-08-18 16:58:48 -0700137 kTestDeviceAddress,
Darin Petkov0828f5f2011-08-11 10:18:52 -0700138 3,
139 Cellular::kTypeGSM,
140 kDBusOwner,
Jason Glasgowa585fc32012-06-06 11:04:09 -0400141 kDBusService,
Darin Petkov137884a2011-10-26 18:52:47 +0200142 kDBusPath,
Thieu Lece4483e2013-01-23 15:12:03 -0800143 &proxy_factory_)) {
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700144 modem_info_.metrics()->RegisterDevice(device_->interface_index(),
145 Technology::kCellular);
Darin Petkov137884a2011-10-26 18:52:47 +0200146 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700147
148 virtual void SetUp() {
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700149 static_cast<Device *>(device_)->rtnl_handler_ = &rtnl_handler_;
Darin Petkov77cb6812011-08-15 16:19:41 -0700150 device_->set_dhcp_provider(&dhcp_provider_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700151 EXPECT_CALL(*modem_info_.mock_manager(), device_info())
152 .WillRepeatedly(Return(&device_info_));
153 EXPECT_CALL(*modem_info_.mock_manager(), DeregisterService(_))
154 .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
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700164 void InitProviderDB() {
165 modem_info_.SetProviderDB(kTestMobileProviderDBPath);
166 }
167
Eric Shienbrood9a245532012-03-07 14:20:39 -0500168 void InvokeEnable(bool enable, Error *error,
169 const ResultCallback &callback, int timeout) {
170 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500171 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500172 void InvokeGetSignalQuality(Error *error,
173 const SignalQualityCallback &callback,
174 int timeout) {
175 callback.Run(kStrength, Error());
176 }
177 void InvokeGetModemStatus(Error *error,
178 const DBusPropertyMapCallback &callback,
179 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500180 DBusPropertiesMap props;
181 props["carrier"].writer().append_string(kTestCarrier);
182 props["unknown-property"].writer().append_string("irrelevant-value");
Eric Shienbrood9a245532012-03-07 14:20:39 -0500183 callback.Run(props, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500184 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500185 void InvokeGetModemInfo(Error *error, const ModemInfoCallback &callback,
186 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500187 static const char kManufacturer[] = "Company";
188 static const char kModelID[] = "Gobi 2000";
189 static const char kHWRev[] = "A00B1234";
190 ModemHardwareInfo info;
191 info._1 = kManufacturer;
192 info._2 = kModelID;
193 info._3 = kHWRev;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500194 callback.Run(info, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500195 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500196 void InvokeGetRegistrationState1X(Error *error,
197 const RegistrationStateCallback &callback,
198 int timeout) {
199 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
200 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
201 Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500202 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500203 void InvokeGetIMEI(Error *error, const GSMIdentifierCallback &callback,
204 int timeout) {
205 callback.Run(kIMEI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500206 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500207 void InvokeGetIMSI(Error *error, const GSMIdentifierCallback &callback,
208 int timeout) {
209 callback.Run(kIMSI, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500210 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500211 void InvokeGetMSISDN(Error *error, const GSMIdentifierCallback &callback,
212 int timeout) {
213 callback.Run(kMSISDN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500214 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500215 void InvokeGetSPN(Error *error, const GSMIdentifierCallback &callback,
216 int timeout) {
Darin Petkova4ca3c32012-08-17 16:05:24 +0200217 callback.Run(kTestCarrierSPN, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500218 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500219 void InvokeGetRegistrationInfo(Error *error,
220 const RegistrationInfoCallback &callback,
221 int timeout) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500222 static const char kNetworkID[] = "22803";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500223 callback.Run(MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING,
224 kNetworkID, kTestCarrier, Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500225 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500226 void InvokeRegister(const string &network_id,
227 Error *error,
228 const ResultCallback &callback,
229 int timeout) {
230 callback.Run(Error());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500231 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500232 void InvokeGetRegistrationState(Error *error,
233 const RegistrationStateCallback &callback,
234 int timeout) {
235 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED,
236 MM_MODEM_CDMA_REGISTRATION_STATE_HOME,
237 Error());
238 }
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400239 void InvokeGetRegistrationStateUnregistered(
240 Error *error,
241 const RegistrationStateCallback &callback,
242 int timeout) {
243 callback.Run(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
244 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN,
245 Error());
Arman Uguray539c4232012-09-11 10:00:22 -0700246 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500247 void InvokeConnect(DBusPropertiesMap props, Error *error,
248 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400249 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500250 callback.Run(Error());
251 }
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400252 void InvokeConnectFail(DBusPropertiesMap props, Error *error,
Thieu Leb5954a22012-05-18 10:37:34 -0700253 const ResultCallback &callback, int timeout) {
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400254 EXPECT_EQ(Service::kStateAssociating, device_->service_->state());
255 callback.Run(Error(Error::kNotOnHomeNetwork));
256 }
Thieu Leb5954a22012-05-18 10:37:34 -0700257 void InvokeConnectFailNoService(DBusPropertiesMap props, Error *error,
258 const ResultCallback &callback, int timeout) {
259 device_->service_ = NULL;
260 callback.Run(Error(Error::kNotOnHomeNetwork));
261 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500262 void InvokeDisconnect(Error *error, const ResultCallback &callback,
263 int timeout) {
264 if (!callback.is_null())
265 callback.Run(Error());
266 }
Arman Uguray539c4232012-09-11 10:00:22 -0700267 void InvokeDisconnectFail(Error *error, const ResultCallback &callback,
268 int timeout) {
269 error->Populate(Error::kOperationFailed);
270 if (!callback.is_null())
271 callback.Run(*error);
272 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500273
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400274 void ExpectCdmaStartModem(string network_technology) {
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400275 if (!device_->IsUnderlyingDeviceEnabled())
276 EXPECT_CALL(*proxy_,
277 Enable(true, _, _, CellularCapability::kTimeoutEnable))
278 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400279 EXPECT_CALL(*simple_proxy_,
280 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
281 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
282 EXPECT_CALL(*proxy_,
283 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
284 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
285 if (network_technology == flimflam::kNetworkTechnology1Xrtt)
286 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400287 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState1X));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400288 else
289 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400290 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationState));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400291 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
292 .Times(2)
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400293 .WillRepeatedly(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400294 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700295 EXPECT_CALL(*modem_info_.mock_manager(), RegisterService(_));
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400296 }
297
Eric Shienbrood9a245532012-03-07 14:20:39 -0500298 MOCK_METHOD1(TestCallback, void(const Error &error));
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500299
Darin Petkov0828f5f2011-08-11 10:18:52 -0700300 protected:
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500301 static const char kTestDeviceName[];
302 static const char kTestDeviceAddress[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500303 static const char kDBusOwner[];
Jason Glasgowa585fc32012-06-06 11:04:09 -0400304 static const char kDBusService[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500305 static const char kDBusPath[];
306 static const char kTestCarrier[];
Darin Petkova4ca3c32012-08-17 16:05:24 +0200307 static const char kTestCarrierSPN[];
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500308 static const char kMEID[];
309 static const char kIMEI[];
310 static const char kIMSI[];
311 static const char kMSISDN[];
312 static const char kTestMobileProviderDBPath[];
Eric Shienbrood9a245532012-03-07 14:20:39 -0500313 static const int kStrength;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500314
Darin Petkov0828f5f2011-08-11 10:18:52 -0700315 class TestProxyFactory : public ProxyFactory {
316 public:
Paul Stewart7355ce12011-09-02 10:47:01 -0700317 explicit TestProxyFactory(CellularTest *test) : test_(test) {}
Darin Petkov0828f5f2011-08-11 10:18:52 -0700318
mukesh agrawal1830fa12011-09-26 14:31:40 -0700319 virtual ModemProxyInterface *CreateModemProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700320 const string &/*path*/,
321 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700322 return test_->proxy_.release();
323 }
324
325 virtual ModemSimpleProxyInterface *CreateModemSimpleProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700326 const string &/*path*/,
327 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700328 return test_->simple_proxy_.release();
329 }
330
331 virtual ModemCDMAProxyInterface *CreateModemCDMAProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700332 const string &/*path*/,
333 const string &/*service*/) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700334 return test_->cdma_proxy_.release();
335 }
336
Darin Petkov975b5e72011-08-30 11:48:08 -0700337 virtual ModemGSMCardProxyInterface *CreateModemGSMCardProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700338 const string &/*path*/,
339 const string &/*service*/) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700340 // TODO(benchan): This code conditionally returns a NULL pointer to avoid
341 // CellularCapabilityGSM::InitProperties (and thus
342 // CellularCapabilityGSM::GetIMSI) from being called during the
343 // construction. Remove this workaround after refactoring the tests.
344 return test_->create_gsm_card_proxy_from_factory_ ?
345 test_->gsm_card_proxy_.release() : NULL;
Darin Petkov975b5e72011-08-30 11:48:08 -0700346 }
347
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700348 virtual ModemGSMNetworkProxyInterface *CreateModemGSMNetworkProxy(
mukesh agrawal1830fa12011-09-26 14:31:40 -0700349 const string &/*path*/,
350 const string &/*service*/) {
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700351 return test_->gsm_network_proxy_.release();
352 }
353
Darin Petkov0828f5f2011-08-11 10:18:52 -0700354 private:
355 CellularTest *test_;
356 };
Darin Petkov0828f5f2011-08-11 10:18:52 -0700357 void StartRTNLHandler();
358 void StopRTNLHandler();
359
Ben Chan3ecdf822012-08-06 12:29:23 -0700360 void AllowCreateGSMCardProxyFromFactory() {
361 create_gsm_card_proxy_from_factory_ = true;
362 }
363
Darin Petkov721ac932011-11-16 15:43:09 +0100364 void SetCellularType(Cellular::Type type) {
Ben Chan3ecdf822012-08-06 12:29:23 -0700365 device_->InitCapability(type);
Darin Petkov721ac932011-11-16 15:43:09 +0100366 }
367
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400368 CellularCapabilityClassic *GetCapabilityClassic() {
369 return dynamic_cast<CellularCapabilityClassic *>(
370 device_->capability_.get());
371 }
372
Darin Petkovae0c64e2011-11-15 15:50:27 +0100373 CellularCapabilityCDMA *GetCapabilityCDMA() {
374 return dynamic_cast<CellularCapabilityCDMA *>(device_->capability_.get());
375 }
376
377 CellularCapabilityGSM *GetCapabilityGSM() {
378 return dynamic_cast<CellularCapabilityGSM *>(device_->capability_.get());
379 }
380
Ben Chan09fa2a02012-11-07 22:09:09 -0800381 CellularCapabilityUniversal *GetCapabilityUniversal() {
382 return dynamic_cast<CellularCapabilityUniversal *>(
383 device_->capability_.get());
384 }
385
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700386 // Different tests simulate a cellular service being set using a real /mock
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700387 // service.
Arman Ugurayf84a4242013-04-09 20:01:07 -0700388 CellularService *SetService() {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700389 device_->service_ = new CellularService(&modem_info_, device_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700390 return device_->service_;
391 }
Arman Ugurayf84a4242013-04-09 20:01:07 -0700392 MockCellularService *SetMockService() {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700393 device_->service_ = new MockCellularService(&modem_info_, device_);
394 return static_cast<MockCellularService *>(device_->service_.get());
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700395 }
396
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700397 EventDispatcher dispatcher_;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700398 MockModemInfo modem_info_;
Chris Masone2ae797d2011-08-23 20:41:00 -0700399 MockDeviceInfo device_info_;
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700400 NiceMock<MockRTNLHandler> rtnl_handler_;
401
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500402 MockDHCPProvider dhcp_provider_;
403 scoped_refptr<MockDHCPConfig> dhcp_config_;
404
Ben Chan3ecdf822012-08-06 12:29:23 -0700405 bool create_gsm_card_proxy_from_factory_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700406 scoped_ptr<MockModemProxy> proxy_;
407 scoped_ptr<MockModemSimpleProxy> simple_proxy_;
408 scoped_ptr<MockModemCDMAProxy> cdma_proxy_;
Darin Petkov975b5e72011-08-30 11:48:08 -0700409 scoped_ptr<MockModemGSMCardProxy> gsm_card_proxy_;
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700410 scoped_ptr<MockModemGSMNetworkProxy> gsm_network_proxy_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700411 TestProxyFactory proxy_factory_;
Ben Chan3ecdf822012-08-06 12:29:23 -0700412 CellularRefPtr device_;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700413};
414
Darin Petkov77cb6812011-08-15 16:19:41 -0700415const char CellularTest::kTestDeviceName[] = "usb0";
Chris Masone626719f2011-08-18 16:58:48 -0700416const char CellularTest::kTestDeviceAddress[] = "00:01:02:03:04:05";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700417const char CellularTest::kDBusOwner[] = ":1.19";
Jason Glasgowa585fc32012-06-06 11:04:09 -0400418const char CellularTest::kDBusService[] = "org.chromium.ModemManager";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700419const char CellularTest::kDBusPath[] = "/org/chromium/ModemManager/Gobi/0";
Darin Petkov51489002011-08-18 13:13:20 -0700420const char CellularTest::kTestCarrier[] = "The Cellular Carrier";
Darin Petkova4ca3c32012-08-17 16:05:24 +0200421const char CellularTest::kTestCarrierSPN[] = "Home Provider";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500422const char CellularTest::kMEID[] = "01234567EF8901";
Darin Petkov975b5e72011-08-30 11:48:08 -0700423const char CellularTest::kIMEI[] = "987654321098765";
424const char CellularTest::kIMSI[] = "123456789012345";
425const char CellularTest::kMSISDN[] = "12345678901";
Darin Petkov137884a2011-10-26 18:52:47 +0200426const char CellularTest::kTestMobileProviderDBPath[] =
427 "provider_db_unittest.bfd";
Eric Shienbrood9a245532012-03-07 14:20:39 -0500428const int CellularTest::kStrength = 90;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700429
Darin Petkove9d12e02011-07-27 15:09:37 -0700430TEST_F(CellularTest, GetStateString) {
Darin Petkovcc044422011-08-17 13:30:06 -0700431 EXPECT_EQ("CellularStateDisabled",
432 device_->GetStateString(Cellular::kStateDisabled));
433 EXPECT_EQ("CellularStateEnabled",
434 device_->GetStateString(Cellular::kStateEnabled));
435 EXPECT_EQ("CellularStateRegistered",
436 device_->GetStateString(Cellular::kStateRegistered));
437 EXPECT_EQ("CellularStateConnected",
438 device_->GetStateString(Cellular::kStateConnected));
439 EXPECT_EQ("CellularStateLinked",
440 device_->GetStateString(Cellular::kStateLinked));
Darin Petkove9d12e02011-07-27 15:09:37 -0700441}
442
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700443TEST_F(CellularTest, StartCDMARegister) {
Darin Petkov721ac932011-11-16 15:43:09 +0100444 SetCellularType(Cellular::kTypeCDMA);
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400445 ExpectCdmaStartModem(flimflam::kNetworkTechnology1Xrtt);
Darin Petkov975b5e72011-08-30 11:48:08 -0700446 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500447 Error error;
448 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
Darin Petkov0828f5f2011-08-11 10:18:52 -0700449 dispatcher_.DispatchPendingEvents();
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400450 EXPECT_EQ(kMEID, GetCapabilityClassic()->meid_);
451 EXPECT_EQ(kTestCarrier, GetCapabilityClassic()->carrier_);
Darin Petkovbac96002011-08-09 13:22:00 -0700452 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovd2045802011-08-23 11:09:25 -0700453 ASSERT_TRUE(device_->service_.get());
454 EXPECT_EQ(flimflam::kNetworkTechnology1Xrtt,
Darin Petkovb72cf402011-11-22 14:51:39 +0100455 device_->service_->network_technology());
Darin Petkov22b72bf2011-08-29 14:01:20 -0700456 EXPECT_EQ(kStrength, device_->service_->strength());
Darin Petkovd2045802011-08-23 11:09:25 -0700457 EXPECT_EQ(flimflam::kRoamingStateHome, device_->service_->roaming_state());
Darin Petkovbac96002011-08-09 13:22:00 -0700458}
459
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700460TEST_F(CellularTest, StartGSMRegister) {
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700461 InitProviderDB();
Eric Shienbrood9a245532012-03-07 14:20:39 -0500462 EXPECT_CALL(*proxy_, Enable(true, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500463 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500464 EXPECT_CALL(*gsm_card_proxy_,
465 GetIMEI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500466 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMEI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500467 EXPECT_CALL(*gsm_card_proxy_,
468 GetIMSI(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500469 .WillOnce(Invoke(this, &CellularTest::InvokeGetIMSI));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500470 EXPECT_CALL(*gsm_card_proxy_,
471 GetSPN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500472 .WillOnce(Invoke(this, &CellularTest::InvokeGetSPN));
473 EXPECT_CALL(*gsm_card_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500474 GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500475 .WillOnce(Invoke(this, &CellularTest::InvokeGetMSISDN));
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700476 EXPECT_CALL(*gsm_network_proxy_, AccessTechnology())
477 .WillOnce(Return(MM_MODEM_GSM_ACCESS_TECH_EDGE));
Darin Petkov63138a92012-02-06 14:09:15 +0100478 EXPECT_CALL(*gsm_card_proxy_, EnabledFacilityLocks())
479 .WillOnce(Return(MM_MODEM_GSM_FACILITY_SIM));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500480 EXPECT_CALL(*proxy_, GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500481 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
Darin Petkov137884a2011-10-26 18:52:47 +0200482 static const char kNetworkID[] = "22803";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500483 EXPECT_CALL(*gsm_network_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500484 GetRegistrationInfo(_, _, CellularCapability::kTimeoutDefault))
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500485 .WillOnce(Invoke(this, &CellularTest::InvokeGetRegistrationInfo));
Eric Shienbrood9a245532012-03-07 14:20:39 -0500486 EXPECT_CALL(*gsm_network_proxy_, GetSignalQuality(NULL, _, _))
487 .Times(2)
488 .WillRepeatedly(Invoke(this,
489 &CellularTest::InvokeGetSignalQuality));
490 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700491 EXPECT_CALL(*modem_info_.mock_manager(), RegisterService(_));
Ben Chan3ecdf822012-08-06 12:29:23 -0700492 AllowCreateGSMCardProxyFromFactory();
493
Eric Shienbrood9a245532012-03-07 14:20:39 -0500494 Error error;
495 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
496 EXPECT_TRUE(error.IsSuccess());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700497 dispatcher_.DispatchPendingEvents();
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400498 EXPECT_EQ(kIMEI, GetCapabilityGSM()->imei_);
499 EXPECT_EQ(kIMSI, GetCapabilityGSM()->imsi_);
Darin Petkova4ca3c32012-08-17 16:05:24 +0200500 EXPECT_EQ(kTestCarrierSPN, GetCapabilityGSM()->spn_);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400501 EXPECT_EQ(kMSISDN, GetCapabilityGSM()->mdn_);
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700502 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
503 ASSERT_TRUE(device_->service_.get());
504 EXPECT_EQ(flimflam::kNetworkTechnologyEdge,
Darin Petkovb72cf402011-11-22 14:51:39 +0100505 device_->service_->network_technology());
Darin Petkov63138a92012-02-06 14:09:15 +0100506 EXPECT_TRUE(GetCapabilityGSM()->sim_lock_status_.enabled);
Darin Petkov22b72bf2011-08-29 14:01:20 -0700507 EXPECT_EQ(kStrength, device_->service_->strength());
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700508 EXPECT_EQ(flimflam::kRoamingStateRoaming, device_->service_->roaming_state());
Darin Petkov137884a2011-10-26 18:52:47 +0200509 EXPECT_EQ(kNetworkID, device_->service_->serving_operator().GetCode());
Darin Petkova4ca3c32012-08-17 16:05:24 +0200510 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Darin Petkov137884a2011-10-26 18:52:47 +0200511 EXPECT_EQ("ch", device_->service_->serving_operator().GetCountry());
Darin Petkova1e0a1c2011-08-25 15:08:33 -0700512}
513
Darin Petkovbac96002011-08-09 13:22:00 -0700514TEST_F(CellularTest, StartConnected) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700515 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
516 .WillOnce(Return(true));
Darin Petkov721ac932011-11-16 15:43:09 +0100517 SetCellularType(Cellular::kTypeCDMA);
Darin Petkovbac96002011-08-09 13:22:00 -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);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500521 Error error;
522 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
523 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700524 dispatcher_.DispatchPendingEvents();
Darin Petkovbac96002011-08-09 13:22:00 -0700525 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
526}
527
Darin Petkov0828f5f2011-08-11 10:18:52 -0700528TEST_F(CellularTest, StartLinked) {
Chris Masone2ae797d2011-08-23 20:41:00 -0700529 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
530 .WillOnce(DoAll(SetArgumentPointee<1>(IFF_UP), Return(true)));
Darin Petkov721ac932011-11-16 15:43:09 +0100531 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700532 device_->set_modem_state(Cellular::kModemStateConnected);
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400533 GetCapabilityClassic()->meid_ = kMEID;
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400534 ExpectCdmaStartModem(flimflam::kNetworkTechnologyEvdo);
Paul Stewartd408fdf2012-05-07 17:15:57 -0700535 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, _))
Darin Petkov77cb6812011-08-15 16:19:41 -0700536 .WillOnce(Return(dhcp_config_));
537 EXPECT_CALL(*dhcp_config_, RequestIP()).WillOnce(Return(true));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700538 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_)).Times(3);
Eric Shienbrood9a245532012-03-07 14:20:39 -0500539 Error error;
540 device_->Start(&error, Bind(&CellularTest::TestCallback, Unretained(this)));
541 EXPECT_TRUE(error.IsSuccess());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700542 dispatcher_.DispatchPendingEvents();
543 EXPECT_EQ(Cellular::kStateLinked, device_->state_);
Darin Petkov60b8c3b2011-08-25 11:03:20 -0700544 EXPECT_EQ(Service::kStateConfiguring, device_->service_->state());
545 device_->SelectService(NULL);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700546}
547
Darin Petkov3335b372011-08-22 11:05:32 -0700548TEST_F(CellularTest, CreateService) {
Darin Petkov721ac932011-11-16 15:43:09 +0100549 SetCellularType(Cellular::kTypeCDMA);
Darin Petkov3335b372011-08-22 11:05:32 -0700550 static const char kPaymentURL[] = "https://payment.url";
551 static const char kUsageURL[] = "https://usage.url";
Darin Petkov3335b372011-08-22 11:05:32 -0700552 device_->home_provider_.SetName(kTestCarrier);
Darin Petkov381928f2012-02-02 23:00:12 +0100553 GetCapabilityCDMA()->olp_.SetURL(kPaymentURL);
Darin Petkovae0c64e2011-11-15 15:50:27 +0100554 GetCapabilityCDMA()->usage_url_ = kUsageURL;
Darin Petkov3335b372011-08-22 11:05:32 -0700555 device_->CreateService();
556 ASSERT_TRUE(device_->service_.get());
Darin Petkov381928f2012-02-02 23:00:12 +0100557 EXPECT_EQ(kPaymentURL, device_->service_->olp().GetURL());
Darin Petkov3335b372011-08-22 11:05:32 -0700558 EXPECT_EQ(kUsageURL, device_->service_->usage_url());
559 EXPECT_EQ(kTestCarrier, device_->service_->serving_operator().GetName());
Ben Chan3d6de0e2012-12-10 12:01:34 -0800560 ASSERT_FALSE(device_->service_->activate_over_non_cellular_network());
Darin Petkov3335b372011-08-22 11:05:32 -0700561}
562
Darin Petkovc5f56562011-08-06 16:40:05 -0700563namespace {
564
565MATCHER(ContainsPhoneNumber, "") {
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400566 return ContainsKey(arg,
567 CellularCapabilityClassic::kConnectPropertyPhoneNumber);
Darin Petkovc5f56562011-08-06 16:40:05 -0700568}
569
Eric Shienbrood9a245532012-03-07 14:20:39 -0500570} // namespace
Darin Petkovc5f56562011-08-06 16:40:05 -0700571
572TEST_F(CellularTest, Connect) {
Darin Petkov4d6d9412011-08-24 13:19:54 -0700573 Error error;
Chris Masone2ae797d2011-08-23 20:41:00 -0700574 EXPECT_CALL(device_info_, GetFlags(device_->interface_index(), _))
Darin Petkov9bac6fe2011-08-26 12:49:05 -0700575 .Times(2)
576 .WillRepeatedly(Return(true));
Darin Petkovc5f56562011-08-06 16:40:05 -0700577 device_->state_ = Cellular::kStateConnected;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700578 device_->Connect(&error);
579 EXPECT_EQ(Error::kAlreadyConnected, error.type());
580 error.Populate(Error::kSuccess);
Darin Petkovc5f56562011-08-06 16:40:05 -0700581
Darin Petkov0828f5f2011-08-11 10:18:52 -0700582 device_->state_ = Cellular::kStateLinked;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700583 device_->Connect(&error);
584 EXPECT_EQ(Error::kAlreadyConnected, error.type());
Darin Petkov0828f5f2011-08-11 10:18:52 -0700585
Thieu Lec7d8cd12013-02-13 11:38:14 -0800586 device_->state_ = Cellular::kStateEnabled;
587 device_->Connect(&error);
588 EXPECT_EQ(Error::kNotRegistered, error.type());
589
590 error.Reset();
591 device_->state_ = Cellular::kStateDisabled;
592 device_->Connect(&error);
593 EXPECT_EQ(Error::kNotRegistered, error.type());
594
Darin Petkovc5f56562011-08-06 16:40:05 -0700595 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700596 SetService();
Darin Petkovd2045802011-08-23 11:09:25 -0700597
Jason Glasgow7b461df2012-05-01 16:38:45 -0400598 device_->allow_roaming_ = false;
Darin Petkovb72cf402011-11-22 14:51:39 +0100599 device_->service_->roaming_state_ = flimflam::kRoamingStateRoaming;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700600 device_->Connect(&error);
Darin Petkov4d6d9412011-08-24 13:19:54 -0700601 EXPECT_EQ(Error::kNotOnHomeNetwork, error.type());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500602
Darin Petkov4d6d9412011-08-24 13:19:54 -0700603 error.Populate(Error::kSuccess);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500604 EXPECT_CALL(*simple_proxy_,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500605 Connect(ContainsPhoneNumber(), _, _,
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500606 CellularCapability::kTimeoutConnect))
607 .Times(2)
608 .WillRepeatedly(Invoke(this, &CellularTest::InvokeConnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400609 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Darin Petkovb72cf402011-11-22 14:51:39 +0100610 device_->service_->roaming_state_ = flimflam::kRoamingStateHome;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500611 device_->state_ = Cellular::kStateRegistered;
Darin Petkov4d6d9412011-08-24 13:19:54 -0700612 device_->Connect(&error);
613 EXPECT_TRUE(error.IsSuccess());
Darin Petkovc5f56562011-08-06 16:40:05 -0700614 dispatcher_.DispatchPendingEvents();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500615 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
616
Jason Glasgow7b461df2012-05-01 16:38:45 -0400617 device_->allow_roaming_ = true;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500618 device_->service_->roaming_state_ = flimflam::kRoamingStateRoaming;
619 device_->state_ = Cellular::kStateRegistered;
620 device_->Connect(&error);
621 EXPECT_TRUE(error.IsSuccess());
622 dispatcher_.DispatchPendingEvents();
623 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
Darin Petkovc5f56562011-08-06 16:40:05 -0700624}
625
Eric Shienbrood9a245532012-03-07 14:20:39 -0500626TEST_F(CellularTest, Disconnect) {
627 Error error;
628 device_->state_ = Cellular::kStateRegistered;
629 device_->Disconnect(&error);
630 EXPECT_EQ(Error::kNotConnected, error.type());
631 error.Reset();
632
Darin Petkovfb0625e2012-01-16 13:05:56 +0100633 device_->state_ = Cellular::kStateConnected;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500634 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800635 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Eric Shienbrood9a245532012-03-07 14:20:39 -0500636 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400637 GetCapabilityClassic()->proxy_.reset(proxy_.release());
Eric Shienbrood9a245532012-03-07 14:20:39 -0500638 device_->Disconnect(&error);
639 EXPECT_TRUE(error.IsSuccess());
640 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100641}
642
Arman Uguray539c4232012-09-11 10:00:22 -0700643TEST_F(CellularTest, DisconnectFailure) {
644 // Test the case where the underlying modem state is set
645 // to disconnecting, but shill thinks it's still connected
646 Error error;
647 device_->state_ = Cellular::kStateConnected;
648 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800649 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Arman Uguray539c4232012-09-11 10:00:22 -0700650 .Times(2)
651 .WillRepeatedly(Invoke(this, &CellularTest::InvokeDisconnectFail));
652 GetCapabilityClassic()->proxy_.reset(proxy_.release());
653 device_->modem_state_ = Cellular::kModemStateDisconnecting;
654 device_->Disconnect(&error);
655 EXPECT_TRUE(error.IsFailure());
656 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
657
658 device_->modem_state_ = Cellular::kModemStateConnected;
659 device_->Disconnect(&error);
660 EXPECT_TRUE(error.IsFailure());
661 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
662}
663
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400664TEST_F(CellularTest, ConnectFailure) {
665 SetCellularType(Cellular::kTypeCDMA);
666 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700667 SetService();
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400668 ASSERT_EQ(Service::kStateIdle, device_->service_->state());
669 EXPECT_CALL(*simple_proxy_,
670 Connect(_, _, _, CellularCapability::kTimeoutConnect))
671 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFail));
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400672 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
Eric Shienbroodcc95c5d2012-03-30 15:25:49 -0400673 Error error;
674 device_->Connect(&error);
675 EXPECT_EQ(Service::kStateFailure, device_->service_->state());
676}
677
Thieu Leb5954a22012-05-18 10:37:34 -0700678TEST_F(CellularTest, ConnectFailureNoService) {
679 // Make sure we don't crash if the connect failed and there is no
680 // CellularService object. This can happen if the modem is enabled and
681 // then quick disabled.
682 SetCellularType(Cellular::kTypeCDMA);
683 device_->state_ = Cellular::kStateRegistered;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700684 SetService();
Thieu Leb5954a22012-05-18 10:37:34 -0700685 EXPECT_CALL(
686 *simple_proxy_,
687 Connect(_, _, _, CellularCapability::kTimeoutConnect))
688 .WillOnce(Invoke(this, &CellularTest::InvokeConnectFailNoService));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700689 EXPECT_CALL(*modem_info_.mock_manager(), UpdateService(_));
Thieu Leb5954a22012-05-18 10:37:34 -0700690 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
691 Error error;
692 device_->Connect(&error);
693}
694
Arman Uguray32c76402012-11-27 14:01:13 -0800695TEST_F(CellularTest, LinkEventWontDestroyService) {
696 // If the network interface goes down, Cellular::LinkEvent should
697 // drop the connection but the service object should persist.
698 device_->state_ = Cellular::kStateLinked;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700699 CellularService *service = SetService();
Arman Uguray32c76402012-11-27 14:01:13 -0800700 device_->LinkEvent(0, 0); // flags doesn't contain IFF_UP
701 EXPECT_EQ(device_->state_, Cellular::kStateConnected);
702 EXPECT_EQ(device_->service_, service);
703}
704
Arman Ugurayed8e6102012-11-29 14:47:20 -0800705TEST_F(CellularTest, UseNoArpGateway) {
706 EXPECT_CALL(dhcp_provider_, CreateConfig(kTestDeviceName, _, _, false))
707 .WillOnce(Return(dhcp_config_));
708 device_->AcquireIPConfig();
709}
710
Ben Chan09fa2a02012-11-07 22:09:09 -0800711TEST_F(CellularTest, HandleNewRegistrationStateForServiceRequiringActivation) {
712 SetCellularType(Cellular::kTypeUniversal);
713
714 // Service activation is needed
715 GetCapabilityUniversal()->mdn_ = "0000000000";
Arman Ugurayf4c61812013-01-10 18:58:39 -0800716 CellularService::OLP olp;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700717 EXPECT_CALL(*modem_info_.mock_cellular_operator_info(), GetOLPByMCCMNC(_))
Arman Ugurayf4c61812013-01-10 18:58:39 -0800718 .WillRepeatedly(Return(&olp));
Arman Uguray41cc6342013-03-29 16:34:39 -0700719 EXPECT_CALL(*modem_info_.mock_pending_activation_store(),
720 GetActivationState(_,_))
721 .WillRepeatedly(Return(PendingActivationStore::kStateUnknown));
Ben Chan09fa2a02012-11-07 22:09:09 -0800722
723 device_->state_ = Cellular::kStateDisabled;
724 device_->HandleNewRegistrationState();
725 EXPECT_FALSE(device_->service_.get());
726
727 device_->state_ = Cellular::kStateEnabled;
728 device_->HandleNewRegistrationState();
729 EXPECT_TRUE(device_->service_.get());
Ben Chan3d6de0e2012-12-10 12:01:34 -0800730 EXPECT_TRUE(device_->service_->activate_over_non_cellular_network());
Ben Chan09fa2a02012-11-07 22:09:09 -0800731}
732
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400733TEST_F(CellularTest, ModemStateChangeEnable) {
734 EXPECT_CALL(*simple_proxy_,
735 GetModemStatus(_, _, CellularCapability::kTimeoutDefault))
736 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemStatus));
737 EXPECT_CALL(*cdma_proxy_, MEID()).WillOnce(Return(kMEID));
738 EXPECT_CALL(*proxy_,
739 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
740 .WillOnce(Invoke(this, &CellularTest::InvokeGetModemInfo));
741 EXPECT_CALL(*cdma_proxy_, GetRegistrationState(NULL, _, _))
742 .WillOnce(Invoke(this,
743 &CellularTest::InvokeGetRegistrationStateUnregistered));
744 EXPECT_CALL(*cdma_proxy_, GetSignalQuality(NULL, _, _))
745 .WillOnce(Invoke(this, &CellularTest::InvokeGetSignalQuality));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700746 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies());
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400747 device_->state_ = Cellular::kStateDisabled;
748 device_->set_modem_state(Cellular::kModemStateDisabled);
749 SetCellularType(Cellular::kTypeCDMA);
750
751 DBusPropertiesMap props;
752 props[CellularCapabilityClassic::kModemPropertyEnabled].writer().
753 append_bool(true);
754 device_->OnDBusPropertiesChanged(MM_MODEM_INTERFACE, props, vector<string>());
755 dispatcher_.DispatchPendingEvents();
756
757 EXPECT_EQ(Cellular::kModemStateEnabled, device_->modem_state());
758 EXPECT_EQ(Cellular::kStateEnabled, device_->state());
759 EXPECT_TRUE(device_->enabled());
760}
761
762TEST_F(CellularTest, ModemStateChangeDisable) {
763 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800764 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400765 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
766 EXPECT_CALL(*proxy_,
Thieu Lec8d2d962012-05-15 14:31:18 -0700767 Enable(false, _, _, CellularCapability::kTimeoutEnable))
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400768 .WillOnce(Invoke(this, &CellularTest::InvokeEnable));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700769 EXPECT_CALL(*modem_info_.mock_manager(), UpdateEnabledTechnologies());
Eric Shienbrood7fce52c2012-04-13 19:11:02 -0400770 device_->enabled_ = true;
771 device_->enabled_pending_ = true;
772 device_->state_ = Cellular::kStateEnabled;
773 device_->set_modem_state(Cellular::kModemStateEnabled);
774 SetCellularType(Cellular::kTypeCDMA);
775 GetCapabilityClassic()->InitProxies();
776
777 GetCapabilityClassic()->OnModemStateChangedSignal(kModemClassicStateEnabled,
778 kModemClassicStateDisabled,
779 0);
780 dispatcher_.DispatchPendingEvents();
781
782 EXPECT_EQ(Cellular::kModemStateDisabled, device_->modem_state());
783 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
784 EXPECT_FALSE(device_->enabled());
785}
786
Thieu Led0012052012-07-25 16:09:09 -0700787TEST_F(CellularTest, ModemStateChangeStaleConnected) {
788 // Test to make sure that we ignore stale modem Connected state transitions.
789 // When a modem is asked to connect and before the connect completes, the
790 // modem is disabled, it may send a stale Connected state transition after
791 // it has been disabled.
792 device_->state_ = Cellular::kStateDisabled;
793 device_->OnModemStateChanged(Cellular::kModemStateEnabling,
794 Cellular::kModemStateConnected,
795 0);
796 EXPECT_EQ(Cellular::kStateDisabled, device_->state());
797}
798
799TEST_F(CellularTest, ModemStateChangeValidConnected) {
800 device_->state_ = Cellular::kStateEnabled;
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700801 SetService();
Thieu Led0012052012-07-25 16:09:09 -0700802 device_->OnModemStateChanged(Cellular::kModemStateConnecting,
803 Cellular::kModemStateConnected,
804 0);
805 EXPECT_EQ(Cellular::kStateConnected, device_->state());
806}
807
Thieu Le5218cf22012-11-26 11:52:57 -0800808TEST_F(CellularTest, ModemStateChangeLostRegistration) {
809 SetCellularType(Cellular::kTypeUniversal);
810 CellularCapabilityUniversal *capability = GetCapabilityUniversal();
811 capability->registration_state_ = MM_MODEM_3GPP_REGISTRATION_STATE_HOME;
812 EXPECT_TRUE(capability->IsRegistered());
813 device_->OnModemStateChanged(Cellular::kModemStateRegistered,
814 Cellular::kModemStateEnabled,
815 0);
816 EXPECT_FALSE(capability->IsRegistered());
817}
818
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700819TEST_F(CellularTest, EnableTrafficMonitor) {
820 SetCellularType(Cellular::kTypeUniversal);
821 CellularCapabilityUniversal *capability = GetCapabilityUniversal();
822 capability->model_id_.clear();
823 EXPECT_CALL(*this, TestCallback(IsSuccess()));
824 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
825 Unretained(this)),
826 Error(Error::kSuccess));
827 EXPECT_FALSE(device_->traffic_monitor_enabled());
Arman Ugurayf84a4242013-04-09 20:01:07 -0700828 Mock::VerifyAndClearExpectations(this);
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700829
830 device_->state_ = Cellular::kStateDisabled;
831
832 capability->model_id_ = CellularCapabilityUniversal::kE362ModelId;
833 EXPECT_CALL(*this, TestCallback(IsFailure()));
834 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
835 Unretained(this)),
836 Error(Error::kOperationFailed));
837 EXPECT_FALSE(device_->traffic_monitor_enabled());
Arman Ugurayf84a4242013-04-09 20:01:07 -0700838 Mock::VerifyAndClearExpectations(this);
Arman Ugurayd42d8ec2013-04-08 19:28:21 -0700839
840 EXPECT_CALL(*this, TestCallback(IsSuccess()));
841 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
842 Unretained(this)),
843 Error(Error::kSuccess));
844 EXPECT_TRUE(device_->traffic_monitor_enabled());
845}
846
Thieu Le37b90032012-05-15 15:18:41 -0700847TEST_F(CellularTest, StartModemCallback) {
Gary Morainbaeefdf2012-04-30 14:53:35 -0700848 EXPECT_CALL(*this, TestCallback(IsSuccess()));
849 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -0700850 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
851 Unretained(this)),
852 Error(Error::kSuccess));
Gary Morainbaeefdf2012-04-30 14:53:35 -0700853 EXPECT_EQ(device_->state_, Cellular::kStateEnabled);
854}
855
Thieu Le37b90032012-05-15 15:18:41 -0700856TEST_F(CellularTest, StartModemCallbackFail) {
Gary Morainbaeefdf2012-04-30 14:53:35 -0700857 EXPECT_CALL(*this, TestCallback(IsFailure()));
858 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
Thieu Le37b90032012-05-15 15:18:41 -0700859 device_->StartModemCallback(Bind(&CellularTest::TestCallback,
860 Unretained(this)),
861 Error(Error::kOperationFailed));
Gary Morainbaeefdf2012-04-30 14:53:35 -0700862 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
863}
864
Thieu Le37b90032012-05-15 15:18:41 -0700865TEST_F(CellularTest, StopModemCallback) {
866 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700867 SetMockService();
Thieu Le37b90032012-05-15 15:18:41 -0700868 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
869 Unretained(this)),
870 Error(Error::kSuccess));
871 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
872 EXPECT_FALSE(device_->service_.get());
873}
874
875TEST_F(CellularTest, StopModemCallbackFail) {
876 EXPECT_CALL(*this, TestCallback(IsFailure()));
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700877 SetMockService();
Thieu Le37b90032012-05-15 15:18:41 -0700878 device_->StopModemCallback(Bind(&CellularTest::TestCallback,
879 Unretained(this)),
880 Error(Error::kOperationFailed));
881 EXPECT_EQ(device_->state_, Cellular::kStateDisabled);
882 EXPECT_FALSE(device_->service_.get());
883}
884
Arman Ugurayf84a4242013-04-09 20:01:07 -0700885TEST_F(CellularTest, OnConnectionHealthCheckerResult) {
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700886 MockCellularService *service(SetMockService());
Arman Ugurayf84a4242013-04-09 20:01:07 -0700887 EXPECT_FALSE(service->out_of_credits_);
888
889 EXPECT_CALL(*service, Disconnect(_)).Times(0);
890 device_->OnConnectionHealthCheckerResult(
891 ConnectionHealthChecker::kResultUnknown);
892 EXPECT_FALSE(service->out_of_credits_);
893 device_->OnConnectionHealthCheckerResult(
894 ConnectionHealthChecker::kResultInProgress);
895 EXPECT_FALSE(service->out_of_credits_);
896 device_->OnConnectionHealthCheckerResult(
897 ConnectionHealthChecker::kResultConnectionFailure);
898 EXPECT_FALSE(service->out_of_credits_);
899 Mock::VerifyAndClearExpectations(service);
900
901 EXPECT_CALL(*service, Disconnect(_)).Times(1);
902 device_->OnConnectionHealthCheckerResult(
903 ConnectionHealthChecker::kResultElongatedTimeWait);
904 EXPECT_TRUE(service->out_of_credits_);
905 Mock::VerifyAndClearExpectations(service);
906
907 service->out_of_credits_ = false;
908 EXPECT_CALL(*service, Disconnect(_)).Times(1);
909 device_->OnConnectionHealthCheckerResult(
910 ConnectionHealthChecker::kResultCongestedTxQueue);
911 EXPECT_TRUE(service->out_of_credits_);
912
913 // Don't leak the service object.
914 device_->service_ = NULL;
915}
916
Liam McLoughlin0fec81c2013-02-28 10:31:47 -0500917// The following test crashes under Clang
918// Disabling it for now (crosbug.com/39351)
919#if defined(__clang__)
920 #define MAYBE_ConnectAddsTerminationAction \
921 DISABLED_ConnectAddsTerminationAction
922#else
923 #define MAYBE_ConnectAddsTerminationAction \
924 ConnectAddsTerminationAction
925#endif // defined(__clang__)
926
927TEST_F(CellularTest, MAYBE_ConnectAddsTerminationAction) {
Gary Moraina9fb3252012-05-31 12:05:31 -0700928 Error error;
929 EXPECT_CALL(*simple_proxy_,
930 Connect(ContainsPhoneNumber(), _, _,
931 CellularCapability::kTimeoutConnect))
932 .WillRepeatedly(Invoke(this, &CellularTest::InvokeConnect));
933 EXPECT_CALL(*proxy_,
Thieu Le049adb52012-11-12 17:14:51 -0800934 Disconnect(_, _, CellularCapability::kTimeoutDisconnect))
Gary Moraina9fb3252012-05-31 12:05:31 -0700935 .WillOnce(Invoke(this, &CellularTest::InvokeDisconnect));
936
937 // TestCallback() will be called when the termination actions complete. This
938 // verifies that the actions were registered, invoked, and report their
939 // status.
940 EXPECT_CALL(*this, TestCallback(IsSuccess())).Times(2);
941
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700942 SetService();
Gary Moraina9fb3252012-05-31 12:05:31 -0700943 GetCapabilityClassic()->proxy_.reset(proxy_.release());
944 GetCapabilityClassic()->simple_proxy_.reset(simple_proxy_.release());
945 device_->state_ = Cellular::kStateRegistered;
946 device_->Connect(&error);
947 EXPECT_TRUE(error.IsSuccess());
948 dispatcher_.DispatchPendingEvents();
949 EXPECT_EQ(Cellular::kStateConnected, device_->state_);
950
951 // If the action of establishing a connection registered a termination action
952 // with the manager, then running the termination action will result in a
953 // disconnect.
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700954 modem_info_.manager()->RunTerminationActions(
Darin Petkov3ec55342012-09-28 14:04:44 +0200955 Bind(&CellularTest::TestCallback, Unretained(this)));
Gary Moraina9fb3252012-05-31 12:05:31 -0700956 EXPECT_EQ(Cellular::kStateRegistered, device_->state_);
957 dispatcher_.DispatchPendingEvents();
958
959 // Verify that the termination action has been removed from the manager.
960 // Running the registered termination actions again should result in
961 // TestCallback being called with success because there are no registered
962 // termination actions.. If the termination action is not removed, then
963 // TestCallback will be called with kOperationTimeout.
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700964 modem_info_.manager()->RunTerminationActions(
Darin Petkov3ec55342012-09-28 14:04:44 +0200965 Bind(&CellularTest::TestCallback, Unretained(this)));
Gary Moraina9fb3252012-05-31 12:05:31 -0700966 dispatcher_.DispatchPendingEvents();
967}
968
Darin Petkove7c6ad32012-06-29 10:22:09 +0200969TEST_F(CellularTest, SetAllowRoaming) {
970 EXPECT_FALSE(device_->allow_roaming_);
Prathmesh Prabhu27526f12013-03-25 19:42:18 -0700971 EXPECT_CALL(*modem_info_.mock_manager(), UpdateDevice(_));
Darin Petkove7c6ad32012-06-29 10:22:09 +0200972 Error error;
973 device_->SetAllowRoaming(true, &error);
974 EXPECT_TRUE(error.IsSuccess());
975 EXPECT_TRUE(device_->allow_roaming_);
976}
977
Chris Masoneb925cc82011-06-22 15:39:57 -0700978} // namespace shill