// 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 "lorgnette/epson_probe.h"

#include <arpa/inet.h>
#include <errno.h>
#include <fcntl.h>
#include <string.h>
#include <sys/socket.h>
#include <time.h>

#include <map>
#include <string>

#include <base/files/scoped_file.h>
#include <base/logging.h>
#include <base/posix/eintr_wrapper.h>
#include <base/stl_util.h>
#include <chromeos/dbus/service_constants.h>

#include "lorgnette/firewall_manager.h"

namespace lorgnette {

namespace epson_probe {

namespace {

const uint16_t kEpsonProbePort = 3289;
const char kEpsonDeviceNamePrefix[] = "epson2:net:";
const int kSyscallSuccess = 0;
const char kScannerManufacturerEpson[] = "Epson";
const char kScannerModelNetwork[] = "Network";
const char kScannerTypeFlatbed[] = "flatbed scanner";
const char kProbePacket[] = "EPSONP\0\xff\0\0\0\0\0\0\0";
const char kReplyPrefix[] = "EPSON";
const int kExpectedReplySize = 76;
const int kReplyWaitTimeSeconds = 1;

static_assert(sizeof(kReplyPrefix) < kExpectedReplySize,
              "Reply prefix should be smaller than the expected reply size");

}  // namespace

static bool GetTimeMonotonic(struct timeval* tv) {
  struct timespec ts;
  if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0) {
    return false;
  }

  tv->tv_sec = ts.tv_sec;
  tv->tv_usec = ts.tv_nsec / 1000;
  return true;
}

static bool CreateBroadcastSocket(int *broadcast_socket, uint16_t *port) {
  int sock = HANDLE_EINTR(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
  if (sock < 0) {
    PLOG(ERROR) << "socket() returns " << sock;
    return false;
  }
  base::ScopedFD scoped_socket(sock);
  CHECK(sock < FD_SETSIZE);

  int result = HANDLE_EINTR(
      fcntl(sock, F_SETFL, fcntl(sock, F_GETFL) | O_NONBLOCK));
  if (result < 0) {
    PLOG(ERROR) << "fcntl(NONBLOCK) returns " << result;
    return false;
  }

  struct sockaddr_in local;
  memset(&local, 0, sizeof(local));
  local.sin_family = AF_INET;
  local.sin_addr.s_addr = INADDR_ANY;
  result = HANDLE_EINTR(
      bind(sock, reinterpret_cast<struct sockaddr*>(&local), sizeof(local)));
  if (result != kSyscallSuccess) {
    PLOG(ERROR) << "bind() returns " << result;
    return false;
  }

  int broadcast_enable = 1;
  result = HANDLE_EINTR(
      setsockopt(sock, SOL_SOCKET, SO_BROADCAST, &broadcast_enable,
                 sizeof(broadcast_enable)));
  if (result != kSyscallSuccess) {
    PLOG(ERROR) << "setsockopt(SO_BROADCAST) returns " << result;
    return false;
  }

  socklen_t local_len = sizeof(local);
  result = HANDLE_EINTR(
      getsockname(sock, reinterpret_cast<struct sockaddr*>(&local),
                  &local_len));
  if (result != kSyscallSuccess || local.sin_port == 0) {
    PLOG(ERROR) << "getsockname() returns " << result;
    return false;
  }

  *broadcast_socket = scoped_socket.release();
  *port = ntohs(local.sin_port);
  LOG(INFO) << "Bound to port " << ntohs(*port);

  return true;
}

static void SendProbeAndListen(uint16_t probe_socket,
                               Manager::ScannerInfo* scanner_list) {
  struct sockaddr_in broadcast;
  memset(&broadcast, 0, sizeof(broadcast));
  broadcast.sin_family = AF_INET;
  broadcast.sin_addr.s_addr = INADDR_BROADCAST;
  broadcast.sin_port = htons(kEpsonProbePort);
  int result = HANDLE_EINTR(
      sendto(probe_socket, kProbePacket, sizeof(kProbePacket), 0,
             reinterpret_cast<struct sockaddr*>(&broadcast),
             sizeof(broadcast)));
  if (result != sizeof(kProbePacket)) {
    LOG(ERROR) << "sendto() returns " << result
               << ": " << (result < 0 ? strerror(errno) : "");
    return;
  }

  struct timeval maximum_wait_duration = { kReplyWaitTimeSeconds, 0 };
  struct timeval now, end_time;
  CHECK(GetTimeMonotonic(&now));
  timeradd(&now, &maximum_wait_duration, &end_time);
  do {
    fd_set read_fds;
    FD_ZERO(&read_fds);
    FD_SET(probe_socket, &read_fds);

    struct timeval wait_duration;
    timersub(&end_time, &now, &wait_duration);
    result = HANDLE_EINTR(
        select(probe_socket + 1, &read_fds, nullptr, nullptr, &wait_duration));
    if (result < 0) {
      PLOG(ERROR) << "select() returns " << result;
      break;
    }

    if (result == 0) {
      break;
    }

    struct sockaddr_in remote;
    memset(&remote, 0, sizeof(remote));
    socklen_t remote_len = sizeof(remote);

    char response[kExpectedReplySize];
    result = HANDLE_EINTR(
        recvfrom(probe_socket, response, sizeof(response), 0,
                 reinterpret_cast<struct sockaddr*>(&remote),
                 &remote_len));
    if (result < 0) {
      PLOG(ERROR) << "recvfrom() returns " << result;
      break;
    }

    if (result == kExpectedReplySize &&
        memcmp(response, kReplyPrefix, sizeof(kReplyPrefix) - 1) == 0) {
      char* ip_address_string = inet_ntoa(remote.sin_addr);
      std::string device_name =
          std::string(kEpsonDeviceNamePrefix) + ip_address_string;
      if (!ContainsKey(*scanner_list, device_name)) {
        // We don't use anything from the response; neither does sane-backends.
        std::map<std::string, std::string> scanner_info;
        scanner_info[kScannerPropertyManufacturer] = kScannerManufacturerEpson;
        scanner_info[kScannerPropertyModel] = kScannerModelNetwork;
        scanner_info[kScannerPropertyType] = kScannerTypeFlatbed;
        (*scanner_list)[device_name] = scanner_info;
      } else {
        LOG(INFO) << "Not adding device " << device_name
                  << "; already in list";
      }
    } else {
      LOG(ERROR) << "Unexpected reply; length was " << result;
    }

    CHECK(GetTimeMonotonic(&now));
  } while (timercmp(&now, &end_time, <));
}

void ProbeForScanners(FirewallManager* firewall_manager,
                      Manager::ScannerInfo* scanner_list) {
  int probe_socket;
  uint16_t local_port;
  if (!CreateBroadcastSocket(&probe_socket, &local_port)) {
    return;
  }
  base::ScopedFD scoped_socket(probe_socket);
  firewall_manager->RequestUdpPortAccess(local_port);
  SendProbeAndListen(probe_socket, scanner_list);
  firewall_manager->ReleaseUdpPortAccess(local_port);
}

}  // namespace epson_probe

}  // namespace lorgnette
