blob: 1430552df42dec5e343417e916e28384a8b108af [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),
Darin Petkovcc044422011-08-17 13:30:06 -070098 activation_state(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
99 prl_version(0) {}
Darin Petkovbec79a22011-08-01 14:47:17 -0700100
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700101Cellular::Cellular(ControlInterface *control_interface,
102 EventDispatcher *dispatcher,
103 Manager *manager,
Darin Petkove9d12e02011-07-27 15:09:37 -0700104 const string &link_name,
105 int interface_index,
106 Type type,
107 const string &owner,
108 const string &path)
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700109 : Device(control_interface,
110 dispatcher,
111 manager,
Darin Petkove9d12e02011-07-27 15:09:37 -0700112 link_name,
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700113 interface_index),
Darin Petkove9d12e02011-07-27 15:09:37 -0700114 type_(type),
115 state_(kStateDisabled),
Darin Petkovbac96002011-08-09 13:22:00 -0700116 modem_state_(kModemStateUnknown),
Darin Petkove9d12e02011-07-27 15:09:37 -0700117 dbus_owner_(owner),
118 dbus_path_(path),
Darin Petkovc5f56562011-08-06 16:40:05 -0700119 task_factory_(this),
Darin Petkove9d12e02011-07-27 15:09:37 -0700120 allow_roaming_(false),
Darin Petkove9d12e02011-07-27 15:09:37 -0700121 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 Petkovcc044422011-08-17 13:30:06 -0700139 store_.RegisterConstUint16(flimflam::kPRLVersionProperty, &cdma_.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 Petkovcc044422011-08-17 13:30:06 -0700157string Cellular::GetTypeString() const {
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 Petkovcc044422011-08-17 13:30:06 -0700166// static
167string Cellular::GetStateString(State state) {
168 switch (state) {
Darin Petkove9d12e02011-07-27 15:09:37 -0700169 case kStateDisabled: return "CellularStateDisabled";
170 case kStateEnabled: return "CellularStateEnabled";
171 case kStateRegistered: return "CellularStateRegistered";
172 case kStateConnected: return "CellularStateConnected";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700173 case kStateLinked: return "CellularStateLinked";
174 default: NOTREACHED();
Darin Petkove9d12e02011-07-27 15:09:37 -0700175 }
Darin Petkovcc044422011-08-17 13:30:06 -0700176 return StringPrintf("CellularStateUnknown-%d", state);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700177}
178
179void Cellular::SetState(State state) {
Darin Petkovcc044422011-08-17 13:30:06 -0700180 VLOG(2) << GetStateString(state_) << " -> " << GetStateString(state);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700181 state_ = state;
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700182}
183
184void Cellular::Start() {
Darin Petkovcc044422011-08-17 13:30:06 -0700185 LOG(INFO) << __func__ << ": " << GetStateString(state_);
Darin Petkovbec79a22011-08-01 14:47:17 -0700186 InitProxies();
Darin Petkovf5f61e02011-07-29 11:35:40 -0700187 EnableModem();
Darin Petkovceb68172011-07-29 14:47:48 -0700188 if (type_ == kTypeGSM) {
189 RegisterGSMModem();
190 }
Darin Petkovf5f61e02011-07-29 11:35:40 -0700191 GetModemStatus();
Darin Petkovceb68172011-07-29 14:47:48 -0700192 GetModemIdentifiers();
193 if (type_ == kTypeGSM) {
194 GetGSMProperties();
195 }
196 GetModemInfo();
197 GetModemRegistrationState();
Darin Petkove9d12e02011-07-27 15:09:37 -0700198 // TODO(petkov): Device::Start();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700199}
200
201void Cellular::Stop() {
Darin Petkove9d12e02011-07-27 15:09:37 -0700202 proxy_.reset();
Darin Petkove604f702011-07-28 15:51:17 -0700203 simple_proxy_.reset();
Darin Petkovbec79a22011-08-01 14:47:17 -0700204 cdma_proxy_.reset();
Chris Masone2b105542011-06-22 10:58:09 -0700205 manager_->DeregisterService(service_);
Darin Petkove9d12e02011-07-27 15:09:37 -0700206 service_ = NULL; // Breaks a reference cycle.
Darin Petkov0828f5f2011-08-11 10:18:52 -0700207 SetState(kStateDisabled);
208 RTNLHandler::GetInstance()->SetInterfaceFlags(interface_index_, 0, IFF_UP);
Darin Petkove9d12e02011-07-27 15:09:37 -0700209 // TODO(petkov): Device::Stop();
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700210}
211
Darin Petkovbec79a22011-08-01 14:47:17 -0700212void Cellular::InitProxies() {
Darin Petkovcc044422011-08-17 13:30:06 -0700213 VLOG(2) << __func__;
Darin Petkovbec79a22011-08-01 14:47:17 -0700214 proxy_.reset(
Darin Petkovc5f56562011-08-06 16:40:05 -0700215 ProxyFactory::factory()->CreateModemProxy(this, dbus_path_, dbus_owner_));
Darin Petkovbec79a22011-08-01 14:47:17 -0700216 simple_proxy_.reset(
217 ProxyFactory::factory()->CreateModemSimpleProxy(
218 dbus_path_, dbus_owner_));
219 switch (type_) {
220 case kTypeGSM:
221 NOTIMPLEMENTED();
222 break;
223 case kTypeCDMA:
224 cdma_proxy_.reset(
225 ProxyFactory::factory()->CreateModemCDMAProxy(
Darin Petkovd9661952011-08-03 16:25:42 -0700226 this, dbus_path_, dbus_owner_));
Darin Petkovbec79a22011-08-01 14:47:17 -0700227 break;
228 default: NOTREACHED();
229 }
230}
231
Darin Petkovf5f61e02011-07-29 11:35:40 -0700232void Cellular::EnableModem() {
233 CHECK_EQ(kStateDisabled, state_);
234 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
235 proxy_->Enable(true);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700236 SetState(kStateEnabled);
Darin Petkovf5f61e02011-07-29 11:35:40 -0700237}
238
239void Cellular::GetModemStatus() {
Darin Petkovceb68172011-07-29 14:47:48 -0700240 CHECK_EQ(kStateEnabled, state_);
Darin Petkovf5f61e02011-07-29 11:35:40 -0700241 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
242 DBusPropertiesMap properties = simple_proxy_->GetStatus();
Darin Petkovceb68172011-07-29 14:47:48 -0700243 if (DBusProperties::GetString(properties, "carrier", &carrier_) &&
244 type_ == kTypeCDMA) {
245 // TODO(petkov): Set Cellular.FirmwareImageName and home_provider based on
246 // the carrier.
Darin Petkovf5f61e02011-07-29 11:35:40 -0700247 }
Darin Petkovceb68172011-07-29 14:47:48 -0700248 DBusProperties::GetString(properties, "meid", &meid_);
249 DBusProperties::GetString(properties, "imei", &imei_);
250 if (DBusProperties::GetString(properties, "imsi", &imsi_) &&
251 type_ == kTypeGSM) {
252 // TODO(petkov): Set GSM provider.
253 }
254 DBusProperties::GetString(properties, "esn", &esn_);
255 DBusProperties::GetString(properties, "mdn", &mdn_);
256 DBusProperties::GetString(properties, "min", &min_);
Darin Petkovceb68172011-07-29 14:47:48 -0700257 DBusProperties::GetString(
258 properties, "firmware_revision", &firmware_revision_);
Darin Petkovb27e5442011-08-16 14:36:45 -0700259
Darin Petkovb27e5442011-08-16 14:36:45 -0700260
Darin Petkovceb68172011-07-29 14:47:48 -0700261 if (type_ == kTypeCDMA) {
262 // TODO(petkov): Get activation_state.
Darin Petkovcc044422011-08-17 13:30:06 -0700263 DBusProperties::GetUint16(properties, "prl_version", &cdma_.prl_version);
264
265 // TODO(petkov): For now, get the payment and usage URLs from ModemManager
266 // to match flimflam. In the future, provide a plugin API to get these
267 // directly from the modem driver.
268 DBusProperties::GetString(properties, "payment_url", &cdma_.payment_url);
269 DBusProperties::GetString(properties, "usage_url", &cdma_.usage_url);
Darin Petkovceb68172011-07-29 14:47:48 -0700270 }
271}
272
273void Cellular::GetModemIdentifiers() {
274 // TODO(petkov): Implement this.
275 NOTIMPLEMENTED();
276}
277
278void Cellular::GetGSMProperties() {
279 // TODO(petkov): Implement this.
280 NOTIMPLEMENTED();
281}
282
283void Cellular::RegisterGSMModem() {
284 // TODO(petkov): Invoke ModemManager.Modem.Gsm.Network.Register.
285 NOTIMPLEMENTED();
286}
287
288void Cellular::GetModemInfo() {
289 ModemProxyInterface::Info info = proxy_->GetInfo();
290 manufacturer_ = info._1;
291 model_id_ = info._2;
292 hardware_revision_ = info._3;
293 VLOG(2) << "ModemInfo: " << manufacturer_ << ", " << model_id_ << ", "
294 << hardware_revision_;
295}
296
297void Cellular::GetModemRegistrationState() {
Darin Petkovbec79a22011-08-01 14:47:17 -0700298 switch (type_) {
299 case kTypeGSM:
300 GetGSMRegistrationState();
301 break;
302 case kTypeCDMA:
303 GetCDMARegistrationState();
304 break;
305 default: NOTREACHED();
306 }
Darin Petkovd9661952011-08-03 16:25:42 -0700307 HandleNewRegistrationState();
Darin Petkovbec79a22011-08-01 14:47:17 -0700308}
309
310void Cellular::GetCDMARegistrationState() {
311 CHECK_EQ(kTypeCDMA, type_);
312 cdma_proxy_->GetRegistrationState(&cdma_.registration_state_1x,
313 &cdma_.registration_state_evdo);
314 VLOG(2) << "CDMA Registration: 1x(" << cdma_.registration_state_1x
315 << ") EVDO(" << cdma_.registration_state_evdo << ")";
316 // TODO(petkov): handle_reported_connect?
317}
318
319void Cellular::GetGSMRegistrationState() {
Darin Petkovceb68172011-07-29 14:47:48 -0700320 // TODO(petkov): Implement this.
321 NOTIMPLEMENTED();
322}
323
Darin Petkovd9661952011-08-03 16:25:42 -0700324bool Cellular::IsModemRegistered() {
325 return cdma_.registration_state_1x !=
326 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN ||
327 cdma_.registration_state_evdo !=
328 MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
329 // TODO(petkov): Handle GSM states.
330}
331
332void Cellular::HandleNewRegistrationState() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700333 dispatcher_->PostTask(
334 task_factory_.NewRunnableMethod(
335 &Cellular::HandleNewRegistrationStateTask));
336}
337
338void Cellular::HandleNewRegistrationStateTask() {
Darin Petkovd9661952011-08-03 16:25:42 -0700339 VLOG(2) << __func__;
340 if (!IsModemRegistered()) {
341 service_ = NULL;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700342 if (state_ == kStateLinked ||
343 state_ == kStateConnected ||
344 state_ == kStateRegistered) {
345 SetState(kStateEnabled);
Darin Petkovd9661952011-08-03 16:25:42 -0700346 }
347 return;
348 }
Darin Petkovd9661952011-08-03 16:25:42 -0700349 if (state_ == kStateEnabled) {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700350 SetState(kStateRegistered);
Darin Petkovd9661952011-08-03 16:25:42 -0700351 }
352 if (!service_.get()) {
353 // For now, no endpoint is created. Revisit if necessary.
354 CreateService();
355 }
356 GetModemSignalQuality();
Darin Petkov0828f5f2011-08-11 10:18:52 -0700357 if (state_ == kStateRegistered && modem_state_ == kModemStateConnected) {
358 SetState(kStateConnected);
359 EstablishLink();
360 }
Darin Petkovd9661952011-08-03 16:25:42 -0700361 // TODO(petkov): Update the service.
362}
363
364void Cellular::GetModemSignalQuality() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700365 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700366 uint32 strength = 0;
367 switch (type_) {
368 case kTypeGSM:
369 strength = GetGSMSignalQuality();
370 break;
371 case kTypeCDMA:
372 strength = GetCDMASignalQuality();
373 break;
374 default: NOTREACHED();
375 }
376 HandleNewSignalQuality(strength);
377}
378
379uint32 Cellular::GetCDMASignalQuality() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700380 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700381 CHECK_EQ(kTypeCDMA, type_);
382 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
383 return cdma_proxy_->GetSignalQuality();
384}
385
386uint32 Cellular::GetGSMSignalQuality() {
Darin Petkovceb68172011-07-29 14:47:48 -0700387 // TODO(petkov): Implement this.
388 NOTIMPLEMENTED();
Darin Petkovd9661952011-08-03 16:25:42 -0700389 return 0;
390}
391
392void Cellular::HandleNewSignalQuality(uint32 strength) {
393 VLOG(2) << "Signal strength: " << strength;
394 if (service_.get()) {
395 service_->set_strength(strength);
396 }
397}
398
399void Cellular::CreateService() {
Darin Petkov0828f5f2011-08-11 10:18:52 -0700400 VLOG(2) << __func__;
Darin Petkovd9661952011-08-03 16:25:42 -0700401 CHECK(!service_.get());
402 service_ =
403 new CellularService(control_interface_, dispatcher_, manager_, this);
Darin Petkovcc044422011-08-17 13:30:06 -0700404 if (type_ == kTypeCDMA) {
405 service_->set_payment_url(cdma_.payment_url);
406 service_->set_usage_url(cdma_.usage_url);
407 }
Darin Petkovd9661952011-08-03 16:25:42 -0700408 // TODO(petkov): Set activation_state.
409 // TODO(petkov): Set operator.
Darin Petkovf5f61e02011-07-29 11:35:40 -0700410}
411
Darin Petkov6f9eaa32011-08-09 15:26:44 -0700412bool Cellular::TechnologyIs(const Device::Technology type) const {
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700413 return type == Device::kCellular;
414}
415
Darin Petkovc5f56562011-08-06 16:40:05 -0700416void Cellular::Connect() {
417 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700418 if (state_ == kStateConnected ||
419 state_ == kStateLinked) {
Darin Petkovc5f56562011-08-06 16:40:05 -0700420 return;
421 }
422 CHECK_EQ(kStateRegistered, state_);
423 DBusPropertiesMap properties;
424 const char *phone_number = NULL;
425 switch (type_) {
426 case kTypeGSM:
427 phone_number = kPhoneNumberGSM;
428 break;
429 case kTypeCDMA:
430 phone_number = kPhoneNumberCDMA;
431 break;
432 default: NOTREACHED();
433 }
434 properties[kConnectPropertyPhoneNumber].writer().append_string(phone_number);
435 // TODO(petkov): Setup apn and "home_only".
436
437 // Defer connect because we may be in a dbus-c++ callback.
438 dispatcher_->PostTask(
439 task_factory_.NewRunnableMethod(&Cellular::ConnectTask, properties));
440}
441
442void Cellular::ConnectTask(const DBusPropertiesMap &properties) {
443 VLOG(2) << __func__;
Darin Petkovbac96002011-08-09 13:22:00 -0700444 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
Darin Petkovc5f56562011-08-06 16:40:05 -0700445 simple_proxy_->Connect(properties);
Darin Petkov0828f5f2011-08-11 10:18:52 -0700446 SetState(kStateConnected);
Darin Petkovbac96002011-08-09 13:22:00 -0700447 EstablishLink();
448}
449
450void Cellular::EstablishLink() {
451 VLOG(2) << __func__;
Darin Petkov0828f5f2011-08-11 10:18:52 -0700452 CHECK_EQ(kStateConnected, state_);
453 unsigned int flags = 0;
454 if (manager_->device_info()->GetFlags(interface_index_, &flags) &&
455 (flags & IFF_UP) != 0) {
456 LinkEvent(flags, IFF_UP);
457 return;
458 }
459 // TODO(petkov): Provide a timeout for a failed link-up request.
460 RTNLHandler::GetInstance()->SetInterfaceFlags(
461 interface_index_, IFF_UP, IFF_UP);
462}
463
464void Cellular::LinkEvent(unsigned int flags, unsigned int change) {
465 Device::LinkEvent(flags, change);
466 if ((flags & IFF_UP) != 0 && state_ == kStateConnected) {
467 LOG(INFO) << link_name_ << " is up.";
468 SetState(kStateLinked);
469 manager_->RegisterService(service_);
470 // TODO(petkov): For GSM, remember the APN.
Darin Petkov77cb6812011-08-15 16:19:41 -0700471 LOG_IF(ERROR, !AcquireDHCPConfig()) << "Unable to acquire DHCP config.";
Darin Petkov0828f5f2011-08-11 10:18:52 -0700472 } else if ((flags & IFF_UP) == 0 && state_ == kStateLinked) {
473 SetState(kStateConnected);
474 manager_->DeregisterService(service_);
Darin Petkov77cb6812011-08-15 16:19:41 -0700475 DestroyIPConfig();
Darin Petkov0828f5f2011-08-11 10:18:52 -0700476 }
Darin Petkovc5f56562011-08-06 16:40:05 -0700477}
478
Darin Petkovb27e5442011-08-16 14:36:45 -0700479void Cellular::OnCDMAActivationStateChanged(
480 uint32 activation_state,
481 uint32 activation_error,
482 const DBusPropertiesMap &status_changes) {
483 CHECK_EQ(kTypeCDMA, type_);
484 DBusProperties::GetString(status_changes, "mdn", &mdn_);
485 DBusProperties::GetString(status_changes, "min", &min_);
Darin Petkovcc044422011-08-17 13:30:06 -0700486 if (DBusProperties::GetString(
487 status_changes, "payment_url", &cdma_.payment_url) &&
Darin Petkovb27e5442011-08-16 14:36:45 -0700488 service_.get()) {
Darin Petkovcc044422011-08-17 13:30:06 -0700489 service_->set_payment_url(cdma_.payment_url);
Darin Petkovb27e5442011-08-16 14:36:45 -0700490 }
491 // TODO(petkov): Handle activation state updates.
492}
493
Darin Petkovd9661952011-08-03 16:25:42 -0700494void Cellular::OnCDMARegistrationStateChanged(uint32 state_1x,
495 uint32 state_evdo) {
496 CHECK_EQ(kTypeCDMA, type_);
497 cdma_.registration_state_1x = state_1x;
498 cdma_.registration_state_evdo = state_evdo;
499 HandleNewRegistrationState();
500}
501
502void Cellular::OnCDMASignalQualityChanged(uint32 strength) {
503 CHECK_EQ(kTypeCDMA, type_);
504 HandleNewSignalQuality(strength);
505}
506
Darin Petkovc5f56562011-08-06 16:40:05 -0700507void Cellular::OnModemStateChanged(uint32 old_state,
508 uint32 new_state,
509 uint32 reason) {
510 // TODO(petkov): Implement this.
511 NOTIMPLEMENTED();
512}
513
Chris Masone889666b2011-07-03 12:58:50 -0700514Stringmaps Cellular::EnumerateNetworks() {
515 Stringmaps to_return;
516 for (vector<Network>::const_iterator it = found_networks_.begin();
517 it != found_networks_.end();
518 ++it) {
519 to_return.push_back(it->ToDict());
520 }
521 return to_return;
522}
523
524StrIntPair Cellular::SimLockStatusToProperty() {
525 return StrIntPair(make_pair(flimflam::kSIMLockTypeProperty,
526 sim_lock_status_.lock_type),
527 make_pair(flimflam::kSIMLockRetriesLeftProperty,
528 sim_lock_status_.retries_left));
529}
530
531void Cellular::HelpRegisterDerivedStringmaps(
532 const string &name,
533 Stringmaps(Cellular::*get)(void),
534 bool(Cellular::*set)(const Stringmaps&)) {
535 store_.RegisterDerivedStringmaps(
536 name,
537 StringmapsAccessor(
538 new CustomAccessor<Cellular, Stringmaps>(this, get, set)));
539}
540
541void Cellular::HelpRegisterDerivedStrIntPair(
542 const string &name,
543 StrIntPair(Cellular::*get)(void),
544 bool(Cellular::*set)(const StrIntPair&)) {
545 store_.RegisterDerivedStrIntPair(
546 name,
547 StrIntPairAccessor(
548 new CustomAccessor<Cellular, StrIntPair>(this, get, set)));
549}
550
Chris Masone3bd3c8c2011-06-13 08:20:26 -0700551} // namespace shill