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 #include "shill/cellular/cellular_capability_universal_cdma.h"
18
19 #include <base/strings/string_number_conversions.h>
20 #include <base/strings/string_util.h>
21 #include <base/strings/stringprintf.h>
22 #if defined(__ANDROID__)
23 #include <dbus/service_constants.h>
24 #else
25 #include <chromeos/dbus/service_constants.h>
26 #endif // __ANDROID__
27
28 #include "shill/cellular/cellular_bearer.h"
29 #include "shill/cellular/cellular_service.h"
30 #include "shill/control_interface.h"
31 #include "shill/dbus_properties_proxy_interface.h"
32 #include "shill/error.h"
33 #include "shill/logging.h"
34 #include "shill/pending_activation_store.h"
35
36 #ifdef MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN
37 #error "Do not include mm-modem.h"
38 #endif
39
40 using base::UintToString;
41
42 using std::string;
43 using std::vector;
44
45 namespace shill {
46
47 namespace Logging {
48 static auto kModuleLogScope = ScopeLogger::kCellular;
ObjectID(CellularCapabilityUniversalCDMA * c)49 static string ObjectID(CellularCapabilityUniversalCDMA* c) {
50 return c->cellular()->GetRpcIdentifier();
51 }
52 }
53
54 namespace {
55
56 const char kPhoneNumber[] = "#777";
57 const char kPropertyConnectNumber[] = "number";
58
59 } // namespace
60
CellularCapabilityUniversalCDMA(Cellular * cellular,ControlInterface * control_interface,ModemInfo * modem_info)61 CellularCapabilityUniversalCDMA::CellularCapabilityUniversalCDMA(
62 Cellular* cellular,
63 ControlInterface* control_interface,
64 ModemInfo* modem_info)
65 : CellularCapabilityUniversal(cellular, control_interface, modem_info),
66 weak_cdma_ptr_factory_(this),
67 activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
68 cdma_1x_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
69 cdma_evdo_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
70 nid_(0),
71 sid_(0) {
72 SLOG(this, 2) << "Cellular capability constructed: Universal CDMA";
73 // TODO(armansito): Update PRL for activation over cellular.
74 // See crbug.com/197330.
75 }
76
~CellularCapabilityUniversalCDMA()77 CellularCapabilityUniversalCDMA::~CellularCapabilityUniversalCDMA() {}
78
InitProxies()79 void CellularCapabilityUniversalCDMA::InitProxies() {
80 SLOG(this, 2) << __func__;
81 modem_cdma_proxy_.reset(
82 control_interface()->CreateMM1ModemModemCdmaProxy(
83 cellular()->dbus_path(), cellular()->dbus_service()));
84 modem_cdma_proxy_->set_activation_state_callback(
85 Bind(&CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal,
86 weak_cdma_ptr_factory_.GetWeakPtr()));
87 CellularCapabilityUniversal::InitProxies();
88 }
89
ReleaseProxies()90 void CellularCapabilityUniversalCDMA::ReleaseProxies() {
91 SLOG(this, 2) << __func__;
92 modem_cdma_proxy_.reset();
93 CellularCapabilityUniversal::ReleaseProxies();
94 }
95
Activate(const string & carrier,Error * error,const ResultCallback & callback)96 void CellularCapabilityUniversalCDMA::Activate(const string& carrier,
97 Error* error,
98 const ResultCallback& callback) {
99 // Currently activation over the cellular network is not supported using
100 // ModemManager-next. Service activation is currently carried through over
101 // non-cellular networks and only the final step of the OTA activation
102 // procedure ("automatic activation") is performed by this class.
103 OnUnsupportedOperation(__func__, error);
104 }
105
CompleteActivation(Error * error)106 void CellularCapabilityUniversalCDMA::CompleteActivation(Error* error) {
107 SLOG(this, 2) << __func__;
108 if (cellular()->state() < Cellular::kStateEnabled) {
109 Error::PopulateAndLog(FROM_HERE, error, Error::kInvalidArguments,
110 "Unable to activate in state " +
111 Cellular::GetStateString(cellular()->state()));
112 return;
113 }
114 ActivateAutomatic();
115 }
116
ActivateAutomatic()117 void CellularCapabilityUniversalCDMA::ActivateAutomatic() {
118 if (!cellular()->serving_operator_info()->IsMobileNetworkOperatorKnown() ||
119 cellular()->serving_operator_info()->activation_code().empty()) {
120 SLOG(this, 2) << "OTA activation cannot be run in the presence of no "
121 << "activation code.";
122 return;
123 }
124
125 PendingActivationStore::State state =
126 modem_info()->pending_activation_store()->GetActivationState(
127 PendingActivationStore::kIdentifierMEID, cellular()->meid());
128 if (state == PendingActivationStore::kStatePending) {
129 SLOG(this, 2) << "There's already a pending activation. Ignoring.";
130 return;
131 }
132 if (state == PendingActivationStore::kStateActivated) {
133 SLOG(this, 2) << "A call to OTA activation has already completed "
134 << "successfully. Ignoring.";
135 return;
136 }
137
138 // Mark as pending activation, so that shill can recover if anything fails
139 // during OTA activation.
140 modem_info()->pending_activation_store()->SetActivationState(
141 PendingActivationStore::kIdentifierMEID,
142 cellular()->meid(),
143 PendingActivationStore::kStatePending);
144
145 // Initiate OTA activation.
146 ResultCallback activation_callback =
147 Bind(&CellularCapabilityUniversalCDMA::OnActivateReply,
148 weak_cdma_ptr_factory_.GetWeakPtr(),
149 ResultCallback());
150
151 Error error;
152 modem_cdma_proxy_->Activate(
153 cellular()->serving_operator_info()->activation_code(),
154 &error,
155 activation_callback,
156 kTimeoutActivate);
157 }
158
UpdatePendingActivationState()159 void CellularCapabilityUniversalCDMA::UpdatePendingActivationState() {
160 SLOG(this, 2) << __func__;
161 if (IsActivated()) {
162 SLOG(this, 3) << "CDMA service activated. Clear store.";
163 modem_info()->pending_activation_store()->RemoveEntry(
164 PendingActivationStore::kIdentifierMEID, cellular()->meid());
165 return;
166 }
167 PendingActivationStore::State state =
168 modem_info()->pending_activation_store()->GetActivationState(
169 PendingActivationStore::kIdentifierMEID, cellular()->meid());
170 if (IsActivating() && state != PendingActivationStore::kStateFailureRetry) {
171 SLOG(this, 3) << "OTA activation in progress. Nothing to do.";
172 return;
173 }
174 switch (state) {
175 case PendingActivationStore::kStateFailureRetry:
176 SLOG(this, 3) << "OTA activation failed. Scheduling a retry.";
177 cellular()->dispatcher()->PostTask(
178 Bind(&CellularCapabilityUniversalCDMA::ActivateAutomatic,
179 weak_cdma_ptr_factory_.GetWeakPtr()));
180 break;
181 case PendingActivationStore::kStateActivated:
182 SLOG(this, 3) << "OTA Activation has completed successfully. "
183 << "Waiting for activation state update to finalize.";
184 break;
185 default:
186 break;
187 }
188 }
189
IsServiceActivationRequired() const190 bool CellularCapabilityUniversalCDMA::IsServiceActivationRequired() const {
191 // If there is no online payment portal information, it's safer to assume
192 // the service does not require activation.
193 if (!cellular()->serving_operator_info()->IsMobileNetworkOperatorKnown() ||
194 cellular()->serving_operator_info()->olp_list().empty()) {
195 return false;
196 }
197
198 // We could also use the MDN to determine whether or not the service is
199 // activated, however, the CDMA ActivatonState property is a more absolute
200 // and fine-grained indicator of activation status.
201 return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED);
202 }
203
IsActivated() const204 bool CellularCapabilityUniversalCDMA::IsActivated() const {
205 return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED);
206 }
207
OnServiceCreated()208 void CellularCapabilityUniversalCDMA::OnServiceCreated() {
209 SLOG(this, 2) << __func__;
210 cellular()->service()->SetActivationType(
211 CellularService::kActivationTypeOTASP);
212 UpdateServiceActivationStateProperty();
213 HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
214 UpdatePendingActivationState();
215 }
216
UpdateServiceActivationStateProperty()217 void CellularCapabilityUniversalCDMA::UpdateServiceActivationStateProperty() {
218 string activation_state;
219 if (IsActivating())
220 activation_state = kActivationStateActivating;
221 else if (IsServiceActivationRequired())
222 activation_state = kActivationStateNotActivated;
223 else
224 activation_state = kActivationStateActivated;
225 cellular()->service()->SetActivationState(activation_state);
226 }
227
UpdateServiceOLP()228 void CellularCapabilityUniversalCDMA::UpdateServiceOLP() {
229 SLOG(this, 2) << __func__;
230
231 // In this case, the Home Provider is trivial. All information comes from the
232 // Serving Operator.
233 if (!cellular()->serving_operator_info()->IsMobileNetworkOperatorKnown()) {
234 return;
235 }
236
237 const vector<MobileOperatorInfo::OnlinePortal>& olp_list =
238 cellular()->serving_operator_info()->olp_list();
239 if (olp_list.empty()) {
240 return;
241 }
242
243 if (olp_list.size() > 1) {
244 SLOG(this, 1) << "Found multiple online portals. Choosing the first.";
245 }
246 string post_data = olp_list[0].post_data;
247 base::ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}",
248 cellular()->esn());
249 base::ReplaceSubstringsAfterOffset(
250 &post_data, 0, "${mdn}",
251 GetMdnForOLP(cellular()->serving_operator_info()));
252 base::ReplaceSubstringsAfterOffset(&post_data, 0,
253 "${meid}", cellular()->meid());
254 base::ReplaceSubstringsAfterOffset(&post_data, 0, "${oem}", "GOG2");
255 cellular()->service()->SetOLP(olp_list[0].url, olp_list[0].method, post_data);
256 }
257
GetProperties()258 void CellularCapabilityUniversalCDMA::GetProperties() {
259 SLOG(this, 2) << __func__;
260 CellularCapabilityUniversal::GetProperties();
261
262 std::unique_ptr<DBusPropertiesProxyInterface> properties_proxy(
263 control_interface()->CreateDBusPropertiesProxy(
264 cellular()->dbus_path(), cellular()->dbus_service()));
265
266 KeyValueStore properties(
267 properties_proxy->GetAll(MM_DBUS_INTERFACE_MODEM_MODEMCDMA));
268 OnModemCDMAPropertiesChanged(properties, vector<string>());
269 }
270
OnActivationStateChangedSignal(uint32_t activation_state,uint32_t activation_error,const KeyValueStore & status_changes)271 void CellularCapabilityUniversalCDMA::OnActivationStateChangedSignal(
272 uint32_t activation_state,
273 uint32_t activation_error,
274 const KeyValueStore& status_changes) {
275 SLOG(this, 2) << __func__;
276
277 activation_state_ =
278 static_cast<MMModemCdmaActivationState>(activation_state);
279
280 string value;
281 if (status_changes.ContainsString("mdn"))
282 cellular()->set_mdn(status_changes.GetString("mdn"));
283 if (status_changes.ContainsString("min"))
284 cellular()->set_min(status_changes.GetString("min"));
285 SLOG(this, 2) << "Activation state: "
286 << GetActivationStateString(activation_state_);
287
288 HandleNewActivationStatus(activation_error);
289 UpdatePendingActivationState();
290 }
291
OnActivateReply(const ResultCallback & callback,const Error & error)292 void CellularCapabilityUniversalCDMA::OnActivateReply(
293 const ResultCallback& callback,
294 const Error& error) {
295 SLOG(this, 2) << __func__;
296 if (error.IsSuccess()) {
297 LOG(INFO) << "Activation completed successfully.";
298 modem_info()->pending_activation_store()->SetActivationState(
299 PendingActivationStore::kIdentifierMEID,
300 cellular()->meid(),
301 PendingActivationStore::kStateActivated);
302 } else {
303 LOG(ERROR) << "Activation failed with error: " << error;
304 modem_info()->pending_activation_store()->SetActivationState(
305 PendingActivationStore::kIdentifierMEID,
306 cellular()->meid(),
307 PendingActivationStore::kStateFailureRetry);
308 }
309 UpdatePendingActivationState();
310
311 // CellularCapabilityUniversalCDMA::ActivateAutomatic passes a dummy
312 // ResultCallback when it calls Activate on the proxy object, in which case
313 // |callback.is_null()| will return true.
314 if (!callback.is_null())
315 callback.Run(error);
316 }
317
HandleNewActivationStatus(uint32_t error)318 void CellularCapabilityUniversalCDMA::HandleNewActivationStatus(
319 uint32_t error) {
320 SLOG(this, 2) << __func__ << "(" << error << ")";
321 if (!cellular()->service().get()) {
322 LOG(ERROR) << "In " << __func__ << "(): service is null.";
323 return;
324 }
325 SLOG(this, 2) << "Activation State: " << activation_state_;
326 cellular()->service()->SetActivationState(
327 GetActivationStateString(activation_state_));
328 cellular()->service()->set_error(GetActivationErrorString(error));
329 UpdateServiceOLP();
330 }
331
332 // static
GetActivationStateString(uint32_t state)333 string CellularCapabilityUniversalCDMA::GetActivationStateString(
334 uint32_t state) {
335 switch (state) {
336 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
337 return kActivationStateActivated;
338 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
339 return kActivationStateActivating;
340 case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
341 return kActivationStateNotActivated;
342 case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED:
343 return kActivationStatePartiallyActivated;
344 default:
345 return kActivationStateUnknown;
346 }
347 }
348
349 // static
GetActivationErrorString(uint32_t error)350 string CellularCapabilityUniversalCDMA::GetActivationErrorString(
351 uint32_t error) {
352 switch (error) {
353 case MM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE:
354 return kErrorNeedEvdo;
355 case MM_CDMA_ACTIVATION_ERROR_ROAMING:
356 return kErrorNeedHomeNetwork;
357 case MM_CDMA_ACTIVATION_ERROR_COULD_NOT_CONNECT:
358 case MM_CDMA_ACTIVATION_ERROR_SECURITY_AUTHENTICATION_FAILED:
359 case MM_CDMA_ACTIVATION_ERROR_PROVISIONING_FAILED:
360 return kErrorOtaspFailed;
361 case MM_CDMA_ACTIVATION_ERROR_NONE:
362 return "";
363 case MM_CDMA_ACTIVATION_ERROR_NO_SIGNAL:
364 default:
365 return kErrorActivationFailed;
366 }
367 }
368
Register(const ResultCallback & callback)369 void CellularCapabilityUniversalCDMA::Register(const ResultCallback& callback) {
370 // TODO(armansito): Remove once 3GPP is implemented in its own class.
371 }
372
RegisterOnNetwork(const string & network_id,Error * error,const ResultCallback & callback)373 void CellularCapabilityUniversalCDMA::RegisterOnNetwork(
374 const string& network_id,
375 Error* error,
376 const ResultCallback& callback) {
377 // TODO(armansito): Remove once 3GPP is implemented in its own class.
378 }
379
IsActivating() const380 bool CellularCapabilityUniversalCDMA::IsActivating() const {
381 PendingActivationStore::State state =
382 modem_info()->pending_activation_store()->GetActivationState(
383 PendingActivationStore::kIdentifierMEID, cellular()->meid());
384 return (state == PendingActivationStore::kStatePending) ||
385 (state == PendingActivationStore::kStateFailureRetry) ||
386 (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING);
387 }
388
IsRegistered() const389 bool CellularCapabilityUniversalCDMA::IsRegistered() const {
390 return (cdma_1x_registration_state_ !=
391 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN ||
392 cdma_evdo_registration_state_ !=
393 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN);
394 }
395
SetUnregistered(bool)396 void CellularCapabilityUniversalCDMA::SetUnregistered(bool /*searching*/) {
397 cdma_1x_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
398 cdma_evdo_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
399 }
400
SetupConnectProperties(KeyValueStore * properties)401 void CellularCapabilityUniversalCDMA::SetupConnectProperties(
402 KeyValueStore* properties) {
403 properties->SetString(kPropertyConnectNumber, kPhoneNumber);
404 }
405
RequirePIN(const string & pin,bool require,Error * error,const ResultCallback & callback)406 void CellularCapabilityUniversalCDMA::RequirePIN(
407 const string& pin, bool require,
408 Error* error, const ResultCallback& callback) {
409 // TODO(armansito): Remove once 3GPP is implemented in its own class.
410 }
411
EnterPIN(const string & pin,Error * error,const ResultCallback & callback)412 void CellularCapabilityUniversalCDMA::EnterPIN(
413 const string& pin,
414 Error* error,
415 const ResultCallback& callback) {
416 // TODO(armansito): Remove once 3GPP is implemented in its own class.
417 }
418
UnblockPIN(const string & unblock_code,const string & pin,Error * error,const ResultCallback & callback)419 void CellularCapabilityUniversalCDMA::UnblockPIN(
420 const string& unblock_code,
421 const string& pin,
422 Error* error,
423 const ResultCallback& callback) {
424 // TODO(armansito): Remove once 3GPP is implemented in its own class.
425 }
426
ChangePIN(const string & old_pin,const string & new_pin,Error * error,const ResultCallback & callback)427 void CellularCapabilityUniversalCDMA::ChangePIN(
428 const string& old_pin, const string& new_pin,
429 Error* error, const ResultCallback& callback) {
430 // TODO(armansito): Remove once 3GPP is implemented in its own class.
431 }
432
Scan(Error * error,const ResultStringmapsCallback & callback)433 void CellularCapabilityUniversalCDMA::Scan(
434 Error* error,
435 const ResultStringmapsCallback& callback) {
436 // TODO(armansito): Remove once 3GPP is implemented in its own class.
437 OnUnsupportedOperation(__func__, error);
438 }
439
OnSimPathChanged(const string & sim_path)440 void CellularCapabilityUniversalCDMA::OnSimPathChanged(
441 const string& sim_path) {
442 // TODO(armansito): Remove once 3GPP is implemented in its own class.
443 }
444
GetRoamingStateString() const445 string CellularCapabilityUniversalCDMA::GetRoamingStateString() const {
446 uint32_t state = cdma_evdo_registration_state_;
447 if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
448 state = cdma_1x_registration_state_;
449 }
450 switch (state) {
451 case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN:
452 case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
453 break;
454 case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
455 return kRoamingStateHome;
456 case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
457 return kRoamingStateRoaming;
458 default:
459 NOTREACHED();
460 }
461 return kRoamingStateUnknown;
462 }
463
OnPropertiesChanged(const string & interface,const KeyValueStore & changed_properties,const vector<string> & invalidated_properties)464 void CellularCapabilityUniversalCDMA::OnPropertiesChanged(
465 const string& interface,
466 const KeyValueStore& changed_properties,
467 const vector<string>& invalidated_properties) {
468 SLOG(this, 2) << __func__ << "(" << interface << ")";
469 if (interface == MM_DBUS_INTERFACE_MODEM_MODEMCDMA) {
470 OnModemCDMAPropertiesChanged(changed_properties, invalidated_properties);
471 } else {
472 CellularCapabilityUniversal::OnPropertiesChanged(
473 interface, changed_properties, invalidated_properties);
474 }
475 }
476
OnModemCDMAPropertiesChanged(const KeyValueStore & properties,const std::vector<std::string> &)477 void CellularCapabilityUniversalCDMA::OnModemCDMAPropertiesChanged(
478 const KeyValueStore& properties,
479 const std::vector<std::string>& /*invalidated_properties*/) {
480 SLOG(this, 2) << __func__;
481 string str_value;
482 if (properties.ContainsString(MM_MODEM_MODEMCDMA_PROPERTY_MEID)) {
483 cellular()->set_meid(
484 properties.GetString(MM_MODEM_MODEMCDMA_PROPERTY_MEID));
485 }
486 if (properties.ContainsString(MM_MODEM_MODEMCDMA_PROPERTY_ESN)) {
487 cellular()->set_esn(properties.GetString(MM_MODEM_MODEMCDMA_PROPERTY_ESN));
488 }
489
490 uint32_t sid = sid_;
491 uint32_t nid = nid_;
492 MMModemCdmaRegistrationState state_1x = cdma_1x_registration_state_;
493 MMModemCdmaRegistrationState state_evdo = cdma_evdo_registration_state_;
494 bool registration_changed = false;
495 if (properties.ContainsUint(
496 MM_MODEM_MODEMCDMA_PROPERTY_CDMA1XREGISTRATIONSTATE)) {
497 state_1x = static_cast<MMModemCdmaRegistrationState>(
498 properties.GetUint(
499 MM_MODEM_MODEMCDMA_PROPERTY_CDMA1XREGISTRATIONSTATE));
500 registration_changed = true;
501 }
502 if (properties.ContainsUint(
503 MM_MODEM_MODEMCDMA_PROPERTY_EVDOREGISTRATIONSTATE)) {
504 state_evdo = static_cast<MMModemCdmaRegistrationState>(
505 properties.GetUint(MM_MODEM_MODEMCDMA_PROPERTY_EVDOREGISTRATIONSTATE));
506 registration_changed = true;
507 }
508 if (properties.ContainsUint(MM_MODEM_MODEMCDMA_PROPERTY_SID)) {
509 sid = properties.GetUint(MM_MODEM_MODEMCDMA_PROPERTY_SID);
510 registration_changed = true;
511 }
512 if (properties.ContainsUint(MM_MODEM_MODEMCDMA_PROPERTY_NID)) {
513 nid = properties.GetUint(MM_MODEM_MODEMCDMA_PROPERTY_NID);
514 registration_changed = true;
515 }
516 if (properties.ContainsUint(MM_MODEM_MODEMCDMA_PROPERTY_ACTIVATIONSTATE)) {
517 activation_state_ = static_cast<MMModemCdmaActivationState>(
518 properties.GetUint(MM_MODEM_MODEMCDMA_PROPERTY_ACTIVATIONSTATE));
519 HandleNewActivationStatus(MM_CDMA_ACTIVATION_ERROR_NONE);
520 }
521 if (registration_changed)
522 OnCDMARegistrationChanged(state_1x, state_evdo, sid, nid);
523 }
524
OnCDMARegistrationChanged(MMModemCdmaRegistrationState state_1x,MMModemCdmaRegistrationState state_evdo,uint32_t sid,uint32_t nid)525 void CellularCapabilityUniversalCDMA::OnCDMARegistrationChanged(
526 MMModemCdmaRegistrationState state_1x,
527 MMModemCdmaRegistrationState state_evdo,
528 uint32_t sid, uint32_t nid) {
529 SLOG(this, 2) << __func__ << ": state_1x=" << state_1x
530 << ", state_evdo=" << state_evdo;
531 cdma_1x_registration_state_ = state_1x;
532 cdma_evdo_registration_state_ = state_evdo;
533 sid_ = sid;
534 nid_ = nid;
535 cellular()->serving_operator_info()->UpdateSID(UintToString(sid));
536 cellular()->serving_operator_info()->UpdateNID(UintToString(nid));
537 cellular()->HandleNewRegistrationState();
538 }
539
540 } // namespace shill
541