blob: ed18c6f290db3344795d77088417898cbcd7205e [file] [log] [blame]
Jason Glasgow82f9ab32012-04-04 14:27:19 -04001// Copyright (c) 2012 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_capability_classic.h"
6
7#include <base/bind.h>
8#include <chromeos/dbus/service_constants.h>
9
10#include "shill/cellular.h"
11#include "shill/error.h"
12#include "shill/property_accessor.h"
13#include "shill/proxy_factory.h"
14
15using base::Bind;
16using base::Callback;
17using base::Closure;
18using std::string;
19
20namespace shill {
21
22const char CellularCapabilityClassic::kConnectPropertyApn[] = "apn";
23const char CellularCapabilityClassic::kConnectPropertyApnUsername[] =
24 "username";
25const char CellularCapabilityClassic::kConnectPropertyApnPassword[] =
26 "password";
27const char CellularCapabilityClassic::kConnectPropertyHomeOnly[] = "home_only";
28const char CellularCapabilityClassic::kConnectPropertyPhoneNumber[] = "number";
29
30CellularCapabilityClassic::CellularCapabilityClassic(
31 Cellular *cellular,
32 ProxyFactory *proxy_factory)
33 : CellularCapability(cellular, proxy_factory),
34 weak_ptr_factory_(this) {
35 PropertyStore *store = cellular->mutable_store();
36 store->RegisterConstString(flimflam::kCarrierProperty, &carrier_);
37 store->RegisterConstBool(flimflam::kSupportNetworkScanProperty,
38 &scanning_supported_);
39 store->RegisterConstString(flimflam::kEsnProperty, &esn_);
40 store->RegisterConstString(flimflam::kFirmwareRevisionProperty,
41 &firmware_revision_);
42 store->RegisterConstString(flimflam::kHardwareRevisionProperty,
43 &hardware_revision_);
44 store->RegisterConstString(flimflam::kImeiProperty, &imei_);
45 store->RegisterConstString(flimflam::kImsiProperty, &imsi_);
46 store->RegisterConstString(flimflam::kManufacturerProperty, &manufacturer_);
47 store->RegisterConstString(flimflam::kMdnProperty, &mdn_);
48 store->RegisterConstString(flimflam::kMeidProperty, &meid_);
49 store->RegisterConstString(flimflam::kMinProperty, &min_);
50 store->RegisterConstString(flimflam::kModelIDProperty, &model_id_);
51}
52
53CellularCapabilityClassic::~CellularCapabilityClassic() {}
54
55void CellularCapabilityClassic::InitProxies() {
56 VLOG(2) << __func__;
57 proxy_.reset(proxy_factory()->CreateModemProxy(
58 cellular()->dbus_path(), cellular()->dbus_owner()));
59 simple_proxy_.reset(proxy_factory()->CreateModemSimpleProxy(
60 cellular()->dbus_path(), cellular()->dbus_owner()));
61 proxy_->set_state_changed_callback(
62 Bind(&CellularCapabilityClassic::OnModemStateChangedSignal,
63 weak_ptr_factory_.GetWeakPtr()));
64}
65
66void CellularCapabilityClassic::ReleaseProxies() {
67 VLOG(2) << __func__;
68 proxy_.reset();
69 simple_proxy_.reset();
70}
71
72void CellularCapabilityClassic::FinishEnable(const ResultCallback &callback) {
73 callback.Run(Error());
74 GetRegistrationState();
75 GetSignalQuality();
76}
77
78void CellularCapabilityClassic::FinishDisable(const ResultCallback &callback) {
79 ReleaseProxies();
80 callback.Run(Error());
81}
82
83void CellularCapabilityClassic::OnUnsupportedOperation(
84 const char *operation,
85 Error *error) {
86 string message("The ");
87 message.append(operation).append(" operation is not supported.");
88 Error::PopulateAndLog(error, Error::kNotSupported, message);
89}
90
91// always called from an async context
92void CellularCapabilityClassic::EnableModem(const ResultCallback &callback) {
93 VLOG(2) << __func__;
94 CHECK(!callback.is_null());
95 Error error;
96 proxy_->Enable(true, &error, callback, kTimeoutEnable);
97 if (error.IsFailure())
98 callback.Run(error);
99}
100
101// always called from an async context
102void CellularCapabilityClassic::DisableModem(const ResultCallback &callback) {
103 VLOG(2) << __func__;
104 CHECK(!callback.is_null());
105 Error error;
106 proxy_->Enable(false, &error, callback, kTimeoutDefault);
107 if (error.IsFailure())
108 callback.Run(error);
109}
110
111// always called from an async context
112void CellularCapabilityClassic::GetModemStatus(const ResultCallback &callback) {
113 VLOG(2) << __func__;
114 CHECK(!callback.is_null());
115 DBusPropertyMapCallback cb = Bind(
116 &CellularCapabilityClassic::OnGetModemStatusReply,
117 weak_ptr_factory_.GetWeakPtr(), callback);
118 Error error;
119 simple_proxy_->GetModemStatus(&error, cb, kTimeoutDefault);
120 if (error.IsFailure())
121 callback.Run(error);
122}
123
124// always called from an async context
125void CellularCapabilityClassic::GetModemInfo(const ResultCallback &callback) {
126 VLOG(2) << __func__;
127 CHECK(!callback.is_null());
128 ModemInfoCallback cb = Bind(&CellularCapabilityClassic::OnGetModemInfoReply,
129 weak_ptr_factory_.GetWeakPtr(), callback);
130 Error error;
131 proxy_->GetModemInfo(&error, cb, kTimeoutDefault);
132 if (error.IsFailure())
133 callback.Run(error);
134}
135
136void CellularCapabilityClassic::StopModem(Error *error,
137 const ResultCallback &callback) {
138 VLOG(2) << __func__;
139
140 CellularTaskList *tasks = new CellularTaskList();
141 ResultCallback cb =
142 Bind(&CellularCapabilityClassic::StepCompletedCallback,
143 weak_ptr_factory_.GetWeakPtr(), callback, false, tasks);
144 ResultCallback cb_ignore_error =
145 Bind(&CellularCapabilityClassic::StepCompletedCallback,
146 weak_ptr_factory_.GetWeakPtr(), callback, true, tasks);
147 tasks->push_back(Bind(&CellularCapabilityClassic::Disconnect,
148 weak_ptr_factory_.GetWeakPtr(),
149 static_cast<Error *>(NULL), cb_ignore_error));
150 tasks->push_back(Bind(&CellularCapabilityClassic::DisableModem,
151 weak_ptr_factory_.GetWeakPtr(), cb));
152 tasks->push_back(Bind(&CellularCapabilityClassic::FinishDisable,
153 weak_ptr_factory_.GetWeakPtr(), cb));
154
155 RunNextStep(tasks);
156}
157
158void CellularCapabilityClassic::Connect(const DBusPropertiesMap &properties,
159 Error *error,
160 const ResultCallback &callback) {
161 VLOG(2) << __func__;
162 ResultCallback cb = Bind(&CellularCapabilityClassic::OnConnectReply,
163 weak_ptr_factory_.GetWeakPtr(),
164 callback);
165 simple_proxy_->Connect(properties, error, cb, kTimeoutConnect);
166}
167
168void CellularCapabilityClassic::Disconnect(Error *error,
169 const ResultCallback &callback) {
170 VLOG(2) << __func__;
171 ResultCallback cb = Bind(&CellularCapabilityClassic::OnDisconnectReply,
172 weak_ptr_factory_.GetWeakPtr(),
173 callback);
174 proxy_->Disconnect(error, cb, kTimeoutDefault);
175}
176
177void CellularCapabilityClassic::Activate(const string &/*carrier*/,
178 Error *error,
179 const ResultCallback &/*callback*/) {
180 OnUnsupportedOperation(__func__, error);
181}
182
183void CellularCapabilityClassic::RegisterOnNetwork(
184 const string &/*network_id*/,
185 Error *error, const ResultCallback &/*callback*/) {
186 OnUnsupportedOperation(__func__, error);
187}
188
189void CellularCapabilityClassic::RequirePIN(const std::string &/*pin*/,
190 bool /*require*/,
191 Error *error,
192 const ResultCallback &/*callback*/) {
193 OnUnsupportedOperation(__func__, error);
194}
195
196void CellularCapabilityClassic::EnterPIN(const string &/*pin*/,
197 Error *error,
198 const ResultCallback &/*callback*/) {
199 OnUnsupportedOperation(__func__, error);
200}
201
202void CellularCapabilityClassic::UnblockPIN(const string &/*unblock_code*/,
203 const string &/*pin*/,
204 Error *error,
205 const ResultCallback &/*callback*/) {
206 OnUnsupportedOperation(__func__, error);
207}
208
209void CellularCapabilityClassic::ChangePIN(const string &/*old_pin*/,
210 const string &/*new_pin*/,
211 Error *error,
212 const ResultCallback &/*callback*/) {
213 OnUnsupportedOperation(__func__, error);
214}
215
216void CellularCapabilityClassic::Scan(Error *error,
217 const ResultCallback &callback) {
218 OnUnsupportedOperation(__func__, error);
219}
220
Jason Glasgow82f9ab32012-04-04 14:27:19 -0400221void CellularCapabilityClassic::OnGetModemStatusReply(
222 const ResultCallback &callback,
223 const DBusPropertiesMap &props,
224 const Error &error) {
225 VLOG(2) << __func__ << " " << props.size() << " props. error " << error;
226 if (error.IsSuccess()) {
227 DBusProperties::GetString(props, "carrier", &carrier_);
228 DBusProperties::GetString(props, "meid", &meid_);
229 DBusProperties::GetString(props, "imei", &imei_);
230 DBusProperties::GetString(props, kPropertyIMSI, &imsi_);
231 DBusProperties::GetString(props, "esn", &esn_);
232 DBusProperties::GetString(props, "mdn", &mdn_);
233 DBusProperties::GetString(props, "min", &min_);
234 DBusProperties::GetString(props, "firmware_revision", &firmware_revision_);
235
236 uint32 state;
237 if (DBusProperties::GetUint32(props, "state", &state))
238 cellular()->set_modem_state(static_cast<Cellular::ModemState>(state));
239
240 UpdateStatus(props);
241 }
242 callback.Run(error);
243}
244
245void CellularCapabilityClassic::OnGetModemInfoReply(
246 const ResultCallback &callback,
247 const ModemHardwareInfo &info,
248 const Error &error) {
249 VLOG(2) << __func__ << "(" << error << ")";
250 if (error.IsSuccess()) {
251 manufacturer_ = info._1;
252 model_id_ = info._2;
253 hardware_revision_ = info._3;
254 VLOG(2) << __func__ << ": " << info._1 << ", " << info._2 << ", "
255 << info._3;
256 }
257 callback.Run(error);
258}
259
260// TODO(ers): use the supplied callback when Connect is fully asynchronous
261void CellularCapabilityClassic::OnConnectReply(const ResultCallback &callback,
262 const Error &error) {
263 VLOG(2) << __func__ << "(" << error << ")";
264 if (error.IsSuccess())
265 cellular()->OnConnected();
266 else
267 cellular()->OnConnectFailed(error);
268 if (!callback.is_null())
269 callback.Run(error);
270}
271
272// TODO(ers): use the supplied callback when Disonnect is fully asynchronous
273void CellularCapabilityClassic::OnDisconnectReply(
274 const ResultCallback &callback,
275 const Error &error) {
276 VLOG(2) << __func__ << "(" << error << ")";
277 if (error.IsSuccess())
278 cellular()->OnDisconnected();
279 else
280 cellular()->OnDisconnectFailed();
281 if (!callback.is_null())
282 callback.Run(error);
283}
284
285void CellularCapabilityClassic::OnModemStateChangedSignal(
286 uint32 old_state, uint32 new_state, uint32 reason) {
287 VLOG(2) << __func__ << "(" << old_state << ", " << new_state << ", "
288 << reason << ")";
289 // TODO(petkov): Complete this (crosbug.com/19662)
290#if 0
291 modem_state_ = static_cast<ModemState>(new_state);
292 if (old_state == new_state) {
293 return;
294 }
295 switch (new_state) {
296 case kModemStateEnabled:
297 if (old_state == kModemStateDisabled ||
298 old_state == kModemStateEnabling) {
299 Start();
300 }
301 // TODO(petkov): Handle the case when the state is downgraded to Enabled.
302 break;
303 default:
304 break;
305 }
306#endif
307}
308
309} // namespace shill