blob: 69e9bf12e85c192cc0917c46b76e1ba57f0957ce [file] [log] [blame]
Arman Uguray72fab6a2013-01-10 19:32:42 -08001// Copyright (c) 2013 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_universal_cdma.h"
6
7#include <chromeos/dbus/service_constants.h>
8#include <base/stringprintf.h>
9#include <base/string_number_conversions.h>
10#include <base/string_util.h>
11
12#include "shill/cellular_operator_info.h"
13#include "shill/dbus_properties_proxy_interface.h"
14#include "shill/logging.h"
15#include "shill/proxy_factory.h"
16
17#ifdef MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN
18#error "Do not include mm-modem.h"
19#endif
20
21using base::UintToString;
22
23using std::string;
24using std::vector;
25
26namespace shill {
27
28namespace {
29
30string FormattedSID(const string &sid) {
31 return "[SID=" + sid + "]";
32}
33
34} // namespace
35
36// static
37unsigned int
38CellularCapabilityUniversalCDMA::friendly_service_name_id_cdma_ = 0;
39
40CellularCapabilityUniversalCDMA::CellularCapabilityUniversalCDMA(
41 Cellular *cellular,
42 ProxyFactory *proxy_factory,
43 ModemInfo *modem_info)
44 : CellularCapabilityUniversal(cellular,
45 proxy_factory,
46 modem_info),
47 cdma_1x_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
48 cdma_evdo_registration_state_(MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN),
49 nid_(0),
50 sid_(0) {
51 SLOG(Cellular, 2) << "Cellular capability constructed: Universal CDMA";
52 // TODO(armansito): Need to expose PRL version here to carry through
53 // activation. PRL version is not obtainable from ModemManager and will
54 // need to be stored in a special place (such as CellularOperatorInfo).
55 // See crbug.com/197330.
56}
57
58void CellularCapabilityUniversalCDMA::InitProxies() {
59 SLOG(Cellular, 2) << __func__;
60 modem_cdma_proxy_.reset(
61 proxy_factory()->CreateMM1ModemModemCdmaProxy(cellular()->dbus_path(),
62 cellular()->dbus_owner()));
63 CellularCapabilityUniversal::InitProxies();
64}
65
66void CellularCapabilityUniversalCDMA::ReleaseProxies() {
67 SLOG(Cellular, 2) << __func__;
68 modem_cdma_proxy_.reset();
69 CellularCapabilityUniversal::ReleaseProxies();
70}
71
72void CellularCapabilityUniversalCDMA::Activate(
73 const string &carrier,
74 Error *error,
75 const ResultCallback &callback) {
76 // TODO(armansito): Implement activation.
77 OnUnsupportedOperation(__func__, error);
78}
79
80void CellularCapabilityUniversalCDMA::CompleteActivation(Error *error) {
81 // TODO(armansito): Implement activation.
82 OnUnsupportedOperation(__func__, error);
83}
84
85void CellularCapabilityUniversalCDMA::DisconnectCleanup() {
86 SLOG(Cellular, 2) << __func__;
87 // TODO(armansito): Handle activation logic here.
88}
89
90void CellularCapabilityUniversalCDMA::OnServiceCreated() {
91 SLOG(Cellular, 2) << __func__;
92 // TODO (armansito): Set storage identifier here based on the superclass
93 // implementation.
94 bool activation_required = IsServiceActivationRequired();
95 cellular()->service()->SetActivationState(
96 activation_required ?
97 flimflam::kActivationStateNotActivated :
98 flimflam::kActivationStateActivated);
99 cellular()->service()->SetActivateOverNonCellularNetwork(activation_required);
100 UpdateServingOperator();
101 UpdateOLP();
102}
103
104void CellularCapabilityUniversalCDMA::UpdateOLP() {
105 SLOG(Cellular,2) << __func__;
106 if (!modem_info()->cellular_operator_info())
107 return;
108
109 const CellularService::OLP *result =
110 modem_info()->cellular_operator_info()->GetOLPBySID(
111 UintToString(sid_));
112 if (!result)
113 return;
114
115 CellularService::OLP olp;
116 olp.CopyFrom(*result);
117 string post_data = olp.GetPostData();
118 ReplaceSubstringsAfterOffset(&post_data, 0, "${esn}", esn());
119 ReplaceSubstringsAfterOffset(&post_data, 0, "${mdn}", mdn());
120 ReplaceSubstringsAfterOffset(&post_data, 0, "${meid}", meid());
121 olp.SetPostData(post_data);
122 cellular()->service()->SetOLP(olp);
123}
124
125void CellularCapabilityUniversalCDMA::GetProperties() {
126 SLOG(Cellular, 2) << __func__;
127 CellularCapabilityUniversal::GetProperties();
128
129 scoped_ptr<DBusPropertiesProxyInterface> properties_proxy(
130 proxy_factory()->CreateDBusPropertiesProxy(cellular()->dbus_path(),
131 cellular()->dbus_owner()));
132 DBusPropertiesMap properties(
133 properties_proxy->GetAll(MM_DBUS_INTERFACE_MODEM_MODEMCDMA));
134 OnModemCDMAPropertiesChanged(properties, vector<string>());
135}
136
137string CellularCapabilityUniversalCDMA::CreateFriendlyServiceName() {
138 SLOG(Cellular, 2) << __func__ << ": " << GetRoamingStateString();
139
140 if (provider_.GetCode().empty()) {
141 UpdateOperatorInfo();
142 }
143
144 string name = provider_.GetName();
145 if (!name.empty()) {
146 // TODO(armansito): We may need to show the provider name in a
147 // specific way if roaming.
148 return name;
149 }
150
151 string code = provider_.GetCode();
152 if (!code.empty()) {
153 return "cellular_sid_" + code;
154 }
155
156 return base::StringPrintf("CDMANetwork%u", friendly_service_name_id_cdma_++);
157}
158
159void CellularCapabilityUniversalCDMA::UpdateOperatorInfo() {
160 SLOG(Cellular, 2) << __func__;
161
162 if (sid_ == 0 || !modem_info()->cellular_operator_info()) {
163 SLOG(Cellular, 2) << "No provider is currently available.";
164 provider_.SetCode("");
165 return;
166 }
167
168 string sid = UintToString(sid_);
169 const CellularOperatorInfo::CellularOperator *provider =
170 modem_info()->cellular_operator_info()->GetCellularOperatorBySID(sid);
171 if (!provider) {
172 SLOG(Cellular, 2) << "CDMA provider with "
173 << FormattedSID(sid)
174 << " not found.";
175 return;
176 }
177
178 if (!provider->name_list().empty()) {
179 provider_.SetName(provider->name_list()[0].name);
180 }
181 provider_.SetCode(sid);
182 provider_.SetCountry(provider->country());
183
184 // TODO(armansito): The CDMA interface only returns information about the
185 // current serving carrier, so for now both the home provider and the
186 // serving operator will be the same in case of roaming. We should figure
187 // out if there is a way to (and whether or not it is necessary to)
188 // determine if we're roaming.
189 cellular()->set_home_provider(provider_);
190
191 UpdateServingOperator();
192}
193
194void CellularCapabilityUniversalCDMA::UpdateServingOperator() {
195 SLOG(Cellular, 2) << __func__;
196 if (cellular()->service().get()) {
197 cellular()->service()->SetServingOperator(cellular()->home_provider());
198 }
199}
200
201void CellularCapabilityUniversalCDMA::Register(const ResultCallback &callback) {
202 // TODO(armansito): Remove once 3GPP is implemented in its own class.
203}
204
205void CellularCapabilityUniversalCDMA::RegisterOnNetwork(
206 const string &network_id,
207 Error *error,
208 const ResultCallback &callback) {
209 // TODO(armansito): Remove once 3GPP is implemented in its own class.
210}
211
212bool CellularCapabilityUniversalCDMA::IsRegistered() {
213 return (cdma_1x_registration_state_ ==
214 MM_MODEM_CDMA_REGISTRATION_STATE_HOME ||
215 cdma_1x_registration_state_ ==
216 MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING ||
217 cdma_evdo_registration_state_ ==
218 MM_MODEM_CDMA_REGISTRATION_STATE_HOME ||
219 cdma_evdo_registration_state_ ==
220 MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING);
221}
222
223void CellularCapabilityUniversalCDMA::SetUnregistered(bool /*searching*/) {
224 cdma_1x_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
225 cdma_evdo_registration_state_ = MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN;
226}
227
228void CellularCapabilityUniversalCDMA::RequirePIN(
229 const string &pin, bool require,
230 Error *error, const ResultCallback &callback) {
231 // TODO(armansito): Remove once 3GPP is implemented in its own class.
232}
233
234void CellularCapabilityUniversalCDMA::EnterPIN(
235 const string &pin,
236 Error *error,
237 const ResultCallback &callback) {
238 // TODO(armansito): Remove once 3GPP is implemented in its own class.
239}
240
241void CellularCapabilityUniversalCDMA::UnblockPIN(
242 const string &unblock_code,
243 const string &pin,
244 Error *error,
245 const ResultCallback &callback) {
246 // TODO(armansito): Remove once 3GPP is implemented in its own class.
247}
248
249void CellularCapabilityUniversalCDMA::ChangePIN(
250 const string &old_pin, const string &new_pin,
251 Error *error, const ResultCallback &callback) {
252 // TODO(armansito): Remove once 3GPP is implemented in its own class.
253}
254
255void CellularCapabilityUniversalCDMA::Scan(Error *error,
256 const ResultCallback &callback) {
257 // TODO(armansito): Remove once 3GPP is implemented in its own class.
258}
259
260void CellularCapabilityUniversalCDMA::OnSimPathChanged(
261 const string &sim_path) {
262 // TODO(armansito): Remove once 3GPP is implemented in its own class.
263}
264
265string CellularCapabilityUniversalCDMA::GetRoamingStateString() const {
266 uint32 state = cdma_evdo_registration_state_;
267 if (state == MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN) {
268 state = cdma_1x_registration_state_;
269 }
270 switch (state) {
271 case MM_MODEM_CDMA_REGISTRATION_STATE_UNKNOWN:
272 case MM_MODEM_CDMA_REGISTRATION_STATE_REGISTERED:
273 break;
274 case MM_MODEM_CDMA_REGISTRATION_STATE_HOME:
275 return flimflam::kRoamingStateHome;
276 case MM_MODEM_CDMA_REGISTRATION_STATE_ROAMING:
277 return flimflam::kRoamingStateRoaming;
278 default:
279 NOTREACHED();
280 }
281 return flimflam::kRoamingStateUnknown;
282}
283
284void CellularCapabilityUniversalCDMA::OnDBusPropertiesChanged(
285 const string &interface,
286 const DBusPropertiesMap &changed_properties,
287 const vector<string> &invalidated_properties) {
288 SLOG(Cellular, 2) << __func__ << "(" << interface << ")";
289 if (interface == MM_DBUS_INTERFACE_MODEM_MODEMCDMA) {
290 OnModemCDMAPropertiesChanged(changed_properties, invalidated_properties);
291 } else {
292 CellularCapabilityUniversal::OnDBusPropertiesChanged(
293 interface, changed_properties, invalidated_properties);
294 }
295}
296
297void CellularCapabilityUniversalCDMA::OnModemCDMAPropertiesChanged(
298 const DBusPropertiesMap &properties,
299 const std::vector<std::string> &/*invalidated_properties*/) {
300 SLOG(Cellular, 2) << __func__;
301 string str_value;
302 if (DBusProperties::GetString(properties,
303 MM_MODEM_MODEMCDMA_PROPERTY_MEID,
304 &str_value))
305 set_meid(str_value);
306 if (DBusProperties::GetString(properties,
307 MM_MODEM_MODEMCDMA_PROPERTY_ESN,
308 &str_value))
309 set_esn(str_value);
310
311 uint32_t sid = sid_;
312 uint32_t nid = nid_;
313 MMModemCdmaRegistrationState state_1x = cdma_1x_registration_state_;
314 MMModemCdmaRegistrationState state_evdo = cdma_evdo_registration_state_;
315 bool registration_changed = false;
316 uint32_t uint_value;
317 if (DBusProperties::GetUint32(
318 properties,
319 MM_MODEM_MODEMCDMA_PROPERTY_CDMA1XREGISTRATIONSTATE,
320 &uint_value)) {
321 state_1x = static_cast<MMModemCdmaRegistrationState>(uint_value);
322 registration_changed = true;
323 }
324 if (DBusProperties::GetUint32(
325 properties,
326 MM_MODEM_MODEMCDMA_PROPERTY_EVDOREGISTRATIONSTATE,
327 &uint_value)) {
328 state_evdo = static_cast<MMModemCdmaRegistrationState>(uint_value);
329 registration_changed = true;
330 }
331 if (DBusProperties::GetUint32(
332 properties,
333 MM_MODEM_MODEMCDMA_PROPERTY_SID,
334 &uint_value)) {
335 sid = uint_value;
336 registration_changed = true;
337 }
338 if (DBusProperties::GetUint32(
339 properties,
340 MM_MODEM_MODEMCDMA_PROPERTY_NID,
341 &uint_value)) {
342 nid = uint_value;
343 registration_changed = true;
344 }
345 if (registration_changed)
346 OnCDMARegistrationChanged(state_1x, state_evdo, sid, nid);
347}
348
349void CellularCapabilityUniversalCDMA::OnCDMARegistrationChanged(
350 MMModemCdmaRegistrationState state_1x,
351 MMModemCdmaRegistrationState state_evdo,
352 uint32_t sid, uint32_t nid) {
353 SLOG(Cellular, 2) << __func__
354 << ": state_1x=" << state_1x
355 << ", state_evdo=" << state_evdo;
356 cdma_1x_registration_state_ = state_1x;
357 cdma_evdo_registration_state_ = state_evdo;
358 sid_ = sid;
359 nid_ = nid;
360 UpdateOperatorInfo();
361 cellular()->HandleNewRegistrationState();
362}
363
364} // namespace shill