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
47using base::Bind;
48using base::StringPrintf;
49using base::Unretained;
50using std::string;
51using std::vector;
52using testing::_;
53using testing::Invoke;
54using testing::NiceMock;
55using testing::Return;
56using testing::SaveArg;
57
58namespace shill {
59
60class CellularCapabilityGSMTest : public testing::Test {
61 public:
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
85  virtual ~CellularCapabilityGSMTest() {
86    cellular_->service_ = nullptr;
87    capability_ = nullptr;
88    device_adaptor_ = nullptr;
89  }
90
91  virtual void SetUp() {
92    capability_ =
93        static_cast<CellularCapabilityGSM*>(cellular_->capability_.get());
94    device_adaptor_ =
95        static_cast<DeviceMockAdaptor*>(cellular_->adaptor());
96  }
97
98  void InvokeEnable(bool enable, Error* error,
99                    const ResultCallback& callback, int timeout) {
100    callback.Run(Error());
101  }
102  void InvokeGetIMEI(Error* error, const GSMIdentifierCallback& callback,
103                     int timeout) {
104    callback.Run(kIMEI, Error());
105  }
106  void InvokeGetIMSI(Error* error, const GSMIdentifierCallback& callback,
107                     int timeout) {
108    callback.Run(kIMSI, Error());
109  }
110  void InvokeGetIMSIFails(Error* error, const GSMIdentifierCallback& callback,
111                          int timeout) {
112    callback.Run("", Error(Error::kOperationFailed));
113  }
114  void InvokeGetMSISDN(Error* error, const GSMIdentifierCallback& callback,
115                       int timeout) {
116    callback.Run(kMSISDN, Error());
117  }
118  void InvokeGetMSISDNFail(Error* error, const GSMIdentifierCallback& callback,
119                           int timeout) {
120    callback.Run("", Error(Error::kOperationFailed));
121  }
122  void InvokeGetSPN(Error* error, const GSMIdentifierCallback& callback,
123                    int timeout) {
124    callback.Run(kTestCarrier, Error());
125  }
126  void InvokeGetSPNFail(Error* error, const GSMIdentifierCallback& callback,
127                        int timeout) {
128    callback.Run("", Error(Error::kOperationFailed));
129  }
130  void InvokeGetSignalQuality(Error* error,
131                              const SignalQualityCallback& callback,
132                              int timeout) {
133    callback.Run(kStrength, Error());
134  }
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  }
141  void InvokeRegister(const string& network_id,
142                      Error* error,
143                      const ResultCallback& callback,
144                      int timeout) {
145    callback.Run(Error());
146  }
147  void InvokeEnablePIN(const string& pin, bool enable,
148                       Error* error, const ResultCallback& callback,
149                       int timeout) {
150    callback.Run(Error());
151  }
152  void InvokeSendPIN(const string& pin, Error* error,
153                     const ResultCallback& callback, int timeout) {
154    callback.Run(Error());
155  }
156  void InvokeSendPUK(const string& puk, const string& pin, Error* error,
157                     const ResultCallback& callback, int timeout) {
158    callback.Run(Error());
159  }
160  void InvokeChangePIN(const string& old_pin, const string& pin, Error* error,
161                       const ResultCallback& callback, int timeout) {
162    callback.Run(Error());
163  }
164  void InvokeGetModemStatus(Error* error,
165                            const KeyValueStoreCallback& callback,
166                            int timeout) {
167    KeyValueStore props;
168    callback.Run(props, Error());
169  }
170  void InvokeGetModemInfo(Error* error, const ModemInfoCallback& callback,
171                          int timeout) {
172    callback.Run("", "", "", Error());
173  }
174
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:
196    explicit TestControl(CellularCapabilityGSMTest* test) : test_(test) {}
197
198    virtual ModemProxyInterface* CreateModemProxy(
199        const string& /*path*/,
200        const string& /*service*/) {
201      return test_->proxy_.release();
202    }
203
204    virtual ModemSimpleProxyInterface* CreateModemSimpleProxy(
205        const string& /*path*/,
206        const string& /*service*/) {
207      return test_->simple_proxy_.release();
208    }
209
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
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
231  void SetProxy() {
232    capability_->proxy_.reset(proxy_.release());
233  }
234
235  void SetCardProxy() {
236    capability_->card_proxy_.reset(card_proxy_.release());
237  }
238
239  void SetNetworkProxy() {
240    capability_->network_proxy_.reset(network_proxy_.release());
241  }
242
243  void SetAccessTechnology(uint32_t technology) {
244    capability_->access_technology_ = technology;
245  }
246
247  void SetRegistrationState(uint32_t state) {
248    capability_->registration_state_ = state;
249  }
250
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
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
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
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
315  void InitProxies() {
316    AllowCreateCardProxyFromFactory();
317    capability_->InitProxies();
318  }
319
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
341const char CellularCapabilityGSMTest::kAddress[] = "1122334455";
342const char CellularCapabilityGSMTest::kTestMobileProviderDBPath[] =
343    "provider_db_unittest.bfd";
344const char CellularCapabilityGSMTest::kTestCarrier[] = "The Cellular Carrier";
345const char CellularCapabilityGSMTest::kTestNetwork[] = "310555";
346const char CellularCapabilityGSMTest::kPIN[] = "9876";
347const char CellularCapabilityGSMTest::kPUK[] = "8765";
348const char CellularCapabilityGSMTest::kIMEI[] = "987654321098765";
349const char CellularCapabilityGSMTest::kIMSI[] = "310150123456789";
350const char CellularCapabilityGSMTest::kMSISDN[] = "12345678901";
351const int CellularCapabilityGSMTest::kStrength = 80;
352
353TEST_F(CellularCapabilityGSMTest, PropertyStore) {
354  EXPECT_TRUE(cellular_->store().Contains(kSIMLockStatusProperty));
355}
356
357TEST_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
369TEST_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.
389TEST_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
428TEST_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
441TEST_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
453TEST_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
465TEST_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
478TEST_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
494TEST_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
507TEST_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
520TEST_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
533TEST_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
546TEST_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
561TEST_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
581TEST_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
604TEST_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
614TEST_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
625TEST_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
648TEST_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
662TEST_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
722TEST_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
738TEST_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
754TEST_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
770TEST_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