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