1 //
2 // Copyright (C) 2012 The Android Open Source Project
3 //
4 // Licensed under the Apache License, Version 2.0 (the "License");
5 // you may not use this file except in compliance with the License.
6 // You may obtain a copy of the License at
7 //
8 //      http://www.apache.org/licenses/LICENSE-2.0
9 //
10 // Unless required by applicable law or agreed to in writing, software
11 // distributed under the License is distributed on an "AS IS" BASIS,
12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 // See the License for the specific language governing permissions and
14 // limitations under the License.
15 //
16 
17 #include "shill/cellular/cellular_capability_gsm.h"
18 
19 #include <string>
20 #include <vector>
21 
22 #include <base/bind.h>
23 #include <base/strings/stringprintf.h>
24 #if defined(__ANDROID__)
25 #include <dbus/service_constants.h>
26 #else
27 #include <chromeos/dbus/service_constants.h>
28 #endif  // __ANDROID__
29 #include <mm/mm-modem.h>
30 
31 #include "shill/cellular/cellular.h"
32 #include "shill/cellular/cellular_service.h"
33 #include "shill/cellular/mock_mobile_operator_info.h"
34 #include "shill/cellular/mock_modem_gsm_card_proxy.h"
35 #include "shill/cellular/mock_modem_gsm_network_proxy.h"
36 #include "shill/cellular/mock_modem_info.h"
37 #include "shill/cellular/mock_modem_proxy.h"
38 #include "shill/cellular/mock_modem_simple_proxy.h"
39 #include "shill/error.h"
40 #include "shill/mock_adaptors.h"
41 #include "shill/mock_control.h"
42 #include "shill/mock_log.h"
43 #include "shill/mock_profile.h"
44 #include "shill/test_event_dispatcher.h"
45 #include "shill/testing.h"
46 
47 using base::Bind;
48 using base::StringPrintf;
49 using base::Unretained;
50 using std::string;
51 using std::vector;
52 using testing::_;
53 using testing::Invoke;
54 using testing::NiceMock;
55 using testing::Return;
56 using testing::SaveArg;
57 
58 namespace shill {
59 
60 class CellularCapabilityGSMTest : public testing::Test {
61  public:
CellularCapabilityGSMTest()62   CellularCapabilityGSMTest()
63       : control_interface_(this),
64         modem_info_(&control_interface_, &dispatcher_, nullptr, nullptr),
65         create_card_proxy_from_factory_(false),
66         proxy_(new MockModemProxy()),
67         simple_proxy_(new MockModemSimpleProxy()),
68         card_proxy_(new MockModemGSMCardProxy()),
69         network_proxy_(new MockModemGSMNetworkProxy()),
70         capability_(nullptr),
71         device_adaptor_(nullptr),
72         cellular_(new Cellular(&modem_info_,
73                                "",
74                                kAddress,
75                                0,
76                                Cellular::kTypeGSM,
77                                "",
78                                "")),
79         mock_home_provider_info_(nullptr),
80         mock_serving_operator_info_(nullptr) {
81     modem_info_.metrics()->RegisterDevice(cellular_->interface_index(),
82                                           Technology::kCellular);
83   }
84 
~CellularCapabilityGSMTest()85   virtual ~CellularCapabilityGSMTest() {
86     cellular_->service_ = nullptr;
87     capability_ = nullptr;
88     device_adaptor_ = nullptr;
89   }
90 
SetUp()91   virtual void SetUp() {
92     capability_ =
93         static_cast<CellularCapabilityGSM*>(cellular_->capability_.get());
94     device_adaptor_ =
95         static_cast<DeviceMockAdaptor*>(cellular_->adaptor());
96   }
97 
InvokeEnable(bool enable,Error * error,const ResultCallback & callback,int timeout)98   void InvokeEnable(bool enable, Error* error,
99                     const ResultCallback& callback, int timeout) {
100     callback.Run(Error());
101   }
InvokeGetIMEI(Error * error,const GSMIdentifierCallback & callback,int timeout)102   void InvokeGetIMEI(Error* error, const GSMIdentifierCallback& callback,
103                      int timeout) {
104     callback.Run(kIMEI, Error());
105   }
InvokeGetIMSI(Error * error,const GSMIdentifierCallback & callback,int timeout)106   void InvokeGetIMSI(Error* error, const GSMIdentifierCallback& callback,
107                      int timeout) {
108     callback.Run(kIMSI, Error());
109   }
InvokeGetIMSIFails(Error * error,const GSMIdentifierCallback & callback,int timeout)110   void InvokeGetIMSIFails(Error* error, const GSMIdentifierCallback& callback,
111                           int timeout) {
112     callback.Run("", Error(Error::kOperationFailed));
113   }
InvokeGetMSISDN(Error * error,const GSMIdentifierCallback & callback,int timeout)114   void InvokeGetMSISDN(Error* error, const GSMIdentifierCallback& callback,
115                        int timeout) {
116     callback.Run(kMSISDN, Error());
117   }
InvokeGetMSISDNFail(Error * error,const GSMIdentifierCallback & callback,int timeout)118   void InvokeGetMSISDNFail(Error* error, const GSMIdentifierCallback& callback,
119                            int timeout) {
120     callback.Run("", Error(Error::kOperationFailed));
121   }
InvokeGetSPN(Error * error,const GSMIdentifierCallback & callback,int timeout)122   void InvokeGetSPN(Error* error, const GSMIdentifierCallback& callback,
123                     int timeout) {
124     callback.Run(kTestCarrier, Error());
125   }
InvokeGetSPNFail(Error * error,const GSMIdentifierCallback & callback,int timeout)126   void InvokeGetSPNFail(Error* error, const GSMIdentifierCallback& callback,
127                         int timeout) {
128     callback.Run("", Error(Error::kOperationFailed));
129   }
InvokeGetSignalQuality(Error * error,const SignalQualityCallback & callback,int timeout)130   void InvokeGetSignalQuality(Error* error,
131                               const SignalQualityCallback& callback,
132                               int timeout) {
133     callback.Run(kStrength, Error());
134   }
InvokeGetRegistrationInfo(Error * error,const RegistrationInfoCallback & callback,int timeout)135   void InvokeGetRegistrationInfo(Error* error,
136                                  const RegistrationInfoCallback& callback,
137                                  int timeout) {
138     callback.Run(MM_MODEM_GSM_NETWORK_REG_STATUS_HOME,
139                  kTestNetwork, kTestCarrier, Error());
140   }
InvokeRegister(const string & network_id,Error * error,const ResultCallback & callback,int timeout)141   void InvokeRegister(const string& network_id,
142                       Error* error,
143                       const ResultCallback& callback,
144                       int timeout) {
145     callback.Run(Error());
146   }
InvokeEnablePIN(const string & pin,bool enable,Error * error,const ResultCallback & callback,int timeout)147   void InvokeEnablePIN(const string& pin, bool enable,
148                        Error* error, const ResultCallback& callback,
149                        int timeout) {
150     callback.Run(Error());
151   }
InvokeSendPIN(const string & pin,Error * error,const ResultCallback & callback,int timeout)152   void InvokeSendPIN(const string& pin, Error* error,
153                      const ResultCallback& callback, int timeout) {
154     callback.Run(Error());
155   }
InvokeSendPUK(const string & puk,const string & pin,Error * error,const ResultCallback & callback,int timeout)156   void InvokeSendPUK(const string& puk, const string& pin, Error* error,
157                      const ResultCallback& callback, int timeout) {
158     callback.Run(Error());
159   }
InvokeChangePIN(const string & old_pin,const string & pin,Error * error,const ResultCallback & callback,int timeout)160   void InvokeChangePIN(const string& old_pin, const string& pin, Error* error,
161                        const ResultCallback& callback, int timeout) {
162     callback.Run(Error());
163   }
InvokeGetModemStatus(Error * error,const KeyValueStoreCallback & callback,int timeout)164   void InvokeGetModemStatus(Error* error,
165                             const KeyValueStoreCallback& callback,
166                             int timeout) {
167     KeyValueStore props;
168     callback.Run(props, Error());
169   }
InvokeGetModemInfo(Error * error,const ModemInfoCallback & callback,int timeout)170   void InvokeGetModemInfo(Error* error, const ModemInfoCallback& callback,
171                           int timeout) {
172     callback.Run("", "", "", Error());
173   }
174 
InvokeConnectFail(KeyValueStore props,Error * error,const ResultCallback & callback,int timeout)175   void InvokeConnectFail(KeyValueStore props, Error* error,
176                          const ResultCallback& callback, int timeout) {
177     callback.Run(Error(Error::kOperationFailed));
178   }
179 
180   MOCK_METHOD1(TestCallback, void(const Error& error));
181 
182  protected:
183   static const char kAddress[];
184   static const char kTestMobileProviderDBPath[];
185   static const char kTestNetwork[];
186   static const char kTestCarrier[];
187   static const char kPIN[];
188   static const char kPUK[];
189   static const char kIMEI[];
190   static const char kIMSI[];
191   static const char kMSISDN[];
192   static const int kStrength;
193 
194   class TestControl : public MockControl {
195    public:
TestControl(CellularCapabilityGSMTest * test)196     explicit TestControl(CellularCapabilityGSMTest* test) : test_(test) {}
197 
CreateModemProxy(const string &,const string &)198     virtual ModemProxyInterface* CreateModemProxy(
199         const string& /*path*/,
200         const string& /*service*/) {
201       return test_->proxy_.release();
202     }
203 
CreateModemSimpleProxy(const string &,const string &)204     virtual ModemSimpleProxyInterface* CreateModemSimpleProxy(
205         const string& /*path*/,
206         const string& /*service*/) {
207       return test_->simple_proxy_.release();
208     }
209 
CreateModemGSMCardProxy(const string &,const string &)210     virtual ModemGSMCardProxyInterface* CreateModemGSMCardProxy(
211         const string& /*path*/,
212         const string& /*service*/) {
213       // TODO(benchan): This code conditionally returns a nullptr to avoid
214       // CellularCapabilityGSM::InitProperties (and thus
215       // CellularCapabilityGSM::GetIMSI) from being called during the
216       // construction. Remove this workaround after refactoring the tests.
217       return test_->create_card_proxy_from_factory_ ?
218           test_->card_proxy_.release() : nullptr;
219     }
220 
CreateModemGSMNetworkProxy(const string &,const string &)221     virtual ModemGSMNetworkProxyInterface* CreateModemGSMNetworkProxy(
222         const string& /*path*/,
223         const string& /*service*/) {
224       return test_->network_proxy_.release();
225     }
226 
227    private:
228     CellularCapabilityGSMTest* test_;
229   };
230 
SetProxy()231   void SetProxy() {
232     capability_->proxy_.reset(proxy_.release());
233   }
234 
SetCardProxy()235   void SetCardProxy() {
236     capability_->card_proxy_.reset(card_proxy_.release());
237   }
238 
SetNetworkProxy()239   void SetNetworkProxy() {
240     capability_->network_proxy_.reset(network_proxy_.release());
241   }
242 
SetAccessTechnology(uint32_t technology)243   void SetAccessTechnology(uint32_t technology) {
244     capability_->access_technology_ = technology;
245   }
246 
SetRegistrationState(uint32_t state)247   void SetRegistrationState(uint32_t state) {
248     capability_->registration_state_ = state;
249   }
250 
CreateService()251   void CreateService() {
252     // The following constants are never directly accessed by the tests.
253     const char kStorageIdentifier[] = "default_test_storage_id";
254     const char kFriendlyServiceName[] = "default_test_service_name";
255     const char kOperatorCode[] = "10010";
256     const char kOperatorName[] = "default_test_operator_name";
257     const char kOperatorCountry[] = "us";
258 
259     // Simulate all the side-effects of Cellular::CreateService
260     auto service = new CellularService(&modem_info_, cellular_);
261     service->SetStorageIdentifier(kStorageIdentifier);
262     service->SetFriendlyName(kFriendlyServiceName);
263 
264     Stringmap serving_operator;
265     serving_operator[kOperatorCodeKey] = kOperatorCode;
266     serving_operator[kOperatorNameKey] = kOperatorName;
267     serving_operator[kOperatorCountryKey] = kOperatorCountry;
268 
269     service->set_serving_operator(serving_operator);
270     cellular_->set_home_provider(serving_operator);
271     cellular_->service_ = service;
272   }
273 
SetMockMobileOperatorInfoObjects()274   void SetMockMobileOperatorInfoObjects() {
275     CHECK(!mock_home_provider_info_);
276     CHECK(!mock_serving_operator_info_);
277     mock_home_provider_info_ =
278         new MockMobileOperatorInfo(&dispatcher_, "HomeProvider");
279     mock_serving_operator_info_ =
280         new MockMobileOperatorInfo(&dispatcher_, "ServingOperator");
281     cellular_->set_home_provider_info(mock_home_provider_info_);
282     cellular_->set_serving_operator_info(mock_serving_operator_info_);
283   }
284 
SetupCommonProxiesExpectations()285   void SetupCommonProxiesExpectations() {
286     EXPECT_CALL(*proxy_, set_state_changed_callback(_));
287     EXPECT_CALL(*network_proxy_, set_signal_quality_callback(_));
288     EXPECT_CALL(*network_proxy_, set_network_mode_callback(_));
289     EXPECT_CALL(*network_proxy_, set_registration_info_callback(_));
290   }
291 
SetupCommonStartModemExpectations()292   void SetupCommonStartModemExpectations() {
293     SetupCommonProxiesExpectations();
294 
295     EXPECT_CALL(*proxy_, Enable(_, _, _, CellularCapability::kTimeoutEnable))
296         .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeEnable));
297     EXPECT_CALL(*card_proxy_,
298                 GetIMEI(_, _, CellularCapability::kTimeoutDefault))
299         .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetIMEI));
300     EXPECT_CALL(*card_proxy_,
301                 GetIMSI(_, _, CellularCapability::kTimeoutDefault))
302         .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetIMSI));
303     EXPECT_CALL(*network_proxy_, AccessTechnology());
304     EXPECT_CALL(*card_proxy_, EnabledFacilityLocks());
305     EXPECT_CALL(*proxy_,
306                 GetModemInfo(_, _, CellularCapability::kTimeoutDefault))
307         .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetModemInfo));
308     EXPECT_CALL(*network_proxy_,
309                 GetRegistrationInfo(_, _, CellularCapability::kTimeoutDefault));
310     EXPECT_CALL(*network_proxy_,
311                 GetSignalQuality(_, _, CellularCapability::kTimeoutDefault));
312     EXPECT_CALL(*this, TestCallback(IsSuccess()));
313   }
314 
InitProxies()315   void InitProxies() {
316     AllowCreateCardProxyFromFactory();
317     capability_->InitProxies();
318   }
319 
AllowCreateCardProxyFromFactory()320   void AllowCreateCardProxyFromFactory() {
321     create_card_proxy_from_factory_ = true;
322   }
323 
324   EventDispatcherForTest dispatcher_;
325   TestControl control_interface_;
326   MockModemInfo modem_info_;
327   bool create_card_proxy_from_factory_;
328   std::unique_ptr<MockModemProxy> proxy_;
329   std::unique_ptr<MockModemSimpleProxy> simple_proxy_;
330   std::unique_ptr<MockModemGSMCardProxy> card_proxy_;
331   std::unique_ptr<MockModemGSMNetworkProxy> network_proxy_;
332   CellularCapabilityGSM* capability_;  // Owned by |cellular_|.
333   DeviceMockAdaptor* device_adaptor_;  // Owned by |cellular_|.
334   CellularRefPtr cellular_;
335 
336   // Set when required and passed to |cellular_|. Owned by |cellular_|.
337   MockMobileOperatorInfo* mock_home_provider_info_;
338   MockMobileOperatorInfo* mock_serving_operator_info_;
339 };
340 
341 const char CellularCapabilityGSMTest::kAddress[] = "1122334455";
342 const char CellularCapabilityGSMTest::kTestMobileProviderDBPath[] =
343     "provider_db_unittest.bfd";
344 const char CellularCapabilityGSMTest::kTestCarrier[] = "The Cellular Carrier";
345 const char CellularCapabilityGSMTest::kTestNetwork[] = "310555";
346 const char CellularCapabilityGSMTest::kPIN[] = "9876";
347 const char CellularCapabilityGSMTest::kPUK[] = "8765";
348 const char CellularCapabilityGSMTest::kIMEI[] = "987654321098765";
349 const char CellularCapabilityGSMTest::kIMSI[] = "310150123456789";
350 const char CellularCapabilityGSMTest::kMSISDN[] = "12345678901";
351 const int CellularCapabilityGSMTest::kStrength = 80;
352 
TEST_F(CellularCapabilityGSMTest,PropertyStore)353 TEST_F(CellularCapabilityGSMTest, PropertyStore) {
354   EXPECT_TRUE(cellular_->store().Contains(kSIMLockStatusProperty));
355 }
356 
TEST_F(CellularCapabilityGSMTest,GetIMEI)357 TEST_F(CellularCapabilityGSMTest, GetIMEI) {
358   EXPECT_CALL(*card_proxy_, GetIMEI(_, _, CellularCapability::kTimeoutDefault))
359       .WillOnce(Invoke(this,
360                        &CellularCapabilityGSMTest::InvokeGetIMEI));
361   EXPECT_CALL(*this, TestCallback(IsSuccess()));
362   SetCardProxy();
363   ASSERT_TRUE(cellular_->imei().empty());
364   capability_->GetIMEI(Bind(&CellularCapabilityGSMTest::TestCallback,
365                             Unretained(this)));
366   EXPECT_EQ(kIMEI, cellular_->imei());
367 }
368 
TEST_F(CellularCapabilityGSMTest,GetIMSI)369 TEST_F(CellularCapabilityGSMTest, GetIMSI) {
370   SetMockMobileOperatorInfoObjects();
371   EXPECT_CALL(*card_proxy_, GetIMSI(_, _, CellularCapability::kTimeoutDefault))
372       .WillOnce(Invoke(this,
373                        &CellularCapabilityGSMTest::InvokeGetIMSI));
374   EXPECT_CALL(*this, TestCallback(IsSuccess()));
375   SetCardProxy();
376   ResultCallback callback = Bind(&CellularCapabilityGSMTest::TestCallback,
377                                  Unretained(this));
378   EXPECT_TRUE(cellular_->imsi().empty());
379   EXPECT_FALSE(cellular_->sim_present());
380   EXPECT_CALL(*mock_home_provider_info_, UpdateIMSI(kIMSI));
381   capability_->GetIMSI(callback);
382   EXPECT_EQ(kIMSI, cellular_->imsi());
383   EXPECT_TRUE(cellular_->sim_present());
384 }
385 
386 // In this test, the call to the proxy's GetIMSI() will always indicate failure,
387 // which will cause the retry logic to call the proxy again a number of times.
388 // Eventually, the retries expire.
TEST_F(CellularCapabilityGSMTest,GetIMSIFails)389 TEST_F(CellularCapabilityGSMTest, GetIMSIFails) {
390   ScopedMockLog log;
391   EXPECT_CALL(log, Log(logging::LOG_INFO,
392                        ::testing::EndsWith("cellular_capability_gsm.cc"),
393                        ::testing::StartsWith("GetIMSI failed - ")));
394   EXPECT_CALL(*card_proxy_, GetIMSI(_, _, CellularCapability::kTimeoutDefault))
395       .Times(CellularCapabilityGSM::kGetIMSIRetryLimit + 2)
396       .WillRepeatedly(Invoke(this,
397                              &CellularCapabilityGSMTest::InvokeGetIMSIFails));
398   EXPECT_CALL(*this, TestCallback(IsFailure())).Times(2);
399   SetCardProxy();
400   ResultCallback callback = Bind(&CellularCapabilityGSMTest::TestCallback,
401                                  Unretained(this));
402   EXPECT_TRUE(cellular_->imsi().empty());
403   EXPECT_FALSE(cellular_->sim_present());
404 
405   capability_->sim_lock_status_.lock_type = "sim-pin";
406   capability_->GetIMSI(callback);
407   EXPECT_TRUE(cellular_->imsi().empty());
408   EXPECT_TRUE(cellular_->sim_present());
409 
410   capability_->sim_lock_status_.lock_type.clear();
411   cellular_->set_sim_present(false);
412   capability_->get_imsi_retries_ = 0;
413   EXPECT_EQ(CellularCapabilityGSM::kGetIMSIRetryDelayMilliseconds,
414             capability_->get_imsi_retry_delay_milliseconds_);
415 
416   // Set the delay to zero to speed up the test.
417   capability_->get_imsi_retry_delay_milliseconds_ = 0;
418   capability_->GetIMSI(callback);
419   for (int i = 0; i < CellularCapabilityGSM::kGetIMSIRetryLimit; ++i) {
420     dispatcher_.DispatchPendingEvents();
421   }
422   EXPECT_EQ(CellularCapabilityGSM::kGetIMSIRetryLimit + 1,
423             capability_->get_imsi_retries_);
424   EXPECT_TRUE(cellular_->imsi().empty());
425   EXPECT_FALSE(cellular_->sim_present());
426 }
427 
TEST_F(CellularCapabilityGSMTest,GetMSISDN)428 TEST_F(CellularCapabilityGSMTest, GetMSISDN) {
429   EXPECT_CALL(*card_proxy_, GetMSISDN(_, _,
430                                       CellularCapability::kTimeoutDefault))
431       .WillOnce(Invoke(this,
432                        &CellularCapabilityGSMTest::InvokeGetMSISDN));
433   EXPECT_CALL(*this, TestCallback(IsSuccess()));
434   SetCardProxy();
435   ASSERT_TRUE(cellular_->mdn().empty());
436   capability_->GetMSISDN(Bind(&CellularCapabilityGSMTest::TestCallback,
437                             Unretained(this)));
438   EXPECT_EQ(kMSISDN, cellular_->mdn());
439 }
440 
TEST_F(CellularCapabilityGSMTest,GetSPN)441 TEST_F(CellularCapabilityGSMTest, GetSPN) {
442   EXPECT_CALL(*card_proxy_, GetSPN(_, _, CellularCapability::kTimeoutDefault))
443       .WillOnce(Invoke(this,
444                        &CellularCapabilityGSMTest::InvokeGetSPN));
445   EXPECT_CALL(*this, TestCallback(IsSuccess()));
446   SetCardProxy();
447   ASSERT_TRUE(capability_->spn_.empty());
448   capability_->GetSPN(Bind(&CellularCapabilityGSMTest::TestCallback,
449                             Unretained(this)));
450   EXPECT_EQ(kTestCarrier, capability_->spn_);
451 }
452 
TEST_F(CellularCapabilityGSMTest,GetSignalQuality)453 TEST_F(CellularCapabilityGSMTest, GetSignalQuality) {
454   EXPECT_CALL(*network_proxy_,
455               GetSignalQuality(_, _, CellularCapability::kTimeoutDefault))
456       .WillOnce(Invoke(this,
457                        &CellularCapabilityGSMTest::InvokeGetSignalQuality));
458   SetNetworkProxy();
459   CreateService();
460   EXPECT_EQ(0, cellular_->service()->strength());
461   capability_->GetSignalQuality();
462   EXPECT_EQ(kStrength, cellular_->service()->strength());
463 }
464 
TEST_F(CellularCapabilityGSMTest,RegisterOnNetwork)465 TEST_F(CellularCapabilityGSMTest, RegisterOnNetwork) {
466   EXPECT_CALL(*network_proxy_, Register(kTestNetwork, _, _,
467                                         CellularCapability::kTimeoutRegister))
468       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeRegister));
469   EXPECT_CALL(*this, TestCallback(IsSuccess()));
470   SetNetworkProxy();
471   Error error;
472   capability_->RegisterOnNetwork(kTestNetwork, &error,
473                                  Bind(&CellularCapabilityGSMTest::TestCallback,
474                                       Unretained(this)));
475   EXPECT_EQ(kTestNetwork, cellular_->selected_network());
476 }
477 
TEST_F(CellularCapabilityGSMTest,IsRegistered)478 TEST_F(CellularCapabilityGSMTest, IsRegistered) {
479   EXPECT_FALSE(capability_->IsRegistered());
480   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE);
481   EXPECT_FALSE(capability_->IsRegistered());
482   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_HOME);
483   EXPECT_TRUE(capability_->IsRegistered());
484   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING);
485   EXPECT_FALSE(capability_->IsRegistered());
486   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED);
487   EXPECT_FALSE(capability_->IsRegistered());
488   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_UNKNOWN);
489   EXPECT_FALSE(capability_->IsRegistered());
490   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING);
491   EXPECT_TRUE(capability_->IsRegistered());
492 }
493 
TEST_F(CellularCapabilityGSMTest,GetRegistrationState)494 TEST_F(CellularCapabilityGSMTest, GetRegistrationState) {
495   ASSERT_FALSE(capability_->IsRegistered());
496   EXPECT_CALL(*network_proxy_,
497               GetRegistrationInfo(_, _, CellularCapability::kTimeoutDefault))
498       .WillOnce(Invoke(this,
499                        &CellularCapabilityGSMTest::InvokeGetRegistrationInfo));
500   SetNetworkProxy();
501   capability_->GetRegistrationState();
502   EXPECT_TRUE(capability_->IsRegistered());
503   EXPECT_EQ(MM_MODEM_GSM_NETWORK_REG_STATUS_HOME,
504             capability_->registration_state_);
505 }
506 
TEST_F(CellularCapabilityGSMTest,RequirePIN)507 TEST_F(CellularCapabilityGSMTest, RequirePIN) {
508   EXPECT_CALL(*card_proxy_, EnablePIN(kPIN, true, _, _,
509                                       CellularCapability::kTimeoutDefault))
510       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeEnablePIN));
511   EXPECT_CALL(*this, TestCallback(IsSuccess()));
512   SetCardProxy();
513   Error error;
514   capability_->RequirePIN(kPIN, true, &error,
515                           Bind(&CellularCapabilityGSMTest::TestCallback,
516                                Unretained(this)));
517   EXPECT_TRUE(error.IsSuccess());
518 }
519 
TEST_F(CellularCapabilityGSMTest,EnterPIN)520 TEST_F(CellularCapabilityGSMTest, EnterPIN) {
521   EXPECT_CALL(*card_proxy_, SendPIN(kPIN, _, _,
522                                     CellularCapability::kTimeoutDefault))
523       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeSendPIN));
524   EXPECT_CALL(*this, TestCallback(IsSuccess()));
525   SetCardProxy();
526   Error error;
527   capability_->EnterPIN(kPIN, &error,
528                         Bind(&CellularCapabilityGSMTest::TestCallback,
529                              Unretained(this)));
530   EXPECT_TRUE(error.IsSuccess());
531 }
532 
TEST_F(CellularCapabilityGSMTest,UnblockPIN)533 TEST_F(CellularCapabilityGSMTest, UnblockPIN) {
534   EXPECT_CALL(*card_proxy_, SendPUK(kPUK, kPIN, _, _,
535                                     CellularCapability::kTimeoutDefault))
536       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeSendPUK));
537   EXPECT_CALL(*this, TestCallback(IsSuccess()));
538   SetCardProxy();
539   Error error;
540   capability_->UnblockPIN(kPUK, kPIN, &error,
541                           Bind(&CellularCapabilityGSMTest::TestCallback,
542                              Unretained(this)));
543   EXPECT_TRUE(error.IsSuccess());
544 }
545 
TEST_F(CellularCapabilityGSMTest,ChangePIN)546 TEST_F(CellularCapabilityGSMTest, ChangePIN) {
547   static const char kOldPIN[] = "1111";
548   EXPECT_CALL(*card_proxy_, ChangePIN(kOldPIN, kPIN, _, _,
549                                     CellularCapability::kTimeoutDefault))
550       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeChangePIN));
551   EXPECT_CALL(*this, TestCallback(IsSuccess()));
552   SetCardProxy();
553   Error error;
554   capability_->ChangePIN(kOldPIN, kPIN, &error,
555                          Bind(&CellularCapabilityGSMTest::TestCallback,
556                              Unretained(this)));
557   EXPECT_TRUE(error.IsSuccess());
558 }
559 
560 
TEST_F(CellularCapabilityGSMTest,ParseScanResult)561 TEST_F(CellularCapabilityGSMTest, ParseScanResult) {
562   static const char kID[] = "123";
563   static const char kLongName[] = "long name";
564   static const char kShortName[] = "short name";
565   GSMScanResult result;
566   result[CellularCapabilityGSM::kNetworkPropertyStatus] = "1";
567   result[CellularCapabilityGSM::kNetworkPropertyID] = kID;
568   result[CellularCapabilityGSM::kNetworkPropertyLongName] = kLongName;
569   result[CellularCapabilityGSM::kNetworkPropertyShortName] = kShortName;
570   result[CellularCapabilityGSM::kNetworkPropertyAccessTechnology] = "3";
571   result["unknown property"] = "random value";
572   Stringmap parsed = capability_->ParseScanResult(result);
573   EXPECT_EQ(5, parsed.size());
574   EXPECT_EQ("available", parsed[kStatusProperty]);
575   EXPECT_EQ(kID, parsed[kNetworkIdProperty]);
576   EXPECT_EQ(kLongName, parsed[kLongNameProperty]);
577   EXPECT_EQ(kShortName, parsed[kShortNameProperty]);
578   EXPECT_EQ(kNetworkTechnologyEdge, parsed[kTechnologyProperty]);
579 }
580 
TEST_F(CellularCapabilityGSMTest,ParseScanResultProviderLookup)581 TEST_F(CellularCapabilityGSMTest, ParseScanResultProviderLookup) {
582   static const char kID[] = "10001";
583   const string kLongName = "TestNetworkLongName";
584   // Replace the |MobileOperatorInfo| used by |ParseScanResult| by a mock.
585   auto* mock_mobile_operator_info = new MockMobileOperatorInfo(
586       &dispatcher_,
587       "MockParseScanResult");
588   capability_->mobile_operator_info_.reset(mock_mobile_operator_info);
589 
590   mock_mobile_operator_info->SetEmptyDefaultsForProperties();
591   EXPECT_CALL(*mock_mobile_operator_info, UpdateMCCMNC(kID));
592   EXPECT_CALL(*mock_mobile_operator_info, IsMobileNetworkOperatorKnown()).
593       WillOnce(Return(true));
594   EXPECT_CALL(*mock_mobile_operator_info, operator_name()).
595       WillRepeatedly(ReturnRef(kLongName));
596   GSMScanResult result;
597   result[CellularCapabilityGSM::kNetworkPropertyID] = kID;
598   Stringmap parsed = capability_->ParseScanResult(result);
599   EXPECT_EQ(2, parsed.size());
600   EXPECT_EQ(kID, parsed[kNetworkIdProperty]);
601   EXPECT_EQ(kLongName, parsed[kLongNameProperty]);
602 }
603 
TEST_F(CellularCapabilityGSMTest,SetAccessTechnology)604 TEST_F(CellularCapabilityGSMTest, SetAccessTechnology) {
605   capability_->SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_GSM);
606   EXPECT_EQ(MM_MODEM_GSM_ACCESS_TECH_GSM, capability_->access_technology_);
607   CreateService();
608   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_HOME);
609   capability_->SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_GPRS);
610   EXPECT_EQ(MM_MODEM_GSM_ACCESS_TECH_GPRS, capability_->access_technology_);
611   EXPECT_EQ(kNetworkTechnologyGprs, cellular_->service()->network_technology());
612 }
613 
TEST_F(CellularCapabilityGSMTest,AllowRoaming)614 TEST_F(CellularCapabilityGSMTest, AllowRoaming) {
615   EXPECT_FALSE(cellular_->allow_roaming_);
616   EXPECT_FALSE(cellular_->provider_requires_roaming());
617   EXPECT_FALSE(capability_->AllowRoaming());
618   cellular_->set_provider_requires_roaming(true);
619   EXPECT_TRUE(capability_->AllowRoaming());
620   cellular_->set_provider_requires_roaming(false);
621   cellular_->allow_roaming_ = true;
622   EXPECT_TRUE(capability_->AllowRoaming());
623 }
624 
TEST_F(CellularCapabilityGSMTest,GetNetworkTechnologyString)625 TEST_F(CellularCapabilityGSMTest, GetNetworkTechnologyString) {
626   EXPECT_EQ("", capability_->GetNetworkTechnologyString());
627   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_GSM);
628   EXPECT_EQ(kNetworkTechnologyGsm, capability_->GetNetworkTechnologyString());
629   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_GSM_COMPACT);
630   EXPECT_EQ(kNetworkTechnologyGsm, capability_->GetNetworkTechnologyString());
631   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_GPRS);
632   EXPECT_EQ(kNetworkTechnologyGprs, capability_->GetNetworkTechnologyString());
633   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_EDGE);
634   EXPECT_EQ(kNetworkTechnologyEdge, capability_->GetNetworkTechnologyString());
635   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_UMTS);
636   EXPECT_EQ(kNetworkTechnologyUmts, capability_->GetNetworkTechnologyString());
637   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_HSDPA);
638   EXPECT_EQ(kNetworkTechnologyHspa, capability_->GetNetworkTechnologyString());
639   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_HSUPA);
640   EXPECT_EQ(kNetworkTechnologyHspa, capability_->GetNetworkTechnologyString());
641   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_HSPA);
642   EXPECT_EQ(kNetworkTechnologyHspa, capability_->GetNetworkTechnologyString());
643   SetAccessTechnology(MM_MODEM_GSM_ACCESS_TECH_HSPA_PLUS);
644   EXPECT_EQ(kNetworkTechnologyHspaPlus,
645             capability_->GetNetworkTechnologyString());
646 }
647 
TEST_F(CellularCapabilityGSMTest,GetRoamingStateString)648 TEST_F(CellularCapabilityGSMTest, GetRoamingStateString) {
649   EXPECT_EQ(kRoamingStateUnknown, capability_->GetRoamingStateString());
650   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_HOME);
651   EXPECT_EQ(kRoamingStateHome, capability_->GetRoamingStateString());
652   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_ROAMING);
653   EXPECT_EQ(kRoamingStateRoaming, capability_->GetRoamingStateString());
654   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_SEARCHING);
655   EXPECT_EQ(kRoamingStateUnknown, capability_->GetRoamingStateString());
656   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_DENIED);
657   EXPECT_EQ(kRoamingStateUnknown, capability_->GetRoamingStateString());
658   SetRegistrationState(MM_MODEM_GSM_NETWORK_REG_STATUS_IDLE);
659   EXPECT_EQ(kRoamingStateUnknown, capability_->GetRoamingStateString());
660 }
661 
TEST_F(CellularCapabilityGSMTest,OnPropertiesChanged)662 TEST_F(CellularCapabilityGSMTest, OnPropertiesChanged) {
663   EXPECT_EQ(MM_MODEM_GSM_ACCESS_TECH_UNKNOWN, capability_->access_technology_);
664   EXPECT_FALSE(capability_->sim_lock_status_.enabled);
665   EXPECT_EQ("", capability_->sim_lock_status_.lock_type);
666   EXPECT_EQ(0, capability_->sim_lock_status_.retries_left);
667   KeyValueStore props;
668   static const char kLockType[] = "sim-pin";
669   const int kRetries = 3;
670   props.SetUint(CellularCapabilityGSM::kPropertyAccessTechnology,
671                 MM_MODEM_GSM_ACCESS_TECH_EDGE);
672   props.SetUint(CellularCapabilityGSM::kPropertyEnabledFacilityLocks,
673                 MM_MODEM_GSM_FACILITY_SIM);
674   props.SetString(CellularCapabilityGSM::kPropertyUnlockRequired, kLockType);
675   props.SetUint(CellularCapabilityGSM::kPropertyUnlockRetries, kRetries);
676   // Call with the 'wrong' interface and nothing should change.
677   capability_->OnPropertiesChanged(MM_MODEM_GSM_INTERFACE, props,
678                                    vector<string>());
679   EXPECT_EQ(MM_MODEM_GSM_ACCESS_TECH_UNKNOWN, capability_->access_technology_);
680   EXPECT_FALSE(capability_->sim_lock_status_.enabled);
681   EXPECT_EQ("", capability_->sim_lock_status_.lock_type);
682   EXPECT_EQ(0, capability_->sim_lock_status_.retries_left);
683 
684   // Call with the MM_MODEM_GSM_NETWORK_INTERFACE interface and expect a change
685   // to the enabled state of the SIM lock.
686   KeyValueStore lock_status;
687   lock_status.SetBool(kSIMLockEnabledProperty, true);
688   lock_status.SetString(kSIMLockTypeProperty, "");
689   lock_status.SetUint(kSIMLockRetriesLeftProperty, 0);
690 
691   EXPECT_CALL(*device_adaptor_, EmitKeyValueStoreChanged(
692       kSIMLockStatusProperty,
693       KeyValueStoreEq(lock_status)));
694 
695   capability_->OnPropertiesChanged(MM_MODEM_GSM_NETWORK_INTERFACE, props,
696                                    vector<string>());
697   EXPECT_EQ(MM_MODEM_GSM_ACCESS_TECH_EDGE, capability_->access_technology_);
698   capability_->OnPropertiesChanged(MM_MODEM_GSM_CARD_INTERFACE, props,
699                                    vector<string>());
700   EXPECT_TRUE(capability_->sim_lock_status_.enabled);
701   EXPECT_TRUE(capability_->sim_lock_status_.lock_type.empty());
702   EXPECT_EQ(0, capability_->sim_lock_status_.retries_left);
703 
704   // Some properties are sent on the MM_MODEM_INTERFACE.
705   capability_->sim_lock_status_.enabled = false;
706   capability_->sim_lock_status_.lock_type = "";
707   capability_->sim_lock_status_.retries_left = 0;
708   KeyValueStore lock_status2;
709   lock_status2.SetBool(kSIMLockEnabledProperty, false);
710   lock_status2.SetString(kSIMLockTypeProperty, kLockType);
711   lock_status2.SetUint(kSIMLockRetriesLeftProperty, kRetries);
712   EXPECT_CALL(*device_adaptor_,
713               EmitKeyValueStoreChanged(kSIMLockStatusProperty,
714                                        KeyValueStoreEq(lock_status2)));
715   capability_->OnPropertiesChanged(MM_MODEM_INTERFACE, props,
716                                    vector<string>());
717   EXPECT_FALSE(capability_->sim_lock_status_.enabled);
718   EXPECT_EQ(kLockType, capability_->sim_lock_status_.lock_type);
719   EXPECT_EQ(kRetries, capability_->sim_lock_status_.retries_left);
720 }
721 
TEST_F(CellularCapabilityGSMTest,StartModemSuccess)722 TEST_F(CellularCapabilityGSMTest, StartModemSuccess) {
723   SetupCommonStartModemExpectations();
724   EXPECT_CALL(*card_proxy_,
725               GetSPN(_, _, CellularCapability::kTimeoutDefault))
726       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetSPN));
727   EXPECT_CALL(*card_proxy_,
728               GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
729       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetMSISDN));
730   AllowCreateCardProxyFromFactory();
731 
732   Error error;
733   capability_->StartModem(
734       &error, Bind(&CellularCapabilityGSMTest::TestCallback, Unretained(this)));
735   dispatcher_.DispatchPendingEvents();
736 }
737 
TEST_F(CellularCapabilityGSMTest,StartModemGetSPNFail)738 TEST_F(CellularCapabilityGSMTest, StartModemGetSPNFail) {
739   SetupCommonStartModemExpectations();
740   EXPECT_CALL(*card_proxy_,
741               GetSPN(_, _, CellularCapability::kTimeoutDefault))
742       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetSPNFail));
743   EXPECT_CALL(*card_proxy_,
744               GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
745       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetMSISDN));
746   AllowCreateCardProxyFromFactory();
747 
748   Error error;
749   capability_->StartModem(
750       &error, Bind(&CellularCapabilityGSMTest::TestCallback, Unretained(this)));
751   dispatcher_.DispatchPendingEvents();
752 }
753 
TEST_F(CellularCapabilityGSMTest,StartModemGetMSISDNFail)754 TEST_F(CellularCapabilityGSMTest, StartModemGetMSISDNFail) {
755   SetupCommonStartModemExpectations();
756   EXPECT_CALL(*card_proxy_,
757               GetSPN(_, _, CellularCapability::kTimeoutDefault))
758       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetSPN));
759   EXPECT_CALL(*card_proxy_,
760               GetMSISDN(_, _, CellularCapability::kTimeoutDefault))
761       .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeGetMSISDNFail));
762   AllowCreateCardProxyFromFactory();
763 
764   Error error;
765   capability_->StartModem(
766       &error, Bind(&CellularCapabilityGSMTest::TestCallback, Unretained(this)));
767   dispatcher_.DispatchPendingEvents();
768 }
769 
TEST_F(CellularCapabilityGSMTest,ConnectFailureNoService)770 TEST_F(CellularCapabilityGSMTest, ConnectFailureNoService) {
771   // Make sure we don't crash if the connect failed and there is no
772   // CellularService object.  This can happen if the modem is enabled and
773   // then quickly disabled.
774   SetupCommonProxiesExpectations();
775   EXPECT_CALL(*simple_proxy_,
776               Connect(_, _, _, CellularCapabilityGSM::kTimeoutConnect))
777        .WillOnce(Invoke(this, &CellularCapabilityGSMTest::InvokeConnectFail));
778   EXPECT_CALL(*this, TestCallback(IsFailure()));
779   InitProxies();
780   EXPECT_FALSE(capability_->cellular()->service());
781   Error error;
782   KeyValueStore props;
783   capability_->Connect(props, &error,
784                        Bind(&CellularCapabilityGSMTest::TestCallback,
785                             Unretained(this)));
786 }
787 
788 }  // namespace shill
789