blob: df1e5896ac482db08a440afd1fd66e58dcf69f5a [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>
8#include <base/stringprintf.h>
9#include <base/string_number_conversions.h>
10#include <base/string_util.h>
11
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
42// static
43unsigned int
44CellularCapabilityUniversalCDMA::friendly_service_name_id_cdma_ = 0;
45
46CellularCapabilityUniversalCDMA::CellularCapabilityUniversalCDMA(
47 Cellular *cellular,
48 ProxyFactory *proxy_factory,
49 ModemInfo *modem_info)
50 : CellularCapabilityUniversal(cellular,
51 proxy_factory,
52 modem_info),
Arman Uguray0a3e2792013-01-17 16:31:50 -080053 weak_cdma_ptr_factory_(this),
54 activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
Arman Uguray72fab6a2013-01-10 19:32:42 -080055 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 Uguray0a3e2792013-01-17 16:31:50 -080060 // TODO(armansito): Update PRL for activation over cellular.
Arman Uguray72fab6a2013-01-10 19:32:42 -080061 // See crbug.com/197330.
62}
63
64void CellularCapabilityUniversalCDMA::InitProxies() {
65 SLOG(Cellular, 2) << __func__;
66 modem_cdma_proxy_.reset(
67 proxy_factory()->CreateMM1ModemModemCdmaProxy(cellular()->dbus_path(),
68 cellular()->dbus_owner()));
Arman Uguray0a3e2792013-01-17 16:31:50 -080069 modem_cdma_proxy_->set_activation_state_callback(
70 Bind(&CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal,
71 weak_cdma_ptr_factory_.GetWeakPtr()));
Arman Uguray72fab6a2013-01-10 19:32:42 -080072 CellularCapabilityUniversal::InitProxies();
73}
74
75void CellularCapabilityUniversalCDMA::ReleaseProxies() {
76 SLOG(Cellular, 2) << __func__;
77 modem_cdma_proxy_.reset();
78 CellularCapabilityUniversal::ReleaseProxies();
79}
80
81void CellularCapabilityUniversalCDMA::Activate(
82 const string &carrier,
83 Error *error,
84 const ResultCallback &callback) {
Arman Uguray0a3e2792013-01-17 16:31:50 -080085 // 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 Uguray72fab6a2013-01-10 19:32:42 -080089 OnUnsupportedOperation(__func__, error);
90}
91
92void CellularCapabilityUniversalCDMA::CompleteActivation(Error *error) {
Arman Uguray0a3e2792013-01-17 16:31:50 -080093 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 Uguray72fab6a2013-01-10 19:32:42 -0800101}
102
Arman Uguray0a3e2792013-01-17 16:31:50 -0800103void 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 Prabhu9f06c872013-11-21 14:08:23 -0800111 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800112 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 Prabhu9f06c872013-11-21 14:08:23 -0800126 cellular()->meid(),
Arman Uguray0a3e2792013-01-17 16:31:50 -0800127 PendingActivationStore::kStatePending);
128
129 // Initiate OTA activation.
130 ResultCallback activation_callback =
131 Bind(&CellularCapabilityUniversalCDMA::OnActivateReply,
132 weak_cdma_ptr_factory_.GetWeakPtr(),
133 ResultCallback());
Arman Ugurayf2b4a342013-05-23 18:26:52 -0700134
Arman Uguray0a3e2792013-01-17 16:31:50 -0800135 Error error;
136 modem_cdma_proxy_->Activate(
137 activation_code_, &error, activation_callback, kTimeoutActivate);
138}
139
140void CellularCapabilityUniversalCDMA::UpdatePendingActivationState() {
Arman Uguray72fab6a2013-01-10 19:32:42 -0800141 SLOG(Cellular, 2) << __func__;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800142 if (IsActivated()) {
143 SLOG(Cellular, 3) << "CDMA service activated. Clear store.";
144 modem_info()->pending_activation_store()->RemoveEntry(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800145 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800146 return;
147 }
148 PendingActivationStore::State state =
149 modem_info()->pending_activation_store()->GetActivationState(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800150 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800151 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
171bool 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
188bool CellularCapabilityUniversalCDMA::IsActivated() const {
189 return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800190}
191
Arman Ugurayc5391232013-09-23 21:30:46 -0700192void 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 Uguray72fab6a2013-01-10 19:32:42 -0800211void CellularCapabilityUniversalCDMA::OnServiceCreated() {
212 SLOG(Cellular, 2) << __func__;
Arman Ugurayc5391232013-09-23 21:30:46 -0700213 UpdateStorageIdentifier();
Arman Uguray0a3e2792013-01-17 16:31:50 -0800214 UpdateServiceActivationStateProperty();
Arman Uguray72fab6a2013-01-10 19:32:42 -0800215 UpdateServingOperator();
Arman Uguray0a3e2792013-01-17 16:31:50 -0800216 HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
217 UpdatePendingActivationState();
Arman Uguray72fab6a2013-01-10 19:32:42 -0800218 UpdateOLP();
219}
220
Arman Uguray0a3e2792013-01-17 16:31:50 -0800221void CellularCapabilityUniversalCDMA::UpdateServiceActivationStateProperty() {
222 bool activation_required = IsServiceActivationRequired();
223 cellular()->service()->SetActivateOverNonCellularNetwork(activation_required);
224 string activation_state;
225 if (IsActivating())
Ben Chan7ea768e2013-09-20 15:08:40 -0700226 activation_state = kActivationStateActivating;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800227 else if (activation_required)
Ben Chan7ea768e2013-09-20 15:08:40 -0700228 activation_state = kActivationStateNotActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800229 else
Ben Chan7ea768e2013-09-20 15:08:40 -0700230 activation_state = kActivationStateActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800231 cellular()->service()->SetActivationState(activation_state);
232}
233
Arman Uguray72fab6a2013-01-10 19:32:42 -0800234void CellularCapabilityUniversalCDMA::UpdateOLP() {
Ben Chan07193fd2013-07-12 22:10:55 -0700235 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 Uguray72fab6a2013-01-10 19:32:42 -0800246 return;
247
248 const CellularService::OLP *result =
Ben Chan07193fd2013-07-12 22:10:55 -0700249 cellular_operator_info->GetOLPBySID(sid_string);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800250 if (!result)
251 return;
252
253 CellularService::OLP olp;
254 olp.CopyFrom(*result);
255 string post_data = olp.GetPostData();
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800256 ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}", cellular()->esn());
Ben Chan07193fd2013-07-12 22:10:55 -0700257 ReplaceSubstringsAfterOffset(&post_data, 0, "${mdn}",
258 GetMdnForOLP(*cellular_operator));
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800259 ReplaceSubstringsAfterOffset(&post_data, 0, "${meid}", cellular()->meid());
Arman Ugurayf87fa2f2013-10-16 14:24:56 -0700260 ReplaceSubstringsAfterOffset(&post_data, 0, "${oem}", "GOG2");
Arman Uguray72fab6a2013-01-10 19:32:42 -0800261 olp.SetPostData(post_data);
Arman Uguray0a3e2792013-01-17 16:31:50 -0800262 if (cellular()->service().get())
263 cellular()->service()->SetOLP(olp);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800264}
265
266void 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
278string 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
300void 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 Uguraye015faf2013-08-16 17:54:59 -0700316 // 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 Uguray72fab6a2013-01-10 19:32:42 -0800328
Arman Uguraye015faf2013-08-16 17:54:59 -0700329 activation_code_ = provider->activation_code();
Arman Uguray72fab6a2013-01-10 19:32:42 -0800330 }
Arman Uguray0a3e2792013-01-17 16:31:50 -0800331
Arman Uguray72fab6a2013-01-10 19:32:42 -0800332 // 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 Uguray72fab6a2013-01-10 19:32:42 -0800338 UpdateServingOperator();
339}
340
341void CellularCapabilityUniversalCDMA::UpdateServingOperator() {
342 SLOG(Cellular, 2) << __func__;
343 if (cellular()->service().get()) {
344 cellular()->service()->SetServingOperator(cellular()->home_provider());
Arman Uguray2269bb62013-07-26 14:53:30 -0700345 cellular()->service()->SetFriendlyName(CreateFriendlyServiceName());
Arman Uguray72fab6a2013-01-10 19:32:42 -0800346 }
347}
348
Arman Uguray0a3e2792013-01-17 16:31:50 -0800349void 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 Prabhu9f06c872013-11-21 14:08:23 -0800360 cellular()->set_mdn(value);
Arman Uguray0a3e2792013-01-17 16:31:50 -0800361 if (DBusProperties::GetString(status_changes, "min", &value))
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800362 cellular()->set_min(value);
Arman Uguray0a3e2792013-01-17 16:31:50 -0800363
364 SLOG(Cellular, 2) << "Activation state: "
365 << GetActivationStateString(activation_state_);
366
367 HandleNewActivationStatus(activation_error);
368 UpdatePendingActivationState();
369}
370
371void 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 Prabhu9f06c872013-11-21 14:08:23 -0800379 cellular()->meid(),
Arman Uguray0a3e2792013-01-17 16:31:50 -0800380 PendingActivationStore::kStateActivated);
381 } else {
382 LOG(ERROR) << "Activation failed with error: " << error;
383 modem_info()->pending_activation_store()->SetActivationState(
384 PendingActivationStore::kIdentifierMEID,
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800385 cellular()->meid(),
Arman Uguray0a3e2792013-01-17 16:31:50 -0800386 PendingActivationStore::kStateFailureRetry);
387 }
388 UpdatePendingActivationState();
Arman Ugurayf2b4a342013-05-23 18:26:52 -0700389
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 Uguray0a3e2792013-01-17 16:31:50 -0800395}
396
397void 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
411string CellularCapabilityUniversalCDMA::GetActivationStateString(
412 uint32 state) {
413 switch (state) {
414 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700415 return kActivationStateActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800416 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
Ben Chan7ea768e2013-09-20 15:08:40 -0700417 return kActivationStateActivating;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800418 case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700419 return kActivationStateNotActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800420 case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED:
Ben Chan7ea768e2013-09-20 15:08:40 -0700421 return kActivationStatePartiallyActivated;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800422 default:
Ben Chan7ea768e2013-09-20 15:08:40 -0700423 return kActivationStateUnknown;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800424 }
425}
426
427// static
428string CellularCapabilityUniversalCDMA::GetActivationErrorString(
429 uint32 error) {
430 switch (error) {
431 case MM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE:
Ben Chan7ea768e2013-09-20 15:08:40 -0700432 return kErrorNeedEvdo;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800433 case MM_CDMA_ACTIVATION_ERROR_ROAMING:
Ben Chan7ea768e2013-09-20 15:08:40 -0700434 return kErrorNeedHomeNetwork;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800435 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 Chan7ea768e2013-09-20 15:08:40 -0700438 return kErrorOtaspFailed;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800439 case MM_CDMA_ACTIVATION_ERROR_NONE:
440 return "";
441 case MM_CDMA_ACTIVATION_ERROR_NO_SIGNAL:
442 default:
Ben Chan7ea768e2013-09-20 15:08:40 -0700443 return kErrorActivationFailed;
Arman Uguray0a3e2792013-01-17 16:31:50 -0800444 }
445}
446
Arman Uguray72fab6a2013-01-10 19:32:42 -0800447void CellularCapabilityUniversalCDMA::Register(const ResultCallback &callback) {
448 // TODO(armansito): Remove once 3GPP is implemented in its own class.
449}
450
451void 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 Uguray0a3e2792013-01-17 16:31:50 -0800458bool CellularCapabilityUniversalCDMA::IsActivating() const {
459 PendingActivationStore::State state =
460 modem_info()->pending_activation_store()->GetActivationState(
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800461 PendingActivationStore::kIdentifierMEID, cellular()->meid());
Arman Uguray0a3e2792013-01-17 16:31:50 -0800462 return (state == PendingActivationStore::kStatePending) ||
463 (state == PendingActivationStore::kStateFailureRetry) ||
464 (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING);
465}
466
Ben Chan31ce5642013-11-14 13:37:40 -0800467bool CellularCapabilityUniversalCDMA::IsRegistered() const {
Ben Chanb2c4a802013-11-14 12:47:52 -0800468 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 Uguray72fab6a2013-01-10 19:32:42 -0800472}
473
474void 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 Ugurayc9673062013-05-13 21:21:53 -0700479void CellularCapabilityUniversalCDMA::SetupConnectProperties(
480 DBusPropertiesMap *properties) {
481 (*properties)[kPropertyConnectNumber].writer().append_string(
482 kPhoneNumber);
483}
484
Arman Uguray72fab6a2013-01-10 19:32:42 -0800485void 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
491void 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
498void 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
506void 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 Prabhu49ffffd2014-01-09 18:28:55 -0800512void CellularCapabilityUniversalCDMA::Scan(
513 Error *error,
514 const ResultStringmapsCallback &callback) {
Arman Uguray72fab6a2013-01-10 19:32:42 -0800515 // TODO(armansito): Remove once 3GPP is implemented in its own class.
Prathmesh Prabhu49ffffd2014-01-09 18:28:55 -0800516 OnUnsupportedOperation(__func__, error);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800517}
518
519void CellularCapabilityUniversalCDMA::OnSimPathChanged(
520 const string &sim_path) {
521 // TODO(armansito): Remove once 3GPP is implemented in its own class.
522}
523
524string 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 Chan7ea768e2013-09-20 15:08:40 -0700534 return kRoamingStateHome;
Arman Uguray72fab6a2013-01-10 19:32:42 -0800535 case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
Ben Chan7ea768e2013-09-20 15:08:40 -0700536 return kRoamingStateRoaming;
Arman Uguray72fab6a2013-01-10 19:32:42 -0800537 default:
538 NOTREACHED();
539 }
Ben Chan7ea768e2013-09-20 15:08:40 -0700540 return kRoamingStateUnknown;
Arman Uguray72fab6a2013-01-10 19:32:42 -0800541}
542
543void 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
556void 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 Prabhu9f06c872013-11-21 14:08:23 -0800564 cellular()->set_meid(str_value);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800565 if (DBusProperties::GetString(properties,
566 MM_MODEM_MODEMCDMA_PROPERTY_ESN,
567 &str_value))
Prathmesh Prabhu9f06c872013-11-21 14:08:23 -0800568 cellular()->set_esn(str_value);
Arman Uguray72fab6a2013-01-10 19:32:42 -0800569
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 Uguray0a3e2792013-01-17 16:31:50 -0800604 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 Uguray72fab6a2013-01-10 19:32:42 -0800611 if (registration_changed)
612 OnCDMARegistrationChanged(state_1x, state_evdo, sid, nid);
613}
614
615void 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