blob: 551caaa8a9823c3906985d5462b60fcb313affc1 [file] [log] [blame]
Darin Petkovdaf43862011-10-27 11:37:28 +02001// 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_capability_cdma.h"
6
7#include <base/logging.h>
Darin Petkov20c13ec2011-11-09 15:07:15 +01008#include <chromeos/dbus/service_constants.h>
9#include <mm/mm-modem.h>
Darin Petkovdaf43862011-10-27 11:37:28 +020010
11#include "shill/cellular.h"
Darin Petkov184c54e2011-11-15 12:44:39 +010012#include "shill/cellular_service.h"
Darin Petkovdaf43862011-10-27 11:37:28 +020013#include "shill/proxy_factory.h"
14
Darin Petkov20c13ec2011-11-09 15:07:15 +010015using std::string;
16
Darin Petkovdaf43862011-10-27 11:37:28 +020017namespace shill {
18
Darin Petkovae0c64e2011-11-15 15:50:27 +010019const char CellularCapabilityCDMA::kPhoneNumber[] = "#777";
20
Darin Petkovdaf43862011-10-27 11:37:28 +020021CellularCapabilityCDMA::CellularCapabilityCDMA(Cellular *cellular)
Darin Petkova3d3be52011-11-14 21:34:16 +010022 : CellularCapability(cellular),
Darin Petkov184c54e2011-11-15 12:44:39 +010023 task_factory_(this),
Darin Petkovae0c64e2011-11-15 15:50:27 +010024 activation_state_(MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED),
Darin Petkov184c54e2011-11-15 12:44:39 +010025 registration_state_evdo_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
Darin Petkovae0c64e2011-11-15 15:50:27 +010026 registration_state_1x_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
27 prl_version_(0) {
Darin Petkov5f316f62011-11-18 12:10:26 +010028 VLOG(2) << "Cellular capability constructed: CDMA";
Darin Petkovae0c64e2011-11-15 15:50:27 +010029 PropertyStore *store = cellular->mutable_store();
30 store->RegisterConstUint16(flimflam::kPRLVersionProperty, &prl_version_);
31}
Darin Petkovdaf43862011-10-27 11:37:28 +020032
Darin Petkov5f316f62011-11-18 12:10:26 +010033void CellularCapabilityCDMA::OnDeviceStarted() {
Darin Petkovdaf43862011-10-27 11:37:28 +020034 VLOG(2) << __func__;
Darin Petkov184c54e2011-11-15 12:44:39 +010035 proxy_.reset(proxy_factory()->CreateModemCDMAProxy(
36 this, cellular()->dbus_path(), cellular()->dbus_owner()));
Darin Petkovdaf43862011-10-27 11:37:28 +020037}
38
Darin Petkov5f316f62011-11-18 12:10:26 +010039void CellularCapabilityCDMA::OnDeviceStopped() {
Darin Petkov721ac932011-11-16 15:43:09 +010040 VLOG(2) << __func__;
41 proxy_.reset();
42}
43
Darin Petkov5f316f62011-11-18 12:10:26 +010044void CellularCapabilityCDMA::OnServiceCreated() {
45 VLOG(2) << __func__;
46 cellular()->service()->set_payment_url(payment_url_);
47 cellular()->service()->set_usage_url(usage_url_);
48 UpdateServingOperator();
49 HandleNewActivationState(MM_MODEM_CDMA_ACTIVATION_ERROR_NO_ERROR);
50}
51
Darin Petkovae0c64e2011-11-15 15:50:27 +010052void CellularCapabilityCDMA::UpdateStatus(const DBusPropertiesMap &properties) {
53 string carrier;
54 if (DBusProperties::GetString(properties, "carrier", &carrier)) {
55 Cellular::Operator oper;
56 oper.SetName(carrier);
57 oper.SetCountry("us");
58 cellular()->set_home_provider(oper);
59 }
60 DBusProperties::GetUint32(
61 properties, "activation_state", &activation_state_);
62 DBusProperties::GetUint16(properties, "prl_version", &prl_version_);
Darin Petkov5f316f62011-11-18 12:10:26 +010063 // TODO(petkov): For now, get the payment and usage URLs from ModemManager to
64 // match flimflam. In the future, get these from an alternative source (e.g.,
65 // database, carrier-specific properties, etc.).
Darin Petkovae0c64e2011-11-15 15:50:27 +010066 DBusProperties::GetString(properties, "payment_url", &payment_url_);
67 DBusProperties::GetString(properties, "usage_url", &usage_url_);
68}
69
70void CellularCapabilityCDMA::SetupConnectProperties(
71 DBusPropertiesMap *properties) {
72 (*properties)[Cellular::kConnectPropertyPhoneNumber].writer().append_string(
73 kPhoneNumber);
74}
75
Darin Petkova3d3be52011-11-14 21:34:16 +010076void CellularCapabilityCDMA::Activate(const string &carrier, Error *error) {
77 VLOG(2) << __func__ << "(" << carrier << ")";
78 if (cellular()->state() != Cellular::kStateEnabled &&
79 cellular()->state() != Cellular::kStateRegistered) {
80 Error::PopulateAndLog(error, Error::kInvalidArguments,
81 "Unable to activate in " +
82 Cellular::GetStateString(cellular()->state()));
83 return;
84 }
85 // Defer because we may be in a dbus-c++ callback.
86 dispatcher()->PostTask(
87 task_factory_.NewRunnableMethod(
88 &CellularCapabilityCDMA::ActivateTask, carrier));
89}
90
91void CellularCapabilityCDMA::ActivateTask(const string &carrier) {
92 VLOG(2) << __func__ << "(" << carrier << ")";
93 if (cellular()->state() != Cellular::kStateEnabled &&
94 cellular()->state() != Cellular::kStateRegistered) {
95 LOG(ERROR) << "Unable to activate in "
96 << Cellular::GetStateString(cellular()->state());
97 return;
98 }
99 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
Darin Petkov184c54e2011-11-15 12:44:39 +0100100 uint32 status = proxy_->Activate(carrier);
Darin Petkova3d3be52011-11-14 21:34:16 +0100101 if (status == MM_MODEM_CDMA_ACTIVATION_ERROR_NO_ERROR) {
Darin Petkovae0c64e2011-11-15 15:50:27 +0100102 activation_state_ = MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING;
Darin Petkova3d3be52011-11-14 21:34:16 +0100103 }
Darin Petkovae0c64e2011-11-15 15:50:27 +0100104 HandleNewActivationState(status);
105}
106
107void CellularCapabilityCDMA::HandleNewActivationState(uint32 error) {
108 if (!cellular()->service().get()) {
109 return;
110 }
111 cellular()->service()->set_activation_state(
112 GetActivationStateString(activation_state_));
113 cellular()->service()->set_error(GetActivationErrorString(error));
114}
115
116// static
117string CellularCapabilityCDMA::GetActivationStateString(uint32 state) {
118 switch (state) {
119 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATED:
120 return flimflam::kActivationStateActivated;
121 case MM_MODEM_CDMA_ACTIVATION_STATE_ACTIVATING:
122 return flimflam::kActivationStateActivating;
123 case MM_MODEM_CDMA_ACTIVATION_STATE_NOT_ACTIVATED:
124 return flimflam::kActivationStateNotActivated;
125 case MM_MODEM_CDMA_ACTIVATION_STATE_PARTIALLY_ACTIVATED:
126 return flimflam::kActivationStatePartiallyActivated;
127 default:
128 return flimflam::kActivationStateUnknown;
129 }
130}
131
132// static
133string CellularCapabilityCDMA::GetActivationErrorString(uint32 error) {
134 switch (error) {
135 case MM_MODEM_CDMA_ACTIVATION_ERROR_WRONG_RADIO_INTERFACE:
136 return flimflam::kErrorNeedEvdo;
137 case MM_MODEM_CDMA_ACTIVATION_ERROR_ROAMING:
138 return flimflam::kErrorNeedHomeNetwork;
139 case MM_MODEM_CDMA_ACTIVATION_ERROR_COULD_NOT_CONNECT:
140 case MM_MODEM_CDMA_ACTIVATION_ERROR_SECURITY_AUTHENTICATION_FAILED:
141 case MM_MODEM_CDMA_ACTIVATION_ERROR_PROVISIONING_FAILED:
142 return flimflam::kErrorOtaspFailed;
143 case MM_MODEM_CDMA_ACTIVATION_ERROR_NO_ERROR:
144 return "";
145 case MM_MODEM_CDMA_ACTIVATION_ERROR_NO_SIGNAL:
146 default:
147 return flimflam::kErrorActivationFailed;
148 }
Darin Petkova3d3be52011-11-14 21:34:16 +0100149}
150
Darin Petkovcb547732011-11-09 13:55:26 +0100151void CellularCapabilityCDMA::GetIdentifiers() {
152 VLOG(2) << __func__;
153 if (cellular()->meid().empty()) {
154 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
Darin Petkov184c54e2011-11-15 12:44:39 +0100155 cellular()->set_meid(proxy_->MEID());
Darin Petkov5f316f62011-11-18 12:10:26 +0100156 VLOG(2) << "MEID: " << cellular()->meid();
Darin Petkovcb547732011-11-09 13:55:26 +0100157 }
158}
159
Darin Petkov184c54e2011-11-15 12:44:39 +0100160void CellularCapabilityCDMA::GetProperties() {
161 VLOG(2) << __func__;
162 // No properties.
163}
164
Darin Petkov20c13ec2011-11-09 15:07:15 +0100165string CellularCapabilityCDMA::GetNetworkTechnologyString() const {
Darin Petkov184c54e2011-11-15 12:44:39 +0100166 if (registration_state_evdo_ != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
Darin Petkov20c13ec2011-11-09 15:07:15 +0100167 return flimflam::kNetworkTechnologyEvdo;
168 }
Darin Petkov184c54e2011-11-15 12:44:39 +0100169 if (registration_state_1x_ != MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
Darin Petkov20c13ec2011-11-09 15:07:15 +0100170 return flimflam::kNetworkTechnology1Xrtt;
171 }
172 return "";
173}
174
175string CellularCapabilityCDMA::GetRoamingStateString() const {
Darin Petkov184c54e2011-11-15 12:44:39 +0100176 uint32 state = registration_state_evdo_;
Darin Petkov20c13ec2011-11-09 15:07:15 +0100177 if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
Darin Petkov184c54e2011-11-15 12:44:39 +0100178 state = registration_state_1x_;
Darin Petkov20c13ec2011-11-09 15:07:15 +0100179 }
180 switch (state) {
181 case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN:
182 case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
183 break;
184 case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
185 return flimflam::kRoamingStateHome;
186 case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
187 return flimflam::kRoamingStateRoaming;
188 default:
189 NOTREACHED();
190 }
191 return flimflam::kRoamingStateUnknown;
192}
193
Darin Petkov3e509242011-11-10 14:46:44 +0100194void CellularCapabilityCDMA::GetSignalQuality() {
195 VLOG(2) << __func__;
196 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
Darin Petkov184c54e2011-11-15 12:44:39 +0100197 uint32 strength = proxy_->GetSignalQuality();
198 cellular()->HandleNewSignalQuality(strength);
199}
200
201void CellularCapabilityCDMA::GetRegistrationState() {
202 VLOG(2) << __func__;
203 // TODO(petkov): Switch to asynchronous calls (crosbug.com/17583).
204 proxy_->GetRegistrationState(
205 &registration_state_1x_, &registration_state_evdo_);
206 VLOG(2) << "CDMA Registration: 1x(" << registration_state_1x_
207 << ") EVDO(" << registration_state_evdo_ << ")";
208 cellular()->HandleNewRegistrationState();
209}
210
Darin Petkovae0c64e2011-11-15 15:50:27 +0100211void CellularCapabilityCDMA::UpdateServingOperator() {
212 VLOG(2) << __func__;
213 if (cellular()->service().get()) {
214 cellular()->service()->set_serving_operator(cellular()->home_provider());
215 }
216}
217
Darin Petkov184c54e2011-11-15 12:44:39 +0100218void CellularCapabilityCDMA::OnCDMAActivationStateChanged(
219 uint32 activation_state,
220 uint32 activation_error,
221 const DBusPropertiesMap &status_changes) {
222 VLOG(2) << __func__;
223 string mdn;
224 if (DBusProperties::GetString(status_changes, "mdn", &mdn)) {
225 cellular()->set_mdn(mdn);
226 }
227 string min;
228 if (DBusProperties::GetString(status_changes, "min", &min)) {
229 cellular()->set_min(min);
230 }
Darin Petkovae0c64e2011-11-15 15:50:27 +0100231 if (DBusProperties::GetString(status_changes, "payment_url", &payment_url_) &&
232 cellular()->service().get()) {
233 cellular()->service()->set_payment_url(payment_url_);
Darin Petkov184c54e2011-11-15 12:44:39 +0100234 }
Darin Petkovae0c64e2011-11-15 15:50:27 +0100235 activation_state_ = activation_state;
236 HandleNewActivationState(activation_error);
Darin Petkov184c54e2011-11-15 12:44:39 +0100237}
238
239void CellularCapabilityCDMA::OnCDMARegistrationStateChanged(
240 uint32 state_1x, uint32 state_evdo) {
241 VLOG(2) << __func__;
242 registration_state_1x_ = state_1x;
243 registration_state_evdo_ = state_evdo;
244 cellular()->HandleNewRegistrationState();
245}
246
Darin Petkovae0c64e2011-11-15 15:50:27 +0100247void CellularCapabilityCDMA::OnModemManagerPropertiesChanged(
248 const DBusPropertiesMap &/*properties*/) {}
249
Darin Petkov184c54e2011-11-15 12:44:39 +0100250void CellularCapabilityCDMA::OnCDMASignalQualityChanged(uint32 strength) {
Darin Petkov3e509242011-11-10 14:46:44 +0100251 cellular()->HandleNewSignalQuality(strength);
252}
253
Darin Petkovdaf43862011-10-27 11:37:28 +0200254} // namespace shill