Home | History | Annotate | Download | only in cellular
      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;
     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 
     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 
     77 CellularCapabilityUniversalCDMA::~CellularCapabilityUniversalCDMA() {}
     78 
     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 
     90 void CellularCapabilityUniversalCDMA::ReleaseProxies() {
     91   SLOG(this, 2) << __func__;
     92   modem_cdma_proxy_.reset();
     93   CellularCapabilityUniversal::ReleaseProxies();
     94 }
     95 
     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 
    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 
    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 
    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 
    190 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 
    204 bool CellularCapabilityUniversalCDMA::IsActivated() const {
    205   return (activation_state_ == MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED);
    206 }
    207 
    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 
    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 
    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 
    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 
    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 
    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 
    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
    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
    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 
    369 void CellularCapabilityUniversalCDMA::Register(const ResultCallback& callback) {
    370   // TODO(armansito): Remove once 3GPP is implemented in its own class.
    371 }
    372 
    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 
    380 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 
    389 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 
    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 
    401 void CellularCapabilityUniversalCDMA::SetupConnectProperties(
    402     KeyValueStore* properties) {
    403   properties->SetString(kPropertyConnectNumber, kPhoneNumber);
    404 }
    405 
    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 
    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 
    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 
    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 
    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 
    440 void CellularCapabilityUniversalCDMA::OnSimPathChanged(
    441     const string& sim_path) {
    442   // TODO(armansito): Remove once 3GPP is implemented in its own class.
    443 }
    444 
    445 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 
    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 
    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 
    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