blob: 801f6885be5b15a565a76b2e31058d102ef035bd [file] [log] [blame]
Darin Petkovac635a82012-01-10 16:51:58 +01001// Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
Darin Petkovdaf43862011-10-27 11:37:28 +02002// 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_cdma.h"
6
Eric Shienbrood3e20a232012-02-16 11:35:56 -05007#include <base/bind.h>
Darin Petkovdaf43862011-10-27 11:37:28 +02008#include <base/logging.h>
Darin Petkovac635a82012-01-10 16:51:58 +01009#include <base/stringprintf.h>
Darin Petkov20c13ec2011-11-09 15:07:15 +010010#include <chromeos/dbus/service_constants.h>
11#include <mm/mm-modem.h>
Darin Petkovdaf43862011-10-27 11:37:28 +020012
13#include "shill/cellular.h"
Darin Petkov184c54e2011-11-15 12:44:39 +010014#include "shill/cellular_service.h"
Darin Petkovdaf43862011-10-27 11:37:28 +020015#include "shill/proxy_factory.h"
16
Eric Shienbrood3e20a232012-02-16 11:35:56 -050017using base::Bind;
Darin Petkov20c13ec2011-11-09 15:07:15 +010018using std::string;
19
Darin Petkovdaf43862011-10-27 11:37:28 +020020namespace shill {
21
Darin Petkovac635a82012-01-10 16:51:58 +010022// static
23unsigned int CellularCapabilityCDMA::friendly_service_name_id_ = 0;
24
Darin Petkovae0c64e2011-11-15 15:50:27 +010025const char CellularCapabilityCDMA::kPhoneNumber[] = "#777";
26
Eric Shienbrood5de44ab2011-12-05 10:46:27 -050027CellularCapabilityCDMA::CellularCapabilityCDMA(Cellular *cellular,
28 ProxyFactory *proxy_factory)
Jason Glasgow82f9ab32012-04-04 14:27:19 -040029 : CellularCapabilityClassic(cellular, proxy_factory),
Eric Shienbrood3e20a232012-02-16 11:35:56 -050030 weak_ptr_factory_(this),
Darin Petkovae0c64e2011-11-15 15:50:27 +010031 activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
Darin Petkov184c54e2011-11-15 12:44:39 +010032 registration_state_evdo_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
Darin Petkovae0c64e2011-11-15 15:50:27 +010033 registration_state_1x_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
34 prl_version_(0) {
Darin Petkov5f316f62011-11-18 12:10:26 +010035 VLOG(2) << "Cellular capability constructed: CDMA";
Darin Petkovae0c64e2011-11-15 15:50:27 +010036 PropertyStore *store = cellular->mutable_store();
37 store->RegisterConstUint16(flimflam::kPRLVersionProperty, &prl_version_);
38}
Darin Petkovdaf43862011-10-27 11:37:28 +020039
Eric Shienbrood9a245532012-03-07 14:20:39 -050040void CellularCapabilityCDMA::InitProxies() {
Jason Glasgow82f9ab32012-04-04 14:27:19 -040041 CellularCapabilityClassic::InitProxies();
Darin Petkov184c54e2011-11-15 12:44:39 +010042 proxy_.reset(proxy_factory()->CreateModemCDMAProxy(
Eric Shienbrood9a245532012-03-07 14:20:39 -050043 cellular()->dbus_path(), cellular()->dbus_owner()));
44 proxy_->set_signal_quality_callback(
45 Bind(&CellularCapabilityCDMA::OnSignalQualitySignal,
46 weak_ptr_factory_.GetWeakPtr()));
47 proxy_->set_activation_state_callback(
48 Bind(&CellularCapabilityCDMA::OnActivationStateChangedSignal,
49 weak_ptr_factory_.GetWeakPtr()));
50 proxy_->set_registration_state_callback(
51 Bind(&CellularCapabilityCDMA::OnRegistrationStateChangedSignal,
52 weak_ptr_factory_.GetWeakPtr()));
Darin Petkovdaf43862011-10-27 11:37:28 +020053}
54
Eric Shienbrood9a245532012-03-07 14:20:39 -050055void CellularCapabilityCDMA::StartModem(Error *error,
56 const ResultCallback &callback) {
Darin Petkov721ac932011-11-16 15:43:09 +010057 VLOG(2) << __func__;
Eric Shienbrood9a245532012-03-07 14:20:39 -050058 InitProxies();
59
60 CellularTaskList *tasks = new CellularTaskList();
61 ResultCallback cb =
62 Bind(&CellularCapabilityCDMA::StepCompletedCallback,
Thieu Le923006b2012-04-05 16:32:58 -070063 weak_ptr_factory_.GetWeakPtr(), callback, false, tasks);
Eric Shienbrood9a245532012-03-07 14:20:39 -050064 tasks->push_back(Bind(&CellularCapabilityCDMA::EnableModem,
65 weak_ptr_factory_.GetWeakPtr(), cb));
66 tasks->push_back(Bind(&CellularCapabilityCDMA::GetModemStatus,
67 weak_ptr_factory_.GetWeakPtr(), cb));
68 tasks->push_back(Bind(&CellularCapabilityCDMA::GetMEID,
69 weak_ptr_factory_.GetWeakPtr(), cb));
70 tasks->push_back(Bind(&CellularCapabilityCDMA::GetModemInfo,
71 weak_ptr_factory_.GetWeakPtr(), cb));
72 tasks->push_back(Bind(&CellularCapabilityCDMA::FinishEnable,
73 weak_ptr_factory_.GetWeakPtr(), cb));
74
75 RunNextStep(tasks);
76}
77
Eric Shienbrood9a245532012-03-07 14:20:39 -050078void CellularCapabilityCDMA::ReleaseProxies() {
Jason Glasgow82f9ab32012-04-04 14:27:19 -040079 CellularCapabilityClassic::ReleaseProxies();
Darin Petkov721ac932011-11-16 15:43:09 +010080 proxy_.reset();
81}
82
Jason Glasgow82f9ab32012-04-04 14:27:19 -040083bool CellularCapabilityCDMA::AllowRoaming() {
84 return allow_roaming_property();
85}
86
87
Darin Petkov5f316f62011-11-18 12:10:26 +010088void CellularCapabilityCDMA::OnServiceCreated() {
89 VLOG(2) << __func__;
Darin Petkov381928f2012-02-02 23:00:12 +010090 cellular()->service()->SetOLP(olp_);
91 cellular()->service()->SetUsageURL(usage_url_);
Darin Petkov5f316f62011-11-18 12:10:26 +010092 UpdateServingOperator();
93 HandleNewActivationState(MM_MODEM_CDMA_ACTIVATION_ERROR_NO_ERROR);
94}
95
Darin Petkovae0c64e2011-11-15 15:50:27 +010096void CellularCapabilityCDMA::UpdateStatus(const DBusPropertiesMap &properties) {
97 string carrier;
98 if (DBusProperties::GetString(properties, "carrier", &carrier)) {
99 Cellular::Operator oper;
100 oper.SetName(carrier);
101 oper.SetCountry("us");
102 cellular()->set_home_provider(oper);
103 }
104 DBusProperties::GetUint32(
105 properties, "activation_state", &activation_state_);
106 DBusProperties::GetUint16(properties, "prl_version", &prl_version_);
Darin Petkov5f316f62011-11-18 12:10:26 +0100107 // TODO(petkov): For now, get the payment and usage URLs from ModemManager to
108 // match flimflam. In the future, get these from an alternative source (e.g.,
109 // database, carrier-specific properties, etc.).
Darin Petkov381928f2012-02-02 23:00:12 +0100110 string payment;
111 if (DBusProperties::GetString(properties, "payment_url", &payment)) {
112 olp_.SetURL(payment);
113 }
114 if (DBusProperties::GetString(properties, "payment_url_method", &payment)) {
115 olp_.SetMethod(payment);
116 }
117 if (DBusProperties::GetString(properties, "payment_url_postdata", &payment)) {
118 olp_.SetPostData(payment);
119 }
Darin Petkovae0c64e2011-11-15 15:50:27 +0100120 DBusProperties::GetString(properties, "usage_url", &usage_url_);
121}
122
123void CellularCapabilityCDMA::SetupConnectProperties(
124 DBusPropertiesMap *properties) {
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500125 (*properties)[kConnectPropertyPhoneNumber].writer().append_string(
Darin Petkovae0c64e2011-11-15 15:50:27 +0100126 kPhoneNumber);
127}
128
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500129void CellularCapabilityCDMA::Activate(const string &carrier,
Eric Shienbrood9a245532012-03-07 14:20:39 -0500130 Error *error,
131 const ResultCallback &callback) {
Darin Petkova3d3be52011-11-14 21:34:16 +0100132 VLOG(2) << __func__ << "(" << carrier << ")";
133 if (cellular()->state() != Cellular::kStateEnabled &&
134 cellular()->state() != Cellular::kStateRegistered) {
Eric Shienbrood9a245532012-03-07 14:20:39 -0500135 Error::PopulateAndLog(error, Error::kInvalidArguments,
Darin Petkova3d3be52011-11-14 21:34:16 +0100136 "Unable to activate in " +
137 Cellular::GetStateString(cellular()->state()));
138 return;
139 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500140 ActivationResultCallback cb = Bind(&CellularCapabilityCDMA::OnActivateReply,
141 weak_ptr_factory_.GetWeakPtr(), callback);
142 proxy_->Activate(carrier, error, cb, kTimeoutActivate);
Darin Petkovae0c64e2011-11-15 15:50:27 +0100143}
144
145void CellularCapabilityCDMA::HandleNewActivationState(uint32 error) {
146 if (!cellular()->service().get()) {
147 return;
148 }
Darin Petkovb9c99332012-01-12 13:13:00 +0100149 cellular()->service()->SetActivationState(
Darin Petkovae0c64e2011-11-15 15:50:27 +0100150 GetActivationStateString(activation_state_));
151 cellular()->service()->set_error(GetActivationErrorString(error));
152}
153
154// static
155string CellularCapabilityCDMA::GetActivationStateString(uint32 state) {
156 switch (state) {
157 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
158 return flimflam::kActivationStateActivated;
159 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
160 return flimflam::kActivationStateActivating;
161 case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
162 return flimflam::kActivationStateNotActivated;
163 case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED:
164 return flimflam::kActivationStatePartiallyActivated;
165 default:
166 return flimflam::kActivationStateUnknown;
167 }
168}
169
170// static
171string CellularCapabilityCDMA::GetActivationErrorString(uint32 error) {
172 switch (error) {
173 case MM_MODEM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE:
174 return flimflam::kErrorNeedEvdo;
175 case MM_MODEM_CDMA_ACTIVATION_ERROR_ROAMING:
176 return flimflam::kErrorNeedHomeNetwork;
177 case MM_MODEM_CDMA_ACTIVATION_ERROR_COULD_NOT_CONNECT:
178 case MM_MODEM_CDMA_ACTIVATION_ERROR_SECURITY_AUTHENTICATION_FAILED:
179 case MM_MODEM_CDMA_ACTIVATION_ERROR_PROVISIONING_FAILED:
180 return flimflam::kErrorOtaspFailed;
181 case MM_MODEM_CDMA_ACTIVATION_ERROR_NO_ERROR:
182 return "";
183 case MM_MODEM_CDMA_ACTIVATION_ERROR_NO_SIGNAL:
184 default:
185 return flimflam::kErrorActivationFailed;
186 }
Darin Petkova3d3be52011-11-14 21:34:16 +0100187}
188
Eric Shienbrood9a245532012-03-07 14:20:39 -0500189void CellularCapabilityCDMA::GetMEID(const ResultCallback &callback) {
Darin Petkovcb547732011-11-09 13:55:26 +0100190 VLOG(2) << __func__;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500191 if (meid_.empty()) {
Darin Petkovcb547732011-11-09 13:55:26 +0100192 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500193 meid_ = proxy_->MEID();
194 VLOG(2) << "MEID: " << meid_;
Darin Petkovcb547732011-11-09 13:55:26 +0100195 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500196 callback.Run(Error());
Darin Petkovcb547732011-11-09 13:55:26 +0100197}
198
Eric Shienbrood9a245532012-03-07 14:20:39 -0500199void CellularCapabilityCDMA::GetProperties(const ResultCallback &callback) {
Darin Petkov184c54e2011-11-15 12:44:39 +0100200 VLOG(2) << __func__;
201 // No properties.
Eric Shienbrood9a245532012-03-07 14:20:39 -0500202 callback.Run(Error());
Darin Petkov184c54e2011-11-15 12:44:39 +0100203}
204
Darin Petkovb72cf402011-11-22 14:51:39 +0100205bool CellularCapabilityCDMA::IsRegistered() {
206 return registration_state_evdo_ != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN ||
207 registration_state_1x_ != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
208}
209
Darin Petkov20c13ec2011-11-09 15:07:15 +0100210string CellularCapabilityCDMA::GetNetworkTechnologyString() const {
Darin Petkov184c54e2011-11-15 12:44:39 +0100211 if (registration_state_evdo_ != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
Darin Petkov20c13ec2011-11-09 15:07:15 +0100212 return flimflam::kNetworkTechnologyEvdo;
213 }
Darin Petkov184c54e2011-11-15 12:44:39 +0100214 if (registration_state_1x_ != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
Darin Petkov20c13ec2011-11-09 15:07:15 +0100215 return flimflam::kNetworkTechnology1Xrtt;
216 }
217 return "";
218}
219
220string CellularCapabilityCDMA::GetRoamingStateString() const {
Darin Petkov184c54e2011-11-15 12:44:39 +0100221 uint32 state = registration_state_evdo_;
Darin Petkov20c13ec2011-11-09 15:07:15 +0100222 if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
Darin Petkov184c54e2011-11-15 12:44:39 +0100223 state = registration_state_1x_;
Darin Petkov20c13ec2011-11-09 15:07:15 +0100224 }
225 switch (state) {
226 case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN:
227 case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
228 break;
229 case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
230 return flimflam::kRoamingStateHome;
231 case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
232 return flimflam::kRoamingStateRoaming;
233 default:
234 NOTREACHED();
235 }
236 return flimflam::kRoamingStateUnknown;
237}
238
Darin Petkov3e509242011-11-10 14:46:44 +0100239void CellularCapabilityCDMA::GetSignalQuality() {
240 VLOG(2) << __func__;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500241 SignalQualityCallback callback =
242 Bind(&CellularCapabilityCDMA::OnGetSignalQualityReply,
243 weak_ptr_factory_.GetWeakPtr());
244 proxy_->GetSignalQuality(NULL, callback, kTimeoutDefault);
Darin Petkov184c54e2011-11-15 12:44:39 +0100245}
246
Eric Shienbrood9a245532012-03-07 14:20:39 -0500247void CellularCapabilityCDMA::GetRegistrationState() {
Darin Petkov184c54e2011-11-15 12:44:39 +0100248 VLOG(2) << __func__;
Eric Shienbrood9a245532012-03-07 14:20:39 -0500249 RegistrationStateCallback callback =
250 Bind(&CellularCapabilityCDMA::OnGetRegistrationStateReply,
251 weak_ptr_factory_.GetWeakPtr());
252 proxy_->GetRegistrationState(NULL, callback, kTimeoutDefault);
Darin Petkov184c54e2011-11-15 12:44:39 +0100253}
254
Darin Petkovac635a82012-01-10 16:51:58 +0100255string CellularCapabilityCDMA::CreateFriendlyServiceName() {
256 VLOG(2) << __func__;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500257 if (!carrier_.empty()) {
258 return carrier_;
Darin Petkovac635a82012-01-10 16:51:58 +0100259 }
260 return base::StringPrintf("CDMANetwork%u", friendly_service_name_id_++);
261}
262
Darin Petkovae0c64e2011-11-15 15:50:27 +0100263void CellularCapabilityCDMA::UpdateServingOperator() {
264 VLOG(2) << __func__;
265 if (cellular()->service().get()) {
Darin Petkov9cb02682012-01-28 00:17:38 +0100266 cellular()->service()->SetServingOperator(cellular()->home_provider());
Darin Petkovae0c64e2011-11-15 15:50:27 +0100267 }
268}
269
Eric Shienbrood9a245532012-03-07 14:20:39 -0500270void CellularCapabilityCDMA::OnActivateReply(
271 const ResultCallback &callback, uint32 status, const Error &error) {
272 if (error.IsSuccess()) {
273 if (status == MM_MODEM_CDMA_ACTIVATION_ERROR_NO_ERROR) {
274 activation_state_ = MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING;
275 }
276 HandleNewActivationState(status);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500277 }
Eric Shienbrood9a245532012-03-07 14:20:39 -0500278 callback.Run(error);
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500279}
280
Eric Shienbrood9a245532012-03-07 14:20:39 -0500281void CellularCapabilityCDMA::OnGetRegistrationStateReply(
282 uint32 state_1x, uint32 state_evdo, const Error &error) {
283 VLOG(2) << __func__;
284 if (error.IsSuccess())
285 OnRegistrationStateChangedSignal(state_1x, state_evdo);
286}
287
288void CellularCapabilityCDMA::OnGetSignalQualityReply(uint32 quality,
289 const Error &error) {
290 if (error.IsSuccess())
291 OnSignalQualitySignal(quality);
292}
293
294void CellularCapabilityCDMA::OnActivationStateChangedSignal(
Darin Petkov184c54e2011-11-15 12:44:39 +0100295 uint32 activation_state,
296 uint32 activation_error,
297 const DBusPropertiesMap &status_changes) {
298 VLOG(2) << __func__;
Eric Shienbrood5de44ab2011-12-05 10:46:27 -0500299 DBusProperties::GetString(status_changes, "mdn", &mdn_);
300 DBusProperties::GetString(status_changes, "min", &min_);
Darin Petkov381928f2012-02-02 23:00:12 +0100301 string payment;
302 if (DBusProperties::GetString(status_changes, "payment_url", &payment)) {
303 olp_.SetURL(payment);
304 }
305 if (DBusProperties::GetString(
306 status_changes, "payment_url_method", &payment)) {
307 olp_.SetMethod(payment);
308 }
309 if (DBusProperties::GetString(
310 status_changes, "payment_url_postdata", &payment)) {
311 olp_.SetPostData(payment);
312 }
313 if (cellular()->service().get()) {
314 cellular()->service()->SetOLP(olp_);
Darin Petkov184c54e2011-11-15 12:44:39 +0100315 }
Darin Petkovae0c64e2011-11-15 15:50:27 +0100316 activation_state_ = activation_state;
317 HandleNewActivationState(activation_error);
Darin Petkov184c54e2011-11-15 12:44:39 +0100318}
319
Eric Shienbrood9a245532012-03-07 14:20:39 -0500320void CellularCapabilityCDMA::OnRegistrationStateChangedSignal(
Darin Petkov184c54e2011-11-15 12:44:39 +0100321 uint32 state_1x, uint32 state_evdo) {
322 VLOG(2) << __func__;
323 registration_state_1x_ = state_1x;
324 registration_state_evdo_ = state_evdo;
325 cellular()->HandleNewRegistrationState();
326}
327
Darin Petkovae0c64e2011-11-15 15:50:27 +0100328void CellularCapabilityCDMA::OnModemManagerPropertiesChanged(
329 const DBusPropertiesMap &/*properties*/) {}
330
Eric Shienbrood9a245532012-03-07 14:20:39 -0500331void CellularCapabilityCDMA::OnSignalQualitySignal(uint32 strength) {
Darin Petkov3e509242011-11-10 14:46:44 +0100332 cellular()->HandleNewSignalQuality(strength);
333}
334
Darin Petkovdaf43862011-10-27 11:37:28 +0200335} // namespace shill