blob: ba9c313c97c0e9c67da47e7caa491cc66664a4b8 [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 -040029
Darin Petkov381928f2012-02-02 23:00:12 +010030// TODO(petkov): Add these to system_api/dbus/service_constants.h
31namespace {
32const char kKeyOLPURL[] = "url";
33const char kKeyOLPMethod[] = "method";
34const char kKeyOLPPostData[] = "postdata";
mukesh agrawal3ffe52c2013-06-20 15:21:29 -070035const char kCellularPPPUsernameProperty[] = "Cellular.PPP.Username";
36const char kCellularPPPPasswordProperty[] = "Cellular.PPP.Password";
37} // namespace
38
39namespace {
40const char kStorageAPN[] = "Cellular.APN";
41const char kStorageLastGoodAPN[] = "Cellular.LastGoodAPN";
42const char kStoragePPPUsername[] = "Cellular.PPP.Username";
43const char kStoragePPPPassword[] = "Cellular.PPP.Password";
Ben Chan19f83972012-10-03 23:25:56 -070044} // namespace
Darin Petkov381928f2012-02-02 23:00:12 +010045
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -040046static bool GetNonEmptyField(const Stringmap &stringmap,
47 const string &fieldname,
48 string *value) {
49 Stringmap::const_iterator it = stringmap.find(fieldname);
50 if (it != stringmap.end() && !it->second.empty()) {
51 *value = it->second;
52 return true;
53 }
54 return false;
55}
56
Darin Petkov381928f2012-02-02 23:00:12 +010057CellularService::OLP::OLP() {
58 SetURL("");
59 SetMethod("");
60 SetPostData("");
61}
62
63CellularService::OLP::~OLP() {}
64
65void CellularService::OLP::CopyFrom(const OLP &olp) {
66 dict_ = olp.dict_;
67}
68
69bool CellularService::OLP::Equals(const OLP &olp) const {
70 return dict_ == olp.dict_;
71}
72
73const string &CellularService::OLP::GetURL() const {
74 return dict_.find(kKeyOLPURL)->second;
75}
76
77void CellularService::OLP::SetURL(const string &url) {
78 dict_[kKeyOLPURL] = url;
79}
80
81const string &CellularService::OLP::GetMethod() const {
82 return dict_.find(kKeyOLPMethod)->second;
83}
84
85void CellularService::OLP::SetMethod(const string &method) {
86 dict_[kKeyOLPMethod] = method;
87}
88
89const string &CellularService::OLP::GetPostData() const {
90 return dict_.find(kKeyOLPPostData)->second;
91}
92
93void CellularService::OLP::SetPostData(const string &post_data) {
94 dict_[kKeyOLPPostData] = post_data;
95}
96
97const Stringmap &CellularService::OLP::ToDict() const {
98 return dict_;
99}
100
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700101CellularService::CellularService(ModemInfo *modem_info,
mukesh agrawal51a7e932011-07-27 16:18:26 -0700102 const CellularRefPtr &device)
Prathmesh Prabhu0d36b4f2013-04-01 11:45:54 -0700103 : Service(modem_info->control_interface(), modem_info->dispatcher(),
104 modem_info->metrics(), modem_info->manager(),
Thieu Le3426c8f2012-01-11 17:35:11 -0800105 Technology::kCellular),
Thieu Le398b1da2013-03-11 17:31:10 -0700106 weak_ptr_factory_(this),
Ben Chan3d6de0e2012-12-10 12:01:34 -0800107 activate_over_non_cellular_network_(false),
Thieu Le7cf36b02013-01-30 17:15:56 -0800108 cellular_(device),
Thieu Le398b1da2013-03-11 17:31:10 -0700109 is_auto_connecting_(false),
110 enforce_out_of_credits_detection_(false),
111 num_connect_attempts_(0),
112 out_of_credits_detection_in_progress_(false),
113 out_of_credits_(false) {
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700114 SetConnectable(true);
mukesh agrawalde29fa82011-09-16 16:16:36 -0700115 PropertyStore *store = this->mutable_store();
Ben Chan3d6de0e2012-12-10 12:01:34 -0800116 store->RegisterConstBool(kActivateOverNonCellularNetworkProperty,
117 &activate_over_non_cellular_network_);
Paul Stewartac4ac002011-08-26 12:04:26 -0700118 store->RegisterConstString(flimflam::kActivationStateProperty,
Chris Masone27c4aa52011-07-02 13:10:14 -0700119 &activation_state_);
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400120 HelpRegisterDerivedStringmap(flimflam::kCellularApnProperty,
121 &CellularService::GetApn,
122 &CellularService::SetApn);
Paul Stewartac4ac002011-08-26 12:04:26 -0700123 store->RegisterConstStringmap(flimflam::kCellularLastGoodApnProperty,
Chris Masone27c4aa52011-07-02 13:10:14 -0700124 &last_good_apn_info_);
Paul Stewartac4ac002011-08-26 12:04:26 -0700125 store->RegisterConstString(flimflam::kNetworkTechnologyProperty,
Darin Petkovb72cf402011-11-22 14:51:39 +0100126 &network_technology_);
Thieu Le398b1da2013-03-11 17:31:10 -0700127 store->RegisterConstBool(kOutOfCreditsProperty, &out_of_credits_);
Darin Petkov381928f2012-02-02 23:00:12 +0100128 store->RegisterConstStringmap(flimflam::kPaymentPortalProperty,
129 &olp_.ToDict());
Paul Stewartac4ac002011-08-26 12:04:26 -0700130 store->RegisterConstString(flimflam::kRoamingStateProperty, &roaming_state_);
131 store->RegisterConstStringmap(flimflam::kServingOperatorProperty,
Darin Petkov3335b372011-08-22 11:05:32 -0700132 &serving_operator_.ToDict());
Paul Stewartac4ac002011-08-26 12:04:26 -0700133 store->RegisterConstString(flimflam::kUsageURLProperty, &usage_url_);
mukesh agrawal3ffe52c2013-06-20 15:21:29 -0700134 store->RegisterString(kCellularPPPUsernameProperty, &ppp_username_);
135 store->RegisterWriteOnlyString(kCellularPPPPasswordProperty, &ppp_password_);
Darin Petkovac635a82012-01-10 16:51:58 +0100136
Darin Petkov457728b2013-01-09 09:49:08 +0100137 string name = device->CreateFriendlyServiceName();
138 set_friendly_name(name);
Darin Petkovdd3e8662012-02-03 13:16:20 +0100139 SetStorageIdentifier(string(flimflam::kTypeCellular) + "_" +
Darin Petkov457728b2013-01-09 09:49:08 +0100140 device->address() + "_" + name);
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700141}
142
143CellularService::~CellularService() { }
144
Ben Chan19f83972012-10-03 23:25:56 -0700145bool CellularService::IsAutoConnectable(const char **reason) const {
146 if (!cellular_->running()) {
147 *reason = kAutoConnDeviceDisabled;
148 return false;
149 }
Christopher Wiley1582bdd2012-11-15 11:31:14 -0800150 if (cellular_->IsActivating()) {
151 *reason = kAutoConnActivating;
152 return false;
153 }
Thieu Le398b1da2013-03-11 17:31:10 -0700154 if (out_of_credits_detection_in_progress_) {
155 *reason = kAutoConnOutOfCreditsDetectionInProgress;
156 return false;
157 }
158 if (out_of_credits_) {
159 *reason = kAutoConnOutOfCredits;
160 return false;
161 }
Ben Chan19f83972012-10-03 23:25:56 -0700162 return Service::IsAutoConnectable(reason);
163}
164
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400165void CellularService::HelpRegisterDerivedStringmap(
166 const string &name,
167 Stringmap(CellularService::*get)(Error *error),
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700168 bool(CellularService::*set)(
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400169 const Stringmap &value, Error *error)) {
170 mutable_store()->RegisterDerivedStringmap(
171 name,
172 StringmapAccessor(
173 new CustomAccessor<CellularService, Stringmap>(this, get, set)));
174}
175
176Stringmap *CellularService::GetUserSpecifiedApn() {
177 Stringmap::iterator it = apn_info_.find(flimflam::kApnProperty);
178 if (it == apn_info_.end() || it->second.empty())
179 return NULL;
180 return &apn_info_;
181}
182
183Stringmap *CellularService::GetLastGoodApn() {
184 Stringmap::iterator it =
185 last_good_apn_info_.find(flimflam::kApnProperty);
186 if (it == last_good_apn_info_.end() || it->second.empty())
187 return NULL;
188 return &last_good_apn_info_;
189}
190
191Stringmap CellularService::GetApn(Error */*error*/) {
192 return apn_info_;
193}
194
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700195bool CellularService::SetApn(const Stringmap &value, Error *error) {
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400196 // Only copy in the fields we care about, and validate the contents.
Eric Shienbroodc7073302012-04-03 14:41:44 -0400197 // If the "apn" field is missing or empty, the APN is cleared.
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400198 string str;
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700199 Stringmap new_apn_info;
200 if (GetNonEmptyField(value, flimflam::kApnProperty, &str)) {
201 new_apn_info[flimflam::kApnProperty] = str;
Eric Shienbroodc7073302012-04-03 14:41:44 -0400202 if (GetNonEmptyField(value, flimflam::kApnUsernameProperty, &str))
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700203 new_apn_info[flimflam::kApnUsernameProperty] = str;
Eric Shienbroodc7073302012-04-03 14:41:44 -0400204 if (GetNonEmptyField(value, flimflam::kApnPasswordProperty, &str))
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700205 new_apn_info[flimflam::kApnPasswordProperty] = str;
206 }
207 if (apn_info_ == new_apn_info) {
208 return false;
209 }
210 apn_info_ = new_apn_info;
211 if (ContainsKey(apn_info_, flimflam::kApnProperty)) {
Eric Shienbroodc7073302012-04-03 14:41:44 -0400212 // Clear the last good APN, otherwise the one the user just
213 // set won't be used, since LastGoodApn comes first in the
214 // search order when trying to connect. Only do this if a
215 // non-empty user APN has been supplied. If the user APN is
216 // being cleared, leave LastGoodApn alone.
217 ClearLastGoodApn();
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400218 }
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400219 adaptor()->EmitStringmapChanged(flimflam::kCellularApnProperty, apn_info_);
220 SaveToCurrentProfile();
mukesh agrawalbebf1b82013-04-23 15:06:33 -0700221 return true;
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400222}
223
224void CellularService::SetLastGoodApn(const Stringmap &apn_info) {
225 last_good_apn_info_ = apn_info;
226 adaptor()->EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
227 last_good_apn_info_);
228 SaveToCurrentProfile();
229}
230
231void CellularService::ClearLastGoodApn() {
232 last_good_apn_info_.clear();
233 adaptor()->EmitStringmapChanged(flimflam::kCellularLastGoodApnProperty,
234 last_good_apn_info_);
235 SaveToCurrentProfile();
236}
237
Thieu Le99dc56d2013-04-01 14:22:21 -0700238void CellularService::OnAfterResume() {
239 Service::OnAfterResume();
240 resume_start_time_ = base::Time::Now();
241}
242
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400243bool CellularService::Load(StoreInterface *storage) {
244 // Load properties common to all Services.
245 if (!Service::Load(storage))
246 return false;
247
248 const string id = GetStorageIdentifier();
249 LoadApn(storage, id, kStorageAPN, &apn_info_);
250 LoadApn(storage, id, kStorageLastGoodAPN, &last_good_apn_info_);
mukesh agrawal3ffe52c2013-06-20 15:21:29 -0700251 storage->GetString(id, kStoragePPPUsername, &ppp_username_);
252 storage->GetString(id, kStoragePPPPassword, &ppp_password_);
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400253 return true;
254}
255
256void CellularService::LoadApn(StoreInterface *storage,
257 const string &storage_group,
258 const string &keytag,
259 Stringmap *apn_info) {
260 if (!LoadApnField(storage, storage_group, keytag,
261 flimflam::kApnProperty, apn_info))
262 return;
263 LoadApnField(storage, storage_group, keytag,
264 flimflam::kApnUsernameProperty, apn_info);
265 LoadApnField(storage, storage_group, keytag,
266 flimflam::kApnPasswordProperty, apn_info);
267}
268
269bool CellularService::LoadApnField(StoreInterface *storage,
270 const string &storage_group,
271 const string &keytag,
272 const string &apntag,
273 Stringmap *apn_info) {
274 string value;
275 if (storage->GetString(storage_group, keytag + "." + apntag, &value) &&
276 !value.empty()) {
277 (*apn_info)[apntag] = value;
278 return true;
279 }
280 return false;
281}
282
Thieu Le398b1da2013-03-11 17:31:10 -0700283void CellularService::PerformOutOfCreditsDetection(ConnectState curr_state,
284 ConnectState new_state) {
285 // WORKAROUND:
286 // Some modems on Verizon network does not properly redirect when a SIM
287 // runs out of credits. This workaround is used to detect an out-of-credits
288 // condition by by retrying a connect request if it was dropped within
289 // kOutOfCreditsConnectionDropSeconds. If the number of retries exceeds
290 // kOutOfCreditsMaxConnectAttempts, then the SIM is considered
291 // out-of-credits and the cellular service kOutOfCreditsProperty is set.
292 // This will signal Chrome to display the appropriate UX and also suppress
293 // auto-connect until the next time the user manually connects.
294 //
295 // TODO(thieule): Remove this workaround (crosbug.com/p/18169).
Thieu Le3a8683d2013-04-17 13:57:24 -0700296 if (out_of_credits_) {
297 SLOG(Cellular, 2) << __func__
298 << ": Already out-of-credits, skipping check";
299 return;
300 }
Thieu Le398b1da2013-03-11 17:31:10 -0700301 base::TimeDelta
Thieu Le99dc56d2013-04-01 14:22:21 -0700302 time_since_resume = base::Time::Now() - resume_start_time_;
303 if (time_since_resume.InSeconds() < kOutOfCreditsResumeIgnoreSeconds) {
304 // On platforms that power down the modem during suspend, make sure that
305 // we do not display a false out-of-credits warning to the user
306 // due to the sequence below by skipping out-of-credits detection
307 // immediately after a resume.
308 // 1. User suspends Chromebook.
309 // 2. Hardware turns off power to modem.
310 // 3. User resumes Chromebook.
311 // 4. Hardware restores power to modem.
312 // 5. ModemManager still has instance of old modem.
313 // ModemManager does not delete this instance until udev fires a
314 // device removed event. ModemManager does not detect new modem
315 // until udev fires a new device event.
316 // 6. Shill performs auto-connect against the old modem.
317 // Make sure at this step that we do not display a false
318 // out-of-credits warning.
319 // 7. Udev fires device removed event.
320 // 8. Udev fires new device event.
321 SLOG(Cellular, 2) <<
322 "Skipping out-of-credits detection, too soon since resume.";
323 ResetOutOfCreditsState();
324 return;
325 }
326 base::TimeDelta
Thieu Le398b1da2013-03-11 17:31:10 -0700327 time_since_connect = base::Time::Now() - connect_start_time_;
328 if (time_since_connect.InSeconds() > kOutOfCreditsConnectionDropSeconds) {
329 ResetOutOfCreditsState();
330 return;
331 }
332 // Verizon can drop the connection in two ways:
333 // - Denies the connect request
334 // - Allows connect request but disconnects later
335 bool connection_dropped =
336 (IsConnectedState(curr_state) || IsConnectingState(curr_state)) &&
337 (new_state == kStateFailure || new_state == kStateIdle);
338 if (!connection_dropped)
339 return;
340 if (explicitly_disconnected())
341 return;
342 if (roaming_state_ == flimflam::kRoamingStateRoaming &&
343 !cellular_->allow_roaming_property())
344 return;
345 if (time_since_connect.InSeconds() <= kOutOfCreditsConnectionDropSeconds) {
346 if (num_connect_attempts_ < kOutOfCreditsMaxConnectAttempts) {
347 SLOG(Cellular, 2) << "Out-Of-Credits detection: Reconnecting "
348 << "(retry #" << num_connect_attempts_ << ")";
349 // Prevent autoconnect logic from kicking in while we perform the
350 // out-of-credits detection.
351 out_of_credits_detection_in_progress_ = true;
352 dispatcher()->PostTask(
353 Bind(&CellularService::OutOfCreditsReconnect,
354 weak_ptr_factory_.GetWeakPtr()));
355 } else {
356 LOG(ERROR) <<
357 "Out-Of-Credits detection: Marking service as out-of-credits";
Thieu Le91fccf62013-04-22 15:23:16 -0700358 metrics()->NotifyCellularOutOfCredits(
359 Metrics::kCellularOutOfCreditsReasonConnectDisconnectLoop);
Thieu Le398b1da2013-03-11 17:31:10 -0700360 SetOutOfCredits(true);
361 ResetOutOfCreditsState();
362 }
363 }
364}
365
366void CellularService::OutOfCreditsReconnect() {
367 Error error;
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700368 Connect(&error, __func__);
Thieu Le398b1da2013-03-11 17:31:10 -0700369}
370
371void CellularService::ResetOutOfCreditsState() {
372 out_of_credits_detection_in_progress_ = false;
373 num_connect_attempts_ = 0;
374}
375
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400376bool CellularService::Save(StoreInterface *storage) {
377 // Save properties common to all Services.
378 if (!Service::Save(storage))
379 return false;
380
381 const string id = GetStorageIdentifier();
382 SaveApn(storage, id, GetUserSpecifiedApn(), kStorageAPN);
383 SaveApn(storage, id, GetLastGoodApn(), kStorageLastGoodAPN);
mukesh agrawal3ffe52c2013-06-20 15:21:29 -0700384 SaveString(storage, id, kStoragePPPUsername, ppp_username_, false, true);
385 SaveString(storage, id, kStoragePPPPassword, ppp_password_, false, true);
Eric Shienbrood30bc0ec2012-03-21 18:19:46 -0400386 return true;
387}
388
389void CellularService::SaveApn(StoreInterface *storage,
390 const string &storage_group,
391 const Stringmap *apn_info,
392 const string &keytag) {
393 SaveApnField(storage, storage_group, apn_info, keytag,
394 flimflam::kApnProperty);
395 SaveApnField(storage, storage_group, apn_info, keytag,
396 flimflam::kApnUsernameProperty);
397 SaveApnField(storage, storage_group, apn_info, keytag,
398 flimflam::kApnPasswordProperty);
399}
400
401void CellularService::SaveApnField(StoreInterface *storage,
402 const string &storage_group,
403 const Stringmap *apn_info,
404 const string &keytag,
405 const string &apntag) {
406 const string key = keytag + "." + apntag;
407 string str;
408 if (apn_info && GetNonEmptyField(*apn_info, apntag, &str))
409 storage->SetString(storage_group, key, str);
410 else
411 storage->DeleteKey(storage_group, key);
412}
413
Thieu Le7cf36b02013-01-30 17:15:56 -0800414void CellularService::AutoConnect() {
415 is_auto_connecting_ = true;
416 Service::AutoConnect();
417 is_auto_connecting_ = false;
418}
419
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700420void CellularService::Connect(Error *error, const char *reason) {
Thieu Le398b1da2013-03-11 17:31:10 -0700421 if (num_connect_attempts_ == 0)
422 SetOutOfCredits(false);
423 connect_start_time_ = base::Time::Now();
424 num_connect_attempts_++;
mukesh agrawaldc7b8442012-09-27 13:48:14 -0700425 Service::Connect(error, reason);
Darin Petkov4d6d9412011-08-24 13:19:54 -0700426 cellular_->Connect(error);
Thieu Le398b1da2013-03-11 17:31:10 -0700427 if (error->IsFailure())
428 ResetOutOfCreditsState();
Darin Petkovc5f56562011-08-06 16:40:05 -0700429}
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700430
Darin Petkovfb0625e2012-01-16 13:05:56 +0100431void CellularService::Disconnect(Error *error) {
432 Service::Disconnect(error);
433 cellular_->Disconnect(error);
434}
435
Darin Petkovb100ae72011-08-24 16:19:45 -0700436void CellularService::ActivateCellularModem(const string &carrier,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500437 Error *error,
438 const ResultCallback &callback) {
439 cellular_->Activate(carrier, error, callback);
Darin Petkovc408e692011-08-17 13:47:15 -0700440}
441
Arman Ugurayc7b15602013-02-16 00:56:18 -0800442void CellularService::CompleteCellularActivation(Error *error) {
443 cellular_->CompleteActivation(error);
444}
445
Thieu Le398b1da2013-03-11 17:31:10 -0700446void CellularService::SetState(ConnectState new_state) {
447 if (enforce_out_of_credits_detection_)
448 PerformOutOfCreditsDetection(state(), new_state);
449 Service::SetState(new_state);
450}
451
Darin Petkov31332412012-01-28 01:50:02 +0100452void CellularService::SetStorageIdentifier(const string &identifier) {
453 storage_identifier_ = identifier;
454 std::replace_if(storage_identifier_.begin(),
455 storage_identifier_.end(),
456 &Service::IllegalChar, '_');
457}
458
Chris Masone6515aab2011-10-12 16:19:09 -0700459string CellularService::GetStorageIdentifier() const {
Darin Petkov31332412012-01-28 01:50:02 +0100460 return storage_identifier_;
Chris Masone34af2182011-08-22 11:59:36 -0700461}
462
Gaurav Shah1b7a6162011-11-09 11:41:01 -0800463string CellularService::GetDeviceRpcId(Error */*error*/) {
Chris Masone95207da2011-06-29 16:50:49 -0700464 return cellular_->GetRpcIdentifier();
465}
466
Ben Chan3d6de0e2012-12-10 12:01:34 -0800467void CellularService::SetActivateOverNonCellularNetwork(bool state) {
468 if (state == activate_over_non_cellular_network_) {
469 return;
470 }
471 activate_over_non_cellular_network_ = state;
472 adaptor()->EmitBoolChanged(kActivateOverNonCellularNetworkProperty, state);
473}
474
Darin Petkovb9c99332012-01-12 13:13:00 +0100475void CellularService::SetActivationState(const string &state) {
476 if (state == activation_state_) {
477 return;
478 }
479 activation_state_ = state;
480 adaptor()->EmitStringChanged(flimflam::kActivationStateProperty, state);
mukesh agrawalcbfb34e2013-04-17 19:33:25 -0700481 SetConnectableFull(state != flimflam::kActivationStateNotActivated);
Darin Petkovb9c99332012-01-12 13:13:00 +0100482}
483
Darin Petkov381928f2012-02-02 23:00:12 +0100484void CellularService::SetOLP(const OLP &olp) {
485 if (olp_.Equals(olp)) {
486 return;
487 }
488 olp_.CopyFrom(olp);
489 adaptor()->EmitStringmapChanged(flimflam::kPaymentPortalProperty,
490 olp.ToDict());
491}
492
Arman Uguray2717a102013-01-29 23:36:06 -0800493void CellularService::SetUsageURL(const string &url) {
Darin Petkov381928f2012-02-02 23:00:12 +0100494 if (url == usage_url_) {
495 return;
496 }
497 usage_url_ = url;
498 adaptor()->EmitStringChanged(flimflam::kUsageURLProperty, url);
499}
500
Darin Petkovb72cf402011-11-22 14:51:39 +0100501void CellularService::SetNetworkTechnology(const string &technology) {
502 if (technology == network_technology_) {
503 return;
504 }
505 network_technology_ = technology;
506 adaptor()->EmitStringChanged(flimflam::kNetworkTechnologyProperty,
507 technology);
508}
509
510void CellularService::SetRoamingState(const string &state) {
511 if (state == roaming_state_) {
512 return;
513 }
514 roaming_state_ = state;
515 adaptor()->EmitStringChanged(flimflam::kRoamingStateProperty, state);
516}
517
Thieu Le398b1da2013-03-11 17:31:10 -0700518void CellularService::SetOutOfCredits(bool state) {
519 if (state == out_of_credits_) {
520 return;
521 }
522 out_of_credits_ = state;
523 adaptor()->EmitBoolChanged(kOutOfCreditsProperty, state);
524}
525
Darin Petkov3335b372011-08-22 11:05:32 -0700526const Cellular::Operator &CellularService::serving_operator() const {
527 return serving_operator_;
528}
529
Darin Petkov9cb02682012-01-28 00:17:38 +0100530void CellularService::SetServingOperator(const Cellular::Operator &oper) {
531 if (serving_operator_.Equals(oper)) {
532 return;
533 }
Darin Petkov3335b372011-08-22 11:05:32 -0700534 serving_operator_.CopyFrom(oper);
Darin Petkov9cb02682012-01-28 00:17:38 +0100535 adaptor()->EmitStringmapChanged(flimflam::kServingOperatorProperty,
536 oper.ToDict());
Darin Petkov3335b372011-08-22 11:05:32 -0700537}
538
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700539} // namespace shill