/* Serial port emulation using sockets.
   Copyright (C) 1998-2024 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.  */

/* This must come before any other includes.  */
#include "defs.h"

#include <errno.h>
#ifdef HAVE_FCNTL_H
#include <fcntl.h>
#endif
#include <netdb.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/select.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <sys/types.h>

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

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

/* 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.  */
#ifdef SIGPIPE
  {
    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);
  }
#endif

  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;
    }
}

/* Provide a prototype to silence -Wmissing-prototypes.  */
extern MODULE_INIT_FN sim_install_dv_sockser;

SIM_RC
sim_install_dv_sockser (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.  */
#if defined(F_GETFL) && defined(O_NONBLOCK)
  flags = fcntl (sockser_fd, F_GETFL);
  flags |= O_NONBLOCK;
  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;
    }
#endif
  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;
}
