1// Copyright 2013 The Chromium 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 "chromeos/network/network_device_handler.h"
6
7#include "base/bind.h"
8#include "base/values.h"
9#include "chromeos/dbus/dbus_thread_manager.h"
10#include "chromeos/dbus/shill_device_client.h"
11#include "chromeos/dbus/shill_ipconfig_client.h"
12#include "chromeos/network/device_state.h"
13#include "chromeos/network/network_event_log.h"
14#include "dbus/object_path.h"
15#include "third_party/cros_system_api/dbus/service_constants.h"
16
17namespace chromeos {
18
19namespace {
20
21// TODO(armansito): Add bindings for these to service_constants.h
22// (crbug.com/256889)
23const char kShillErrorFailure[] = "org.chromium.flimflam.Error.Failure";
24const char kShillErrorNotSupported[] =
25    "org.chromium.flimflam.Error.NotSupported";
26
27std::string GetErrorNameForShillError(const std::string& shill_error_name) {
28  // TODO(armansito): Use the new SIM error names once the ones below get
29  // deprecated (crbug.com/256855)
30  if (shill_error_name == kShillErrorFailure)
31    return NetworkDeviceHandler::kErrorFailure;
32  if (shill_error_name == kShillErrorNotSupported)
33    return NetworkDeviceHandler::kErrorNotSupported;
34  if (shill_error_name == shill::kErrorIncorrectPinMsg)
35    return NetworkDeviceHandler::kErrorIncorrectPin;
36  if (shill_error_name == shill::kErrorPinBlockedMsg)
37    return NetworkDeviceHandler::kErrorPinBlocked;
38  if (shill_error_name == shill::kErrorPinRequiredMsg)
39    return NetworkDeviceHandler::kErrorPinRequired;
40  return NetworkDeviceHandler::kErrorUnknown;
41}
42
43void HandleShillCallFailure(
44    const std::string& device_path,
45    const network_handler::ErrorCallback& error_callback,
46    const std::string& shill_error_name,
47    const std::string& shill_error_message) {
48  network_handler::ShillErrorCallbackFunction(
49      GetErrorNameForShillError(shill_error_name),
50      device_path,
51      error_callback,
52      shill_error_name,
53      shill_error_message);
54}
55
56void IPConfigRefreshCallback(const std::string& ipconfig_path,
57                             DBusMethodCallStatus call_status) {
58  if (call_status != DBUS_METHOD_CALL_SUCCESS) {
59    NET_LOG_ERROR(
60        base::StringPrintf("IPConfigs.Refresh Failed: %d", call_status),
61        ipconfig_path);
62  } else {
63    NET_LOG_EVENT("IPConfigs.Refresh Succeeded", ipconfig_path);
64  }
65}
66
67void RefreshIPConfigsCallback(
68    const base::Closure& callback,
69    const network_handler::ErrorCallback& error_callback,
70    const std::string& device_path,
71    const base::DictionaryValue& properties) {
72  const ListValue* ip_configs;
73  if (!properties.GetListWithoutPathExpansion(
74          shill::kIPConfigsProperty, &ip_configs)) {
75    NET_LOG_ERROR("RequestRefreshIPConfigs Failed", device_path);
76    network_handler::ShillErrorCallbackFunction(
77        "RequestRefreshIPConfigs Failed",
78        device_path,
79        error_callback,
80        std::string("Missing ") + shill::kIPConfigsProperty, "");
81    return;
82  }
83
84  for (size_t i = 0; i < ip_configs->GetSize(); i++) {
85    std::string ipconfig_path;
86    if (!ip_configs->GetString(i, &ipconfig_path))
87      continue;
88    DBusThreadManager::Get()->GetShillIPConfigClient()->Refresh(
89        dbus::ObjectPath(ipconfig_path),
90        base::Bind(&IPConfigRefreshCallback, ipconfig_path));
91  }
92  // It is safe to invoke |callback| here instead of waiting for the
93  // IPConfig.Refresh callbacks to complete because the Refresh DBus calls will
94  // be executed in order and thus before any further DBus requests that
95  // |callback| may issue.
96  if (!callback.is_null())
97    callback.Run();
98}
99
100void ProposeScanCallback(
101    const std::string& device_path,
102    const base::Closure& callback,
103    const network_handler::ErrorCallback& error_callback,
104    DBusMethodCallStatus call_status) {
105  if (call_status != DBUS_METHOD_CALL_SUCCESS) {
106    NET_LOG_ERROR(
107        base::StringPrintf("Device.ProposeScan failed: %d", call_status),
108        device_path);
109    network_handler::ShillErrorCallbackFunction(
110        "Device.ProposeScan Failed",
111        device_path,
112        error_callback,
113        base::StringPrintf("DBus call failed: %d", call_status), "");
114    return;
115  }
116  NET_LOG_EVENT("Device.ProposeScan succeeded.", device_path);
117  if (!callback.is_null())
118    callback.Run();
119}
120
121}  // namespace
122
123const char NetworkDeviceHandler::kErrorFailure[] = "failure";
124const char NetworkDeviceHandler::kErrorIncorrectPin[] = "incorrect-pin";
125const char NetworkDeviceHandler::kErrorNotSupported[] = "not-supported";
126const char NetworkDeviceHandler::kErrorPinBlocked[] = "pin-blocked";
127const char NetworkDeviceHandler::kErrorPinRequired[] = "pin-required";
128const char NetworkDeviceHandler::kErrorUnknown[] = "unknown";
129
130NetworkDeviceHandler::~NetworkDeviceHandler() {
131}
132
133void NetworkDeviceHandler::GetDeviceProperties(
134    const std::string& device_path,
135    const network_handler::DictionaryResultCallback& callback,
136    const network_handler::ErrorCallback& error_callback) const {
137  DBusThreadManager::Get()->GetShillDeviceClient()->GetProperties(
138      dbus::ObjectPath(device_path),
139      base::Bind(&network_handler::GetPropertiesCallback,
140                 callback, error_callback, device_path));
141}
142
143void NetworkDeviceHandler::SetDeviceProperty(
144    const std::string& device_path,
145    const std::string& name,
146    const base::Value& value,
147    const base::Closure& callback,
148    const network_handler::ErrorCallback& error_callback) {
149  DBusThreadManager::Get()->GetShillDeviceClient()->SetProperty(
150      dbus::ObjectPath(device_path),
151      name,
152      value,
153      callback,
154      base::Bind(&HandleShillCallFailure, device_path, error_callback));
155}
156
157void NetworkDeviceHandler::RequestRefreshIPConfigs(
158    const std::string& device_path,
159    const base::Closure& callback,
160    const network_handler::ErrorCallback& error_callback) {
161  GetDeviceProperties(device_path,
162                      base::Bind(&RefreshIPConfigsCallback,
163                                 callback, error_callback),
164                      error_callback);
165}
166
167void NetworkDeviceHandler::ProposeScan(
168    const std::string& device_path,
169    const base::Closure& callback,
170    const network_handler::ErrorCallback& error_callback) {
171  DBusThreadManager::Get()->GetShillDeviceClient()->ProposeScan(
172      dbus::ObjectPath(device_path),
173      base::Bind(&ProposeScanCallback, device_path, callback, error_callback));
174}
175
176void NetworkDeviceHandler::RegisterCellularNetwork(
177    const std::string& device_path,
178    const std::string& network_id,
179    const base::Closure& callback,
180    const network_handler::ErrorCallback& error_callback) {
181  DBusThreadManager::Get()->GetShillDeviceClient()->Register(
182      dbus::ObjectPath(device_path),
183      network_id,
184      callback,
185      base::Bind(&HandleShillCallFailure, device_path, error_callback));
186}
187
188void NetworkDeviceHandler::SetCarrier(
189    const std::string& device_path,
190    const std::string& carrier,
191    const base::Closure& callback,
192    const network_handler::ErrorCallback& error_callback) {
193  DBusThreadManager::Get()->GetShillDeviceClient()->SetCarrier(
194      dbus::ObjectPath(device_path),
195      carrier,
196      callback,
197      base::Bind(&HandleShillCallFailure, device_path, error_callback));
198}
199
200void NetworkDeviceHandler::RequirePin(
201    const std::string& device_path,
202    bool require_pin,
203    const std::string& pin,
204    const base::Closure& callback,
205    const network_handler::ErrorCallback& error_callback) {
206  DBusThreadManager::Get()->GetShillDeviceClient()->RequirePin(
207      dbus::ObjectPath(device_path),
208      pin,
209      require_pin,
210      callback,
211      base::Bind(&HandleShillCallFailure, device_path, error_callback));
212}
213
214void NetworkDeviceHandler::EnterPin(
215    const std::string& device_path,
216    const std::string& pin,
217    const base::Closure& callback,
218    const network_handler::ErrorCallback& error_callback) {
219  DBusThreadManager::Get()->GetShillDeviceClient()->EnterPin(
220      dbus::ObjectPath(device_path),
221      pin,
222      callback,
223      base::Bind(&HandleShillCallFailure, device_path, error_callback));
224}
225
226void NetworkDeviceHandler::UnblockPin(
227    const std::string& device_path,
228    const std::string& puk,
229    const std::string& new_pin,
230    const base::Closure& callback,
231    const network_handler::ErrorCallback& error_callback) {
232  DBusThreadManager::Get()->GetShillDeviceClient()->UnblockPin(
233      dbus::ObjectPath(device_path),
234      puk,
235      new_pin,
236      callback,
237      base::Bind(&HandleShillCallFailure, device_path, error_callback));
238}
239
240void NetworkDeviceHandler::ChangePin(
241    const std::string& device_path,
242    const std::string& old_pin,
243    const std::string& new_pin,
244    const base::Closure& callback,
245    const network_handler::ErrorCallback& error_callback) {
246  DBusThreadManager::Get()->GetShillDeviceClient()->ChangePin(
247      dbus::ObjectPath(device_path),
248      old_pin,
249      new_pin,
250      callback,
251      base::Bind(&HandleShillCallFailure, device_path, error_callback));
252}
253
254NetworkDeviceHandler::NetworkDeviceHandler() {
255}
256
257}  // namespace chromeos
258