Home | History | Annotate | Download | only in cellular
      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 {
    151     ModemModes()
    152         : allowed_modes(MM_MODEM_MODE_NONE),
    153           preferred_mode(MM_MODEM_MODE_NONE) {}
    154 
    155     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:
    259     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.
    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