1//
2// Copyright (C) 2015 The Android Open Source Project
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8//      http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15//
16
17#include "shill/dbus/chromeos_wimax_device_proxy.h"
18
19#include <memory>
20
21#include <base/bind.h>
22#include <base/strings/stringprintf.h>
23#if defined(__ANDROID__)
24#include <dbus/service_constants.h>
25#else
26#include <chromeos/dbus/service_constants.h>
27#endif  // __ANDROID__
28
29#include "shill/error.h"
30#include "shill/logging.h"
31
32using std::string;
33using std::vector;
34using wimax_manager::DeviceStatus;
35
36namespace shill {
37
38namespace Logging {
39static auto kModuleLogScope = ScopeLogger::kDBus;
40static string ObjectID(const dbus::ObjectPath* path) {
41  return "wimax_device_proxy (" + path->value() + ")";
42}
43}
44
45// static.
46const char ChromeosWiMaxDeviceProxy::kPropertyIndex[] = "Index";
47const char ChromeosWiMaxDeviceProxy::kPropertyName[] = "Name";
48const char ChromeosWiMaxDeviceProxy::kPropertyNetworks[] = "Networks";
49
50ChromeosWiMaxDeviceProxy::PropertySet::PropertySet(
51    dbus::ObjectProxy* object_proxy,
52    const std::string& interface_name,
53    const PropertyChangedCallback& callback)
54    : dbus::PropertySet(object_proxy, interface_name, callback) {
55  RegisterProperty(kPropertyIndex, &index);
56  RegisterProperty(kPropertyName, &name);
57  RegisterProperty(kPropertyNetworks, &networks);
58}
59
60ChromeosWiMaxDeviceProxy::ChromeosWiMaxDeviceProxy(
61    const scoped_refptr<dbus::Bus>& bus,
62    const std::string& rpc_identifier)
63    : proxy_(
64        new org::chromium::WiMaxManager::DeviceProxy(
65            bus,
66            wimax_manager::kWiMaxManagerServiceName,
67            dbus::ObjectPath(rpc_identifier))) {
68  // Register signal handlers.
69  proxy_->RegisterNetworksChangedSignalHandler(
70      base::Bind(&ChromeosWiMaxDeviceProxy::NetworksChanged,
71                 weak_factory_.GetWeakPtr()),
72      base::Bind(&ChromeosWiMaxDeviceProxy::OnSignalConnected,
73                 weak_factory_.GetWeakPtr()));
74  proxy_->RegisterStatusChangedSignalHandler(
75      base::Bind(&ChromeosWiMaxDeviceProxy::StatusChanged,
76                 weak_factory_.GetWeakPtr()),
77      base::Bind(&ChromeosWiMaxDeviceProxy::OnSignalConnected,
78                 weak_factory_.GetWeakPtr()));
79
80  // Register properties.
81  properties_.reset(
82      new PropertySet(
83          proxy_->GetObjectProxy(),
84          wimax_manager::kWiMaxManagerDeviceInterface,
85          base::Bind(&ChromeosWiMaxDeviceProxy::OnPropertyChanged,
86                     weak_factory_.GetWeakPtr())));
87  properties_->ConnectSignals();
88  properties_->GetAll();
89}
90
91ChromeosWiMaxDeviceProxy::~ChromeosWiMaxDeviceProxy() {
92  proxy_->ReleaseObjectProxy(base::Bind(&base::DoNothing));
93}
94
95void ChromeosWiMaxDeviceProxy::Enable(Error* /*error*/,
96                                      const ResultCallback& callback,
97                                      int /*timeout*/) {
98  proxy_->EnableAsync(
99      base::Bind(&ChromeosWiMaxDeviceProxy::OnSuccess,
100                 weak_factory_.GetWeakPtr(),
101                 callback,
102                 __func__),
103      base::Bind(&ChromeosWiMaxDeviceProxy::OnFailure,
104                 weak_factory_.GetWeakPtr(),
105                 callback,
106                 __func__));
107}
108
109void ChromeosWiMaxDeviceProxy::Disable(Error* /*error*/,
110                                       const ResultCallback& callback,
111                                       int /*timeout*/) {
112  proxy_->DisableAsync(
113      base::Bind(&ChromeosWiMaxDeviceProxy::OnSuccess,
114                 weak_factory_.GetWeakPtr(),
115                 callback,
116                 __func__),
117      base::Bind(&ChromeosWiMaxDeviceProxy::OnFailure,
118                 weak_factory_.GetWeakPtr(),
119                 callback,
120                 __func__));
121}
122
123void ChromeosWiMaxDeviceProxy::ScanNetworks(Error* /*error*/,
124                                            const ResultCallback& callback,
125                                            int /*timeout*/) {
126  proxy_->ScanNetworksAsync(
127      base::Bind(&ChromeosWiMaxDeviceProxy::OnSuccess,
128                 weak_factory_.GetWeakPtr(),
129                 callback,
130                 __func__),
131      base::Bind(&ChromeosWiMaxDeviceProxy::OnFailure,
132                 weak_factory_.GetWeakPtr(),
133                 callback,
134                 __func__));
135}
136
137void ChromeosWiMaxDeviceProxy::Connect(const RpcIdentifier& network,
138                                       const KeyValueStore& parameters,
139                                       Error* /*error*/,
140                                       const ResultCallback& callback,
141                                       int /*timeout*/) {
142  proxy_->ConnectAsync(
143      dbus::ObjectPath(network),
144      parameters.properties(),
145      base::Bind(&ChromeosWiMaxDeviceProxy::OnSuccess,
146                 weak_factory_.GetWeakPtr(),
147                 callback,
148                 __func__),
149      base::Bind(&ChromeosWiMaxDeviceProxy::OnFailure,
150                 weak_factory_.GetWeakPtr(),
151                 callback,
152                 __func__));
153}
154
155void ChromeosWiMaxDeviceProxy::Disconnect(Error* /*error*/,
156                                          const ResultCallback& callback,
157                                          int /*timeout*/) {
158  proxy_->DisconnectAsync(
159      base::Bind(&ChromeosWiMaxDeviceProxy::OnSuccess,
160                 weak_factory_.GetWeakPtr(),
161                 callback,
162                 __func__),
163      base::Bind(&ChromeosWiMaxDeviceProxy::OnFailure,
164                 weak_factory_.GetWeakPtr(),
165                 callback,
166                 __func__));
167}
168
169void ChromeosWiMaxDeviceProxy::set_networks_changed_callback(
170    const NetworksChangedCallback& callback) {
171  networks_changed_callback_ = callback;
172}
173
174void ChromeosWiMaxDeviceProxy::set_status_changed_callback(
175    const StatusChangedCallback& callback) {
176  status_changed_callback_ = callback;
177}
178
179uint8_t ChromeosWiMaxDeviceProxy::Index(Error* /*error*/) {
180  SLOG(&proxy_->GetObjectPath(), 2) << __func__;
181  if (!properties_->index.GetAndBlock()) {
182    LOG(ERROR) << "Failed to get Index";
183    return 0;
184  }
185  return properties_->index.value();
186}
187
188string ChromeosWiMaxDeviceProxy::Name(Error* /*error*/) {
189  SLOG(&proxy_->GetObjectPath(), 2) << __func__;
190  if (!properties_->name.GetAndBlock()) {
191    LOG(ERROR) << "Failed to get Name";
192    return string();
193  }
194  return properties_->name.value();
195}
196
197RpcIdentifiers ChromeosWiMaxDeviceProxy::Networks(Error* /*error*/) {
198  SLOG(&proxy_->GetObjectPath(), 2) << __func__;
199  RpcIdentifiers rpc_networks;
200  KeyValueStore::ConvertPathsToRpcIdentifiers(properties_->networks.value(),
201                                              &rpc_networks);
202  return rpc_networks;
203}
204
205void ChromeosWiMaxDeviceProxy::OnSignalConnected(
206    const string& interface_name, const string& signal_name, bool success) {
207  SLOG(&proxy_->GetObjectPath(), 2) << __func__
208      << "interface: " << interface_name << " signal: " << signal_name
209      << "success: " << success;
210  if (!success) {
211    LOG(ERROR) << "Failed to connect signal " << signal_name
212        << " to interface " << interface_name;
213  }
214}
215
216void ChromeosWiMaxDeviceProxy::OnPropertyChanged(
217    const std::string& property_name) {
218  SLOG(&proxy_->GetObjectPath(), 2) << __func__ << ": " << property_name;
219}
220
221void ChromeosWiMaxDeviceProxy::NetworksChanged(
222    const vector<dbus::ObjectPath>& networks) {
223  SLOG(&proxy_->GetObjectPath(), 2) << __func__
224      << "(" << networks.size() << ")";
225  if (networks_changed_callback_.is_null()) {
226    return;
227  }
228  RpcIdentifiers rpc_networks;
229  KeyValueStore::ConvertPathsToRpcIdentifiers(networks, &rpc_networks);
230  networks_changed_callback_.Run(rpc_networks);
231}
232
233void ChromeosWiMaxDeviceProxy::StatusChanged(int32_t status) {
234  SLOG(&proxy_->GetObjectPath(), 2) << __func__ << "(" << status << ")";
235  if (status_changed_callback_.is_null()) {
236    return;
237  }
238  status_changed_callback_.Run(static_cast<DeviceStatus>(status));
239}
240
241void ChromeosWiMaxDeviceProxy::OnSuccess(const ResultCallback& callback,
242                                         const string& method) {
243  SLOG(&proxy_->GetObjectPath(), 2) << __func__ << ": " << method;
244  Error error;
245  callback.Run(error);
246}
247
248void ChromeosWiMaxDeviceProxy::OnFailure(const ResultCallback& callback,
249                                         const string& method,
250                                         brillo::Error* dbus_error) {
251  Error error;
252  Error::PopulateAndLog(
253      FROM_HERE, &error, Error::kOperationFailed,
254      base::StringPrintf("%s failed: %s %s",
255                         method.c_str(),
256                         dbus_error->GetCode().c_str(),
257                         dbus_error->GetMessage().c_str()));
258  callback.Run(error);
259}
260
261}  // namespace shill
262