blob: d5a54c0a60b66aa41268c69f45854ee11ac20b86 [file] [log] [blame]
mukesh agrawal8a3188d2011-12-01 20:56:44 +00001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Chris Masone3bd3c8c2011-06-13 08:20:26 -07002// 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_service.h"
6
7#include <string>
8
Chris Masone34af2182011-08-22 11:59:36 -07009#include <base/stringprintf.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070010#include <chromeos/dbus/service_constants.h>
11
Darin Petkovb72cf402011-11-22 14:51:39 +010012#include "shill/adaptor_interfaces.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013#include "shill/cellular.h"
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -040014#include "shill/property_accessor.h"
15#include "shill/store_interface.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070016
17using std::string;
18
19namespace shill {
Darin Petkovc5f56562011-08-06 16:40:05 -070020
Christopher Wiley1582bdd2012-11-15 11:31:14 -080021const char CellularService::kAutoConnActivating[] = "activating";
Ben Chan19f83972012-10-03 23:25:56 -070022const char CellularService::kAutoConnDeviceDisabled[] = "device disabled";
Thieu Le398b1da2013-03-11 17:31:10 -070023const char CellularService::kAutoConnOutOfCredits[] = "device out of credits";
24const char CellularService::kAutoConnOutOfCreditsDetectionInProgress[] =
25 "device detecting out-of-credits";
26const int64 CellularService::kOutOfCreditsConnectionDropSeconds = 15;
27const int CellularService::kOutOfCreditsMaxConnectAttempts = 3;
Thieu Le99dc56d2013-04-01 14:22:21 -070028const int64 CellularService::kOutOfCreditsResumeIgnoreSeconds = 5;
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -040029const char CellularService::kStorageAPN[] = "Cellular.APN";
30const char CellularService::kStorageLastGoodAPN[] = "Cellular.LastGoodAPN";
31
Darin Petkov381928f2012-02-02 23:00:12 +010032// TODO(petkov): Add these to system_api/dbus/service_constants.h
33namespace {
34const char kKeyOLPURL[] = "url";
35const char kKeyOLPMethod[] = "method";
36const char kKeyOLPPostData[] = "postdata";
Ben Chan19f83972012-10-03 23:25:56 -070037} // namespace
Darin Petkov381928f2012-02-02 23:00:12 +010038
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -040039static bool GetNonEmptyField(const Stringmap &stringmap,
40 const string &fieldname,
41 string *value) {
42 Stringmap::const_iterator it = stringmap.find(fieldname);
43 if (it != stringmap.end() && !it->second.empty()) {
44 *value = it->second;
45 return true;
46 }
47 return false;
48}
49
Darin Petkov381928f2012-02-02 23:00:12 +010050CellularService::OLP::OLP() {
51 SetURL("");
52 SetMethod("");
53 SetPostData("");
54}
55
56CellularService::OLP::~OLP() {}
57
58void CellularService::OLP::CopyFrom(const OLP &olp) {
59 dict_ = olp.dict_;
60}
61
62bool CellularService::OLP::Equals(const OLP &olp) const {
63 return dict_ == olp.dict_;
64}
65
66const string &CellularService::OLP::GetURL() const {
67 return dict_.find(kKeyOLPURL)->second;
68}
69
70void CellularService::OLP::SetURL(const string &url) {
71 dict_[kKeyOLPURL] = url;
72}
73
74const string &CellularService::OLP::GetMethod() const {
75 return dict_.find(kKeyOLPMethod)->second;
76}
77
78void CellularService::OLP::SetMethod(const string &method) {
79 dict_[kKeyOLPMethod] = method;
80}
81
82const string &CellularService::OLP::GetPostData() const {
83 return dict_.find(kKeyOLPPostData)->second;
84}
85
86void CellularService::OLP::SetPostData(const string &post_data) {
87 dict_[kKeyOLPPostData] = post_data;
88}
89
90const Stringmap &CellularService::OLP::ToDict() const {
91 return dict_;
92}
93
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -070094CellularService::CellularService(ModemInfo *modem_info,
mukesh agrawal51a7e932011-07-27 16:18:26 -070095 const CellularRefPtr &device)
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -070096 : Service(modem_info->control_interface(), modem_info->dispatcher(),
97 modem_info->metrics(), modem_info->manager(),
Thieu Le3426c8f2012-01-11 17:35:11 -080098 Technology::kCellular),
Thieu Le398b1da2013-03-11 17:31:10 -070099 weak_ptr_factory_(this),
Ben Chan3d6de0e2012-12-10 12:01:34 -0800100 activate_over_non_cellular_network_(false),
Thieu Le7cf36b02013-01-30 17:15:56 -0800101 cellular_(device),
Thieu Le398b1da2013-03-11 17:31:10 -0700102 is_auto_connecting_(false),
103 enforce_out_of_credits_detection_(false),
104 num_connect_attempts_(0),
105 out_of_credits_detection_in_progress_(false),
106 out_of_credits_(false) {
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700107 SetConnectable(true);
mukesh agrawalde29fa82011-09-16 16:16:36 -0700108 PropertyStore *store = this->mutable_store();
Ben Chan3d6de0e2012-12-10 12:01:34 -0800109 store->RegisterConstBool(kActivateOverNonCellularNetworkProperty,
110 &activate_over_non_cellular_network_);
Paul Stewartac4ac002011-08-26 12:04:26 -0700111 store->RegisterConstString(flimflam::kActivationStateProperty,
Chris Masone27c4aa52011-07-02 13:10:14 -0700112 &activation_state_);
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400113 HelpRegisterDerivedStringmap(flimflam::kCellularApnProperty,
114 &CellularService::GetApn,
115 &CellularService::SetApn);
Paul Stewartac4ac002011-08-26 12:04:26 -0700116 store->RegisterConstStringmap(flimflam::kCellularLastGoodApnProperty,
Chris Masone27c4aa52011-07-02 13:10:14 -0700117 &last_good_apn_info_);
Paul Stewartac4ac002011-08-26 12:04:26 -0700118 store->RegisterConstString(flimflam::kNetworkTechnologyProperty,
Darin Petkovb72cf402011-11-22 14:51:39 +0100119 &network_technology_);
Thieu Le398b1da2013-03-11 17:31:10 -0700120 store->RegisterConstBool(kOutOfCreditsProperty, &out_of_credits_);
Darin Petkov381928f2012-02-02 23:00:12 +0100121 store->RegisterConstStringmap(flimflam::kPaymentPortalProperty,
122 &olp_.ToDict());
Paul Stewartac4ac002011-08-26 12:04:26 -0700123 store->RegisterConstString(flimflam::kRoamingStateProperty, &roaming_state_);
124 store->RegisterConstStringmap(flimflam::kServingOperatorProperty,
Darin Petkov3335b372011-08-22 11:05:32 -0700125 &serving_operator_.ToDict());
Paul Stewartac4ac002011-08-26 12:04:26 -0700126 store->RegisterConstString(flimflam::kUsageURLProperty, &usage_url_);
Darin Petkovac635a82012-01-10 16:51:58 +0100127
Darin Petkov457728b2013-01-09 09:49:08 +0100128 string name = device->CreateFriendlyServiceName();
129 set_friendly_name(name);
Darin Petkovdd3e8662012-02-03 13:16:20 +0100130 SetStorageIdentifier(string(flimflam::kTypeCellular) + "_" +
Darin Petkov457728b2013-01-09 09:49:08 +0100131 device->address() + "_" + name);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700132}
133
134CellularService::~CellularService() { }
135
Ben Chan19f83972012-10-03 23:25:56 -0700136bool CellularService::IsAutoConnectable(const char **reason) const {
137 if (!cellular_->running()) {
138 *reason = kAutoConnDeviceDisabled;
139 return false;
140 }
Christopher Wiley1582bdd2012-11-15 11:31:14 -0800141 if (cellular_->IsActivating()) {
142 *reason = kAutoConnActivating;
143 return false;
144 }
Thieu Le398b1da2013-03-11 17:31:10 -0700145 if (out_of_credits_detection_in_progress_) {
146 *reason = kAutoConnOutOfCreditsDetectionInProgress;
147 return false;
148 }
149 if (out_of_credits_) {
150 *reason = kAutoConnOutOfCredits;
151 return false;
152 }
Ben Chan19f83972012-10-03 23:25:56 -0700153 return Service::IsAutoConnectable(reason);
154}
155
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400156void CellularService::HelpRegisterDerivedStringmap(
157 const string &name,
158 Stringmap(CellularService::*get)(Error *error),
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700159 bool(CellularService::*set)(
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400160 const Stringmap &value, Error *error)) {
161 mutable_store()->RegisterDerivedStringmap(
162 name,
163 StringmapAccessor(
164 new CustomAccessor<CellularService, Stringmap>(this, get, set)));
165}
166
167Stringmap *CellularService::GetUserSpecifiedApn() {
168 Stringmap::iterator it = apn_info_.find(flimflam::kApnProperty);
169 if (it == apn_info_.end() || it->second.empty())
170 return NULL;
171 return &apn_info_;
172}
173
174Stringmap *CellularService::GetLastGoodApn() {
175 Stringmap::iterator it =
176 last_good_apn_info_.find(flimflam::kApnProperty);
177 if (it == last_good_apn_info_.end() || it->second.empty())
178 return NULL;
179 return &last_good_apn_info_;
180}
181
182Stringmap CellularService::GetApn(Error */*error*/) {
183 return apn_info_;
184}
185
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700186bool CellularService::SetApn(const Stringmap &value, Error *error) {
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400187 // Only copy in the fields we care about, and validate the contents.
Eric Shienbroodc7073302012-04-03 14:41:44 -0400188 // If the "apn" field is missing or empty, the APN is cleared.
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400189 string str;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700190 Stringmap new_apn_info;
191 if (GetNonEmptyField(value, flimflam::kApnProperty, &str)) {
192 new_apn_info[flimflam::kApnProperty] = str;
Eric Shienbroodc7073302012-04-03 14:41:44 -0400193 if (GetNonEmptyField(value, flimflam::kApnUsernameProperty, &str))
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700194 new_apn_info[flimflam::kApnUsernameProperty] = str;
Eric Shienbroodc7073302012-04-03 14:41:44 -0400195 if (GetNonEmptyField(value, flimflam::kApnPasswordProperty, &str))
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700196 new_apn_info[flimflam::kApnPasswordProperty] = str;
197 }
198 if (apn_info_ == new_apn_info) {
199 return false;
200 }
201 apn_info_ = new_apn_info;
202 if (ContainsKey(apn_info_, flimflam::kApnProperty)) {
Eric Shienbroodc7073302012-04-03 14:41:44 -0400203 // Clear the last good APN, otherwise the one the user just
204 // set won't be used, since LastGoodApn comes first in the
205 // search order when trying to connect. Only do this if a
206 // non-empty user APN has been supplied. If the user APN is
207 // being cleared, leave LastGoodApn alone.
208 ClearLastGoodApn();
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400209 }
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400210 adaptor()->EmitStringmapChanged(flimflam::kCellularApnProperty, apn_info_);
211 SaveToCurrentProfile();
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700212 return true;
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400213}
214
215void CellularService::SetLastGoodApn(const Stringmap &apn_info) {
216 last_good_apn_info_ = apn_info;
217 adaptor()->EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
218 last_good_apn_info_);
219 SaveToCurrentProfile();
220}
221
222void CellularService::ClearLastGoodApn() {
223 last_good_apn_info_.clear();
224 adaptor()->EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
225 last_good_apn_info_);
226 SaveToCurrentProfile();
227}
228
Thieu Le99dc56d2013-04-01 14:22:21 -0700229void CellularService::OnAfterResume() {
230 Service::OnAfterResume();
231 resume_start_time_ = base::Time::Now();
232}
233
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400234bool CellularService::Load(StoreInterface *storage) {
235 // Load properties common to all Services.
236 if (!Service::Load(storage))
237 return false;
238
239 const string id = GetStorageIdentifier();
240 LoadApn(storage, id, kStorageAPN, &apn_info_);
241 LoadApn(storage, id, kStorageLastGoodAPN, &last_good_apn_info_);
242 return true;
243}
244
245void CellularService::LoadApn(StoreInterface *storage,
246 const string &storage_group,
247 const string &keytag,
248 Stringmap *apn_info) {
249 if (!LoadApnField(storage, storage_group, keytag,
250 flimflam::kApnProperty, apn_info))
251 return;
252 LoadApnField(storage, storage_group, keytag,
253 flimflam::kApnUsernameProperty, apn_info);
254 LoadApnField(storage, storage_group, keytag,
255 flimflam::kApnPasswordProperty, apn_info);
256}
257
258bool CellularService::LoadApnField(StoreInterface *storage,
259 const string &storage_group,
260 const string &keytag,
261 const string &apntag,
262 Stringmap *apn_info) {
263 string value;
264 if (storage->GetString(storage_group, keytag + "." + apntag, &value) &&
265 !value.empty()) {
266 (*apn_info)[apntag] = value;
267 return true;
268 }
269 return false;
270}
271
Thieu Le398b1da2013-03-11 17:31:10 -0700272void CellularService::PerformOutOfCreditsDetection(ConnectState curr_state,
273 ConnectState new_state) {
274 // WORKAROUND:
275 // Some modems on Verizon network does not properly redirect when a SIM
276 // runs out of credits. This workaround is used to detect an out-of-credits
277 // condition by by retrying a connect request if it was dropped within
278 // kOutOfCreditsConnectionDropSeconds. If the number of retries exceeds
279 // kOutOfCreditsMaxConnectAttempts, then the SIM is considered
280 // out-of-credits and the cellular service kOutOfCreditsProperty is set.
281 // This will signal Chrome to display the appropriate UX and also suppress
282 // auto-connect until the next time the user manually connects.
283 //
284 // TODO(thieule): Remove this workaround (crosbug.com/p/18169).
Thieu Le3a8683d2013-04-17 13:57:24 -0700285 if (out_of_credits_) {
286 SLOG(Cellular, 2) << __func__
287 << ": Already out-of-credits, skipping check";
288 return;
289 }
Thieu Le398b1da2013-03-11 17:31:10 -0700290 base::TimeDelta
Thieu Le99dc56d2013-04-01 14:22:21 -0700291 time_since_resume = base::Time::Now() - resume_start_time_;
292 if (time_since_resume.InSeconds() < kOutOfCreditsResumeIgnoreSeconds) {
293 // On platforms that power down the modem during suspend, make sure that
294 // we do not display a false out-of-credits warning to the user
295 // due to the sequence below by skipping out-of-credits detection
296 // immediately after a resume.
297 // 1. User suspends Chromebook.
298 // 2. Hardware turns off power to modem.
299 // 3. User resumes Chromebook.
300 // 4. Hardware restores power to modem.
301 // 5. ModemManager still has instance of old modem.
302 // ModemManager does not delete this instance until udev fires a
303 // device removed event. ModemManager does not detect new modem
304 // until udev fires a new device event.
305 // 6. Shill performs auto-connect against the old modem.
306 // Make sure at this step that we do not display a false
307 // out-of-credits warning.
308 // 7. Udev fires device removed event.
309 // 8. Udev fires new device event.
310 SLOG(Cellular, 2) <<
311 "Skipping out-of-credits detection, too soon since resume.";
312 ResetOutOfCreditsState();
313 return;
314 }
315 base::TimeDelta
Thieu Le398b1da2013-03-11 17:31:10 -0700316 time_since_connect = base::Time::Now() - connect_start_time_;
317 if (time_since_connect.InSeconds() > kOutOfCreditsConnectionDropSeconds) {
318 ResetOutOfCreditsState();
319 return;
320 }
321 // Verizon can drop the connection in two ways:
322 // - Denies the connect request
323 // - Allows connect request but disconnects later
324 bool connection_dropped =
325 (IsConnectedState(curr_state) || IsConnectingState(curr_state)) &&
326 (new_state == kStateFailure || new_state == kStateIdle);
327 if (!connection_dropped)
328 return;
329 if (explicitly_disconnected())
330 return;
331 if (roaming_state_ == flimflam::kRoamingStateRoaming &&
332 !cellular_->allow_roaming_property())
333 return;
334 if (time_since_connect.InSeconds() <= kOutOfCreditsConnectionDropSeconds) {
335 if (num_connect_attempts_ < kOutOfCreditsMaxConnectAttempts) {
336 SLOG(Cellular, 2) << "Out-Of-Credits detection: Reconnecting "
337 << "(retry #" << num_connect_attempts_ << ")";
338 // Prevent autoconnect logic from kicking in while we perform the
339 // out-of-credits detection.
340 out_of_credits_detection_in_progress_ = true;
341 dispatcher()->PostTask(
342 Bind(&CellularService::OutOfCreditsReconnect,
343 weak_ptr_factory_.GetWeakPtr()));
344 } else {
345 LOG(ERROR) <<
346 "Out-Of-Credits detection: Marking service as out-of-credits";
Thieu Le91fccf62013-04-22 15:23:16 -0700347 metrics()->NotifyCellularOutOfCredits(
348 Metrics::kCellularOutOfCreditsReasonConnectDisconnectLoop);
Thieu Le398b1da2013-03-11 17:31:10 -0700349 SetOutOfCredits(true);
350 ResetOutOfCreditsState();
351 }
352 }
353}
354
355void CellularService::OutOfCreditsReconnect() {
356 Error error;
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700357 Connect(&error, __func__);
Thieu Le398b1da2013-03-11 17:31:10 -0700358}
359
360void CellularService::ResetOutOfCreditsState() {
361 out_of_credits_detection_in_progress_ = false;
362 num_connect_attempts_ = 0;
363}
364
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400365bool CellularService::Save(StoreInterface *storage) {
366 // Save properties common to all Services.
367 if (!Service::Save(storage))
368 return false;
369
370 const string id = GetStorageIdentifier();
371 SaveApn(storage, id, GetUserSpecifiedApn(), kStorageAPN);
372 SaveApn(storage, id, GetLastGoodApn(), kStorageLastGoodAPN);
373 return true;
374}
375
376void CellularService::SaveApn(StoreInterface *storage,
377 const string &storage_group,
378 const Stringmap *apn_info,
379 const string &keytag) {
380 SaveApnField(storage, storage_group, apn_info, keytag,
381 flimflam::kApnProperty);
382 SaveApnField(storage, storage_group, apn_info, keytag,
383 flimflam::kApnUsernameProperty);
384 SaveApnField(storage, storage_group, apn_info, keytag,
385 flimflam::kApnPasswordProperty);
386}
387
388void CellularService::SaveApnField(StoreInterface *storage,
389 const string &storage_group,
390 const Stringmap *apn_info,
391 const string &keytag,
392 const string &apntag) {
393 const string key = keytag + "." + apntag;
394 string str;
395 if (apn_info && GetNonEmptyField(*apn_info, apntag, &str))
396 storage->SetString(storage_group, key, str);
397 else
398 storage->DeleteKey(storage_group, key);
399}
400
Thieu Le7cf36b02013-01-30 17:15:56 -0800401void CellularService::AutoConnect() {
402 is_auto_connecting_ = true;
403 Service::AutoConnect();
404 is_auto_connecting_ = false;
405}
406
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700407void CellularService::Connect(Error *error, const char *reason) {
Thieu Le398b1da2013-03-11 17:31:10 -0700408 if (num_connect_attempts_ == 0)
409 SetOutOfCredits(false);
410 connect_start_time_ = base::Time::Now();
411 num_connect_attempts_++;
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700412 Service::Connect(error, reason);
Darin Petkov4d6d9412011-08-24 13:19:54 -0700413 cellular_->Connect(error);
Thieu Le398b1da2013-03-11 17:31:10 -0700414 if (error->IsFailure())
415 ResetOutOfCreditsState();
Darin Petkovc5f56562011-08-06 16:40:05 -0700416}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700417
Darin Petkovfb0625e2012-01-16 13:05:56 +0100418void CellularService::Disconnect(Error *error) {
419 Service::Disconnect(error);
420 cellular_->Disconnect(error);
421}
422
Darin Petkovb100ae72011-08-24 16:19:45 -0700423void CellularService::ActivateCellularModem(const string &carrier,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500424 Error *error,
425 const ResultCallback &callback) {
426 cellular_->Activate(carrier, error, callback);
Darin Petkovc408e692011-08-17 13:47:15 -0700427}
428
Arman Ugurayc7b15602013-02-16 00:56:18 -0800429void CellularService::CompleteCellularActivation(Error *error) {
430 cellular_->CompleteActivation(error);
431}
432
Thieu Le398b1da2013-03-11 17:31:10 -0700433void CellularService::SetState(ConnectState new_state) {
434 if (enforce_out_of_credits_detection_)
435 PerformOutOfCreditsDetection(state(), new_state);
436 Service::SetState(new_state);
437}
438
Darin Petkov31332412012-01-28 01:50:02 +0100439void CellularService::SetStorageIdentifier(const string &identifier) {
440 storage_identifier_ = identifier;
441 std::replace_if(storage_identifier_.begin(),
442 storage_identifier_.end(),
443 &Service::IllegalChar, '_');
444}
445
Chris Masone6515aab2011-10-12 16:19:09 -0700446string CellularService::GetStorageIdentifier() const {
Darin Petkov31332412012-01-28 01:50:02 +0100447 return storage_identifier_;
Chris Masone34af2182011-08-22 11:59:36 -0700448}
449
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800450string CellularService::GetDeviceRpcId(Error */*error*/) {
Chris Masone95207da2011-06-29 16:50:49 -0700451 return cellular_->GetRpcIdentifier();
452}
453
Ben Chan3d6de0e2012-12-10 12:01:34 -0800454void CellularService::SetActivateOverNonCellularNetwork(bool state) {
455 if (state == activate_over_non_cellular_network_) {
456 return;
457 }
458 activate_over_non_cellular_network_ = state;
459 adaptor()->EmitBoolChanged(kActivateOverNonCellularNetworkProperty, state);
460}
461
Darin Petkovb9c99332012-01-12 13:13:00 +0100462void CellularService::SetActivationState(const string &state) {
463 if (state == activation_state_) {
464 return;
465 }
466 activation_state_ = state;
467 adaptor()->EmitStringChanged(flimflam::kActivationStateProperty, state);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700468 SetConnectableFull(state != flimflam::kActivationStateNotActivated);
Darin Petkovb9c99332012-01-12 13:13:00 +0100469}
470
Darin Petkov381928f2012-02-02 23:00:12 +0100471void CellularService::SetOLP(const OLP &olp) {
472 if (olp_.Equals(olp)) {
473 return;
474 }
475 olp_.CopyFrom(olp);
476 adaptor()->EmitStringmapChanged(flimflam::kPaymentPortalProperty,
477 olp.ToDict());
478}
479
Arman Uguray2717a102013-01-29 23:36:06 -0800480void CellularService::SetUsageURL(const string &url) {
Darin Petkov381928f2012-02-02 23:00:12 +0100481 if (url == usage_url_) {
482 return;
483 }
484 usage_url_ = url;
485 adaptor()->EmitStringChanged(flimflam::kUsageURLProperty, url);
486}
487
Darin Petkovb72cf402011-11-22 14:51:39 +0100488void CellularService::SetNetworkTechnology(const string &technology) {
489 if (technology == network_technology_) {
490 return;
491 }
492 network_technology_ = technology;
493 adaptor()->EmitStringChanged(flimflam::kNetworkTechnologyProperty,
494 technology);
495}
496
497void CellularService::SetRoamingState(const string &state) {
498 if (state == roaming_state_) {
499 return;
500 }
501 roaming_state_ = state;
502 adaptor()->EmitStringChanged(flimflam::kRoamingStateProperty, state);
503}
504
Thieu Le398b1da2013-03-11 17:31:10 -0700505void CellularService::SetOutOfCredits(bool state) {
506 if (state == out_of_credits_) {
507 return;
508 }
509 out_of_credits_ = state;
510 adaptor()->EmitBoolChanged(kOutOfCreditsProperty, state);
511}
512
Darin Petkov3335b372011-08-22 11:05:32 -0700513const Cellular::Operator &CellularService::serving_operator() const {
514 return serving_operator_;
515}
516
Darin Petkov9cb02682012-01-28 00:17:38 +0100517void CellularService::SetServingOperator(const Cellular::Operator &oper) {
518 if (serving_operator_.Equals(oper)) {
519 return;
520 }
Darin Petkov3335b372011-08-22 11:05:32 -0700521 serving_operator_.CopyFrom(oper);
Darin Petkov9cb02682012-01-28 00:17:38 +0100522 adaptor()->EmitStringmapChanged(flimflam::kServingOperatorProperty,
523 oper.ToDict());
Darin Petkov3335b372011-08-22 11:05:32 -0700524}
525
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700526} // namespace shill