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