blob: 43af14af5991e4257b86804b697564278f23e8b6 [file] [log] [blame]
Arman Uguray72fab6a2013-01-10 19:32:42 -08001// 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>
Ben Chana0ddf462014-02-06 11:32:42 -08008#include <base/strings/stringprintf.h>
9#include <base/strings/string_number_conversions.h>
10#include <base/strings/string_util.h>
Arman Uguray72fab6a2013-01-10 19:32:42 -080011
Ben Chan539ab022014-02-03 16:34:57 -080012#include "shill/cellular_bearer.h"
Arman Uguray72fab6a2013-01-10 19:32:42 -080013#include "shill/cellular_operator_info.h"
14#include "shill/dbus_properties_proxy_interface.h"
Arman Uguray0a3e2792013-01-17 16:31:50 -080015#include "shill/error.h"
Arman Uguray72fab6a2013-01-10 19:32:42 -080016#include "shill/logging.h"
Arman Uguray0a3e2792013-01-17 16:31:50 -080017#include "shill/pending_activation_store.h"
Arman Uguray72fab6a2013-01-10 19:32:42 -080018#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
24using base::UintToString;
25
26using std::string;
27using std::vector;
28
29namespace shill {
30
31namespace {
32
Arman Ugurayc9673062013-05-13 21:21:53 -070033const char kPhoneNumber[] = "#777";
34const char kPropertyConnectNumber[] = "number";
35
Arman Uguray72fab6a2013-01-10 19:32:42 -080036string FormattedSID(const string &sid) {
37 return "[SID=" + sid + "]";
38}
39
40} // namespace
41
Arman Uguray72fab6a2013-01-10 19:32:42 -080042CellularCapabilityUniversalCDMA::CellularCapabilityUniversalCDMA(
43 Cellular *cellular,
44 ProxyFactory *proxy_factory,
45 ModemInfo *modem_info)
Ben Chanf98f00e2014-02-05 14:48:43 -080046 : CellularCapabilityUniversal(cellular, proxy_factory, modem_info),
Arman Uguray0a3e2792013-01-17 16:31:50 -080047 weak_cdma_ptr_factory_(this),
48 activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
Arman Uguray72fab6a2013-01-10 19:32:42 -080049 cdma_1x_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
50 cdma_evdo_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
51 nid_(0),
52 sid_(0) {
53 SLOG(Cellular, 2) << "Cellular capability constructed: Universal CDMA";
Arman Uguray0a3e2792013-01-17 16:31:50 -080054 // TODO(armansito): Update PRL for activation over cellular.
Arman Uguray72fab6a2013-01-10 19:32:42 -080055 // See crbug.com/197330.
56}
57
Ben Chanf98f00e2014-02-05 14:48:43 -080058CellularCapabilityUniversalCDMA::~CellularCapabilityUniversalCDMA() {}
59
Arman Uguray72fab6a2013-01-10 19:32:42 -080060void CellularCapabilityUniversalCDMA::InitProxies() {
61 SLOG(Cellular, 2) << __func__;
62 modem_cdma_proxy_.reset(
63 proxy_factory()->CreateMM1ModemModemCdmaProxy(cellular()->dbus_path(),
64 cellular()->dbus_owner()));
Arman Uguray0a3e2792013-01-17 16:31:50 -080065 modem_cdma_proxy_->set_activation_state_callback(
66 Bind(&CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal,
67 weak_cdma_ptr_factory_.GetWeakPtr()));
Arman Uguray72fab6a2013-01-10 19:32:42 -080068 CellularCapabilityUniversal::InitProxies();
69}
70
71void CellularCapabilityUniversalCDMA::ReleaseProxies() {
72 SLOG(Cellular, 2) << __func__;
73 modem_cdma_proxy_.reset();
74 CellularCapabilityUniversal::ReleaseProxies();
75}
76
Ben Chanf98f00e2014-02-05 14:48:43 -080077void CellularCapabilityUniversalCDMA::Activate(const string &carrier,
78 Error *error,
79 const ResultCallback &callback) {
Arman Uguray0a3e2792013-01-17 16:31:50 -080080 // Currently activation over the cellular network is not supported using
81 // ModemManager-next. Service activation is currently carried through over
82 // non-cellular networks and only the final step of the OTA activation
83 // procedure ("automatic activation") is performed by this class.
Arman Uguray72fab6a2013-01-10 19:32:42 -080084 OnUnsupportedOperation(__func__, error);
85}
86
87void CellularCapabilityUniversalCDMA::CompleteActivation(Error *error) {
Arman Uguray0a3e2792013-01-17 16:31:50 -080088 SLOG(Cellular, 2) << __func__;
89 if (cellular()->state() < Cellular::kStateEnabled) {
90 Error::PopulateAndLog(error, Error::kInvalidArguments,
91 "Unable to activate in state " +
92 Cellular::GetStateString(cellular()->state()));
93 return;
94 }
95 ActivateAutomatic();
Arman Uguray72fab6a2013-01-10 19:32:42 -080096}
97
Arman Uguray0a3e2792013-01-17 16:31:50 -080098void CellularCapabilityUniversalCDMA::ActivateAutomatic() {
99 if (activation_code_.empty()) {
100 SLOG(Cellular, 2) << "OTA activation cannot be run in the presence of no "
101 << "activation code.";
102 return;
103 }
104 PendingActivationStore::State state =
105 modem_info()->pending_activation_store()->GetActivationState(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800106 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800107 if (state == PendingActivationStore::kStatePending) {
108 SLOG(Cellular, 2) << "There's already a pending activation. Ignoring.";
109 return;
110 }
111 if (state == PendingActivationStore::kStateActivated) {
112 SLOG(Cellular, 2) << "A call to OTA activation has already completed "
113 << "successfully. Ignoring.";
114 return;
115 }
116
117 // Mark as pending activation, so that shill can recover if anything fails
118 // during OTA activation.
119 modem_info()->pending_activation_store()->SetActivationState(
120 PendingActivationStore::kIdentifierMEID,
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800121 cellular()->meid(),
Arman Uguray0a3e2792013-01-17 16:31:50 -0800122 PendingActivationStore::kStatePending);
123
124 // Initiate OTA activation.
125 ResultCallback activation_callback =
126 Bind(&CellularCapabilityUniversalCDMA::OnActivateReply,
127 weak_cdma_ptr_factory_.GetWeakPtr(),
128 ResultCallback());
Arman Ugurayf2b4a342013-05-23 18:26:52 -0700129
Arman Uguray0a3e2792013-01-17 16:31:50 -0800130 Error error;
131 modem_cdma_proxy_->Activate(
132 activation_code_, &error, activation_callback, kTimeoutActivate);
133}
134
135void CellularCapabilityUniversalCDMA::UpdatePendingActivationState() {
Arman Uguray72fab6a2013-01-10 19:32:42 -0800136 SLOG(Cellular, 2) << __func__;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800137 if (IsActivated()) {
138 SLOG(Cellular, 3) << "CDMA service activated. Clear store.";
139 modem_info()->pending_activation_store()->RemoveEntry(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800140 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800141 return;
142 }
143 PendingActivationStore::State state =
144 modem_info()->pending_activation_store()->GetActivationState(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800145 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800146 if (IsActivating() && state != PendingActivationStore::kStateFailureRetry) {
147 SLOG(Cellular, 3) << "OTA activation in progress. Nothing to do.";
148 return;
149 }
150 switch (state) {
151 case PendingActivationStore::kStateFailureRetry:
152 SLOG(Cellular, 3) << "OTA activation failed. Scheduling a retry.";
153 cellular()->dispatcher()->PostTask(
154 Bind(&CellularCapabilityUniversalCDMA::ActivateAutomatic,
155 weak_cdma_ptr_factory_.GetWeakPtr()));
156 break;
157 case PendingActivationStore::kStateActivated:
158 SLOG(Cellular, 3) << "OTA Activation has completed successfully. "
159 << "Waiting for activation state update to finalize.";
160 break;
161 default:
162 break;
163 }
164}
165
166bool CellularCapabilityUniversalCDMA::IsServiceActivationRequired() const {
167 // If there is no online payment portal information, it's safer to assume
168 // the service does not require activation.
169 if (!modem_info()->cellular_operator_info())
170 return false;
171
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700172 const CellularOperatorInfo::OLP *olp =
Arman Uguray0a3e2792013-01-17 16:31:50 -0800173 modem_info()->cellular_operator_info()->GetOLPBySID(UintToString(sid_));
174 if (!olp)
175 return false;
176
177 // We could also use the MDN to determine whether or not the service is
178 // activated, however, the CDMA ActivatonState property is a more absolute
179 // and fine-grained indicator of activation status.
180 return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED);
181}
182
183bool CellularCapabilityUniversalCDMA::IsActivated() const {
184 return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800185}
186
187void CellularCapabilityUniversalCDMA::OnServiceCreated() {
188 SLOG(Cellular, 2) << __func__;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800189 UpdateServiceActivationStateProperty();
Arman Uguray72fab6a2013-01-10 19:32:42 -0800190 UpdateServingOperator();
Arman Uguray0a3e2792013-01-17 16:31:50 -0800191 HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
192 UpdatePendingActivationState();
Arman Uguray72fab6a2013-01-10 19:32:42 -0800193}
194
Arman Uguray0a3e2792013-01-17 16:31:50 -0800195void CellularCapabilityUniversalCDMA::UpdateServiceActivationStateProperty() {
196 bool activation_required = IsServiceActivationRequired();
197 cellular()->service()->SetActivateOverNonCellularNetwork(activation_required);
198 string activation_state;
199 if (IsActivating())
Ben Chan7ea768e2013-09-20 15:08:40 -0700200 activation_state = kActivationStateActivating;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800201 else if (activation_required)
Ben Chan7ea768e2013-09-20 15:08:40 -0700202 activation_state = kActivationStateNotActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800203 else
Ben Chan7ea768e2013-09-20 15:08:40 -0700204 activation_state = kActivationStateActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800205 cellular()->service()->SetActivationState(activation_state);
206}
207
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700208void CellularCapabilityUniversalCDMA::UpdateServiceOLP() {
Ben Chan07193fd2013-07-12 22:10:55 -0700209 SLOG(Cellular, 2) << __func__;
210
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700211 // In this case, the Home Provider is trivial. All information comes from the
212 // Serving Operator.
213 if (!cellular()->serving_operator_info()->IsMobileNetworkOperatorKnown()) {
Ben Chan07193fd2013-07-12 22:10:55 -0700214 return;
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700215 }
Ben Chan07193fd2013-07-12 22:10:55 -0700216
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700217 const vector<MobileOperatorInfo::OnlinePortal> &olp_list =
218 cellular()->serving_operator_info()->olp_list();
219 if (olp_list.empty()) {
Arman Uguray72fab6a2013-01-10 19:32:42 -0800220 return;
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700221 }
Arman Uguray72fab6a2013-01-10 19:32:42 -0800222
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700223 if (olp_list.size() > 1) {
224 SLOG(Cellular, 1) << "Found multiple online portals. Choosing the first.";
225 }
226 string post_data = olp_list[0].post_data;
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800227 ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}", cellular()->esn());
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700228 ReplaceSubstringsAfterOffset(
229 &post_data, 0, "${mdn}",
230 GetMdnForOLP(cellular()->serving_operator_info()));
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800231 ReplaceSubstringsAfterOffset(&post_data, 0, "${meid}", cellular()->meid());
Arman Ugurayf87fa2f2013-10-16 14:24:56 -0700232 ReplaceSubstringsAfterOffset(&post_data, 0, "${oem}", "GOG2");
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700233 cellular()->service()->SetOLP(olp_list[0].url, olp_list[0].method, post_data);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800234}
235
236void CellularCapabilityUniversalCDMA::GetProperties() {
237 SLOG(Cellular, 2) << __func__;
238 CellularCapabilityUniversal::GetProperties();
239
240 scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
241 proxy_factory()->CreateDBusPropertiesProxy(cellular()->dbus_path(),
242 cellular()->dbus_owner()));
243 DBusPropertiesMap properties(
244 properties_proxy->GetAll(MM_DBUS_INTERFACE_MODEM_MODEMCDMA));
245 OnModemCDMAPropertiesChanged(properties, vector<string>());
246}
247
Arman Uguray72fab6a2013-01-10 19:32:42 -0800248void CellularCapabilityUniversalCDMA::UpdateOperatorInfo() {
249 SLOG(Cellular, 2) << __func__;
250
251 if (sid_ == 0 || !modem_info()->cellular_operator_info()) {
252 SLOG(Cellular, 2) << "No provider is currently available.";
253 provider_.SetCode("");
254 return;
255 }
256
257 string sid = UintToString(sid_);
258 const CellularOperatorInfo::CellularOperator *provider =
259 modem_info()->cellular_operator_info()->GetCellularOperatorBySID(sid);
260 if (!provider) {
261 SLOG(Cellular, 2) << "CDMA provider with "
262 << FormattedSID(sid)
263 << " not found.";
Arman Uguraye015faf2013-08-16 17:54:59 -0700264 // If a matching provider is not found, shill should update the
265 // Cellular.ServingOperator property to to display the Sid.
266 provider_.SetCode(sid);
267 provider_.SetCountry("");
268 provider_.SetName("");
269 activation_code_.clear();
270 } else {
271 if (!provider->name_list().empty()) {
272 provider_.SetName(provider->name_list()[0].name);
273 }
274 provider_.SetCode(sid);
275 provider_.SetCountry(provider->country());
Arman Uguray72fab6a2013-01-10 19:32:42 -0800276
Arman Uguraye015faf2013-08-16 17:54:59 -0700277 activation_code_ = provider->activation_code();
Arman Uguray72fab6a2013-01-10 19:32:42 -0800278 }
Arman Uguray0a3e2792013-01-17 16:31:50 -0800279
Arman Uguray72fab6a2013-01-10 19:32:42 -0800280 // TODO(armansito): The CDMA interface only returns information about the
281 // current serving carrier, so for now both the home provider and the
282 // serving operator will be the same in case of roaming. We should figure
283 // out if there is a way to (and whether or not it is necessary to)
284 // determine if we're roaming.
285 cellular()->set_home_provider(provider_);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800286 UpdateServingOperator();
287}
288
289void CellularCapabilityUniversalCDMA::UpdateServingOperator() {
290 SLOG(Cellular, 2) << __func__;
291 if (cellular()->service().get()) {
292 cellular()->service()->SetServingOperator(cellular()->home_provider());
293 }
294}
295
Arman Uguray0a3e2792013-01-17 16:31:50 -0800296void CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal(
297 uint32 activation_state,
298 uint32 activation_error,
299 const DBusPropertiesMap &status_changes) {
300 SLOG(Cellular, 2) << __func__;
301
302 activation_state_ =
303 static_cast<MMModemCdmaActivationState>(activation_state);
304
305 string value;
306 if (DBusProperties::GetString(status_changes, "mdn", &value))
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800307 cellular()->set_mdn(value);
Arman Uguray0a3e2792013-01-17 16:31:50 -0800308 if (DBusProperties::GetString(status_changes, "min", &value))
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800309 cellular()->set_min(value);
Arman Uguray0a3e2792013-01-17 16:31:50 -0800310
311 SLOG(Cellular, 2) << "Activation state: "
312 << GetActivationStateString(activation_state_);
313
314 HandleNewActivationStatus(activation_error);
315 UpdatePendingActivationState();
316}
317
318void CellularCapabilityUniversalCDMA::OnActivateReply(
319 const ResultCallback &callback,
320 const Error &error) {
321 SLOG(Cellular, 2) << __func__;
322 if (error.IsSuccess()) {
323 LOG(INFO) << "Activation completed successfully.";
324 modem_info()->pending_activation_store()->SetActivationState(
325 PendingActivationStore::kIdentifierMEID,
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800326 cellular()->meid(),
Arman Uguray0a3e2792013-01-17 16:31:50 -0800327 PendingActivationStore::kStateActivated);
328 } else {
329 LOG(ERROR) << "Activation failed with error: " << error;
330 modem_info()->pending_activation_store()->SetActivationState(
331 PendingActivationStore::kIdentifierMEID,
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800332 cellular()->meid(),
Arman Uguray0a3e2792013-01-17 16:31:50 -0800333 PendingActivationStore::kStateFailureRetry);
334 }
335 UpdatePendingActivationState();
Arman Ugurayf2b4a342013-05-23 18:26:52 -0700336
337 // CellularCapabilityUniversalCDMA::ActivateAutomatic passes a dummy
338 // ResultCallback when it calls Activate on the proxy object, in which case
339 // |callback.is_null()| will return true.
340 if (!callback.is_null())
341 callback.Run(error);
Arman Uguray0a3e2792013-01-17 16:31:50 -0800342}
343
344void CellularCapabilityUniversalCDMA::HandleNewActivationStatus(uint32 error) {
345 SLOG(Cellular, 2) << __func__ << "(" << error << ")";
346 if (!cellular()->service().get()) {
347 LOG(ERROR) << "In " << __func__ << "(): service is null.";
348 return;
349 }
350 SLOG(Cellular, 2) << "Activation State: " << activation_state_;
351 cellular()->service()->SetActivationState(
352 GetActivationStateString(activation_state_));
353 cellular()->service()->set_error(GetActivationErrorString(error));
Prathmesh Prabhu92df6192014-04-29 18:08:08 -0700354 UpdateServiceOLP();
Arman Uguray0a3e2792013-01-17 16:31:50 -0800355}
356
357// static
358string CellularCapabilityUniversalCDMA::GetActivationStateString(
359 uint32 state) {
360 switch (state) {
361 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700362 return kActivationStateActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800363 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
Ben Chan7ea768e2013-09-20 15:08:40 -0700364 return kActivationStateActivating;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800365 case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700366 return kActivationStateNotActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800367 case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700368 return kActivationStatePartiallyActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800369 default:
Ben Chan7ea768e2013-09-20 15:08:40 -0700370 return kActivationStateUnknown;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800371 }
372}
373
374// static
375string CellularCapabilityUniversalCDMA::GetActivationErrorString(
376 uint32 error) {
377 switch (error) {
378 case MM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE:
Ben Chan7ea768e2013-09-20 15:08:40 -0700379 return kErrorNeedEvdo;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800380 case MM_CDMA_ACTIVATION_ERROR_ROAMING:
Ben Chan7ea768e2013-09-20 15:08:40 -0700381 return kErrorNeedHomeNetwork;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800382 case MM_CDMA_ACTIVATION_ERROR_COULD_NOT_CONNECT:
383 case MM_CDMA_ACTIVATION_ERROR_SECURITY_AUTHENTICATION_FAILED:
384 case MM_CDMA_ACTIVATION_ERROR_PROVISIONING_FAILED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700385 return kErrorOtaspFailed;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800386 case MM_CDMA_ACTIVATION_ERROR_NONE:
387 return "";
388 case MM_CDMA_ACTIVATION_ERROR_NO_SIGNAL:
389 default:
Ben Chan7ea768e2013-09-20 15:08:40 -0700390 return kErrorActivationFailed;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800391 }
392}
393
Arman Uguray72fab6a2013-01-10 19:32:42 -0800394void CellularCapabilityUniversalCDMA::Register(const ResultCallback &callback) {
395 // TODO(armansito): Remove once 3GPP is implemented in its own class.
396}
397
398void CellularCapabilityUniversalCDMA::RegisterOnNetwork(
399 const string &network_id,
400 Error *error,
401 const ResultCallback &callback) {
402 // TODO(armansito): Remove once 3GPP is implemented in its own class.
403}
404
Arman Uguray0a3e2792013-01-17 16:31:50 -0800405bool CellularCapabilityUniversalCDMA::IsActivating() const {
406 PendingActivationStore::State state =
407 modem_info()->pending_activation_store()->GetActivationState(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800408 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800409 return (state == PendingActivationStore::kStatePending) ||
410 (state == PendingActivationStore::kStateFailureRetry) ||
411 (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING);
412}
413
Ben Chan31ce5642013-11-14 13:37:40 -0800414bool CellularCapabilityUniversalCDMA::IsRegistered() const {
Ben Chanb2c4a802013-11-14 12:47:52 -0800415 return (cdma_1x_registration_state_ !=
416 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN ||
417 cdma_evdo_registration_state_ !=
418 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800419}
420
421void CellularCapabilityUniversalCDMA::SetUnregistered(bool /*searching*/) {
422 cdma_1x_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
423 cdma_evdo_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
424}
425
Arman Ugurayc9673062013-05-13 21:21:53 -0700426void CellularCapabilityUniversalCDMA::SetupConnectProperties(
427 DBusPropertiesMap *properties) {
428 (*properties)[kPropertyConnectNumber].writer().append_string(
429 kPhoneNumber);
430}
431
Arman Uguray72fab6a2013-01-10 19:32:42 -0800432void CellularCapabilityUniversalCDMA::RequirePIN(
433 const string &pin, bool require,
434 Error *error, const ResultCallback &callback) {
435 // TODO(armansito): Remove once 3GPP is implemented in its own class.
436}
437
438void CellularCapabilityUniversalCDMA::EnterPIN(
439 const string &pin,
440 Error *error,
441 const ResultCallback &callback) {
442 // TODO(armansito): Remove once 3GPP is implemented in its own class.
443}
444
445void CellularCapabilityUniversalCDMA::UnblockPIN(
446 const string &unblock_code,
447 const string &pin,
448 Error *error,
449 const ResultCallback &callback) {
450 // TODO(armansito): Remove once 3GPP is implemented in its own class.
451}
452
453void CellularCapabilityUniversalCDMA::ChangePIN(
454 const string &old_pin, const string &new_pin,
455 Error *error, const ResultCallback &callback) {
456 // TODO(armansito): Remove once 3GPP is implemented in its own class.
457}
458
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -0800459void CellularCapabilityUniversalCDMA::Scan(
460 Error *error,
461 const ResultStringmapsCallback &callback) {
Arman Uguray72fab6a2013-01-10 19:32:42 -0800462 // TODO(armansito): Remove once 3GPP is implemented in its own class.
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -0800463 OnUnsupportedOperation(__func__, error);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800464}
465
466void CellularCapabilityUniversalCDMA::OnSimPathChanged(
467 const string &sim_path) {
468 // TODO(armansito): Remove once 3GPP is implemented in its own class.
469}
470
471string CellularCapabilityUniversalCDMA::GetRoamingStateString() const {
472 uint32 state = cdma_evdo_registration_state_;
473 if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
474 state = cdma_1x_registration_state_;
475 }
476 switch (state) {
477 case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN:
478 case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
479 break;
480 case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
Ben Chan7ea768e2013-09-20 15:08:40 -0700481 return kRoamingStateHome;
Arman Uguray72fab6a2013-01-10 19:32:42 -0800482 case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
Ben Chan7ea768e2013-09-20 15:08:40 -0700483 return kRoamingStateRoaming;
Arman Uguray72fab6a2013-01-10 19:32:42 -0800484 default:
485 NOTREACHED();
486 }
Ben Chan7ea768e2013-09-20 15:08:40 -0700487 return kRoamingStateUnknown;
Arman Uguray72fab6a2013-01-10 19:32:42 -0800488}
489
490void CellularCapabilityUniversalCDMA::OnDBusPropertiesChanged(
491 const string &interface,
492 const DBusPropertiesMap &changed_properties,
493 const vector<string> &invalidated_properties) {
494 SLOG(Cellular, 2) << __func__ << "(" << interface << ")";
495 if (interface == MM_DBUS_INTERFACE_MODEM_MODEMCDMA) {
496 OnModemCDMAPropertiesChanged(changed_properties, invalidated_properties);
497 } else {
498 CellularCapabilityUniversal::OnDBusPropertiesChanged(
499 interface, changed_properties, invalidated_properties);
500 }
501}
502
503void CellularCapabilityUniversalCDMA::OnModemCDMAPropertiesChanged(
504 const DBusPropertiesMap &properties,
505 const std::vector<std::string> &/*invalidated_properties*/) {
506 SLOG(Cellular, 2) << __func__;
507 string str_value;
508 if (DBusProperties::GetString(properties,
509 MM_MODEM_MODEMCDMA_PROPERTY_MEID,
510 &str_value))
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800511 cellular()->set_meid(str_value);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800512 if (DBusProperties::GetString(properties,
513 MM_MODEM_MODEMCDMA_PROPERTY_ESN,
514 &str_value))
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800515 cellular()->set_esn(str_value);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800516
517 uint32_t sid = sid_;
518 uint32_t nid = nid_;
519 MMModemCdmaRegistrationState state_1x = cdma_1x_registration_state_;
520 MMModemCdmaRegistrationState state_evdo = cdma_evdo_registration_state_;
521 bool registration_changed = false;
522 uint32_t uint_value;
523 if (DBusProperties::GetUint32(
524 properties,
525 MM_MODEM_MODEMCDMA_PROPERTY_CDMA1XREGISTRATIONSTATE,
526 &uint_value)) {
527 state_1x = static_cast<MMModemCdmaRegistrationState>(uint_value);
528 registration_changed = true;
529 }
530 if (DBusProperties::GetUint32(
531 properties,
532 MM_MODEM_MODEMCDMA_PROPERTY_EVDOREGISTRATIONSTATE,
533 &uint_value)) {
534 state_evdo = static_cast<MMModemCdmaRegistrationState>(uint_value);
535 registration_changed = true;
536 }
537 if (DBusProperties::GetUint32(
538 properties,
539 MM_MODEM_MODEMCDMA_PROPERTY_SID,
540 &uint_value)) {
541 sid = uint_value;
542 registration_changed = true;
543 }
544 if (DBusProperties::GetUint32(
545 properties,
546 MM_MODEM_MODEMCDMA_PROPERTY_NID,
547 &uint_value)) {
548 nid = uint_value;
549 registration_changed = true;
550 }
Arman Uguray0a3e2792013-01-17 16:31:50 -0800551 if (DBusProperties::GetUint32(
552 properties,
553 MM_MODEM_MODEMCDMA_PROPERTY_ACTIVATIONSTATE,
554 &uint_value)) {
555 activation_state_ = static_cast<MMModemCdmaActivationState>(uint_value);
556 HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
557 }
Arman Uguray72fab6a2013-01-10 19:32:42 -0800558 if (registration_changed)
559 OnCDMARegistrationChanged(state_1x, state_evdo, sid, nid);
560}
561
562void CellularCapabilityUniversalCDMA::OnCDMARegistrationChanged(
563 MMModemCdmaRegistrationState state_1x,
564 MMModemCdmaRegistrationState state_evdo,
565 uint32_t sid, uint32_t nid) {
566 SLOG(Cellular, 2) << __func__
567 << ": state_1x=" << state_1x
568 << ", state_evdo=" << state_evdo;
569 cdma_1x_registration_state_ = state_1x;
570 cdma_evdo_registration_state_ = state_evdo;
571 sid_ = sid;
572 nid_ = nid;
Prathmesh Prabhu8599e052014-04-25 14:20:22 -0700573 cellular()->serving_operator_info()->UpdateSID(UintToString(sid));
574 cellular()->serving_operator_info()->UpdateNID(UintToString(nid));
Arman Uguray72fab6a2013-01-10 19:32:42 -0800575 UpdateOperatorInfo();
576 cellular()->HandleNewRegistrationState();
577}
578
579} // namespace shill