/* Generic serial interface routines
   Copyright 1992, 1993, 1996, 1997, 1999, 2000 Free Software Foundation, Inc.

   This file is part of GDB.

   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 2 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, write to the Free Software
   Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.  */

#include "defs.h"
#include <ctype.h>
#include "serial.h"
#include "gdb_string.h"
#include "gdbcmd.h"

extern void _initialize_serial (void);

/* Is serial being debugged? */

static int global_serial_debug_p;

/* Linked list of serial I/O handlers */

static struct serial_ops *serial_ops_list = NULL;

/* This is the last serial stream opened.  Used by connect command. */

static serial_t last_serial_opened = NULL;

/* Pointer to list of scb's. */

static serial_t scb_base;

/* Non-NULL gives filename which contains a recording of the remote session,
   suitable for playback by gdbserver. */

static char *serial_logfile = NULL;
static struct ui_file *serial_logfp = NULL;

static struct serial_ops *serial_interface_lookup (char *);
static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout);
static char logbase_hex[] = "hex";
static char logbase_octal[] = "octal";
static char logbase_ascii[] = "ascii";
static char *logbase_enums[] =
{logbase_hex, logbase_octal, logbase_ascii, NULL};
static char *serial_logbase = logbase_ascii;



static int serial_current_type = 0;

/* Log char CH of type CHTYPE, with TIMEOUT */

/* Define bogus char to represent a BREAK.  Should be careful to choose a value
   that can't be confused with a normal char, or an error code.  */
#define SERIAL_BREAK 1235

static void
serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
{
  if (ch_type != serial_current_type)
    {
      fprintf_unfiltered (stream, "\n%c ", ch_type);
      serial_current_type = ch_type;
    }

  if (serial_logbase != logbase_ascii)
    fputc_unfiltered (' ', stream);

  switch (ch)
    {
    case SERIAL_TIMEOUT:
      fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
      return;
    case SERIAL_ERROR:
      fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
      return;
    case SERIAL_EOF:
      fputs_unfiltered ("<Eof>", stream);
      return;
    case SERIAL_BREAK:
      fputs_unfiltered ("<Break>", stream);
      return;
    default:
      if (serial_logbase == logbase_hex)
	fprintf_unfiltered (stream, "%02x", ch & 0xff);
      else if (serial_logbase == logbase_octal)
	fprintf_unfiltered (stream, "%03o", ch & 0xff);
      else
	switch (ch)
	  {
	  case '\\':
	    fputs_unfiltered ("\\\\", stream);
	    break;
	  case '\b':
	    fputs_unfiltered ("\\b", stream);
	    break;
	  case '\f':
	    fputs_unfiltered ("\\f", stream);
	    break;
	  case '\n':
	    fputs_unfiltered ("\\n", stream);
	    break;
	  case '\r':
	    fputs_unfiltered ("\\r", stream);
	    break;
	  case '\t':
	    fputs_unfiltered ("\\t", stream);
	    break;
	  case '\v':
	    fputs_unfiltered ("\\v", stream);
	    break;
	  default:
	    fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
	    break;
	  }
    }
}

void
serial_log_command (const char *cmd)
{
  if (!serial_logfp)
    return;

  serial_current_type = 'c';

  fputs_unfiltered ("\nc ", serial_logfp);
  fputs_unfiltered (cmd, serial_logfp);

  /* Make sure that the log file is as up-to-date as possible,
     in case we are getting ready to dump core or something. */
  gdb_flush (serial_logfp);
}


static struct serial_ops *
serial_interface_lookup (char *name)
{
  struct serial_ops *ops;

  for (ops = serial_ops_list; ops; ops = ops->next)
    if (strcmp (name, ops->name) == 0)
      return ops;

  return NULL;
}

void
serial_add_interface (struct serial_ops *optable)
{
  optable->next = serial_ops_list;
  serial_ops_list = optable;
}

/* Open up a device or a network socket, depending upon the syntax of NAME. */

serial_t
serial_open (const char *name)
{
  serial_t scb;
  struct serial_ops *ops;
  const char *open_name = name;

  for (scb = scb_base; scb; scb = scb->next)
    if (scb->name && strcmp (scb->name, name) == 0)
      {
	scb->refcnt++;
	return scb;
      }

  if (strcmp (name, "ocd") == 0)
    ops = serial_interface_lookup ("ocd");
  else if (strcmp (name, "pc") == 0)
    ops = serial_interface_lookup ("pc");
  else if (strchr (name, ':'))
    ops = serial_interface_lookup ("tcp");
  else if (strncmp (name, "lpt", 3) == 0)
    ops = serial_interface_lookup ("parallel");
  else if (strncmp (name, "|", 1) == 0)
    {
      ops = serial_interface_lookup ("pipe");
      open_name = name + 1; /* discard ``|'' */
    }
  else
    ops = serial_interface_lookup ("hardwire");

  if (!ops)
    return NULL;

  scb = (serial_t) xmalloc (sizeof (struct _serial_t));

  scb->ops = ops;

  scb->bufcnt = 0;
  scb->bufp = scb->buf;

  if (scb->ops->open (scb, open_name))
    {
      free (scb);
      return NULL;
    }

  scb->name = strsave (name);
  scb->next = scb_base;
  scb->refcnt = 1;
  scb->debug_p = 0;
  scb->async_state = 0;
  scb->async_handler = NULL;
  scb->async_context = NULL;
  scb_base = scb;

  last_serial_opened = scb;

  if (serial_logfile != NULL)
    {
      serial_logfp = gdb_fopen (serial_logfile, "w");
      if (serial_logfp == NULL)
	perror_with_name (serial_logfile);
    }

  return scb;
}

serial_t
serial_fdopen (const int fd)
{
  serial_t scb;
  struct serial_ops *ops;

  for (scb = scb_base; scb; scb = scb->next)
    if (scb->fd == fd)
      {
	scb->refcnt++;
	return scb;
      }

  ops = serial_interface_lookup ("hardwire");

  if (!ops)
    return NULL;

  scb = (serial_t) xmalloc (sizeof (struct _serial_t));

  scb->ops = ops;

  scb->bufcnt = 0;
  scb->bufp = scb->buf;

  scb->fd = fd;

  scb->name = NULL;
  scb->next = scb_base;
  scb->refcnt = 1;
  scb->debug_p = 0;
  scb->async_state = 0;
  scb->async_handler = NULL;
  scb->async_context = NULL;
  scb_base = scb;

  last_serial_opened = scb;

  return scb;
}

static void
do_serial_close (serial_t scb, int really_close)
{
  serial_t tmp_scb;

  last_serial_opened = NULL;

  if (serial_logfp)
    {
      fputs_unfiltered ("\nEnd of log\n", serial_logfp);
      serial_current_type = 0;

      /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
      ui_file_delete (serial_logfp);
      serial_logfp = NULL;
    }

/* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
   should fix your code instead.  */

  if (!scb)
    return;

  scb->refcnt--;
  if (scb->refcnt > 0)
    return;

  /* ensure that the FD has been taken out of async mode */
  if (scb->async_handler != NULL)
    serial_async (scb, NULL, NULL);

  if (really_close)
    scb->ops->close (scb);

  if (scb->name)
    free (scb->name);

  if (scb_base == scb)
    scb_base = scb_base->next;
  else
    for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
      {
	if (tmp_scb->next != scb)
	  continue;

	tmp_scb->next = tmp_scb->next->next;
	break;
      }

  free (scb);
}

void
serial_close (serial_t scb)
{
  do_serial_close (scb, 1);
}

void
serial_un_fdopen (serial_t scb)
{
  do_serial_close (scb, 0);
}

int
serial_readchar (serial_t scb, int timeout)
{
  int ch;

  /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
     code is finished. */
  if (0 && SERIAL_IS_ASYNC_P (scb) && timeout < 0)
    internal_error ("serial_readchar: blocking read in async mode");

  ch = scb->ops->readchar (scb, timeout);
  if (serial_logfp != NULL)
    {
      serial_logchar (serial_logfp, 'r', ch, timeout);

      /* Make sure that the log file is as up-to-date as possible,
         in case we are getting ready to dump core or something. */
      gdb_flush (serial_logfp);
    }
  if (SERIAL_DEBUG_P (scb))
    {
      fprintf_unfiltered (gdb_stdlog, "[");
      serial_logchar (gdb_stdlog, 'r', ch, timeout);
      fprintf_unfiltered (gdb_stdlog, "]");
      gdb_flush (gdb_stdlog);
    }

  return (ch);
}

int
serial_write (serial_t scb, const char *str, int len)
{
  if (serial_logfp != NULL)
    {
      int count;

      for (count = 0; count < len; count++)
	serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);

      /* Make sure that the log file is as up-to-date as possible,
         in case we are getting ready to dump core or something. */
      gdb_flush (serial_logfp);
    }

  return (scb->ops->write (scb, str, len));
}

void
serial_printf (serial_t desc, const char *format,...)
{
  va_list args;
  char *buf;
  va_start (args, format);

  vasprintf (&buf, format, args);
  SERIAL_WRITE (desc, buf, strlen (buf));

  free (buf);
  va_end (args);
}

int
serial_drain_output (serial_t scb)
{
  return scb->ops->drain_output (scb);
}

int
serial_flush_output (serial_t scb)
{
  return scb->ops->flush_output (scb);
}

int
serial_flush_input (serial_t scb)
{
  return scb->ops->flush_input (scb);
}

int
serial_send_break (serial_t scb)
{
  if (serial_logfp != NULL)
    serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);

  return (scb->ops->send_break (scb));
}

void
serial_raw (serial_t scb)
{
  scb->ops->go_raw (scb);
}

serial_ttystate
serial_get_tty_state (serial_t scb)
{
  return scb->ops->get_tty_state (scb);
}

int
serial_set_tty_state (serial_t scb, serial_ttystate ttystate)
{
  return scb->ops->set_tty_state (scb, ttystate);
}

void
serial_print_tty_state (serial_t scb,
			serial_ttystate ttystate,
			struct ui_file *stream)
{
  scb->ops->print_tty_state (scb, ttystate, stream);
}

int
serial_noflush_set_tty_state (serial_t scb,
			      serial_ttystate new_ttystate,
			      serial_ttystate old_ttystate)
{
  return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
}

int
serial_setbaudrate (serial_t scb, int rate)
{
  return scb->ops->setbaudrate (scb, rate);
}

int
serial_setstopbits (serial_t scb, int num)
{
  return scb->ops->setstopbits (scb, num);
}

int
serial_can_async_p (serial_t scb)
{
  return (scb->ops->async != NULL);
}

int
serial_is_async_p (serial_t scb)
{
  return (scb->ops->async != NULL) && (scb->async_handler != NULL);
}

void
serial_async (serial_t scb,
	      serial_event_ftype *handler,
	      void *context)
{
  /* Only change mode if there is a need. */
  if ((scb->async_handler == NULL)
      != (handler == NULL))
    scb->ops->async (scb, handler != NULL);
  scb->async_handler = handler;
  scb->async_context = context;
}

int
deprecated_serial_fd (serial_t scb)
{
  /* FIXME: should this output a warning that deprecated code is being
     called? */
  if (scb->fd < 0)
    {
      internal_error ("serial: FD not valid");
    }
  return scb->fd; /* sigh */
}

void
serial_debug (serial_t scb, int debug_p)
{
  scb->debug_p = debug_p;
}

int
serial_debug_p (serial_t scb)
{
  return scb->debug_p || global_serial_debug_p;
}


#if 0
/*
   The connect command is #if 0 because I hadn't thought of an elegant
   way to wait for I/O on two serial_t's simultaneously.  Two solutions
   came to mind:

   1) Fork, and have have one fork handle the to user direction,
   and have the other hand the to target direction.  This
   obviously won't cut it for MSDOS.

   2) Use something like select.  This assumes that stdin and
   the target side can both be waited on via the same
   mechanism.  This may not be true for DOS, if GDB is
   talking to the target via a TCP socket.
   -grossman, 8 Jun 93
 */

/* Connect the user directly to the remote system.  This command acts just like
   the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */

static serial_t tty_desc;	/* Controlling terminal */

static void
cleanup_tty (serial_ttystate ttystate)
{
  printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
  SERIAL_SET_TTY_STATE (tty_desc, ttystate);
  free (ttystate);
  SERIAL_CLOSE (tty_desc);
}

static void
connect_command (char *args, int fromtty)
{
  int c;
  char cur_esc = 0;
  serial_ttystate ttystate;
  serial_t port_desc;		/* TTY port */

  dont_repeat ();

  if (args)
    fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");

  printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");

  tty_desc = SERIAL_FDOPEN (0);
  port_desc = last_serial_opened;

  ttystate = SERIAL_GET_TTY_STATE (tty_desc);

  SERIAL_RAW (tty_desc);
  SERIAL_RAW (port_desc);

  make_cleanup (cleanup_tty, ttystate);

  while (1)
    {
      int mask;

      mask = SERIAL_WAIT_2 (tty_desc, port_desc, -1);

      if (mask & 2)
	{			/* tty input */
	  char cx;

	  while (1)
	    {
	      c = SERIAL_READCHAR (tty_desc, 0);

	      if (c == SERIAL_TIMEOUT)
		break;

	      if (c < 0)
		perror_with_name ("connect");

	      cx = c;
	      SERIAL_WRITE (port_desc, &cx, 1);

	      switch (cur_esc)
		{
		case 0:
		  if (c == '\r')
		    cur_esc = c;
		  break;
		case '\r':
		  if (c == '~')
		    cur_esc = c;
		  else
		    cur_esc = 0;
		  break;
		case '~':
		  if (c == '.' || c == '\004')
		    return;
		  else
		    cur_esc = 0;
		}
	    }
	}

      if (mask & 1)
	{			/* Port input */
	  char cx;

	  while (1)
	    {
	      c = SERIAL_READCHAR (port_desc, 0);

	      if (c == SERIAL_TIMEOUT)
		break;

	      if (c < 0)
		perror_with_name ("connect");

	      cx = c;

	      SERIAL_WRITE (tty_desc, &cx, 1);
	    }
	}
    }
}
#endif /* 0 */

void
_initialize_serial (void)
{
#if 0
  add_com ("connect", class_obscure, connect_command,
	   "Connect the terminal directly up to the command monitor.\n\
Use <CR>~. or <CR>~^D to break out.");
#endif /* 0 */

  add_show_from_set
    (add_set_cmd ("remotelogfile", no_class,
		  var_filename, (char *) &serial_logfile,
		  "Set filename for remote session recording.\n\
This file is used to record the remote session for future playback\n\
by gdbserver.",
		  &setlist),
     &showlist);

  add_show_from_set
    (add_set_enum_cmd ("remotelogbase", no_class,
		       logbase_enums, (char *) &serial_logbase,
		       "Set numerical base for remote session logging",
		       &setlist),
     &showlist);

  add_show_from_set (add_set_cmd ("serialdebug",
				  class_maintenance,
				  var_zinteger,
				  (char *)&global_serial_debug_p,
				  "Set serial debugging.\n\
When non-zero, serial port debugging is enabled.", &setlist),
		     &showlist);
}
