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