Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 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 | #include "shill/cellular_capability_universal_cdma.h" |
| 6 | |
| 7 | #include <chromeos/dbus/service_constants.h> |
| 8 | #include <base/stringprintf.h> |
| 9 | #include <base/string_number_conversions.h> |
| 10 | #include <base/string_util.h> |
| 11 | |
Ben Chan | 539ab02 | 2014-02-03 16:34:57 -0800 | [diff] [blame^] | 12 | #include "shill/cellular_bearer.h" |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 13 | #include "shill/cellular_operator_info.h" |
| 14 | #include "shill/dbus_properties_proxy_interface.h" |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 15 | #include "shill/error.h" |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 16 | #include "shill/logging.h" |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 17 | #include "shill/pending_activation_store.h" |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 18 | #include "shill/proxy_factory.h" |
| 19 | |
| 20 | #ifdef MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN |
| 21 | #error "Do not include mm-modem.h" |
| 22 | #endif |
| 23 | |
| 24 | using base::UintToString; |
| 25 | |
| 26 | using std::string; |
| 27 | using std::vector; |
| 28 | |
| 29 | namespace shill { |
| 30 | |
| 31 | namespace { |
| 32 | |
Arman Uguray | c967306 | 2013-05-13 21:21:53 -0700 | [diff] [blame] | 33 | const char kPhoneNumber[] = "#777"; |
| 34 | const char kPropertyConnectNumber[] = "number"; |
| 35 | |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 36 | string FormattedSID(const string &sid) { |
| 37 | return "[SID=" + sid + "]"; |
| 38 | } |
| 39 | |
| 40 | } // namespace |
| 41 | |
| 42 | // static |
| 43 | unsigned int |
| 44 | CellularCapabilityUniversalCDMA::friendly_service_name_id_cdma_ = 0; |
| 45 | |
| 46 | CellularCapabilityUniversalCDMA::CellularCapabilityUniversalCDMA( |
| 47 | Cellular *cellular, |
| 48 | ProxyFactory *proxy_factory, |
| 49 | ModemInfo *modem_info) |
| 50 | : CellularCapabilityUniversal(cellular, |
| 51 | proxy_factory, |
| 52 | modem_info), |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 53 | weak_cdma_ptr_factory_(this), |
| 54 | activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED), |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 55 | cdma_1x_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN), |
| 56 | cdma_evdo_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN), |
| 57 | nid_(0), |
| 58 | sid_(0) { |
| 59 | SLOG(Cellular, 2) << "Cellular capability constructed: Universal CDMA"; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 60 | // TODO(armansito): Update PRL for activation over cellular. |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 61 | // See crbug.com/197330. |
| 62 | } |
| 63 | |
| 64 | void CellularCapabilityUniversalCDMA::InitProxies() { |
| 65 | SLOG(Cellular, 2) << __func__; |
| 66 | modem_cdma_proxy_.reset( |
| 67 | proxy_factory()->CreateMM1ModemModemCdmaProxy(cellular()->dbus_path(), |
| 68 | cellular()->dbus_owner())); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 69 | modem_cdma_proxy_->set_activation_state_callback( |
| 70 | Bind(&CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal, |
| 71 | weak_cdma_ptr_factory_.GetWeakPtr())); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 72 | CellularCapabilityUniversal::InitProxies(); |
| 73 | } |
| 74 | |
| 75 | void CellularCapabilityUniversalCDMA::ReleaseProxies() { |
| 76 | SLOG(Cellular, 2) << __func__; |
| 77 | modem_cdma_proxy_.reset(); |
| 78 | CellularCapabilityUniversal::ReleaseProxies(); |
| 79 | } |
| 80 | |
| 81 | void CellularCapabilityUniversalCDMA::Activate( |
| 82 | const string &carrier, |
| 83 | Error *error, |
| 84 | const ResultCallback &callback) { |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 85 | // Currently activation over the cellular network is not supported using |
| 86 | // ModemManager-next. Service activation is currently carried through over |
| 87 | // non-cellular networks and only the final step of the OTA activation |
| 88 | // procedure ("automatic activation") is performed by this class. |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 89 | OnUnsupportedOperation(__func__, error); |
| 90 | } |
| 91 | |
| 92 | void CellularCapabilityUniversalCDMA::CompleteActivation(Error *error) { |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 93 | SLOG(Cellular, 2) << __func__; |
| 94 | if (cellular()->state() < Cellular::kStateEnabled) { |
| 95 | Error::PopulateAndLog(error, Error::kInvalidArguments, |
| 96 | "Unable to activate in state " + |
| 97 | Cellular::GetStateString(cellular()->state())); |
| 98 | return; |
| 99 | } |
| 100 | ActivateAutomatic(); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 101 | } |
| 102 | |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 103 | void CellularCapabilityUniversalCDMA::ActivateAutomatic() { |
| 104 | if (activation_code_.empty()) { |
| 105 | SLOG(Cellular, 2) << "OTA activation cannot be run in the presence of no " |
| 106 | << "activation code."; |
| 107 | return; |
| 108 | } |
| 109 | PendingActivationStore::State state = |
| 110 | modem_info()->pending_activation_store()->GetActivationState( |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 111 | PendingActivationStore::kIdentifierMEID, cellular()->meid()); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 112 | if (state == PendingActivationStore::kStatePending) { |
| 113 | SLOG(Cellular, 2) << "There's already a pending activation. Ignoring."; |
| 114 | return; |
| 115 | } |
| 116 | if (state == PendingActivationStore::kStateActivated) { |
| 117 | SLOG(Cellular, 2) << "A call to OTA activation has already completed " |
| 118 | << "successfully. Ignoring."; |
| 119 | return; |
| 120 | } |
| 121 | |
| 122 | // Mark as pending activation, so that shill can recover if anything fails |
| 123 | // during OTA activation. |
| 124 | modem_info()->pending_activation_store()->SetActivationState( |
| 125 | PendingActivationStore::kIdentifierMEID, |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 126 | cellular()->meid(), |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 127 | PendingActivationStore::kStatePending); |
| 128 | |
| 129 | // Initiate OTA activation. |
| 130 | ResultCallback activation_callback = |
| 131 | Bind(&CellularCapabilityUniversalCDMA::OnActivateReply, |
| 132 | weak_cdma_ptr_factory_.GetWeakPtr(), |
| 133 | ResultCallback()); |
Arman Uguray | f2b4a34 | 2013-05-23 18:26:52 -0700 | [diff] [blame] | 134 | |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 135 | Error error; |
| 136 | modem_cdma_proxy_->Activate( |
| 137 | activation_code_, &error, activation_callback, kTimeoutActivate); |
| 138 | } |
| 139 | |
| 140 | void CellularCapabilityUniversalCDMA::UpdatePendingActivationState() { |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 141 | SLOG(Cellular, 2) << __func__; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 142 | if (IsActivated()) { |
| 143 | SLOG(Cellular, 3) << "CDMA service activated. Clear store."; |
| 144 | modem_info()->pending_activation_store()->RemoveEntry( |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 145 | PendingActivationStore::kIdentifierMEID, cellular()->meid()); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 146 | return; |
| 147 | } |
| 148 | PendingActivationStore::State state = |
| 149 | modem_info()->pending_activation_store()->GetActivationState( |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 150 | PendingActivationStore::kIdentifierMEID, cellular()->meid()); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 151 | if (IsActivating() && state != PendingActivationStore::kStateFailureRetry) { |
| 152 | SLOG(Cellular, 3) << "OTA activation in progress. Nothing to do."; |
| 153 | return; |
| 154 | } |
| 155 | switch (state) { |
| 156 | case PendingActivationStore::kStateFailureRetry: |
| 157 | SLOG(Cellular, 3) << "OTA activation failed. Scheduling a retry."; |
| 158 | cellular()->dispatcher()->PostTask( |
| 159 | Bind(&CellularCapabilityUniversalCDMA::ActivateAutomatic, |
| 160 | weak_cdma_ptr_factory_.GetWeakPtr())); |
| 161 | break; |
| 162 | case PendingActivationStore::kStateActivated: |
| 163 | SLOG(Cellular, 3) << "OTA Activation has completed successfully. " |
| 164 | << "Waiting for activation state update to finalize."; |
| 165 | break; |
| 166 | default: |
| 167 | break; |
| 168 | } |
| 169 | } |
| 170 | |
| 171 | bool CellularCapabilityUniversalCDMA::IsServiceActivationRequired() const { |
| 172 | // If there is no online payment portal information, it's safer to assume |
| 173 | // the service does not require activation. |
| 174 | if (!modem_info()->cellular_operator_info()) |
| 175 | return false; |
| 176 | |
| 177 | const CellularService::OLP *olp = |
| 178 | modem_info()->cellular_operator_info()->GetOLPBySID(UintToString(sid_)); |
| 179 | if (!olp) |
| 180 | return false; |
| 181 | |
| 182 | // We could also use the MDN to determine whether or not the service is |
| 183 | // activated, however, the CDMA ActivatonState property is a more absolute |
| 184 | // and fine-grained indicator of activation status. |
| 185 | return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED); |
| 186 | } |
| 187 | |
| 188 | bool CellularCapabilityUniversalCDMA::IsActivated() const { |
| 189 | return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 190 | } |
| 191 | |
Arman Uguray | c539123 | 2013-09-23 21:30:46 -0700 | [diff] [blame] | 192 | void CellularCapabilityUniversalCDMA::UpdateStorageIdentifier() { |
| 193 | if (!cellular()->service().get()) |
| 194 | return; |
| 195 | |
| 196 | // Lookup the unique identifier assigned to the current network and base the |
| 197 | // service's storage identifier on it. |
| 198 | const CellularOperatorInfo::CellularOperator *provider = |
| 199 | modem_info()->cellular_operator_info()->GetCellularOperatorBySID( |
| 200 | UintToString(sid_)); |
| 201 | if (!provider || provider->identifier().empty()) |
| 202 | // Don't update the identifier if a better one could not be built. The |
| 203 | // default identifier initialized in cellular_service.cc still applies |
| 204 | // here. |
| 205 | return; |
| 206 | cellular()->service()->SetStorageIdentifier( |
| 207 | string(shill::kTypeCellular) + "_" + cellular()->address() + |
| 208 | "_" + provider->identifier()); |
| 209 | } |
| 210 | |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 211 | void CellularCapabilityUniversalCDMA::OnServiceCreated() { |
| 212 | SLOG(Cellular, 2) << __func__; |
Arman Uguray | c539123 | 2013-09-23 21:30:46 -0700 | [diff] [blame] | 213 | UpdateStorageIdentifier(); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 214 | UpdateServiceActivationStateProperty(); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 215 | UpdateServingOperator(); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 216 | HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE); |
| 217 | UpdatePendingActivationState(); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 218 | UpdateOLP(); |
| 219 | } |
| 220 | |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 221 | void CellularCapabilityUniversalCDMA::UpdateServiceActivationStateProperty() { |
| 222 | bool activation_required = IsServiceActivationRequired(); |
| 223 | cellular()->service()->SetActivateOverNonCellularNetwork(activation_required); |
| 224 | string activation_state; |
| 225 | if (IsActivating()) |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 226 | activation_state = kActivationStateActivating; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 227 | else if (activation_required) |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 228 | activation_state = kActivationStateNotActivated; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 229 | else |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 230 | activation_state = kActivationStateActivated; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 231 | cellular()->service()->SetActivationState(activation_state); |
| 232 | } |
| 233 | |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 234 | void CellularCapabilityUniversalCDMA::UpdateOLP() { |
Ben Chan | 07193fd | 2013-07-12 22:10:55 -0700 | [diff] [blame] | 235 | SLOG(Cellular, 2) << __func__; |
| 236 | |
| 237 | const CellularOperatorInfo *cellular_operator_info = |
| 238 | modem_info()->cellular_operator_info(); |
| 239 | if (!cellular_operator_info) |
| 240 | return; |
| 241 | |
| 242 | string sid_string = UintToString(sid_); |
| 243 | const CellularOperatorInfo::CellularOperator *cellular_operator = |
| 244 | cellular_operator_info->GetCellularOperatorBySID(sid_string); |
| 245 | if (!cellular_operator) |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 246 | return; |
| 247 | |
| 248 | const CellularService::OLP *result = |
Ben Chan | 07193fd | 2013-07-12 22:10:55 -0700 | [diff] [blame] | 249 | cellular_operator_info->GetOLPBySID(sid_string); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 250 | if (!result) |
| 251 | return; |
| 252 | |
| 253 | CellularService::OLP olp; |
| 254 | olp.CopyFrom(*result); |
| 255 | string post_data = olp.GetPostData(); |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 256 | ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}", cellular()->esn()); |
Ben Chan | 07193fd | 2013-07-12 22:10:55 -0700 | [diff] [blame] | 257 | ReplaceSubstringsAfterOffset(&post_data, 0, "${mdn}", |
| 258 | GetMdnForOLP(*cellular_operator)); |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 259 | ReplaceSubstringsAfterOffset(&post_data, 0, "${meid}", cellular()->meid()); |
Arman Uguray | f87fa2f | 2013-10-16 14:24:56 -0700 | [diff] [blame] | 260 | ReplaceSubstringsAfterOffset(&post_data, 0, "${oem}", "GOG2"); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 261 | olp.SetPostData(post_data); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 262 | if (cellular()->service().get()) |
| 263 | cellular()->service()->SetOLP(olp); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 264 | } |
| 265 | |
| 266 | void CellularCapabilityUniversalCDMA::GetProperties() { |
| 267 | SLOG(Cellular, 2) << __func__; |
| 268 | CellularCapabilityUniversal::GetProperties(); |
| 269 | |
| 270 | scoped_ptr<DBusPropertiesProxyInterface> properties_proxy( |
| 271 | proxy_factory()->CreateDBusPropertiesProxy(cellular()->dbus_path(), |
| 272 | cellular()->dbus_owner())); |
| 273 | DBusPropertiesMap properties( |
| 274 | properties_proxy->GetAll(MM_DBUS_INTERFACE_MODEM_MODEMCDMA)); |
| 275 | OnModemCDMAPropertiesChanged(properties, vector<string>()); |
| 276 | } |
| 277 | |
| 278 | string CellularCapabilityUniversalCDMA::CreateFriendlyServiceName() { |
| 279 | SLOG(Cellular, 2) << __func__ << ": " << GetRoamingStateString(); |
| 280 | |
| 281 | if (provider_.GetCode().empty()) { |
| 282 | UpdateOperatorInfo(); |
| 283 | } |
| 284 | |
| 285 | string name = provider_.GetName(); |
| 286 | if (!name.empty()) { |
| 287 | // TODO(armansito): We may need to show the provider name in a |
| 288 | // specific way if roaming. |
| 289 | return name; |
| 290 | } |
| 291 | |
| 292 | string code = provider_.GetCode(); |
| 293 | if (!code.empty()) { |
| 294 | return "cellular_sid_" + code; |
| 295 | } |
| 296 | |
| 297 | return base::StringPrintf("CDMANetwork%u", friendly_service_name_id_cdma_++); |
| 298 | } |
| 299 | |
| 300 | void CellularCapabilityUniversalCDMA::UpdateOperatorInfo() { |
| 301 | SLOG(Cellular, 2) << __func__; |
| 302 | |
| 303 | if (sid_ == 0 || !modem_info()->cellular_operator_info()) { |
| 304 | SLOG(Cellular, 2) << "No provider is currently available."; |
| 305 | provider_.SetCode(""); |
| 306 | return; |
| 307 | } |
| 308 | |
| 309 | string sid = UintToString(sid_); |
| 310 | const CellularOperatorInfo::CellularOperator *provider = |
| 311 | modem_info()->cellular_operator_info()->GetCellularOperatorBySID(sid); |
| 312 | if (!provider) { |
| 313 | SLOG(Cellular, 2) << "CDMA provider with " |
| 314 | << FormattedSID(sid) |
| 315 | << " not found."; |
Arman Uguray | e015faf | 2013-08-16 17:54:59 -0700 | [diff] [blame] | 316 | // If a matching provider is not found, shill should update the |
| 317 | // Cellular.ServingOperator property to to display the Sid. |
| 318 | provider_.SetCode(sid); |
| 319 | provider_.SetCountry(""); |
| 320 | provider_.SetName(""); |
| 321 | activation_code_.clear(); |
| 322 | } else { |
| 323 | if (!provider->name_list().empty()) { |
| 324 | provider_.SetName(provider->name_list()[0].name); |
| 325 | } |
| 326 | provider_.SetCode(sid); |
| 327 | provider_.SetCountry(provider->country()); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 328 | |
Arman Uguray | e015faf | 2013-08-16 17:54:59 -0700 | [diff] [blame] | 329 | activation_code_ = provider->activation_code(); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 330 | } |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 331 | |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 332 | // TODO(armansito): The CDMA interface only returns information about the |
| 333 | // current serving carrier, so for now both the home provider and the |
| 334 | // serving operator will be the same in case of roaming. We should figure |
| 335 | // out if there is a way to (and whether or not it is necessary to) |
| 336 | // determine if we're roaming. |
| 337 | cellular()->set_home_provider(provider_); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 338 | UpdateServingOperator(); |
| 339 | } |
| 340 | |
| 341 | void CellularCapabilityUniversalCDMA::UpdateServingOperator() { |
| 342 | SLOG(Cellular, 2) << __func__; |
| 343 | if (cellular()->service().get()) { |
| 344 | cellular()->service()->SetServingOperator(cellular()->home_provider()); |
Arman Uguray | 2269bb6 | 2013-07-26 14:53:30 -0700 | [diff] [blame] | 345 | cellular()->service()->SetFriendlyName(CreateFriendlyServiceName()); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 346 | } |
| 347 | } |
| 348 | |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 349 | void CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal( |
| 350 | uint32 activation_state, |
| 351 | uint32 activation_error, |
| 352 | const DBusPropertiesMap &status_changes) { |
| 353 | SLOG(Cellular, 2) << __func__; |
| 354 | |
| 355 | activation_state_ = |
| 356 | static_cast<MMModemCdmaActivationState>(activation_state); |
| 357 | |
| 358 | string value; |
| 359 | if (DBusProperties::GetString(status_changes, "mdn", &value)) |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 360 | cellular()->set_mdn(value); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 361 | if (DBusProperties::GetString(status_changes, "min", &value)) |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 362 | cellular()->set_min(value); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 363 | |
| 364 | SLOG(Cellular, 2) << "Activation state: " |
| 365 | << GetActivationStateString(activation_state_); |
| 366 | |
| 367 | HandleNewActivationStatus(activation_error); |
| 368 | UpdatePendingActivationState(); |
| 369 | } |
| 370 | |
| 371 | void CellularCapabilityUniversalCDMA::OnActivateReply( |
| 372 | const ResultCallback &callback, |
| 373 | const Error &error) { |
| 374 | SLOG(Cellular, 2) << __func__; |
| 375 | if (error.IsSuccess()) { |
| 376 | LOG(INFO) << "Activation completed successfully."; |
| 377 | modem_info()->pending_activation_store()->SetActivationState( |
| 378 | PendingActivationStore::kIdentifierMEID, |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 379 | cellular()->meid(), |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 380 | PendingActivationStore::kStateActivated); |
| 381 | } else { |
| 382 | LOG(ERROR) << "Activation failed with error: " << error; |
| 383 | modem_info()->pending_activation_store()->SetActivationState( |
| 384 | PendingActivationStore::kIdentifierMEID, |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 385 | cellular()->meid(), |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 386 | PendingActivationStore::kStateFailureRetry); |
| 387 | } |
| 388 | UpdatePendingActivationState(); |
Arman Uguray | f2b4a34 | 2013-05-23 18:26:52 -0700 | [diff] [blame] | 389 | |
| 390 | // CellularCapabilityUniversalCDMA::ActivateAutomatic passes a dummy |
| 391 | // ResultCallback when it calls Activate on the proxy object, in which case |
| 392 | // |callback.is_null()| will return true. |
| 393 | if (!callback.is_null()) |
| 394 | callback.Run(error); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 395 | } |
| 396 | |
| 397 | void CellularCapabilityUniversalCDMA::HandleNewActivationStatus(uint32 error) { |
| 398 | SLOG(Cellular, 2) << __func__ << "(" << error << ")"; |
| 399 | if (!cellular()->service().get()) { |
| 400 | LOG(ERROR) << "In " << __func__ << "(): service is null."; |
| 401 | return; |
| 402 | } |
| 403 | SLOG(Cellular, 2) << "Activation State: " << activation_state_; |
| 404 | cellular()->service()->SetActivationState( |
| 405 | GetActivationStateString(activation_state_)); |
| 406 | cellular()->service()->set_error(GetActivationErrorString(error)); |
| 407 | UpdateOLP(); |
| 408 | } |
| 409 | |
| 410 | // static |
| 411 | string CellularCapabilityUniversalCDMA::GetActivationStateString( |
| 412 | uint32 state) { |
| 413 | switch (state) { |
| 414 | case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 415 | return kActivationStateActivated; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 416 | case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 417 | return kActivationStateActivating; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 418 | case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 419 | return kActivationStateNotActivated; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 420 | case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 421 | return kActivationStatePartiallyActivated; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 422 | default: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 423 | return kActivationStateUnknown; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 424 | } |
| 425 | } |
| 426 | |
| 427 | // static |
| 428 | string CellularCapabilityUniversalCDMA::GetActivationErrorString( |
| 429 | uint32 error) { |
| 430 | switch (error) { |
| 431 | case MM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 432 | return kErrorNeedEvdo; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 433 | case MM_CDMA_ACTIVATION_ERROR_ROAMING: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 434 | return kErrorNeedHomeNetwork; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 435 | case MM_CDMA_ACTIVATION_ERROR_COULD_NOT_CONNECT: |
| 436 | case MM_CDMA_ACTIVATION_ERROR_SECURITY_AUTHENTICATION_FAILED: |
| 437 | case MM_CDMA_ACTIVATION_ERROR_PROVISIONING_FAILED: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 438 | return kErrorOtaspFailed; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 439 | case MM_CDMA_ACTIVATION_ERROR_NONE: |
| 440 | return ""; |
| 441 | case MM_CDMA_ACTIVATION_ERROR_NO_SIGNAL: |
| 442 | default: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 443 | return kErrorActivationFailed; |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 444 | } |
| 445 | } |
| 446 | |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 447 | void CellularCapabilityUniversalCDMA::Register(const ResultCallback &callback) { |
| 448 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 449 | } |
| 450 | |
| 451 | void CellularCapabilityUniversalCDMA::RegisterOnNetwork( |
| 452 | const string &network_id, |
| 453 | Error *error, |
| 454 | const ResultCallback &callback) { |
| 455 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 456 | } |
| 457 | |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 458 | bool CellularCapabilityUniversalCDMA::IsActivating() const { |
| 459 | PendingActivationStore::State state = |
| 460 | modem_info()->pending_activation_store()->GetActivationState( |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 461 | PendingActivationStore::kIdentifierMEID, cellular()->meid()); |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 462 | return (state == PendingActivationStore::kStatePending) || |
| 463 | (state == PendingActivationStore::kStateFailureRetry) || |
| 464 | (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING); |
| 465 | } |
| 466 | |
Ben Chan | 31ce564 | 2013-11-14 13:37:40 -0800 | [diff] [blame] | 467 | bool CellularCapabilityUniversalCDMA::IsRegistered() const { |
Ben Chan | b2c4a80 | 2013-11-14 12:47:52 -0800 | [diff] [blame] | 468 | return (cdma_1x_registration_state_ != |
| 469 | MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN || |
| 470 | cdma_evdo_registration_state_ != |
| 471 | MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 472 | } |
| 473 | |
| 474 | void CellularCapabilityUniversalCDMA::SetUnregistered(bool /*searching*/) { |
| 475 | cdma_1x_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN; |
| 476 | cdma_evdo_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN; |
| 477 | } |
| 478 | |
Arman Uguray | c967306 | 2013-05-13 21:21:53 -0700 | [diff] [blame] | 479 | void CellularCapabilityUniversalCDMA::SetupConnectProperties( |
| 480 | DBusPropertiesMap *properties) { |
| 481 | (*properties)[kPropertyConnectNumber].writer().append_string( |
| 482 | kPhoneNumber); |
| 483 | } |
| 484 | |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 485 | void CellularCapabilityUniversalCDMA::RequirePIN( |
| 486 | const string &pin, bool require, |
| 487 | Error *error, const ResultCallback &callback) { |
| 488 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 489 | } |
| 490 | |
| 491 | void CellularCapabilityUniversalCDMA::EnterPIN( |
| 492 | const string &pin, |
| 493 | Error *error, |
| 494 | const ResultCallback &callback) { |
| 495 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 496 | } |
| 497 | |
| 498 | void CellularCapabilityUniversalCDMA::UnblockPIN( |
| 499 | const string &unblock_code, |
| 500 | const string &pin, |
| 501 | Error *error, |
| 502 | const ResultCallback &callback) { |
| 503 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 504 | } |
| 505 | |
| 506 | void CellularCapabilityUniversalCDMA::ChangePIN( |
| 507 | const string &old_pin, const string &new_pin, |
| 508 | Error *error, const ResultCallback &callback) { |
| 509 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 510 | } |
| 511 | |
Prathmesh Prabhu | 49ffffd | 2014-01-09 18:28:55 -0800 | [diff] [blame] | 512 | void CellularCapabilityUniversalCDMA::Scan( |
| 513 | Error *error, |
| 514 | const ResultStringmapsCallback &callback) { |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 515 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
Prathmesh Prabhu | 49ffffd | 2014-01-09 18:28:55 -0800 | [diff] [blame] | 516 | OnUnsupportedOperation(__func__, error); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 517 | } |
| 518 | |
| 519 | void CellularCapabilityUniversalCDMA::OnSimPathChanged( |
| 520 | const string &sim_path) { |
| 521 | // TODO(armansito): Remove once 3GPP is implemented in its own class. |
| 522 | } |
| 523 | |
| 524 | string CellularCapabilityUniversalCDMA::GetRoamingStateString() const { |
| 525 | uint32 state = cdma_evdo_registration_state_; |
| 526 | if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) { |
| 527 | state = cdma_1x_registration_state_; |
| 528 | } |
| 529 | switch (state) { |
| 530 | case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN: |
| 531 | case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED: |
| 532 | break; |
| 533 | case MM_MODEM_CDMA_REGISTRATION_STATE_HOME: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 534 | return kRoamingStateHome; |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 535 | case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING: |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 536 | return kRoamingStateRoaming; |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 537 | default: |
| 538 | NOTREACHED(); |
| 539 | } |
Ben Chan | 7ea768e | 2013-09-20 15:08:40 -0700 | [diff] [blame] | 540 | return kRoamingStateUnknown; |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 541 | } |
| 542 | |
| 543 | void CellularCapabilityUniversalCDMA::OnDBusPropertiesChanged( |
| 544 | const string &interface, |
| 545 | const DBusPropertiesMap &changed_properties, |
| 546 | const vector<string> &invalidated_properties) { |
| 547 | SLOG(Cellular, 2) << __func__ << "(" << interface << ")"; |
| 548 | if (interface == MM_DBUS_INTERFACE_MODEM_MODEMCDMA) { |
| 549 | OnModemCDMAPropertiesChanged(changed_properties, invalidated_properties); |
| 550 | } else { |
| 551 | CellularCapabilityUniversal::OnDBusPropertiesChanged( |
| 552 | interface, changed_properties, invalidated_properties); |
| 553 | } |
| 554 | } |
| 555 | |
| 556 | void CellularCapabilityUniversalCDMA::OnModemCDMAPropertiesChanged( |
| 557 | const DBusPropertiesMap &properties, |
| 558 | const std::vector<std::string> &/*invalidated_properties*/) { |
| 559 | SLOG(Cellular, 2) << __func__; |
| 560 | string str_value; |
| 561 | if (DBusProperties::GetString(properties, |
| 562 | MM_MODEM_MODEMCDMA_PROPERTY_MEID, |
| 563 | &str_value)) |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 564 | cellular()->set_meid(str_value); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 565 | if (DBusProperties::GetString(properties, |
| 566 | MM_MODEM_MODEMCDMA_PROPERTY_ESN, |
| 567 | &str_value)) |
Prathmesh Prabhu | 9f06c87 | 2013-11-21 14:08:23 -0800 | [diff] [blame] | 568 | cellular()->set_esn(str_value); |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 569 | |
| 570 | uint32_t sid = sid_; |
| 571 | uint32_t nid = nid_; |
| 572 | MMModemCdmaRegistrationState state_1x = cdma_1x_registration_state_; |
| 573 | MMModemCdmaRegistrationState state_evdo = cdma_evdo_registration_state_; |
| 574 | bool registration_changed = false; |
| 575 | uint32_t uint_value; |
| 576 | if (DBusProperties::GetUint32( |
| 577 | properties, |
| 578 | MM_MODEM_MODEMCDMA_PROPERTY_CDMA1XREGISTRATIONSTATE, |
| 579 | &uint_value)) { |
| 580 | state_1x = static_cast<MMModemCdmaRegistrationState>(uint_value); |
| 581 | registration_changed = true; |
| 582 | } |
| 583 | if (DBusProperties::GetUint32( |
| 584 | properties, |
| 585 | MM_MODEM_MODEMCDMA_PROPERTY_EVDOREGISTRATIONSTATE, |
| 586 | &uint_value)) { |
| 587 | state_evdo = static_cast<MMModemCdmaRegistrationState>(uint_value); |
| 588 | registration_changed = true; |
| 589 | } |
| 590 | if (DBusProperties::GetUint32( |
| 591 | properties, |
| 592 | MM_MODEM_MODEMCDMA_PROPERTY_SID, |
| 593 | &uint_value)) { |
| 594 | sid = uint_value; |
| 595 | registration_changed = true; |
| 596 | } |
| 597 | if (DBusProperties::GetUint32( |
| 598 | properties, |
| 599 | MM_MODEM_MODEMCDMA_PROPERTY_NID, |
| 600 | &uint_value)) { |
| 601 | nid = uint_value; |
| 602 | registration_changed = true; |
| 603 | } |
Arman Uguray | 0a3e279 | 2013-01-17 16:31:50 -0800 | [diff] [blame] | 604 | if (DBusProperties::GetUint32( |
| 605 | properties, |
| 606 | MM_MODEM_MODEMCDMA_PROPERTY_ACTIVATIONSTATE, |
| 607 | &uint_value)) { |
| 608 | activation_state_ = static_cast<MMModemCdmaActivationState>(uint_value); |
| 609 | HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE); |
| 610 | } |
Arman Uguray | 72fab6a | 2013-01-10 19:32:42 -0800 | [diff] [blame] | 611 | if (registration_changed) |
| 612 | OnCDMARegistrationChanged(state_1x, state_evdo, sid, nid); |
| 613 | } |
| 614 | |
| 615 | void CellularCapabilityUniversalCDMA::OnCDMARegistrationChanged( |
| 616 | MMModemCdmaRegistrationState state_1x, |
| 617 | MMModemCdmaRegistrationState state_evdo, |
| 618 | uint32_t sid, uint32_t nid) { |
| 619 | SLOG(Cellular, 2) << __func__ |
| 620 | << ": state_1x=" << state_1x |
| 621 | << ", state_evdo=" << state_evdo; |
| 622 | cdma_1x_registration_state_ = state_1x; |
| 623 | cdma_evdo_registration_state_ = state_evdo; |
| 624 | sid_ = sid; |
| 625 | nid_ = nid; |
| 626 | UpdateOperatorInfo(); |
| 627 | cellular()->HandleNewRegistrationState(); |
| 628 | } |
| 629 | |
| 630 | } // namespace shill |