// Copyright 2015 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "apmanager/hostapd_monitor.h"

#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>

#include <base/bind.h>
#include <base/logging.h>
#include <base/strings/stringprintf.h>
#include <shill/net/io_handler_factory_container.h>
#include <shill/net/sockets.h>

using base::Bind;
using base::Unretained;
using shill::IOHandlerFactoryContainer;
using std::string;

namespace apmanager {

// static.
const char HostapdMonitor::kLocalPathFormat[] =
    "/var/run/apmanager/hostapd/hostapd_ctrl_%s";
const char HostapdMonitor::kHostapdCmdAttach[] = "ATTACH";
const char HostapdMonitor::kHostapdRespOk[] = "OK\n";
const char HostapdMonitor::kHostapdEventStationConnected[] = "AP-STA-CONNECTED";
const char HostapdMonitor::kHostapdEventStationDisconnected[] =
    "AP-STA-DISCONNECTED";
const int HostapdMonitor::kHostapdCtrlIfaceCheckIntervalMs = 500;
const int HostapdMonitor::kHostapdCtrlIfaceCheckMaxAttempts = 5;
const int HostapdMonitor::kHostapdAttachTimeoutMs = 1000;
const int HostapdMonitor::kInvalidSocket = -1;

HostapdMonitor::HostapdMonitor(const EventCallback& callback,
                               const string& control_interface_path,
                               const string& network_interface_name)
    : sockets_(new shill::Sockets()),
      event_callback_(callback),
      dest_path_(base::StringPrintf("%s/%s",
                                    control_interface_path.c_str(),
                                    network_interface_name.c_str())),
      local_path_(base::StringPrintf(kLocalPathFormat,
                                     network_interface_name.c_str())),
      hostapd_socket_(kInvalidSocket),
      io_handler_factory_(
          IOHandlerFactoryContainer::GetInstance()->GetIOHandlerFactory()),
      event_dispatcher_(EventDispatcher::GetInstance()),
      weak_ptr_factory_(this),
      started_(false) {}

HostapdMonitor::~HostapdMonitor() {
  if (hostapd_socket_ != kInvalidSocket) {
    unlink(local_path_.c_str());
    sockets_->Close(hostapd_socket_);
  }
}

void HostapdMonitor::Start() {
  if (started_) {
    LOG(ERROR) << "HostapdMonitor already started";
    return;
  }

  hostapd_ctrl_iface_check_count_ = 0;
  // Start off by checking the control interface file for the hostapd process.
  event_dispatcher_->PostTask(
      Bind(&HostapdMonitor::HostapdCtrlIfaceCheckTask,
           weak_ptr_factory_.GetWeakPtr()));
  started_ = true;
}

void HostapdMonitor::HostapdCtrlIfaceCheckTask() {
  struct stat buf;
  if (stat(dest_path_.c_str(), &buf) != 0) {
    if (hostapd_ctrl_iface_check_count_ >= kHostapdCtrlIfaceCheckMaxAttempts) {
      // This indicates the hostapd failed to start. Invoke callback indicating
      // hostapd start failed.
      LOG(ERROR) << "Timeout waiting for hostapd control interface";
      event_callback_.Run(kHostapdFailed, "");
    } else {
      hostapd_ctrl_iface_check_count_++;
      event_dispatcher_->PostDelayedTask(
          base::Bind(&HostapdMonitor::HostapdCtrlIfaceCheckTask,
                     weak_ptr_factory_.GetWeakPtr()),
          kHostapdCtrlIfaceCheckIntervalMs);
    }
    return;
  }

  // Control interface is up, meaning hostapd started successfully.
  event_callback_.Run(kHostapdStarted, "");

  // Attach to the control interface to receive unsolicited event notifications.
  AttachToHostapd();
}

void HostapdMonitor::AttachToHostapd() {
  if (hostapd_socket_ != kInvalidSocket) {
    LOG(ERROR) << "Socket already initialized";
    return;
  }

  // Setup socket address for local file and remote file.
  struct sockaddr_un local;
  local.sun_family = AF_UNIX;
  snprintf(local.sun_path, sizeof(local.sun_path), "%s", local_path_.c_str());
  struct sockaddr_un dest;
  dest.sun_family = AF_UNIX;
  snprintf(dest.sun_path, sizeof(dest.sun_path), "%s", dest_path_.c_str());

  // Setup socket for interprocess communication.
  hostapd_socket_ = sockets_->Socket(PF_UNIX, SOCK_DGRAM, 0);
  if (hostapd_socket_ < 0) {
    LOG(ERROR) << "Failed to open hostapd socket";
    return;
  }
  if (sockets_->Bind(hostapd_socket_,
                     reinterpret_cast<struct sockaddr*>(&local),
                     sizeof(local)) < 0) {
    LOG(ERROR) << "Failed to bind to local socket: " << strerror(errno);
    return;
  }
  if (sockets_->Connect(hostapd_socket_,
                        reinterpret_cast<struct sockaddr*>(&dest),
                        sizeof(dest)) < 0) {
    LOG(ERROR) << "Failed to connect: " << strerror(errno);
    return;
  }

  // Setup IO Input handler.
  hostapd_input_handler_.reset(io_handler_factory_->CreateIOInputHandler(
      hostapd_socket_,
      Bind(&HostapdMonitor::ParseMessage, Unretained(this)),
      Bind(&HostapdMonitor::OnReadError, Unretained(this))));

  if (!SendMessage(kHostapdCmdAttach, strlen(kHostapdCmdAttach))) {
    LOG(ERROR) << "Failed to attach to hostapd";
    return;
  }

  // Start a timer for ATTACH response.
  attach_timeout_callback_.Reset(
      Bind(&HostapdMonitor::AttachTimeoutHandler,
           weak_ptr_factory_.GetWeakPtr()));
  event_dispatcher_->PostDelayedTask(attach_timeout_callback_.callback(),
                                     kHostapdAttachTimeoutMs);
  return;
}

void HostapdMonitor::AttachTimeoutHandler() {
  LOG(ERROR) << "Timeout waiting for attach response";
}

// Method for sending message to hostapd control interface.
bool HostapdMonitor::SendMessage(const char* message, size_t length) {
  if (sockets_->Send(hostapd_socket_, message, length, 0) < 0) {
    LOG(ERROR) << "Send to hostapd failed: " << strerror(errno);
    return false;
  }

  return true;
}

void HostapdMonitor::ParseMessage(shill::InputData* data) {
  string str(reinterpret_cast<const char*>(data->buf), data->len);
  // "OK" response for the "ATTACH" command.
  if (str == kHostapdRespOk) {
    attach_timeout_callback_.Cancel();
    return;
  }

  // Event messages are in format of <[Level]>[Event] [Detail message].
  // For example: <2>AP-STA-CONNECTED 00:11:22:33:44:55
  // Refer to wpa_ctrl.h for complete list of possible events.
  if (str.find_first_of('<', 0) == 0 && str.find_first_of('>', 0) == 2) {
    // Remove the log level.
    string msg = str.substr(3);
    string event;
    string data;
    size_t pos = msg.find_first_of(' ', 0);
    if (pos == string::npos) {
      event = msg;
    } else {
      event = msg.substr(0, pos);
      data = msg.substr(pos + 1);
    }

    Event event_code;
    if (event == kHostapdEventStationConnected) {
      event_code = kStationConnected;
    } else if (event == kHostapdEventStationDisconnected) {
      event_code = kStationDisconnected;
    } else {
      LOG(INFO) << "Received unknown event: " << event;
      return;
    }
    event_callback_.Run(event_code, data);
    return;
  }

  LOG(INFO) << "Received unknown message: " << str;
}

void HostapdMonitor::OnReadError(const string& error_msg) {
  LOG(FATAL) << "Hostapd Socket read returns error: "
             << error_msg;
}

}  // namespace apmanager
