blob: 9577a95f82ff78b5298ad1e84a8008891540ecbd [file] [log] [blame]
Darin Petkovc64fe5e2012-01-11 12:46:13 +01001// 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.h"
6
Darin Petkov0828f5f2011-08-11 10:18:52 -07007#include <netinet/in.h>
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -07008#include <linux/if.h> // Needs definitions from netinet/in.h
Darin Petkov0828f5f2011-08-11 10:18:52 -07009
Chris Masone3bd3c8c2011-06-13 08:20:26 -070010#include <string>
Chris Masone889666b2011-07-03 12:58:50 -070011#include <utility>
12#include <vector>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070013
14#include <base/logging.h>
Darin Petkove9d12e02011-07-27 15:09:37 -070015#include <base/stringprintf.h>
Chris Masoneb925cc82011-06-22 15:39:57 -070016#include <chromeos/dbus/service_constants.h>
Darin Petkovbec79a22011-08-01 14:47:17 -070017#include <mm/mm-modem.h>
Darin Petkov137884a2011-10-26 18:52:47 +020018#include <mobile_provider.h>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070019
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050020#include "shill/adaptor_interfaces.h"
Darin Petkovdaf43862011-10-27 11:37:28 +020021#include "shill/cellular_capability_cdma.h"
22#include "shill/cellular_capability_gsm.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070023#include "shill/cellular_service.h"
24#include "shill/control_interface.h"
25#include "shill/device.h"
26#include "shill/device_info.h"
Darin Petkov4d6d9412011-08-24 13:19:54 -070027#include "shill/error.h"
Paul Stewart26b327e2011-10-19 11:38:09 -070028#include "shill/event_dispatcher.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070029#include "shill/manager.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070030#include "shill/profile.h"
Chris Masone889666b2011-07-03 12:58:50 -070031#include "shill/property_accessor.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070032#include "shill/proxy_factory.h"
Darin Petkov0828f5f2011-08-11 10:18:52 -070033#include "shill/rtnl_handler.h"
Gaurav Shah435de2c2011-11-17 19:01:07 -080034#include "shill/technology.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070035
Darin Petkovc0865312011-09-16 15:31:20 -070036using std::map;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070037using std::string;
Chris Masone889666b2011-07-03 12:58:50 -070038using std::vector;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070039
40namespace shill {
41
Darin Petkov3335b372011-08-22 11:05:32 -070042Cellular::Operator::Operator() {
43 SetName("");
44 SetCode("");
45 SetCountry("");
46}
47
48Cellular::Operator::~Operator() {}
49
50void Cellular::Operator::CopyFrom(const Operator &oper) {
51 dict_ = oper.dict_;
52}
53
54const string &Cellular::Operator::GetName() const {
55 return dict_.find(flimflam::kOperatorNameKey)->second;
56}
57
58void Cellular::Operator::SetName(const string &name) {
59 dict_[flimflam::kOperatorNameKey] = name;
60}
61
62const string &Cellular::Operator::GetCode() const {
63 return dict_.find(flimflam::kOperatorCodeKey)->second;
64}
65
66void Cellular::Operator::SetCode(const string &code) {
67 dict_[flimflam::kOperatorCodeKey] = code;
68}
69
70const string &Cellular::Operator::GetCountry() const {
71 return dict_.find(flimflam::kOperatorCountryKey)->second;
72}
73
74void Cellular::Operator::SetCountry(const string &country) {
75 dict_[flimflam::kOperatorCountryKey] = country;
76}
77
78const Stringmap &Cellular::Operator::ToDict() const {
79 return dict_;
80}
81
Chris Masone3bd3c8c2011-06-13 08:20:26 -070082Cellular::Cellular(ControlInterface *control_interface,
83 EventDispatcher *dispatcher,
Thieu Le3426c8f2012-01-11 17:35:11 -080084 Metrics *metrics,
Chris Masone3bd3c8c2011-06-13 08:20:26 -070085 Manager *manager,
Darin Petkove9d12e02011-07-27 15:09:37 -070086 const string &link_name,
Darin Petkov3335b372011-08-22 11:05:32 -070087 const string &address,
Darin Petkove9d12e02011-07-27 15:09:37 -070088 int interface_index,
89 Type type,
90 const string &owner,
Darin Petkov137884a2011-10-26 18:52:47 +020091 const string &path,
92 mobile_provider_db *provider_db)
Chris Masone3bd3c8c2011-06-13 08:20:26 -070093 : Device(control_interface,
94 dispatcher,
Thieu Le3426c8f2012-01-11 17:35:11 -080095 metrics,
Chris Masone3bd3c8c2011-06-13 08:20:26 -070096 manager,
Darin Petkove9d12e02011-07-27 15:09:37 -070097 link_name,
Chris Masone626719f2011-08-18 16:58:48 -070098 address,
Gaurav Shah435de2c2011-11-17 19:01:07 -080099 interface_index,
100 Technology::kCellular),
Darin Petkove9d12e02011-07-27 15:09:37 -0700101 state_(kStateDisabled),
Darin Petkovbac96002011-08-09 13:22:00 -0700102 modem_state_(kModemStateUnknown),
Darin Petkove9d12e02011-07-27 15:09:37 -0700103 dbus_owner_(owner),
104 dbus_path_(path),
Darin Petkov137884a2011-10-26 18:52:47 +0200105 provider_db_(provider_db),
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500106 task_factory_(this) {
mukesh agrawalde29fa82011-09-16 16:16:36 -0700107 PropertyStore *store = this->mutable_store();
Paul Stewartac4ac002011-08-26 12:04:26 -0700108 store->RegisterConstString(flimflam::kDBusConnectionProperty, &dbus_owner_);
109 store->RegisterConstString(flimflam::kDBusObjectProperty, &dbus_path_);
Paul Stewartac4ac002011-08-26 12:04:26 -0700110 store->RegisterConstStringmap(flimflam::kHomeProviderProperty,
Darin Petkov3335b372011-08-22 11:05:32 -0700111 &home_provider_.ToDict());
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500112 // For now, only a single capability is supported.
113 InitCapability(type, ProxyFactory::GetInstance());
Chris Masoneb925cc82011-06-22 15:39:57 -0700114
Darin Petkov5f316f62011-11-18 12:10:26 +0100115 VLOG(2) << "Cellular device " << this->link_name() << " initialized.";
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700116}
117
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500118Cellular::~Cellular() {
119}
Darin Petkove9d12e02011-07-27 15:09:37 -0700120
Darin Petkovcc044422011-08-17 13:30:06 -0700121// static
122string Cellular::GetStateString(State state) {
123 switch (state) {
Darin Petkove9d12e02011-07-27 15:09:37 -0700124 case kStateDisabled: return "CellularStateDisabled";
125 case kStateEnabled: return "CellularStateEnabled";
126 case kStateRegistered: return "CellularStateRegistered";
127 case kStateConnected: return "CellularStateConnected";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700128 case kStateLinked: return "CellularStateLinked";
129 default: NOTREACHED();
Darin Petkove9d12e02011-07-27 15:09:37 -0700130 }
Darin Petkovcc044422011-08-17 13:30:06 -0700131 return StringPrintf("CellularStateUnknown-%d", state);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700132}
133
134void Cellular::SetState(State state) {
Darin Petkovcc044422011-08-17 13:30:06 -0700135 VLOG(2) << GetStateString(state_) << " -> " << GetStateString(state);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700136 state_ = state;
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700137}
138
139void Cellular::Start() {
Darin Petkovcc044422011-08-17 13:30:06 -0700140 LOG(INFO) << __func__ << ": " << GetStateString(state_);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500141 if (state_ != kStateDisabled) {
142 return;
143 }
Darin Petkov3335b372011-08-22 11:05:32 -0700144 Device::Start();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500145 if (modem_state_ == kModemStateEnabled) {
146 // Modem already enabled.
147 OnModemEnabled();
148 return;
149 }
150 // TODO(ers): this should not be done automatically. It should
151 // require an explicit Enable request to start the modem.
152 capability_->StartModem();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700153}
154
155void Cellular::Stop() {
Darin Petkovfb0625e2012-01-16 13:05:56 +0100156 DestroyService();
157 DisconnectModem();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500158 if (state_ != kStateDisabled)
159 capability_->DisableModem(NULL);
160 capability_->StopModem();
Darin Petkov3335b372011-08-22 11:05:32 -0700161 Device::Stop();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700162}
163
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500164void Cellular::InitCapability(Type type, ProxyFactory *proxy_factory) {
Darin Petkov5f316f62011-11-18 12:10:26 +0100165 // TODO(petkov): Consider moving capability construction into a factory that's
166 // external to the Cellular class.
167 VLOG(2) << __func__ << "(" << type << ")";
168 switch (type) {
Darin Petkovdaf43862011-10-27 11:37:28 +0200169 case kTypeGSM:
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500170 capability_.reset(new CellularCapabilityGSM(this, proxy_factory));
Darin Petkovdaf43862011-10-27 11:37:28 +0200171 break;
172 case kTypeCDMA:
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500173 capability_.reset(new CellularCapabilityCDMA(this, proxy_factory));
Darin Petkovdaf43862011-10-27 11:37:28 +0200174 break;
175 default: NOTREACHED();
176 }
177}
178
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500179void Cellular::OnModemEnabled() {
180 VLOG(2) << __func__ << ": " << GetStateString(state_);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100181 if (state_ == kStateDisabled) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500182 SetState(kStateEnabled);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100183 }
Darin Petkovfb0625e2012-01-16 13:05:56 +0100184}
185
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500186void Cellular::OnModemDisabled() {
187 VLOG(2) << __func__ << ": " << GetStateString(state_);
188 if (state_ != kStateDisabled) {
189 SetState(kStateDisabled);
Darin Petkovd2045802011-08-23 11:09:25 -0700190 }
Darin Petkovceb68172011-07-29 14:47:48 -0700191}
192
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500193void Cellular::Activate(const std::string &carrier,
194 ReturnerInterface *returner) {
195 capability_->Activate(carrier, new AsyncCallHandler(returner));
Darin Petkov9ae310f2011-08-30 15:41:13 -0700196}
197
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500198void Cellular::RegisterOnNetwork(const string &network_id,
199 ReturnerInterface *returner) {
200 capability_->RegisterOnNetwork(network_id, new AsyncCallHandler(returner));
Darin Petkova3d3be52011-11-14 21:34:16 +0100201}
202
Darin Petkovc64fe5e2012-01-11 12:46:13 +0100203void Cellular::RequirePIN(
204 const string &pin, bool require, ReturnerInterface *returner) {
205 VLOG(2) << __func__ << "(" << returner << ")";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500206 capability_->RequirePIN(pin, require, new AsyncCallHandler(returner));
Darin Petkove42e1012011-08-31 12:35:04 -0700207}
208
Darin Petkove5bc2cb2011-12-07 14:47:32 +0100209void Cellular::EnterPIN(const string &pin, ReturnerInterface *returner) {
210 VLOG(2) << __func__ << "(" << returner << ")";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500211 capability_->EnterPIN(pin, new AsyncCallHandler(returner));
Darin Petkove42e1012011-08-31 12:35:04 -0700212}
213
Darin Petkovc64fe5e2012-01-11 12:46:13 +0100214void Cellular::UnblockPIN(const string &unblock_code,
215 const string &pin,
216 ReturnerInterface *returner) {
217 VLOG(2) << __func__ << "(" << returner << ")";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500218 capability_->UnblockPIN(unblock_code, pin, new AsyncCallHandler(returner));
Darin Petkove42e1012011-08-31 12:35:04 -0700219}
220
Darin Petkovb05315f2011-11-07 10:14:25 +0100221void Cellular::ChangePIN(
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500222 const string &old_pin, const string &new_pin,
223 ReturnerInterface *returner) {
Darin Petkovc64fe5e2012-01-11 12:46:13 +0100224 VLOG(2) << __func__ << "(" << returner << ")";
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500225 capability_->ChangePIN(old_pin, new_pin, new AsyncCallHandler(returner));
Darin Petkove42e1012011-08-31 12:35:04 -0700226}
227
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500228void Cellular::Scan(Error * /*error*/) {
229 // TODO(ers): for now report immediate success.
230 capability_->Scan(NULL);
Darin Petkovceb68172011-07-29 14:47:48 -0700231}
232
Darin Petkovd9661952011-08-03 16:25:42 -0700233void Cellular::HandleNewRegistrationState() {
Paul Stewartac4ac002011-08-26 12:04:26 -0700234 dispatcher()->PostTask(
Darin Petkov0828f5f2011-08-11 10:18:52 -0700235 task_factory_.NewRunnableMethod(
236 &Cellular::HandleNewRegistrationStateTask));
237}
238
239void Cellular::HandleNewRegistrationStateTask() {
Darin Petkovd9661952011-08-03 16:25:42 -0700240 VLOG(2) << __func__;
Darin Petkovb72cf402011-11-22 14:51:39 +0100241 if (!capability_->IsRegistered()) {
Darin Petkov2c377382012-01-11 11:40:43 +0100242 DestroyService();
Darin Petkov0828f5f2011-08-11 10:18:52 -0700243 if (state_ == kStateLinked ||
244 state_ == kStateConnected ||
245 state_ == kStateRegistered) {
246 SetState(kStateEnabled);
Darin Petkovd9661952011-08-03 16:25:42 -0700247 }
248 return;
249 }
Darin Petkovd9661952011-08-03 16:25:42 -0700250 if (state_ == kStateEnabled) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700251 SetState(kStateRegistered);
Darin Petkovd9661952011-08-03 16:25:42 -0700252 }
253 if (!service_.get()) {
Darin Petkovd9661952011-08-03 16:25:42 -0700254 CreateService();
255 }
Darin Petkov3e509242011-11-10 14:46:44 +0100256 capability_->GetSignalQuality();
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500257 if (state_ == kStateRegistered && modem_state_ == kModemStateConnected)
258 OnConnected();
Darin Petkovb72cf402011-11-22 14:51:39 +0100259 service_->SetNetworkTechnology(capability_->GetNetworkTechnologyString());
260 service_->SetRoamingState(capability_->GetRoamingStateString());
Darin Petkovd9661952011-08-03 16:25:42 -0700261}
262
Darin Petkovd9661952011-08-03 16:25:42 -0700263void Cellular::HandleNewSignalQuality(uint32 strength) {
264 VLOG(2) << "Signal strength: " << strength;
Darin Petkovd78ee7e2012-01-12 11:21:10 +0100265 if (service_) {
266 service_->SetStrength(strength);
Darin Petkovd9661952011-08-03 16:25:42 -0700267 }
268}
269
270void Cellular::CreateService() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700271 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700272 CHECK(!service_.get());
273 service_ =
Thieu Le3426c8f2012-01-11 17:35:11 -0800274 new CellularService(control_interface(), dispatcher(), metrics(),
275 manager(), this);
Eric Shienbrood04e63582012-01-19 13:41:12 -0500276 manager()->RegisterService(service_);
Darin Petkovae0c64e2011-11-15 15:50:27 +0100277 capability_->OnServiceCreated();
Darin Petkovf5f61e02011-07-29 11:35:40 -0700278}
279
Darin Petkov2c377382012-01-11 11:40:43 +0100280void Cellular::DestroyService() {
281 VLOG(2) << __func__;
282 DestroyIPConfig();
283 if (service_) {
284 manager()->DeregisterService(service_);
285 service_ = NULL;
286 }
287 SelectService(NULL);
288}
289
Paul Stewartfdd16072011-09-16 12:41:35 -0700290bool Cellular::TechnologyIs(const Technology::Identifier type) const {
291 return type == Technology::kCellular;
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700292}
293
Darin Petkov4d6d9412011-08-24 13:19:54 -0700294void Cellular::Connect(Error *error) {
Darin Petkovc5f56562011-08-06 16:40:05 -0700295 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700296 if (state_ == kStateConnected ||
297 state_ == kStateLinked) {
Paul Stewartbe005172011-11-02 18:10:29 -0700298 Error::PopulateAndLog(error, Error::kAlreadyConnected,
299 "Already connected; connection request ignored.");
Darin Petkovc5f56562011-08-06 16:40:05 -0700300 return;
301 }
302 CHECK_EQ(kStateRegistered, state_);
Darin Petkovd2045802011-08-23 11:09:25 -0700303
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500304 if (!capability_->allow_roaming() &&
Darin Petkovd2045802011-08-23 11:09:25 -0700305 service_->roaming_state() == flimflam::kRoamingStateRoaming) {
Paul Stewartbe005172011-11-02 18:10:29 -0700306 Error::PopulateAndLog(error, Error::kNotOnHomeNetwork,
307 "Roaming disallowed; connection request ignored.");
Darin Petkovd2045802011-08-23 11:09:25 -0700308 return;
309 }
310
Darin Petkovc5f56562011-08-06 16:40:05 -0700311 DBusPropertiesMap properties;
Darin Petkovae0c64e2011-11-15 15:50:27 +0100312 capability_->SetupConnectProperties(&properties);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500313 capability_->Connect(properties);
Darin Petkovc5f56562011-08-06 16:40:05 -0700314}
315
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500316void Cellular::OnConnected() {
Darin Petkovc5f56562011-08-06 16:40:05 -0700317 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700318 SetState(kStateConnected);
Darin Petkovbac96002011-08-09 13:22:00 -0700319 EstablishLink();
320}
321
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500322void Cellular::OnConnectFailed() {
323 // TODO(ers): Signal failure.
324}
325
Darin Petkovfb0625e2012-01-16 13:05:56 +0100326void Cellular::Disconnect(Error *error) {
327 VLOG(2) << __func__;
328 if (state_ != kStateConnected &&
329 state_ != kStateLinked) {
330 Error::PopulateAndLog(
331 error, Error::kInProgress, "Not connected; request ignored.");
332 return;
333 }
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500334 capability_->Disconnect();
Darin Petkovfb0625e2012-01-16 13:05:56 +0100335}
336
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500337void Cellular::OnDisconnected() {
Darin Petkovfb0625e2012-01-16 13:05:56 +0100338 VLOG(2) << __func__;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500339 SetState(kStateRegistered);
Darin Petkovfb0625e2012-01-16 13:05:56 +0100340}
341
342void Cellular::DisconnectModem() {
343 VLOG(2) << __func__;
344 if (state_ != kStateConnected &&
345 state_ != kStateLinked) {
346 return;
347 }
348 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583). Note,
349 // however, that this is invoked by the Stop method, so some extra refactoring
350 // may be needed to prevent the device instance from being destroyed before
351 // the modem manager calls are complete. Maybe Disconnect and Disable need to
352 // be handled by the parent Modem class.
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500353 capability_->Disconnect();
354}
355
356void Cellular::OnDisconnectFailed() {
357 // TODO(ers): Signal failure.
Darin Petkovfb0625e2012-01-16 13:05:56 +0100358}
359
Darin Petkovbac96002011-08-09 13:22:00 -0700360void Cellular::EstablishLink() {
361 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700362 CHECK_EQ(kStateConnected, state_);
363 unsigned int flags = 0;
Paul Stewartac4ac002011-08-26 12:04:26 -0700364 if (manager()->device_info()->GetFlags(interface_index(), &flags) &&
Darin Petkov0828f5f2011-08-11 10:18:52 -0700365 (flags & IFF_UP) != 0) {
366 LinkEvent(flags, IFF_UP);
367 return;
368 }
369 // TODO(petkov): Provide a timeout for a failed link-up request.
mukesh agrawal5c4dd0b2011-09-14 13:53:14 -0700370 rtnl_handler()->SetInterfaceFlags(interface_index(), IFF_UP, IFF_UP);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700371}
372
373void Cellular::LinkEvent(unsigned int flags, unsigned int change) {
374 Device::LinkEvent(flags, change);
375 if ((flags & IFF_UP) != 0 && state_ == kStateConnected) {
Paul Stewartac4ac002011-08-26 12:04:26 -0700376 LOG(INFO) << link_name() << " is up.";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700377 SetState(kStateLinked);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700378 // TODO(petkov): For GSM, remember the APN.
Paul Stewart2bf1d352011-12-06 15:02:55 -0800379 if (AcquireIPConfig()) {
Darin Petkov60b8c3b2011-08-25 11:03:20 -0700380 SelectService(service_);
381 SetServiceState(Service::kStateConfiguring);
382 } else {
383 LOG(ERROR) << "Unable to acquire DHCP config.";
384 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700385 } else if ((flags & IFF_UP) == 0 && state_ == kStateLinked) {
386 SetState(kStateConnected);
Darin Petkov2c377382012-01-11 11:40:43 +0100387 DestroyService();
Darin Petkov0828f5f2011-08-11 10:18:52 -0700388 }
Darin Petkovc5f56562011-08-06 16:40:05 -0700389}
390
Darin Petkovae0c64e2011-11-15 15:50:27 +0100391void Cellular::OnModemManagerPropertiesChanged(
392 const DBusPropertiesMap &properties) {
Darin Petkov721ac932011-11-16 15:43:09 +0100393 capability_->OnModemManagerPropertiesChanged(properties);
Chris Masone889666b2011-07-03 12:58:50 -0700394}
395
Darin Petkovae0c64e2011-11-15 15:50:27 +0100396void Cellular::set_home_provider(const Operator &oper) {
397 home_provider_.CopyFrom(oper);
398}
399
Darin Petkovac635a82012-01-10 16:51:58 +0100400string Cellular::CreateFriendlyServiceName() {
401 VLOG(2) << __func__;
402 return capability_.get() ? capability_->CreateFriendlyServiceName() : "";
403}
404
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700405} // namespace shill