cellular_capability_universal.h revision 6acd966cabe0d75e0d9ae3f84c727c9b44a899b3
1// Copyright (c) 2013 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#ifndef SHILL_CELLULAR_CELLULAR_CAPABILITY_UNIVERSAL_H_
6#define SHILL_CELLULAR_CELLULAR_CAPABILITY_UNIVERSAL_H_
7
8#include <deque>
9#include <map>
10#include <string>
11#include <vector>
12
13#include <base/memory/weak_ptr.h>
14#include <gtest/gtest_prod.h>  // for FRIEND_TEST
15#include <ModemManager/ModemManager.h>
16
17#include "shill/accessor_interface.h"
18#include "shill/cellular/cellular.h"
19#include "shill/cellular/cellular_bearer.h"
20#include "shill/cellular/cellular_capability.h"
21#include "shill/cellular/mm1_modem_modem3gpp_proxy_interface.h"
22#include "shill/cellular/mm1_modem_proxy_interface.h"
23#include "shill/cellular/mm1_modem_simple_proxy_interface.h"
24#include "shill/cellular/mm1_sim_proxy_interface.h"
25#include "shill/cellular/out_of_credits_detector.h"
26
27struct mobile_provider;
28
29namespace shill {
30
31class ModemInfo;
32
33// CellularCapabilityUniversal handles modems using the
34// org.chromium.ModemManager1 DBUS interface.  This class is used for
35// all types of modems, i.e. CDMA, GSM, and LTE modems.
36class CellularCapabilityUniversal : public CellularCapability {
37 public:
38  typedef std::vector<DBusPropertiesMap> ScanResults;
39  typedef DBusPropertiesMap ScanResult;
40  typedef std::map<uint32_t, uint32_t> LockRetryData;
41
42  // Constants used in connect method call.  Make available to test matchers.
43  // TODO(jglasgow): Generate from modem manager into
44  // ModemManager-names.h.
45  // See http://crbug.com/212909.
46  static const char kConnectPin[];
47  static const char kConnectOperatorId[];
48  static const char kConnectApn[];
49  static const char kConnectIPType[];
50  static const char kConnectUser[];
51  static const char kConnectPassword[];
52  static const char kConnectNumber[];
53  static const char kConnectAllowRoaming[];
54  static const char kConnectRMProtocol[];
55
56  CellularCapabilityUniversal(Cellular *cellular,
57                              ProxyFactory *proxy_factory,
58                              ModemInfo *modem_info);
59  ~CellularCapabilityUniversal() override;
60
61  // Inherited from CellularCapability.
62  std::string GetTypeString() const override;
63  void OnDBusPropertiesChanged(
64      const std::string &interface,
65      const DBusPropertiesMap &changed_properties,
66      const std::vector<std::string> &invalidated_properties) override;
67  // Checks the modem state.  If the state is kModemStateDisabled, then the
68  // modem is enabled.  Otherwise, the enable command is buffered until the
69  // modem becomes disabled.  ModemManager rejects the enable command if the
70  // modem is not disabled, for example, if it is initializing instead.
71  void StartModem(Error *error, const ResultCallback &callback) override;
72  void StopModem(Error *error, const ResultCallback &callback) override;
73  void Reset(Error *error, const ResultCallback &callback) override;
74  bool AreProxiesInitialized() const override;
75  bool IsServiceActivationRequired() const override;
76  void CompleteActivation(Error *error) override;
77  void Scan(Error *error, const ResultStringmapsCallback &callback) override;
78  void RegisterOnNetwork(const std::string &network_id,
79                         Error *error,
80                         const ResultCallback &callback) override;
81  bool IsRegistered() const override;
82  void SetUnregistered(bool searching) override;
83  void OnServiceCreated() override;
84  std::string GetNetworkTechnologyString() const override;
85  std::string GetRoamingStateString() const override;
86  bool AllowRoaming() override;
87  void GetSignalQuality() override;
88  void SetupConnectProperties(DBusPropertiesMap *properties) override;
89  void Connect(const DBusPropertiesMap &properties,
90               Error *error,
91               const ResultCallback &callback) override;
92  void Disconnect(Error *error, const ResultCallback &callback) override;
93  CellularBearer *GetActiveBearer() const override;
94  void RequirePIN(const std::string &pin,
95                  bool require,
96                  Error *error,
97                  const ResultCallback &callback) override;
98  void EnterPIN(const std::string &pin,
99                Error *error,
100                const ResultCallback &callback) override;
101  void UnblockPIN(const std::string &unblock_code,
102                  const std::string &pin,
103                  Error *error,
104                  const ResultCallback &callback) override;
105  void ChangePIN(const std::string &old_pin,
106                 const std::string &new_pin,
107                 Error *error,
108                 const ResultCallback &callback) override;
109
110  virtual void GetProperties();
111  virtual void Register(const ResultCallback &callback);
112
113 protected:
114  virtual void InitProxies();
115  void ReleaseProxies() override;
116
117  // Updates the |sim_path_| variable and creates a new proxy to the
118  // DBUS ModemManager1.Sim interface.
119  // TODO(armansito): Put this method in a 3GPP-only subclass.
120  virtual void OnSimPathChanged(const std::string &sim_path);
121
122  // Updates the online payment portal information, if any, for the cellular
123  // provider.
124  void UpdateServiceOLP() override;
125
126  // Post-payment activation handlers.
127  virtual void UpdatePendingActivationState();
128
129  // Returns the operator-specific form of |mdn|, which is passed to the online
130  // payment portal of a cellular operator.
131  std::string GetMdnForOLP(const MobileOperatorInfo *operator_info) const;
132
133 private:
134  struct ModemModes {
135    ModemModes()
136        : allowed_modes(MM_MODEM_MODE_NONE),
137          preferred_mode(MM_MODEM_MODE_NONE) {}
138
139    ModemModes(uint32_t allowed, MMModemMode preferred)
140        : allowed_modes(allowed),
141          preferred_mode(preferred) {}
142
143    uint32_t allowed_modes;        // Bits based on MMModemMode.
144    MMModemMode preferred_mode;  // A single MMModemMode bit.
145  };
146
147  // Constants used in scan results.  Make available to unit tests.
148  // TODO(jglasgow): Generate from modem manager into ModemManager-names.h.
149  // See http://crbug.com/212909.
150  static const char kStatusProperty[];
151  static const char kOperatorLongProperty[];
152  static const char kOperatorShortProperty[];
153  static const char kOperatorCodeProperty[];
154  static const char kOperatorAccessTechnologyProperty[];
155
156  // Plugin strings via ModemManager.
157  static const char kAltairLTEMMPlugin[];
158  static const char kNovatelLTEMMPlugin[];
159
160  static const int64_t kActivationRegistrationTimeoutMilliseconds;
161  static const int64_t kEnterPinTimeoutMilliseconds;
162  static const int64_t kRegistrationDroppedUpdateTimeoutMilliseconds;
163  static const int kSetPowerStateTimeoutMilliseconds;
164
165
166  // Root path. The SIM path is reported by ModemManager to be the root path
167  // when no SIM is present.
168  static const char kRootPath[];
169
170  friend class CellularTest;
171  friend class CellularCapabilityTest;
172  friend class CellularCapabilityUniversalTest;
173  friend class CellularCapabilityUniversalCDMATest;
174  FRIEND_TEST(CellularCapabilityUniversalCDMAMainTest, PropertiesChanged);
175  FRIEND_TEST(CellularCapabilityUniversalMainTest, AllowRoaming);
176  FRIEND_TEST(CellularCapabilityUniversalMainTest,
177              ActivationWaitForRegisterTimeout);
178  FRIEND_TEST(CellularCapabilityUniversalMainTest, Connect);
179  FRIEND_TEST(CellularCapabilityUniversalMainTest, ConnectApns);
180  FRIEND_TEST(CellularCapabilityUniversalMainTest, DisconnectNoProxy);
181  FRIEND_TEST(CellularCapabilityUniversalMainTest,
182              DisconnectWithDeferredCallback);
183  FRIEND_TEST(CellularCapabilityUniversalMainTest, ExtractPcoValue);
184  FRIEND_TEST(CellularCapabilityUniversalMainTest, GetMdnForOLP);
185  FRIEND_TEST(CellularCapabilityUniversalMainTest,
186              GetNetworkTechnologyStringOnE362);
187  FRIEND_TEST(CellularCapabilityUniversalMainTest,
188              GetOutOfCreditsDetectionType);
189  FRIEND_TEST(CellularCapabilityUniversalMainTest, GetTypeString);
190  FRIEND_TEST(CellularCapabilityUniversalMainTest, IsMdnValid);
191  FRIEND_TEST(CellularCapabilityUniversalMainTest, IsRegistered);
192  FRIEND_TEST(CellularCapabilityUniversalMainTest, IsServiceActivationRequired);
193  FRIEND_TEST(CellularCapabilityUniversalMainTest, IsValidSimPath);
194  FRIEND_TEST(CellularCapabilityUniversalMainTest, NormalizeMdn);
195  FRIEND_TEST(CellularCapabilityUniversalMainTest, OnLockRetriesChanged);
196  FRIEND_TEST(CellularCapabilityUniversalMainTest, OnLockTypeChanged);
197  FRIEND_TEST(CellularCapabilityUniversalMainTest,
198              OnModemCurrentCapabilitiesChanged);
199  FRIEND_TEST(CellularCapabilityUniversalMainTest, OnSimLockPropertiesChanged);
200  FRIEND_TEST(CellularCapabilityUniversalMainTest, PropertiesChanged);
201  FRIEND_TEST(CellularCapabilityUniversalMainTest, Reset);
202  FRIEND_TEST(CellularCapabilityUniversalMainTest, Scan);
203  FRIEND_TEST(CellularCapabilityUniversalMainTest, ScanFailure);
204  FRIEND_TEST(CellularCapabilityUniversalMainTest, SimLockStatusChanged);
205  FRIEND_TEST(CellularCapabilityUniversalMainTest, SimLockStatusToProperty);
206  FRIEND_TEST(CellularCapabilityUniversalMainTest, SimPathChanged);
207  FRIEND_TEST(CellularCapabilityUniversalMainTest, SimPropertiesChanged);
208  FRIEND_TEST(CellularCapabilityUniversalMainTest, StartModem);
209  FRIEND_TEST(CellularCapabilityUniversalMainTest, StartModemFailure);
210  FRIEND_TEST(CellularCapabilityUniversalMainTest, StartModemInWrongState);
211  FRIEND_TEST(CellularCapabilityUniversalMainTest,
212              StartModemWithDeferredEnableFailure);
213  FRIEND_TEST(CellularCapabilityUniversalMainTest, StopModem);
214  FRIEND_TEST(CellularCapabilityUniversalMainTest, StopModemAltair);
215  FRIEND_TEST(CellularCapabilityUniversalMainTest,
216              StopModemAltairDeleteBearerFailure);
217  FRIEND_TEST(CellularCapabilityUniversalMainTest, StopModemAltairNotConnected);
218  FRIEND_TEST(CellularCapabilityUniversalMainTest, StopModemConnected);
219  FRIEND_TEST(CellularCapabilityUniversalMainTest, TerminationAction);
220  FRIEND_TEST(CellularCapabilityUniversalMainTest,
221              TerminationActionRemovedByStopModem);
222  FRIEND_TEST(CellularCapabilityUniversalMainTest, UpdateActiveBearer);
223  FRIEND_TEST(CellularCapabilityUniversalMainTest,
224              UpdatePendingActivationState);
225  FRIEND_TEST(CellularCapabilityUniversalMainTest,
226              UpdateRegistrationState);
227  FRIEND_TEST(CellularCapabilityUniversalMainTest,
228              UpdateRegistrationStateModemNotConnected);
229  FRIEND_TEST(CellularCapabilityUniversalMainTest,
230              UpdateServiceActivationState);
231  FRIEND_TEST(CellularCapabilityUniversalMainTest, UpdateServiceOLP);
232  FRIEND_TEST(CellularCapabilityUniversalTimerTest, CompleteActivation);
233  FRIEND_TEST(CellularTest, EnableTrafficMonitor);
234  FRIEND_TEST(CellularTest,
235              HandleNewRegistrationStateForServiceRequiringActivation);
236  FRIEND_TEST(CellularTest, ModemStateChangeLostRegistration);
237  FRIEND_TEST(CellularTest, OnPPPDied);
238
239  // SimLockStatus represents the fields in the Cellular.SIMLockStatus
240  // DBUS property of the shill device.
241  struct SimLockStatus {
242   public:
243    SimLockStatus() : enabled(false),
244                      lock_type(MM_MODEM_LOCK_UNKNOWN),
245                      retries_left(0) {}
246
247    bool enabled;
248    MMModemLock lock_type;
249    uint32_t retries_left;
250  };
251
252  // SubscriptionState represents the provisioned state of SIM. It is used
253  // currently by activation logic for LTE to determine if activation process is
254  // complete.
255  enum SubscriptionState {
256    kSubscriptionStateUnknown = 0,
257    kSubscriptionStateUnprovisioned = 1,
258    kSubscriptionStateProvisioned = 2,
259    kSubscriptionStateOutOfData = 3
260  };
261
262  // Methods used in starting a modem
263  void EnableModem(bool deferralbe,
264                   Error *error,
265                   const ResultCallback& callback);
266  void EnableModemCompleted(bool deferrable,
267                            const ResultCallback &callback,
268                            const Error &error);
269
270  // Methods used in stopping a modem
271  void Stop_DeleteActiveBearer(const ResultCallback &callback);
272  void Stop_DeleteActiveBearerCompleted(const ResultCallback &callback,
273                                        const Error &error);
274  void Stop_Disable(const ResultCallback &callback);
275  void Stop_DisableCompleted(const ResultCallback &callback,
276                             const Error &error);
277  void Stop_PowerDown(const ResultCallback &callback);
278  void Stop_PowerDownCompleted(const ResultCallback &callback,
279                               const Error &error);
280
281  // Updates |active_bearer_| to match the currently active bearer.
282  void UpdateActiveBearer();
283
284  Stringmap ParseScanResult(const ScanResult &result);
285
286  KeyValueStore SimLockStatusToProperty(Error *error);
287
288  void SetupApnTryList();
289  void FillConnectPropertyMap(DBusPropertiesMap *properties);
290
291  void HelpRegisterConstDerivedKeyValueStore(
292      const std::string &name,
293      KeyValueStore(CellularCapabilityUniversal::*get)(Error *error));
294
295  // Returns true if a connect error should be retried.  This function
296  // abstracts modem specific behavior for modems which do a lousy job
297  // of returning specific errors on connect failures.
298  bool RetriableConnectError(const Error &error) const;
299
300  // Signal callbacks
301  void OnNetworkModeSignal(uint32_t mode);
302  void OnModemStateChangedSignal(int32_t old_state,
303                                 int32_t new_state,
304                                 uint32_t reason);
305
306  // Property Change notification handlers
307  void OnModemPropertiesChanged(
308      const DBusPropertiesMap &properties,
309      const std::vector<std::string> &invalidated_properties);
310
311  void OnSignalQualityChanged(uint32_t quality);
312
313  void OnSupportedCapabilitesChanged(
314      const std::vector<uint32_t> &supported_capabilities);
315  void OnModemCurrentCapabilitiesChanged(uint32_t current_capabilities);
316  void OnMdnChanged(const std::string &mdn);
317  void OnModemRevisionChanged(const std::string &revision);
318  void OnModemStateChanged(Cellular::ModemState state);
319  void OnAccessTechnologiesChanged(uint32_t access_technologies);
320  void OnSupportedModesChanged(const std::vector<ModemModes> &supported_modes);
321  void OnCurrentModesChanged(const ModemModes &current_modes);
322  void OnBearersChanged(const RpcIdentifiers &bearers);
323  void OnLockRetriesChanged(const LockRetryData &lock_retries);
324  void OnLockTypeChanged(MMModemLock unlock_required);
325  void OnSimLockStatusChanged();
326
327  // Returns false if the MDN is empty or if the MDN consists of all 0s.
328  bool IsMdnValid() const;
329
330  // 3GPP property change handlers
331  virtual void OnModem3GPPPropertiesChanged(
332      const DBusPropertiesMap &properties,
333      const std::vector<std::string> &invalidated_properties);
334  void On3GPPRegistrationChanged(MMModem3gppRegistrationState state,
335                                 const std::string &operator_code,
336                                 const std::string &operator_name);
337  void Handle3GPPRegistrationChange(
338      MMModem3gppRegistrationState updated_state,
339      std::string updated_operator_code,
340      std::string updated_operator_name);
341  void On3GPPSubscriptionStateChanged(MMModem3gppSubscriptionState state);
342  void OnFacilityLocksChanged(uint32_t locks);
343
344  // SIM property change handlers
345  // TODO(armansito): Put these methods in a 3GPP-only subclass.
346  void OnSimPropertiesChanged(
347      const DBusPropertiesMap &props,
348      const std::vector<std::string> &invalidated_properties);
349  void OnSpnChanged(const std::string &spn);
350  void OnSimIdentifierChanged(const std::string &id);
351  void OnOperatorIdChanged(const std::string &operator_id);
352  void OnOperatorNameChanged(const std::string &operator_name);
353
354  // Method callbacks
355  void OnRegisterReply(const ResultCallback &callback,
356                       const Error &error);
357  void OnResetReply(const ResultCallback &callback, const Error &error);
358  void OnScanReply(const ResultStringmapsCallback &callback,
359                   const ScanResults &results,
360                   const Error &error);
361  void OnConnectReply(const ResultCallback &callback,
362                      const DBus::Path &bearer,
363                      const Error &error);
364
365  // Returns true, if |sim_path| constitutes a valid SIM path. Currently, a
366  // path is accepted to be valid, as long as it is not equal to one of ""
367  // and "/".
368  bool IsValidSimPath(const std::string &sim_path) const;
369
370  // Returns the normalized version of |mdn| by keeping only digits in |mdn|
371  // and removing other non-digit characters.
372  std::string NormalizeMdn(const std::string &mdn) const;
373
374  // Post-payment activation handlers.
375  void ResetAfterActivation();
376  void UpdateServiceActivationState();
377  void OnResetAfterActivationReply(const Error &error);
378
379  static bool IsRegisteredState(MMModem3gppRegistrationState state);
380
381  // Returns the out-of-credits detection algorithm to be used on this modem.
382  OutOfCreditsDetector::OOCType GetOutOfCreditsDetectionType() const;
383
384  // For unit tests.
385  void set_active_bearer(CellularBearer *bearer) {
386    active_bearer_.reset(bearer);  // Takes ownership
387  }
388
389  std::unique_ptr<mm1::ModemModem3gppProxyInterface> modem_3gpp_proxy_;
390  std::unique_ptr<mm1::ModemProxyInterface> modem_proxy_;
391  std::unique_ptr<mm1::ModemSimpleProxyInterface> modem_simple_proxy_;
392  std::unique_ptr<mm1::SimProxyInterface> sim_proxy_;
393  // Used to enrich information about the network operator in |ParseScanResult|.
394  // TODO(pprabhu) Instead instantiate a local |MobileOperatorInfo| instance
395  // once the context has been separated out. (crbug.com/363874)
396  std::unique_ptr<MobileOperatorInfo> mobile_operator_info_;
397
398  base::WeakPtrFactory<CellularCapabilityUniversal> weak_ptr_factory_;
399
400  MMModem3gppRegistrationState registration_state_;
401
402  // Bits based on MMModemCapabilities
403  std::vector<uint32_t> supported_capabilities_;  // Technologies supported
404  uint32_t current_capabilities_;  // Technologies supported without a reload
405  uint32_t access_technologies_;   // Bits based on MMModemAccessTechnology
406  std::vector<ModemModes> supported_modes_;
407  ModemModes current_modes_;
408
409  Stringmap serving_operator_;
410  std::string spn_;
411  std::string desired_network_;
412
413  // Properties.
414  std::deque<Stringmap> apn_try_list_;
415  bool resetting_;
416  SimLockStatus sim_lock_status_;
417  SubscriptionState subscription_state_;
418  std::string sim_path_;
419  std::unique_ptr<CellularBearer> active_bearer_;
420  RpcIdentifiers bearer_paths_;
421  bool reset_done_;
422
423  // If the modem is not in a state to be enabled when StartModem is called,
424  // enabling is deferred using this callback.
425  base::Closure deferred_enable_modem_callback_;
426
427  // Sometimes flaky cellular network causes the 3GPP registration state to
428  // rapidly change from registered --> searching and back. Delay such updates
429  // a little to smooth over temporary registration loss.
430  base::CancelableClosure registration_dropped_update_callback_;
431  int64_t registration_dropped_update_timeout_milliseconds_;
432
433  DISALLOW_COPY_AND_ASSIGN(CellularCapabilityUniversal);
434};
435
436}  // namespace shill
437
438#endif  // SHILL_CELLULAR_CELLULAR_CAPABILITY_UNIVERSAL_H_
439