/* Serial port emulation using sockets.
   Copyright (C) 1998-2013 Free Software Foundation, Inc.
   Contributed by Cygnus Solutions.

This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

/* FIXME: will obviously need to evolve.
   - connectionless sockets might be more appropriate.  */

#include "sim-main.h"

#ifdef HAVE_STRING_H
#include <string.h>
#else
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
#endif
#include <signal.h>
#ifdef HAVE_STDLIB_H
#include <stdlib.h>
#endif
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif

#include <errno.h>
#include <sys/types.h>
#include <sys/time.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include <sys/socket.h>

#ifndef __CYGWIN32__
#include <netinet/tcp.h>
#endif

#include "sim-assert.h"
#include "sim-options.h"

#include "dv-sockser.h"

#ifndef HAVE_SOCKLEN_T
typedef int socklen_t;
#endif

/* Get definitions for both O_NONBLOCK and O_NDELAY.  */

#ifndef O_NDELAY
#ifdef FNDELAY
#define O_NDELAY FNDELAY
#else /* ! defined (FNDELAY) */
#define O_NDELAY 0
#endif /* ! defined (FNDELAY) */
#endif /* ! defined (O_NDELAY) */

#ifndef O_NONBLOCK
#ifdef FNBLOCK
#define O_NONBLOCK FNBLOCK
#else /* ! defined (FNBLOCK) */
#define O_NONBLOCK 0
#endif /* ! defined (FNBLOCK) */
#endif /* ! defined (O_NONBLOCK) */


/* Compromise between eating cpu and properly busy-waiting.
   One could have an option to set this but for now that seems
   like featuritis.  */
#define DEFAULT_TIMEOUT 1000 /* microseconds */

/* FIXME: These should allocated at run time and kept with other simulator
   state (duh...).  Later.  */
const char * sockser_addr = NULL;
/* Timeout in microseconds during status flag computation.
   Setting this to zero achieves proper busy wait semantics but eats cpu.  */
static unsigned int sockser_timeout = DEFAULT_TIMEOUT;
static int sockser_listen_fd = -1;
static int sockser_fd = -1;

/* FIXME: use tree properties when they're ready.  */

typedef enum {
  OPTION_ADDR = OPTION_START
} SOCKSER_OPTIONS;

static DECLARE_OPTION_HANDLER (sockser_option_handler);

static const OPTION sockser_options[] =
{
  { { "sockser-addr", required_argument, NULL, OPTION_ADDR },
      '\0', "SOCKET ADDRESS", "Set serial emulation socket address",
      sockser_option_handler, NULL },
  { { NULL, no_argument, NULL, 0 }, '\0', NULL, NULL, NULL, NULL }
};

static SIM_RC
sockser_option_handler (SIM_DESC sd, sim_cpu *cpu, int opt,
			char *arg, int is_command)
{
  switch (opt)
    {
    case OPTION_ADDR :
      sockser_addr = arg;
      break;
    }

  return SIM_RC_OK;
}

static SIM_RC
dv_sockser_init (SIM_DESC sd)
{
  struct hostent *hostent;
  struct sockaddr_in sockaddr;
  char hostname[100];
  const char *port_str;
  int tmp,port;

  if (STATE_ENVIRONMENT (sd) != OPERATING_ENVIRONMENT
      || sockser_addr == NULL)
    return SIM_RC_OK;

  if (*sockser_addr == '/')
    {
      /* support for these can come later */
      sim_io_eprintf (sd, "sockser init: unix domain sockets not supported: `%s'\n",
		      sockser_addr);
      return SIM_RC_FAIL;
    }

  port_str = strchr (sockser_addr, ':');
  if (!port_str)
    {
      sim_io_eprintf (sd, "sockser init: missing port number: `%s'\n",
		      sockser_addr);
      return SIM_RC_FAIL;
    }
  tmp = port_str - sockser_addr;
  if (tmp >= sizeof hostname)
    tmp = sizeof (hostname) - 1;
  strncpy (hostname, sockser_addr, tmp);
  hostname[tmp] = '\000';
  port = atoi (port_str + 1);

  hostent = gethostbyname (hostname);
  if (! hostent)
    {
      sim_io_eprintf (sd, "sockser init: unknown host: %s\n",
		      hostname);
      return SIM_RC_FAIL;
    }

  sockser_listen_fd = socket (PF_INET, SOCK_STREAM, 0);
  if (sockser_listen_fd == -1)
    {
      sim_io_eprintf (sd, "sockser init: unable to get socket: %s\n",
		      strerror (errno));
      return SIM_RC_FAIL;
    }

  sockaddr.sin_family = PF_INET;
  sockaddr.sin_port = htons (port);
  memcpy (&sockaddr.sin_addr.s_addr, hostent->h_addr,
	  sizeof (struct in_addr));

  tmp = 1;
  if (setsockopt (sockser_listen_fd, SOL_SOCKET, SO_REUSEADDR, (void*)& tmp, sizeof (tmp)) < 0)
    {
      sim_io_eprintf (sd, "sockser init: unable to set SO_REUSEADDR: %s\n",
		      strerror (errno));
    }
  if (bind (sockser_listen_fd, (struct sockaddr *) &sockaddr, sizeof (sockaddr)) < 0)
    {
      sim_io_eprintf (sd, "sockser init: unable to bind socket address: %s\n",
		      strerror (errno));
      close (sockser_listen_fd);
      sockser_listen_fd = -1;
      return SIM_RC_FAIL;
    }
  if (listen (sockser_listen_fd, 1) < 0)
    {
      sim_io_eprintf (sd, "sockser init: unable to set up listener: %s\n",
		      strerror (errno));
      close (sockser_listen_fd);
      sockser_listen_fd = -1;
      return SIM_RC_OK;
    }

  /* Handle writes to missing client -> SIGPIPE.
     ??? Need a central signal management module.  */
  {
    RETSIGTYPE (*orig) ();
    orig = signal (SIGPIPE, SIG_IGN);
    /* If a handler is already set up, don't mess with it.  */
    if (orig != SIG_DFL && orig != SIG_IGN)
      signal (SIGPIPE, orig);
  }

  return SIM_RC_OK;
}

static void
dv_sockser_uninstall (SIM_DESC sd)
{
  if (sockser_listen_fd != -1)
    {
      close (sockser_listen_fd);
      sockser_listen_fd = -1;
    }
  if (sockser_fd != -1)
    {
      close (sockser_fd);
      sockser_fd = -1;
    }
}

SIM_RC
dv_sockser_install (SIM_DESC sd)
{
  SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
  if (sim_add_option_table (sd, NULL, sockser_options) != SIM_RC_OK)
    return SIM_RC_FAIL;
  sim_module_add_init_fn (sd, dv_sockser_init);
  sim_module_add_uninstall_fn (sd, dv_sockser_uninstall);
  return SIM_RC_OK;
}

static int
connected_p (SIM_DESC sd)
{
  int numfds,flags;
  struct timeval tv;
  fd_set readfds;
  struct sockaddr sockaddr;
  socklen_t addrlen;

  if (sockser_listen_fd == -1)
    return 0;

  if (sockser_fd >= 0)
    {
      /* FIXME: has client gone away? */
      return 1;
    }

  /* Not connected.  Connect with a client if there is one.  */

  FD_ZERO (&readfds);
  FD_SET (sockser_listen_fd, &readfds);

  /* ??? One can certainly argue this should be done differently,
     but for now this is sufficient.  */
  tv.tv_sec = 0;
  tv.tv_usec = sockser_timeout;

  numfds = select (sockser_listen_fd + 1, &readfds, 0, 0, &tv);
  if (numfds <= 0)
    return 0;

  addrlen = sizeof (sockaddr);
  sockser_fd = accept (sockser_listen_fd, &sockaddr, &addrlen);
  if (sockser_fd == -1)
    return 0;

  /* Set non-blocking i/o.  */
  flags = fcntl (sockser_fd, F_GETFL);
  flags |= O_NONBLOCK | O_NDELAY;
  if (fcntl (sockser_fd, F_SETFL, flags) == -1)
    {
      sim_io_eprintf (sd, "unable to set nonblocking i/o");
      close (sockser_fd);
      sockser_fd = -1;
      return 0;
    }
  return 1;
}

int
dv_sockser_status (SIM_DESC sd)
{
  int numrfds,numwfds,status;
  struct timeval tv;
  fd_set readfds,writefds;

  /* status to return if the socket isn't set up, or select fails */
  status = DV_SOCKSER_INPUT_EMPTY | DV_SOCKSER_OUTPUT_EMPTY |
	   DV_SOCKSER_DISCONNECTED;

  if (! connected_p (sd))
    return status;

  FD_ZERO (&readfds);
  FD_ZERO (&writefds);
  FD_SET (sockser_fd, &readfds);
  FD_SET (sockser_fd, &writefds);

  /* ??? One can certainly argue this should be done differently,
     but for now this is sufficient.  The read is done separately
     from the write to enforce the delay which we heuristically set to
     once every SOCKSER_TIMEOUT_FREQ tries.
     No, this isn't great for SMP situations, blah blah blah.  */

  {
    static int n;
#define SOCKSER_TIMEOUT_FREQ 42
    if (++n == SOCKSER_TIMEOUT_FREQ)
      n = 0;
    if (n == 0)
      {
	tv.tv_sec = 0;
	tv.tv_usec = sockser_timeout;
	numrfds = select (sockser_fd + 1, &readfds, 0, 0, &tv);
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	numwfds = select (sockser_fd + 1, 0, &writefds, 0, &tv);
      }
    else /* do both selects at once */
      {
	tv.tv_sec = 0;
	tv.tv_usec = 0;
	numrfds = numwfds = select (sockser_fd + 1, &readfds, &writefds, 0, &tv);
      }
  }

  status = 0;
  if (numrfds <= 0 || ! FD_ISSET (sockser_fd, &readfds))
    status |= DV_SOCKSER_INPUT_EMPTY;
  if (numwfds <= 0 || FD_ISSET (sockser_fd, &writefds))
    status |= DV_SOCKSER_OUTPUT_EMPTY;
  return status;
}

int
dv_sockser_write_buffer (SIM_DESC sd, const unsigned char *buffer,
			 unsigned nr_bytes)
{
  int n;

  if (! connected_p (sd))
    return -1;
  n = write (sockser_fd, buffer, nr_bytes);
  if (n == -1)
    {
      if (errno == EPIPE)
	{
	  close (sockser_fd);
	  sockser_fd = -1;
	}
      return -1;
    }
  if (n != nr_bytes)
    return -1;
  return nr_bytes;
}

int
dv_sockser_write (SIM_DESC sd, unsigned char c)
{
  return dv_sockser_write_buffer (sd, &c, 1);
}

int
dv_sockser_read (SIM_DESC sd)
{
  unsigned char c;
  int n;

  if (! connected_p (sd))
    return -1;
  n = read (sockser_fd, &c, 1);
  /* ??? We're assuming semantics that may not be correct for all hosts.
     In particular (from cvssrc/src/server.c), this assumes that we are using
     BSD or POSIX nonblocking I/O.  System V nonblocking I/O returns zero if
     there is nothing to read.  */
  if (n == 0)
    {
      close (sockser_fd);
      sockser_fd = -1;
      return -1;
    }
  if (n != 1)
    return -1;
  return c;
}
