Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chromeos / network / network_device_handler_impl.cc
index 02fbdb9..ce0d787 100644 (file)
@@ -6,6 +6,8 @@
 
 #include "base/bind.h"
 #include "base/location.h"
+#include "base/message_loop/message_loop_proxy.h"
+#include "base/time/time.h"
 #include "base/values.h"
 #include "chromeos/dbus/dbus_thread_manager.h"
 #include "chromeos/dbus/shill_device_client.h"
@@ -22,25 +24,19 @@ namespace chromeos {
 
 namespace {
 
-// TODO(armansito): Add bindings for these to service_constants.h
-// (crbug.com/256889)
-const char kShillErrorFailure[] = "org.chromium.flimflam.Error.Failure";
-const char kShillErrorNotSupported[] =
-    "org.chromium.flimflam.Error.NotSupported";
-
 std::string GetErrorNameForShillError(const std::string& shill_error_name) {
-  // TODO(armansito): Use the new SIM error names once the ones below get
-  // deprecated (crbug.com/256855)
-  if (shill_error_name == kShillErrorFailure)
+  if (shill_error_name == shill::kErrorResultFailure)
     return NetworkDeviceHandler::kErrorFailure;
-  if (shill_error_name == kShillErrorNotSupported)
+  if (shill_error_name == shill::kErrorResultNotSupported)
     return NetworkDeviceHandler::kErrorNotSupported;
-  if (shill_error_name == shill::kErrorIncorrectPinMsg)
+  if (shill_error_name == shill::kErrorResultIncorrectPin)
     return NetworkDeviceHandler::kErrorIncorrectPin;
-  if (shill_error_name == shill::kErrorPinBlockedMsg)
+  if (shill_error_name == shill::kErrorResultPinBlocked)
     return NetworkDeviceHandler::kErrorPinBlocked;
-  if (shill_error_name == shill::kErrorPinRequiredMsg)
+  if (shill_error_name == shill::kErrorResultPinRequired)
     return NetworkDeviceHandler::kErrorPinRequired;
+  if (shill_error_name == shill::kErrorResultNotFound)
+    return NetworkDeviceHandler::kErrorDeviceMissing;
   return NetworkDeviceHandler::kErrorUnknown;
 }
 
@@ -142,6 +138,118 @@ void SetDevicePropertyInternal(
       base::Bind(&HandleShillCallFailure, device_path, error_callback));
 }
 
+// Struct containing TDLS Operation parameters.
+struct TDLSOperationParams {
+  TDLSOperationParams() : retry_count(0) {}
+  std::string operation;
+  std::string ip_or_mac_address;
+  int retry_count;
+};
+
+// Forward declare for PostDelayedTask.
+void CallPerformTDLSOperation(
+    const std::string& device_path,
+    const TDLSOperationParams& params,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback);
+
+void TDLSSuccessCallback(
+    const std::string& device_path,
+    const TDLSOperationParams& params,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback,
+    const std::string& result) {
+  std::string event_desc = "TDLSSuccessCallback: " + params.operation;
+  if (!result.empty())
+    event_desc += ": " + result;
+  NET_LOG_EVENT(event_desc, device_path);
+  if (params.operation != shill::kTDLSSetupOperation) {
+    if (!callback.is_null())
+      callback.Run(result);
+    return;
+  }
+
+  if (!result.empty())
+    NET_LOG_ERROR("Unexpected TDLS result: " + result, device_path);
+
+  // Send a delayed Status request after a successful Setup call.
+  TDLSOperationParams status_params;
+  status_params.operation = shill::kTDLSStatusOperation;
+  status_params.ip_or_mac_address = params.ip_or_mac_address;
+
+  const int64 kRequestStatusDelayMs = 500;
+  base::TimeDelta request_delay;
+  if (!DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface())
+    request_delay = base::TimeDelta::FromMilliseconds(kRequestStatusDelayMs);
+
+  base::MessageLoopProxy::current()->PostDelayedTask(
+      FROM_HERE,
+      base::Bind(&CallPerformTDLSOperation,
+                 device_path, status_params, callback, error_callback),
+      request_delay);
+}
+
+void TDLSErrorCallback(
+    const std::string& device_path,
+    const TDLSOperationParams& params,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback,
+    const std::string& dbus_error_name,
+    const std::string& dbus_error_message) {
+  // If a Setup operation receives an InProgress error, retry.
+  const int kMaxRetries = 5;
+  if (params.operation == shill::kTDLSSetupOperation &&
+      dbus_error_name == shill::kErrorResultInProgress &&
+      params.retry_count < kMaxRetries) {
+    TDLSOperationParams retry_params = params;
+    ++retry_params.retry_count;
+    NET_LOG_EVENT(base::StringPrintf("TDLS Retry: %d", params.retry_count),
+                  device_path);
+    const int64 kReRequestDelayMs = 1000;
+    base::TimeDelta request_delay;
+    if (!DBusThreadManager::Get()->GetShillDeviceClient()->GetTestInterface())
+      request_delay = base::TimeDelta::FromMilliseconds(kReRequestDelayMs);
+
+    base::MessageLoopProxy::current()->PostDelayedTask(
+        FROM_HERE,
+        base::Bind(&CallPerformTDLSOperation,
+                   device_path, retry_params, callback, error_callback),
+        request_delay);
+    return;
+  }
+
+  NET_LOG_ERROR("TDLS Error:" + dbus_error_name + ":" + dbus_error_message,
+                device_path);
+  if (error_callback.is_null())
+    return;
+
+  const std::string error_name =
+      dbus_error_name == shill::kErrorResultInProgress ?
+      NetworkDeviceHandler::kErrorTimeout : NetworkDeviceHandler::kErrorUnknown;
+  const std::string& error_detail = params.ip_or_mac_address;
+  scoped_ptr<base::DictionaryValue> error_data(
+      network_handler::CreateDBusErrorData(
+          device_path, error_name, error_detail,
+          dbus_error_name, dbus_error_message));
+  error_callback.Run(error_name, error_data.Pass());
+}
+
+void CallPerformTDLSOperation(
+    const std::string& device_path,
+    const TDLSOperationParams& params,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback) {
+  NET_LOG_EVENT("CallPerformTDLSOperation: " + params.operation, device_path);
+  DBusThreadManager::Get()->GetShillDeviceClient()->PerformTDLSOperation(
+      dbus::ObjectPath(device_path),
+      params.operation,
+      params.ip_or_mac_address,
+      base::Bind(&TDLSSuccessCallback,
+                 device_path, params, callback, error_callback),
+      base::Bind(&TDLSErrorCallback,
+                 device_path, params, callback, error_callback));
+}
+
 }  // namespace
 
 NetworkDeviceHandlerImpl::~NetworkDeviceHandlerImpl() {
@@ -286,6 +394,50 @@ void NetworkDeviceHandlerImpl::SetCellularAllowRoaming(
   ApplyCellularAllowRoamingToShill();
 }
 
+void NetworkDeviceHandlerImpl::SetWifiTDLSEnabled(
+    const std::string& ip_or_mac_address,
+    bool enabled,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback) {
+  const DeviceState* device_state =
+      network_state_handler_->GetDeviceStateByType(NetworkTypePattern::WiFi());
+  if (!device_state) {
+    if (error_callback.is_null())
+      return;
+    scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue);
+    error_data->SetString(network_handler::kErrorName, kErrorDeviceMissing);
+    error_callback.Run(kErrorDeviceMissing, error_data.Pass());
+    return;
+  }
+  TDLSOperationParams params;
+  params.operation = enabled ? shill::kTDLSSetupOperation
+      : shill::kTDLSTeardownOperation;
+  params.ip_or_mac_address = ip_or_mac_address;
+  CallPerformTDLSOperation(
+      device_state->path(), params, callback, error_callback);
+}
+
+void NetworkDeviceHandlerImpl::GetWifiTDLSStatus(
+    const std::string& ip_or_mac_address,
+    const network_handler::StringResultCallback& callback,
+    const network_handler::ErrorCallback& error_callback) {
+  const DeviceState* device_state =
+      network_state_handler_->GetDeviceStateByType(NetworkTypePattern::WiFi());
+  if (!device_state) {
+    if (error_callback.is_null())
+      return;
+    scoped_ptr<base::DictionaryValue> error_data(new base::DictionaryValue);
+    error_data->SetString(network_handler::kErrorName, kErrorDeviceMissing);
+    error_callback.Run(kErrorDeviceMissing, error_data.Pass());
+    return;
+  }
+  TDLSOperationParams params;
+  params.operation = shill::kTDLSStatusOperation;
+  params.ip_or_mac_address = ip_or_mac_address;
+  CallPerformTDLSOperation(
+      device_state->path(), params, callback, error_callback);
+}
+
 void NetworkDeviceHandlerImpl::DeviceListChanged() {
   ApplyCellularAllowRoamingToShill();
 }