blob: a8dd456514732f9927756ffe0918c0cd2d52d003 [file] [log] [blame]
Jason Glasgowef965562012-04-10 16:12:35 -04001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
2// 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_capability_universal.h"
6
Nathan Williams4b7c2a82012-04-13 15:19:47 -04007#include <string>
8#include <vector>
9
Jason Glasgowef965562012-04-10 16:12:35 -040010#include <base/bind.h>
11#include <chromeos/dbus/service_constants.h>
12#include <gtest/gtest.h>
13#include <mobile_provider.h>
Jason Glasgowaf583282012-04-18 15:18:22 -040014#include <mm/ModemManager-names.h>
Jason Glasgowef965562012-04-10 16:12:35 -040015
16#include "shill/cellular.h"
17#include "shill/cellular_service.h"
Jason Glasgowaf583282012-04-18 15:18:22 -040018#include "shill/dbus_adaptor.h"
Jason Glasgowef965562012-04-10 16:12:35 -040019#include "shill/error.h"
20#include "shill/event_dispatcher.h"
21#include "shill/mock_adaptors.h"
Jason Glasgowaf583282012-04-18 15:18:22 -040022#include "shill/mock_dbus_properties_proxy.h"
Jason Glasgowef965562012-04-10 16:12:35 -040023#include "shill/mock_glib.h"
24#include "shill/mock_manager.h"
25#include "shill/mock_metrics.h"
26#include "shill/mock_mm1_modem_modem3gpp_proxy.h"
27#include "shill/mock_mm1_modem_modemcdma_proxy.h"
28#include "shill/mock_mm1_modem_proxy.h"
29#include "shill/mock_mm1_modem_simple_proxy.h"
30#include "shill/mock_mm1_sim_proxy.h"
31#include "shill/mock_profile.h"
32#include "shill/mock_rtnl_handler.h"
33#include "shill/nice_mock_control.h"
34#include "shill/proxy_factory.h"
35
36using base::Bind;
37using base::Unretained;
38using std::string;
Nathan Williams4b7c2a82012-04-13 15:19:47 -040039using std::vector;
Jason Glasgowef965562012-04-10 16:12:35 -040040using testing::InSequence;
41using testing::NiceMock;
42using testing::Return;
43using testing::_;
44
45namespace shill {
46
47MATCHER(IsSuccess, "") {
48 return arg.IsSuccess();
49}
50MATCHER(IsFailure, "") {
51 return arg.IsFailure();
52}
53
54class CellularCapabilityUniversalTest : public testing::Test {
55 public:
56 CellularCapabilityUniversalTest()
57 : manager_(&control_, &dispatcher_, &metrics_, &glib_),
58 cellular_(new Cellular(&control_,
59 &dispatcher_,
60 NULL,
61 &manager_,
62 "",
63 "",
64 0,
65 Cellular::kTypeUniversal,
66 "",
67 "",
68 NULL)),
69 modem_3gpp_proxy_(new mm1::MockModemModem3gppProxy()),
70 modem_cdma_proxy_(new mm1::MockModemModemCdmaProxy()),
71 modem_proxy_(new mm1::MockModemProxy()),
72 modem_simple_proxy_(new mm1::MockModemSimpleProxy()),
73 sim_proxy_(new mm1::MockSimProxy()),
Jason Glasgowaf583282012-04-18 15:18:22 -040074 properties_proxy_(new MockDBusPropertiesProxy()),
Jason Glasgowef965562012-04-10 16:12:35 -040075 proxy_factory_(this),
76 capability_(NULL),
77 device_adaptor_(NULL) {}
78
79 virtual ~CellularCapabilityUniversalTest() {
80 cellular_->service_ = NULL;
81 capability_ = NULL;
82 device_adaptor_ = NULL;
83 }
84
85 virtual void SetUp() {
86 capability_ = dynamic_cast<CellularCapabilityUniversal *>(
87 cellular_->capability_.get());
88 capability_->proxy_factory_ = &proxy_factory_;
89 device_adaptor_ =
90 dynamic_cast<NiceMock<DeviceMockAdaptor> *>(cellular_->adaptor());
91 }
92
93 virtual void TearDown() {
94 capability_->proxy_factory_ = NULL;
95 }
96
Jason Glasgow4380f0d2012-05-03 18:05:04 -040097 void InitProviderDB() {
98 const char kTestMobileProviderDBPath[] = "provider_db_unittest.bfd";
99
100 provider_db_ = mobile_provider_open_db(kTestMobileProviderDBPath);
101 ASSERT_TRUE(provider_db_);
102 cellular_->provider_db_ = provider_db_;
103 }
104
Jason Glasgowef965562012-04-10 16:12:35 -0400105 void InvokeEnable(bool enable, Error *error,
106 const ResultCallback &callback, int timeout) {
107 callback.Run(Error());
108 }
109 void InvokeEnableFail(bool enable, Error *error,
110 const ResultCallback &callback, int timeout) {
111 callback.Run(Error(Error::kOperationFailed));
112 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400113 void InvokeRegister(const string &operator_id, Error *error,
114 const ResultCallback &callback, int timeout) {
115 callback.Run(Error());
116 }
117
Jason Glasgowef965562012-04-10 16:12:35 -0400118
119 MOCK_METHOD1(TestCallback, void(const Error &error));
120
121 protected:
122 static const char kImei[];
Jason Glasgowaf583282012-04-18 15:18:22 -0400123 static const char kSimPath[];
124 static const uint32 kAccessTechnologies;
Jason Glasgowef965562012-04-10 16:12:35 -0400125
126 class TestProxyFactory : public ProxyFactory {
127 public:
128 explicit TestProxyFactory(CellularCapabilityUniversalTest *test) :
129 test_(test) {}
130
131 virtual mm1::ModemModem3gppProxyInterface *CreateMM1ModemModem3gppProxy(
132 const std::string &/* path */,
133 const std::string &/* service */) {
134 return test_->modem_3gpp_proxy_.release();
135 }
136
137 virtual mm1::ModemModemCdmaProxyInterface *CreateMM1ModemModemCdmaProxy(
138 const std::string &/* path */,
139 const std::string &/* service */) {
140 return test_->modem_cdma_proxy_.release();
141 }
142
143 virtual mm1::ModemProxyInterface *CreateMM1ModemProxy(
144 const std::string &/* path */,
145 const std::string &/* service */) {
146 return test_->modem_proxy_.release();
147 }
148
149 virtual mm1::ModemSimpleProxyInterface *CreateMM1ModemSimpleProxy(
150 const std::string &/* path */,
151 const std::string &/* service */) {
152 return test_->modem_simple_proxy_.release();
153 }
154
155 virtual mm1::SimProxyInterface *CreateSimProxy(
156 const std::string &/* path */,
157 const std::string &/* service */) {
158 return test_->sim_proxy_.release();
159 }
Jason Glasgowaf583282012-04-18 15:18:22 -0400160 virtual DBusPropertiesProxyInterface *CreateDBusPropertiesProxy(
161 const std::string &/* path */,
162 const std::string &/* service */) {
163 return test_->properties_proxy_.release();
164 }
Jason Glasgowef965562012-04-10 16:12:35 -0400165
166 private:
167 CellularCapabilityUniversalTest *test_;
168 };
169
170 NiceMockControl control_;
171 EventDispatcher dispatcher_;
172 MockMetrics metrics_;
173 MockGLib glib_;
174 MockManager manager_;
175 CellularRefPtr cellular_;
176 scoped_ptr<mm1::MockModemModem3gppProxy> modem_3gpp_proxy_;
177 scoped_ptr<mm1::MockModemModemCdmaProxy> modem_cdma_proxy_;
178 scoped_ptr<mm1::MockModemProxy> modem_proxy_;
179 scoped_ptr<mm1::MockModemSimpleProxy> modem_simple_proxy_;
180 scoped_ptr<mm1::MockSimProxy> sim_proxy_;
Jason Glasgowaf583282012-04-18 15:18:22 -0400181 scoped_ptr<MockDBusPropertiesProxy> properties_proxy_;
Jason Glasgowef965562012-04-10 16:12:35 -0400182 TestProxyFactory proxy_factory_;
183 CellularCapabilityUniversal *capability_; // Owned by |cellular_|.
184 NiceMock<DeviceMockAdaptor> *device_adaptor_; // Owned by |cellular_|.
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400185 mobile_provider_db *provider_db_;
Jason Glasgowef965562012-04-10 16:12:35 -0400186};
187
188const char CellularCapabilityUniversalTest::kImei[] = "999911110000";
Jason Glasgowaf583282012-04-18 15:18:22 -0400189const char CellularCapabilityUniversalTest::kSimPath[] = "/foo/sim";
190const uint32 CellularCapabilityUniversalTest::kAccessTechnologies =
191 MM_MODEM_ACCESS_TECHNOLOGY_LTE |
192 MM_MODEM_ACCESS_TECHNOLOGY_HSPA_PLUS;
Jason Glasgowef965562012-04-10 16:12:35 -0400193
194TEST_F(CellularCapabilityUniversalTest, StartModem) {
Jason Glasgowaf583282012-04-18 15:18:22 -0400195 // Set up mock modem properties
196 DBusPropertiesMap modem_properties;
197 string operator_name = "TestOperator";
198 string operator_code = "001400";
199
200 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
201 writer().append_uint32(kAccessTechnologies);
202
203 ::DBus::Variant v;
204 ::DBus::MessageIter writer = v.writer();
Jason Glasgowef965562012-04-10 16:12:35 -0400205 ::DBus::Struct< uint32_t, bool > quality;
206 quality._1 = 90;
207 quality._2 = true;
Jason Glasgowaf583282012-04-18 15:18:22 -0400208 writer << quality;
209 modem_properties[MM_MODEM_PROPERTY_SIGNALQUALITY] = v;
210
211 // Set up mock modem 3gpp properties
212 DBusPropertiesMap modem3gpp_properties;
213 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
214 writer().append_uint32(0);
215 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
216 writer().append_string(kImei);
217
218 EXPECT_CALL(*modem_proxy_,
219 Enable(true, _, _, CellularCapability::kTimeoutEnable))
220 .WillOnce(Invoke(this, &CellularCapabilityUniversalTest::InvokeEnable));
221 EXPECT_CALL(*properties_proxy_,
222 GetAll(MM_DBUS_INTERFACE_MODEM))
223 .WillOnce(Return(modem_properties));
224 EXPECT_CALL(*properties_proxy_,
225 GetAll(MM_DBUS_INTERFACE_MODEM_MODEM3GPP))
226 .WillOnce(Return(modem3gpp_properties));
Jason Glasgowef965562012-04-10 16:12:35 -0400227
228 // After setup we lose pointers to the proxies, so it is hard to set
229 // expectations.
230 SetUp();
231
232 Error error;
Jason Glasgowaf583282012-04-18 15:18:22 -0400233 EXPECT_CALL(*this, TestCallback(IsSuccess()));
Jason Glasgowef965562012-04-10 16:12:35 -0400234 ResultCallback callback =
235 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
236 capability_->StartModem(&error, callback);
237 EXPECT_TRUE(error.IsSuccess());
Jason Glasgowaf583282012-04-18 15:18:22 -0400238 EXPECT_EQ(kImei, capability_->imei_);
239 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
Jason Glasgowef965562012-04-10 16:12:35 -0400240}
241
242TEST_F(CellularCapabilityUniversalTest, StartModemFail) {
243 EXPECT_CALL(*modem_proxy_,
244 Enable(true, _, _, CellularCapability::kTimeoutEnable))
245 .WillOnce(
246 Invoke(this, &CellularCapabilityUniversalTest::InvokeEnableFail));
247 EXPECT_CALL(*this, TestCallback(IsFailure()));
248 ResultCallback callback =
249 Bind(&CellularCapabilityUniversalTest::TestCallback, Unretained(this));
250 SetUp();
251
252 Error error;
253 capability_->StartModem(&error, callback);
254 EXPECT_TRUE(error.IsSuccess());
255}
256
Jason Glasgowaf583282012-04-18 15:18:22 -0400257TEST_F(CellularCapabilityUniversalTest, PropertiesChanged) {
258 // Set up mock modem properties
259 DBusPropertiesMap modem_properties;
260 modem_properties[MM_MODEM_PROPERTY_ACCESSTECHNOLOGIES].
261 writer().append_uint32(kAccessTechnologies);
262 modem_properties[MM_MODEM_PROPERTY_SIM].
263 writer().append_path(kSimPath);
264
265 // Set up mock modem 3gpp properties
266 DBusPropertiesMap modem3gpp_properties;
267 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_ENABLEDFACILITYLOCKS].
268 writer().append_uint32(0);
269 modem3gpp_properties[MM_MODEM_MODEM3GPP_PROPERTY_IMEI].
270 writer().append_string(kImei);
271
272 // Set up mock modem sim properties
273 DBusPropertiesMap sim_properties;
274
275 // After setup we lose pointers to the proxies, so it is hard to set
276 // expectations.
277 EXPECT_CALL(*properties_proxy_,
278 GetAll(MM_DBUS_INTERFACE_SIM))
279 .WillOnce(Return(sim_properties));
280
281 SetUp();
282
283 EXPECT_EQ("", capability_->imei_);
284 EXPECT_EQ(MM_MODEM_ACCESS_TECHNOLOGY_UNKNOWN,
285 capability_->access_technologies_);
286 EXPECT_FALSE(capability_->sim_proxy_.get());
287 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
288 modem_properties, vector<string>());
289 EXPECT_EQ(kAccessTechnologies, capability_->access_technologies_);
290 EXPECT_EQ(kSimPath, capability_->sim_path_);
291 EXPECT_TRUE(capability_->sim_proxy_.get());
292
293 // Changing properties on wrong interface will not have an effect
294 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
295 modem3gpp_properties,
296 vector<string>());
297 EXPECT_EQ("", capability_->imei_);
298
299 // Changing properties on the right interface gets reflected in the
300 // capabilities object
301 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM_MODEM3GPP,
302 modem3gpp_properties,
303 vector<string>());
304 EXPECT_EQ(kImei, capability_->imei_);
305}
306
307TEST_F(CellularCapabilityUniversalTest, SimPropertiesChanged) {
308 // Set up mock modem properties
309 DBusPropertiesMap modem_properties;
310 modem_properties[MM_MODEM_PROPERTY_SIM].writer().append_path(kSimPath);
311
312 // Set up mock modem sim properties
313 const char kImsi[] = "310100000001";
314 DBusPropertiesMap sim_properties;
315 sim_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kImsi);
316
317 EXPECT_CALL(*properties_proxy_, GetAll(MM_DBUS_INTERFACE_SIM))
318 .WillOnce(Return(sim_properties));
319
320 // After setup we lose pointers to the proxies, so it is hard to set
321 // expectations.
322 SetUp();
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400323 InitProviderDB();
Jason Glasgowaf583282012-04-18 15:18:22 -0400324
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400325 EXPECT_TRUE(cellular_->home_provider().GetName().empty());
326 EXPECT_TRUE(cellular_->home_provider().GetCountry().empty());
327 EXPECT_TRUE(cellular_->home_provider().GetCode().empty());
Jason Glasgowaf583282012-04-18 15:18:22 -0400328 EXPECT_FALSE(capability_->sim_proxy_.get());
329 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_MODEM,
330 modem_properties, vector<string>());
331 EXPECT_EQ(kSimPath, capability_->sim_path_);
332 EXPECT_TRUE(capability_->sim_proxy_.get());
333 EXPECT_EQ(kImsi, capability_->imsi_);
334
335 // Updating the SIM
336 DBusPropertiesMap new_properties;
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400337 const char kCountry[] = "us";
338 const char kCode[] = "310160";
339 const char kNewImsi[] = "310240123456789";
Jason Glasgowaf583282012-04-18 15:18:22 -0400340 const char kSimIdentifier[] = "9999888";
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400341 const char kOperatorIdentifier[] = "310240";
342 const char kOperatorName[] = "Custom SPN";
Jason Glasgowaf583282012-04-18 15:18:22 -0400343 new_properties[MM_SIM_PROPERTY_IMSI].writer().append_string(kNewImsi);
344 new_properties[MM_SIM_PROPERTY_SIMIDENTIFIER].writer().
345 append_string(kSimIdentifier);
346 new_properties[MM_SIM_PROPERTY_OPERATORIDENTIFIER].writer().
347 append_string(kOperatorIdentifier);
Jason Glasgowaf583282012-04-18 15:18:22 -0400348 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
349 new_properties,
350 vector<string>());
351 EXPECT_EQ(kNewImsi, capability_->imsi_);
352 EXPECT_EQ(kSimIdentifier, capability_->sim_identifier_);
353 EXPECT_EQ(kOperatorIdentifier, capability_->operator_id_);
Jason Glasgow4380f0d2012-05-03 18:05:04 -0400354 EXPECT_EQ("", capability_->spn_);
355 EXPECT_EQ("T-Mobile", cellular_->home_provider().GetName());
356 EXPECT_EQ(kCountry, cellular_->home_provider().GetCountry());
357 EXPECT_EQ(kCode, cellular_->home_provider().GetCode());
358 EXPECT_EQ(4, capability_->apn_list_.size());
359
360 new_properties[MM_SIM_PROPERTY_OPERATORNAME].writer().
361 append_string(kOperatorName);
362 capability_->OnDBusPropertiesChanged(MM_DBUS_INTERFACE_SIM,
363 new_properties,
364 vector<string>());
365 EXPECT_EQ(kOperatorName, cellular_->home_provider().GetName());
Jason Glasgowaf583282012-04-18 15:18:22 -0400366 EXPECT_EQ(kOperatorName, capability_->spn_);
367}
368
Jason Glasgowef965562012-04-10 16:12:35 -0400369} // namespace shill