blob: 5473d01b9c049addd172bf05ca9fb6570890b09b [file] [log] [blame]
Chris Masone3bd3c8c2011-06-13 08:20:26 -07001// Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
2// 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>
8#include <linux/if.h>
9
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>
Chris Masone3bd3c8c2011-06-13 08:20:26 -070018
19#include "shill/cellular_service.h"
20#include "shill/control_interface.h"
21#include "shill/device.h"
22#include "shill/device_info.h"
23#include "shill/manager.h"
Darin Petkove604f702011-07-28 15:51:17 -070024#include "shill/modem_simple_proxy_interface.h"
Chris Masone7aa5f902011-07-11 11:13:35 -070025#include "shill/profile.h"
Chris Masone889666b2011-07-03 12:58:50 -070026#include "shill/property_accessor.h"
Darin Petkove9d12e02011-07-27 15:09:37 -070027#include "shill/proxy_factory.h"
Darin Petkov0828f5f2011-08-11 10:18:52 -070028#include "shill/rtnl_handler.h"
Chris Masone3bd3c8c2011-06-13 08:20:26 -070029#include "shill/shill_event.h"
30
Chris Masone889666b2011-07-03 12:58:50 -070031using std::make_pair;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070032using std::string;
Chris Masone889666b2011-07-03 12:58:50 -070033using std::vector;
Chris Masone3bd3c8c2011-06-13 08:20:26 -070034
35namespace shill {
36
Darin Petkovc5f56562011-08-06 16:40:05 -070037const char Cellular::kConnectPropertyPhoneNumber[] = "number";
38const char Cellular::kPhoneNumberCDMA[] = "#777";
39const char Cellular::kPhoneNumberGSM[] = "*99#";
40
Chris Masone889666b2011-07-03 12:58:50 -070041Cellular::Network::Network() {
42 dict_[flimflam::kStatusProperty] = "";
43 dict_[flimflam::kNetworkIdProperty] = "";
44 dict_[flimflam::kShortNameProperty] = "";
45 dict_[flimflam::kLongNameProperty] = "";
46 dict_[flimflam::kTechnologyProperty] = "";
47}
48
49Cellular::Network::~Network() {}
50
51const std::string &Cellular::Network::GetStatus() const {
52 return dict_.find(flimflam::kStatusProperty)->second;
53}
54
55void Cellular::Network::SetStatus(const std::string &status) {
56 dict_[flimflam::kStatusProperty] = status;
57}
58
59const std::string &Cellular::Network::GetId() const {
60 return dict_.find(flimflam::kNetworkIdProperty)->second;
61}
62
63void Cellular::Network::SetId(const std::string &id) {
64 dict_[flimflam::kNetworkIdProperty] = id;
65}
66
67const std::string &Cellular::Network::GetShortName() const {
68 return dict_.find(flimflam::kShortNameProperty)->second;
69}
70
71void Cellular::Network::SetShortName(const std::string &name) {
72 dict_[flimflam::kShortNameProperty] = name;
73}
74
75const std::string &Cellular::Network::GetLongName() const {
76 return dict_.find(flimflam::kLongNameProperty)->second;
77}
78
79void Cellular::Network::SetLongName(const std::string &name) {
80 dict_[flimflam::kLongNameProperty] = name;
81}
82
83const std::string &Cellular::Network::GetTechnology() const {
84 return dict_.find(flimflam::kTechnologyProperty)->second;
85}
86
87void Cellular::Network::SetTechnology(const std::string &technology) {
88 dict_[flimflam::kTechnologyProperty] = technology;
89}
90
91const Stringmap &Cellular::Network::ToDict() const {
92 return dict_;
93}
94
Darin Petkovbec79a22011-08-01 14:47:17 -070095Cellular::CDMA::CDMA()
96 : registration_state_evdo(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
97 registration_state_1x(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
98 activation_state(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED) {}
99
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700100Cellular::Cellular(ControlInterface *control_interface,
101 EventDispatcher *dispatcher,
102 Manager *manager,
Darin Petkove9d12e02011-07-27 15:09:37 -0700103 const string &link_name,
104 int interface_index,
105 Type type,
106 const string &owner,
107 const string &path)
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700108 : Device(control_interface,
109 dispatcher,
110 manager,
Darin Petkove9d12e02011-07-27 15:09:37 -0700111 link_name,
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700112 interface_index),
Darin Petkove9d12e02011-07-27 15:09:37 -0700113 type_(type),
114 state_(kStateDisabled),
Darin Petkovbac96002011-08-09 13:22:00 -0700115 modem_state_(kModemStateUnknown),
Darin Petkove9d12e02011-07-27 15:09:37 -0700116 dbus_owner_(owner),
117 dbus_path_(path),
Darin Petkovc5f56562011-08-06 16:40:05 -0700118 task_factory_(this),
Darin Petkove9d12e02011-07-27 15:09:37 -0700119 allow_roaming_(false),
120 prl_version_(0),
121 scanning_(false),
122 scan_interval_(0) {
123 store_.RegisterConstString(flimflam::kDBusConnectionProperty, &dbus_owner_);
124 store_.RegisterConstString(flimflam::kDBusObjectProperty, &dbus_path_);
Chris Masone27c4aa52011-07-02 13:10:14 -0700125 store_.RegisterConstString(flimflam::kCarrierProperty, &carrier_);
Chris Masone4d42df82011-07-02 17:09:39 -0700126 store_.RegisterBool(flimflam::kCellularAllowRoamingProperty, &allow_roaming_);
Chris Masone27c4aa52011-07-02 13:10:14 -0700127 store_.RegisterConstString(flimflam::kEsnProperty, &esn_);
Chris Masone27c4aa52011-07-02 13:10:14 -0700128 store_.RegisterConstString(flimflam::kFirmwareRevisionProperty,
129 &firmware_revision_);
130 store_.RegisterConstString(flimflam::kHardwareRevisionProperty,
131 &hardware_revision_);
Chris Masone4d42df82011-07-02 17:09:39 -0700132 store_.RegisterConstString(flimflam::kImeiProperty, &imei_);
133 store_.RegisterConstString(flimflam::kImsiProperty, &imsi_);
134 store_.RegisterConstString(flimflam::kManufacturerProperty, &manufacturer_);
135 store_.RegisterConstString(flimflam::kMdnProperty, &mdn_);
136 store_.RegisterConstString(flimflam::kMeidProperty, &meid_);
137 store_.RegisterConstString(flimflam::kMinProperty, &min_);
138 store_.RegisterConstString(flimflam::kModelIDProperty, &model_id_);
Darin Petkovceb68172011-07-29 14:47:48 -0700139 store_.RegisterConstUint16(flimflam::kPRLVersionProperty, &prl_version_);
Chris Masoneb925cc82011-06-22 15:39:57 -0700140
Chris Masone889666b2011-07-03 12:58:50 -0700141 HelpRegisterDerivedStrIntPair(flimflam::kSIMLockStatusProperty,
142 &Cellular::SimLockStatusToProperty,
143 NULL);
144 HelpRegisterDerivedStringmaps(flimflam::kFoundNetworksProperty,
145 &Cellular::EnumerateNetworks,
146 NULL);
Chris Masoneb925cc82011-06-22 15:39:57 -0700147
Chris Masone4d42df82011-07-02 17:09:39 -0700148 store_.RegisterConstBool(flimflam::kScanningProperty, &scanning_);
149 store_.RegisterUint16(flimflam::kScanIntervalProperty, &scan_interval_);
150
Darin Petkove9d12e02011-07-27 15:09:37 -0700151 VLOG(2) << "Cellular device " << link_name_ << " initialized: "
152 << GetTypeString();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700153}
154
Darin Petkove9d12e02011-07-27 15:09:37 -0700155Cellular::~Cellular() {}
156
Darin Petkov0828f5f2011-08-11 10:18:52 -0700157string Cellular::GetTypeString() {
Darin Petkove9d12e02011-07-27 15:09:37 -0700158 switch (type_) {
159 case kTypeGSM: return "CellularTypeGSM";
160 case kTypeCDMA: return "CellularTypeCDMA";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700161 default: NOTREACHED();
Darin Petkove9d12e02011-07-27 15:09:37 -0700162 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700163 return StringPrintf("CellularTypeUnknown-%d", type_);
Darin Petkove9d12e02011-07-27 15:09:37 -0700164}
165
Darin Petkov0828f5f2011-08-11 10:18:52 -0700166string Cellular::GetStateString() {
Darin Petkove9d12e02011-07-27 15:09:37 -0700167 switch (state_) {
168 case kStateDisabled: return "CellularStateDisabled";
169 case kStateEnabled: return "CellularStateEnabled";
170 case kStateRegistered: return "CellularStateRegistered";
171 case kStateConnected: return "CellularStateConnected";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700172 case kStateLinked: return "CellularStateLinked";
173 default: NOTREACHED();
Darin Petkove9d12e02011-07-27 15:09:37 -0700174 }
Darin Petkov0828f5f2011-08-11 10:18:52 -0700175 return StringPrintf("CellularStateUnknown-%d", state_);
176}
177
178void Cellular::SetState(State state) {
179 VLOG(2) << "Current state: " << GetStateString();
180 state_ = state;
181 VLOG(2) << "New state: " << GetStateString();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700182}
183
184void Cellular::Start() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700185 LOG(INFO) << "Start";
Darin Petkovf5f61e02011-07-29 11:35:40 -0700186 VLOG(2) << __func__ << ": " << GetStateString();
Darin Petkovbec79a22011-08-01 14:47:17 -0700187 InitProxies();
Darin Petkovf5f61e02011-07-29 11:35:40 -0700188 EnableModem();
Darin Petkovceb68172011-07-29 14:47:48 -0700189 if (type_ == kTypeGSM) {
190 RegisterGSMModem();
191 }
Darin Petkovf5f61e02011-07-29 11:35:40 -0700192 GetModemStatus();
Darin Petkovceb68172011-07-29 14:47:48 -0700193 GetModemIdentifiers();
194 if (type_ == kTypeGSM) {
195 GetGSMProperties();
196 }
197 GetModemInfo();
198 GetModemRegistrationState();
Darin Petkove9d12e02011-07-27 15:09:37 -0700199 // TODO(petkov): Device::Start();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700200}
201
202void Cellular::Stop() {
Darin Petkove9d12e02011-07-27 15:09:37 -0700203 proxy_.reset();
Darin Petkove604f702011-07-28 15:51:17 -0700204 simple_proxy_.reset();
Darin Petkovbec79a22011-08-01 14:47:17 -0700205 cdma_proxy_.reset();
Chris Masone2b105542011-06-22 10:58:09 -0700206 manager_->DeregisterService(service_);
Darin Petkove9d12e02011-07-27 15:09:37 -0700207 service_ = NULL; // Breaks a reference cycle.
Darin Petkov0828f5f2011-08-11 10:18:52 -0700208 SetState(kStateDisabled);
209 RTNLHandler::GetInstance()->SetInterfaceFlags(interface_index_, 0, IFF_UP);
Darin Petkove9d12e02011-07-27 15:09:37 -0700210 // TODO(petkov): Device::Stop();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700211}
212
Darin Petkovbec79a22011-08-01 14:47:17 -0700213void Cellular::InitProxies() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700214 LOG(INFO) << "InitProxies";
Darin Petkovbec79a22011-08-01 14:47:17 -0700215 proxy_.reset(
Darin Petkovc5f56562011-08-06 16:40:05 -0700216 ProxyFactory::factory()->CreateModemProxy(this, dbus_path_, dbus_owner_));
Darin Petkovbec79a22011-08-01 14:47:17 -0700217 simple_proxy_.reset(
218 ProxyFactory::factory()->CreateModemSimpleProxy(
219 dbus_path_, dbus_owner_));
220 switch (type_) {
221 case kTypeGSM:
222 NOTIMPLEMENTED();
223 break;
224 case kTypeCDMA:
225 cdma_proxy_.reset(
226 ProxyFactory::factory()->CreateModemCDMAProxy(
Darin Petkovd9661952011-08-03 16:25:42 -0700227 this, dbus_path_, dbus_owner_));
Darin Petkovbec79a22011-08-01 14:47:17 -0700228 break;
229 default: NOTREACHED();
230 }
231}
232
Darin Petkovf5f61e02011-07-29 11:35:40 -0700233void Cellular::EnableModem() {
234 CHECK_EQ(kStateDisabled, state_);
235 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
236 proxy_->Enable(true);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700237 SetState(kStateEnabled);
Darin Petkovf5f61e02011-07-29 11:35:40 -0700238}
239
240void Cellular::GetModemStatus() {
Darin Petkovceb68172011-07-29 14:47:48 -0700241 CHECK_EQ(kStateEnabled, state_);
Darin Petkovf5f61e02011-07-29 11:35:40 -0700242 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
243 DBusPropertiesMap properties = simple_proxy_->GetStatus();
Darin Petkovceb68172011-07-29 14:47:48 -0700244 if (DBusProperties::GetString(properties, "carrier", &carrier_) &&
245 type_ == kTypeCDMA) {
246 // TODO(petkov): Set Cellular.FirmwareImageName and home_provider based on
247 // the carrier.
Darin Petkovf5f61e02011-07-29 11:35:40 -0700248 }
Darin Petkovceb68172011-07-29 14:47:48 -0700249 DBusProperties::GetString(properties, "meid", &meid_);
250 DBusProperties::GetString(properties, "imei", &imei_);
251 if (DBusProperties::GetString(properties, "imsi", &imsi_) &&
252 type_ == kTypeGSM) {
253 // TODO(petkov): Set GSM provider.
254 }
255 DBusProperties::GetString(properties, "esn", &esn_);
256 DBusProperties::GetString(properties, "mdn", &mdn_);
257 DBusProperties::GetString(properties, "min", &min_);
258 DBusProperties::GetUint16(properties, "prl_version", &prl_version_);
259 DBusProperties::GetString(
260 properties, "firmware_revision", &firmware_revision_);
261 // TODO(petkov): Get payment_url/olp_url/usage_url. For now, get these from
262 // ModemManager to match flimflam. In the future, provide a plugin API to get
263 // these directly from the modem driver.
264 if (type_ == kTypeCDMA) {
265 // TODO(petkov): Get activation_state.
266 }
267}
268
269void Cellular::GetModemIdentifiers() {
270 // TODO(petkov): Implement this.
271 NOTIMPLEMENTED();
272}
273
274void Cellular::GetGSMProperties() {
275 // TODO(petkov): Implement this.
276 NOTIMPLEMENTED();
277}
278
279void Cellular::RegisterGSMModem() {
280 // TODO(petkov): Invoke ModemManager.Modem.Gsm.Network.Register.
281 NOTIMPLEMENTED();
282}
283
284void Cellular::GetModemInfo() {
285 ModemProxyInterface::Info info = proxy_->GetInfo();
286 manufacturer_ = info._1;
287 model_id_ = info._2;
288 hardware_revision_ = info._3;
289 VLOG(2) << "ModemInfo: " << manufacturer_ << ", " << model_id_ << ", "
290 << hardware_revision_;
291}
292
293void Cellular::GetModemRegistrationState() {
Darin Petkovbec79a22011-08-01 14:47:17 -0700294 switch (type_) {
295 case kTypeGSM:
296 GetGSMRegistrationState();
297 break;
298 case kTypeCDMA:
299 GetCDMARegistrationState();
300 break;
301 default: NOTREACHED();
302 }
Darin Petkovd9661952011-08-03 16:25:42 -0700303 HandleNewRegistrationState();
Darin Petkovbec79a22011-08-01 14:47:17 -0700304}
305
306void Cellular::GetCDMARegistrationState() {
307 CHECK_EQ(kTypeCDMA, type_);
308 cdma_proxy_->GetRegistrationState(&cdma_.registration_state_1x,
309 &cdma_.registration_state_evdo);
310 VLOG(2) << "CDMA Registration: 1x(" << cdma_.registration_state_1x
311 << ") EVDO(" << cdma_.registration_state_evdo << ")";
312 // TODO(petkov): handle_reported_connect?
313}
314
315void Cellular::GetGSMRegistrationState() {
Darin Petkovceb68172011-07-29 14:47:48 -0700316 // TODO(petkov): Implement this.
317 NOTIMPLEMENTED();
318}
319
Darin Petkovd9661952011-08-03 16:25:42 -0700320bool Cellular::IsModemRegistered() {
321 return cdma_.registration_state_1x !=
322 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN ||
323 cdma_.registration_state_evdo !=
324 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
325 // TODO(petkov): Handle GSM states.
326}
327
328void Cellular::HandleNewRegistrationState() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700329 dispatcher_->PostTask(
330 task_factory_.NewRunnableMethod(
331 &Cellular::HandleNewRegistrationStateTask));
332}
333
334void Cellular::HandleNewRegistrationStateTask() {
Darin Petkovd9661952011-08-03 16:25:42 -0700335 VLOG(2) << __func__;
336 if (!IsModemRegistered()) {
337 service_ = NULL;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700338 if (state_ == kStateLinked ||
339 state_ == kStateConnected ||
340 state_ == kStateRegistered) {
341 SetState(kStateEnabled);
Darin Petkovd9661952011-08-03 16:25:42 -0700342 }
343 return;
344 }
Darin Petkovd9661952011-08-03 16:25:42 -0700345 if (state_ == kStateEnabled) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700346 SetState(kStateRegistered);
Darin Petkovd9661952011-08-03 16:25:42 -0700347 }
348 if (!service_.get()) {
349 // For now, no endpoint is created. Revisit if necessary.
350 CreateService();
351 }
352 GetModemSignalQuality();
Darin Petkov0828f5f2011-08-11 10:18:52 -0700353 if (state_ == kStateRegistered && modem_state_ == kModemStateConnected) {
354 SetState(kStateConnected);
355 EstablishLink();
356 }
Darin Petkovd9661952011-08-03 16:25:42 -0700357 // TODO(petkov): Update the service.
358}
359
360void Cellular::GetModemSignalQuality() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700361 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700362 uint32 strength = 0;
363 switch (type_) {
364 case kTypeGSM:
365 strength = GetGSMSignalQuality();
366 break;
367 case kTypeCDMA:
368 strength = GetCDMASignalQuality();
369 break;
370 default: NOTREACHED();
371 }
372 HandleNewSignalQuality(strength);
373}
374
375uint32 Cellular::GetCDMASignalQuality() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700376 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700377 CHECK_EQ(kTypeCDMA, type_);
378 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
379 return cdma_proxy_->GetSignalQuality();
380}
381
382uint32 Cellular::GetGSMSignalQuality() {
Darin Petkovceb68172011-07-29 14:47:48 -0700383 // TODO(petkov): Implement this.
384 NOTIMPLEMENTED();
Darin Petkovd9661952011-08-03 16:25:42 -0700385 return 0;
386}
387
388void Cellular::HandleNewSignalQuality(uint32 strength) {
389 VLOG(2) << "Signal strength: " << strength;
390 if (service_.get()) {
391 service_->set_strength(strength);
392 }
393}
394
395void Cellular::CreateService() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700396 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700397 CHECK(!service_.get());
398 service_ =
399 new CellularService(control_interface_, dispatcher_, manager_, this);
400 // TODO(petkov): Set activation_state.
401 // TODO(petkov): Set operator.
402 // TODO(petkov): Set old_url/usage_url.
Darin Petkovf5f61e02011-07-29 11:35:40 -0700403}
404
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700405bool Cellular::TechnologyIs(const Device::Technology type) const {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700406 return type == Device::kCellular;
407}
408
Darin Petkovc5f56562011-08-06 16:40:05 -0700409void Cellular::Connect() {
410 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700411 if (state_ == kStateConnected ||
412 state_ == kStateLinked) {
Darin Petkovc5f56562011-08-06 16:40:05 -0700413 return;
414 }
415 CHECK_EQ(kStateRegistered, state_);
416 DBusPropertiesMap properties;
417 const char *phone_number = NULL;
418 switch (type_) {
419 case kTypeGSM:
420 phone_number = kPhoneNumberGSM;
421 break;
422 case kTypeCDMA:
423 phone_number = kPhoneNumberCDMA;
424 break;
425 default: NOTREACHED();
426 }
427 properties[kConnectPropertyPhoneNumber].writer().append_string(phone_number);
428 // TODO(petkov): Setup apn and "home_only".
429
430 // Defer connect because we may be in a dbus-c++ callback.
431 dispatcher_->PostTask(
432 task_factory_.NewRunnableMethod(&Cellular::ConnectTask, properties));
433}
434
435void Cellular::ConnectTask(const DBusPropertiesMap &properties) {
436 VLOG(2) << __func__;
Darin Petkovbac96002011-08-09 13:22:00 -0700437 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
Darin Petkovc5f56562011-08-06 16:40:05 -0700438 simple_proxy_->Connect(properties);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700439 SetState(kStateConnected);
Darin Petkovbac96002011-08-09 13:22:00 -0700440 EstablishLink();
441}
442
443void Cellular::EstablishLink() {
444 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700445 CHECK_EQ(kStateConnected, state_);
446 unsigned int flags = 0;
447 if (manager_->device_info()->GetFlags(interface_index_, &flags) &&
448 (flags & IFF_UP) != 0) {
449 LinkEvent(flags, IFF_UP);
450 return;
451 }
452 // TODO(petkov): Provide a timeout for a failed link-up request.
453 RTNLHandler::GetInstance()->SetInterfaceFlags(
454 interface_index_, IFF_UP, IFF_UP);
455}
456
457void Cellular::LinkEvent(unsigned int flags, unsigned int change) {
458 Device::LinkEvent(flags, change);
459 if ((flags & IFF_UP) != 0 && state_ == kStateConnected) {
460 LOG(INFO) << link_name_ << " is up.";
461 SetState(kStateLinked);
462 manager_->RegisterService(service_);
463 // TODO(petkov): For GSM, remember the APN.
Darin Petkov77cb6812011-08-15 16:19:41 -0700464 LOG_IF(ERROR, !AcquireDHCPConfig()) << "Unable to acquire DHCP config.";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700465 } else if ((flags & IFF_UP) == 0 && state_ == kStateLinked) {
466 SetState(kStateConnected);
467 manager_->DeregisterService(service_);
Darin Petkov77cb6812011-08-15 16:19:41 -0700468 DestroyIPConfig();
Darin Petkov0828f5f2011-08-11 10:18:52 -0700469 }
Darin Petkovc5f56562011-08-06 16:40:05 -0700470}
471
Darin Petkovd9661952011-08-03 16:25:42 -0700472void Cellular::OnCDMARegistrationStateChanged(uint32 state_1x,
473 uint32 state_evdo) {
474 CHECK_EQ(kTypeCDMA, type_);
475 cdma_.registration_state_1x = state_1x;
476 cdma_.registration_state_evdo = state_evdo;
477 HandleNewRegistrationState();
478}
479
480void Cellular::OnCDMASignalQualityChanged(uint32 strength) {
481 CHECK_EQ(kTypeCDMA, type_);
482 HandleNewSignalQuality(strength);
483}
484
Darin Petkovc5f56562011-08-06 16:40:05 -0700485void Cellular::OnModemStateChanged(uint32 old_state,
486 uint32 new_state,
487 uint32 reason) {
488 // TODO(petkov): Implement this.
489 NOTIMPLEMENTED();
490}
491
Chris Masone889666b2011-07-03 12:58:50 -0700492Stringmaps Cellular::EnumerateNetworks() {
493 Stringmaps to_return;
494 for (vector<Network>::const_iterator it = found_networks_.begin();
495 it != found_networks_.end();
496 ++it) {
497 to_return.push_back(it->ToDict());
498 }
499 return to_return;
500}
501
502StrIntPair Cellular::SimLockStatusToProperty() {
503 return StrIntPair(make_pair(flimflam::kSIMLockTypeProperty,
504 sim_lock_status_.lock_type),
505 make_pair(flimflam::kSIMLockRetriesLeftProperty,
506 sim_lock_status_.retries_left));
507}
508
509void Cellular::HelpRegisterDerivedStringmaps(
510 const string &name,
511 Stringmaps(Cellular::*get)(void),
512 bool(Cellular::*set)(const Stringmaps&)) {
513 store_.RegisterDerivedStringmaps(
514 name,
515 StringmapsAccessor(
516 new CustomAccessor<Cellular, Stringmaps>(this, get, set)));
517}
518
519void Cellular::HelpRegisterDerivedStrIntPair(
520 const string &name,
521 StrIntPair(Cellular::*get)(void),
522 bool(Cellular::*set)(const StrIntPair&)) {
523 store_.RegisterDerivedStrIntPair(
524 name,
525 StrIntPairAccessor(
526 new CustomAccessor<Cellular, StrIntPair>(this, get, set)));
527}
528
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700529} // namespace shill