1/* Generic serial interface routines
2
3   Copyright (C) 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
4   2002, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
5
6   This file is part of GDB.
7
8   This program is free software; you can redistribute it and/or modify
9   it under the terms of the GNU General Public License as published by
10   the Free Software Foundation; either version 3 of the License, or
11   (at your option) any later version.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18   You should have received a copy of the GNU General Public License
19   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
20
21#include "defs.h"
22#include <ctype.h>
23#include "serial.h"
24#include "gdb_string.h"
25#include "gdbcmd.h"
26
27extern void _initialize_serial (void);
28
29/* Is serial being debugged? */
30
31static int global_serial_debug_p;
32
33/* Linked list of serial I/O handlers */
34
35static struct serial_ops *serial_ops_list = NULL;
36
37/* This is the last serial stream opened.  Used by connect command. */
38
39static struct serial *last_serial_opened = NULL;
40
41/* Pointer to list of scb's. */
42
43static struct serial *scb_base;
44
45/* Non-NULL gives filename which contains a recording of the remote session,
46   suitable for playback by gdbserver. */
47
48static char *serial_logfile = NULL;
49static struct ui_file *serial_logfp = NULL;
50
51static struct serial_ops *serial_interface_lookup (char *);
52static void serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout);
53static const char logbase_hex[] = "hex";
54static const char logbase_octal[] = "octal";
55static const char logbase_ascii[] = "ascii";
56static const char *logbase_enums[] =
57{logbase_hex, logbase_octal, logbase_ascii, NULL};
58static const char *serial_logbase = logbase_ascii;
59
60
61static int serial_current_type = 0;
62
63/* Log char CH of type CHTYPE, with TIMEOUT */
64
65/* Define bogus char to represent a BREAK.  Should be careful to choose a value
66   that can't be confused with a normal char, or an error code.  */
67#define SERIAL_BREAK 1235
68
69static void
70serial_logchar (struct ui_file *stream, int ch_type, int ch, int timeout)
71{
72  if (ch_type != serial_current_type)
73    {
74      fprintf_unfiltered (stream, "\n%c ", ch_type);
75      serial_current_type = ch_type;
76    }
77
78  if (serial_logbase != logbase_ascii)
79    fputc_unfiltered (' ', stream);
80
81  switch (ch)
82    {
83    case SERIAL_TIMEOUT:
84      fprintf_unfiltered (stream, "<Timeout: %d seconds>", timeout);
85      return;
86    case SERIAL_ERROR:
87      fprintf_unfiltered (stream, "<Error: %s>", safe_strerror (errno));
88      return;
89    case SERIAL_EOF:
90      fputs_unfiltered ("<Eof>", stream);
91      return;
92    case SERIAL_BREAK:
93      fputs_unfiltered ("<Break>", stream);
94      return;
95    default:
96      if (serial_logbase == logbase_hex)
97	fprintf_unfiltered (stream, "%02x", ch & 0xff);
98      else if (serial_logbase == logbase_octal)
99	fprintf_unfiltered (stream, "%03o", ch & 0xff);
100      else
101	switch (ch)
102	  {
103	  case '\\':
104	    fputs_unfiltered ("\\\\", stream);
105	    break;
106	  case '\b':
107	    fputs_unfiltered ("\\b", stream);
108	    break;
109	  case '\f':
110	    fputs_unfiltered ("\\f", stream);
111	    break;
112	  case '\n':
113	    fputs_unfiltered ("\\n", stream);
114	    break;
115	  case '\r':
116	    fputs_unfiltered ("\\r", stream);
117	    break;
118	  case '\t':
119	    fputs_unfiltered ("\\t", stream);
120	    break;
121	  case '\v':
122	    fputs_unfiltered ("\\v", stream);
123	    break;
124	  default:
125	    fprintf_unfiltered (stream, isprint (ch) ? "%c" : "\\x%02x", ch & 0xFF);
126	    break;
127	  }
128    }
129}
130
131void
132serial_log_command (const char *cmd)
133{
134  if (!serial_logfp)
135    return;
136
137  serial_current_type = 'c';
138
139  fputs_unfiltered ("\nc ", serial_logfp);
140  fputs_unfiltered (cmd, serial_logfp);
141
142  /* Make sure that the log file is as up-to-date as possible,
143     in case we are getting ready to dump core or something. */
144  gdb_flush (serial_logfp);
145}
146
147
148static struct serial_ops *
149serial_interface_lookup (char *name)
150{
151  struct serial_ops *ops;
152
153  for (ops = serial_ops_list; ops; ops = ops->next)
154    if (strcmp (name, ops->name) == 0)
155      return ops;
156
157  return NULL;
158}
159
160void
161serial_add_interface (struct serial_ops *optable)
162{
163  optable->next = serial_ops_list;
164  serial_ops_list = optable;
165}
166
167/* Open up a device or a network socket, depending upon the syntax of NAME. */
168
169struct serial *
170serial_open (const char *name)
171{
172  struct serial *scb;
173  struct serial_ops *ops;
174  const char *open_name = name;
175
176  for (scb = scb_base; scb; scb = scb->next)
177    if (scb->name && strcmp (scb->name, name) == 0)
178      {
179	scb->refcnt++;
180	return scb;
181      }
182
183  if (strcmp (name, "pc") == 0)
184    ops = serial_interface_lookup ("pc");
185  else if (strncmp (name, "lpt", 3) == 0)
186    ops = serial_interface_lookup ("parallel");
187  else if (strncmp (name, "|", 1) == 0)
188    {
189      ops = serial_interface_lookup ("pipe");
190      /* Discard ``|'' and any space before the command itself.  */
191      ++open_name;
192      while (isspace (*open_name))
193	++open_name;
194    }
195  /* Check for a colon, suggesting an IP address/port pair.
196     Do this *after* checking for all the interesting prefixes.  We
197     don't want to constrain the syntax of what can follow them.  */
198  else if (strchr (name, ':'))
199    ops = serial_interface_lookup ("tcp");
200  else
201    ops = serial_interface_lookup ("hardwire");
202
203  if (!ops)
204    return NULL;
205
206  scb = XMALLOC (struct serial);
207
208  scb->ops = ops;
209
210  scb->bufcnt = 0;
211  scb->bufp = scb->buf;
212  scb->error_fd = -1;
213
214  /* `...->open (...)' would get expanded by an the open(2) syscall macro.  */
215  if ((*scb->ops->open) (scb, open_name))
216    {
217      xfree (scb);
218      return NULL;
219    }
220
221  scb->name = xstrdup (name);
222  scb->next = scb_base;
223  scb->refcnt = 1;
224  scb->debug_p = 0;
225  scb->async_state = 0;
226  scb->async_handler = NULL;
227  scb->async_context = NULL;
228  scb_base = scb;
229
230  last_serial_opened = scb;
231
232  if (serial_logfile != NULL)
233    {
234      serial_logfp = gdb_fopen (serial_logfile, "w");
235      if (serial_logfp == NULL)
236	perror_with_name (serial_logfile);
237    }
238
239  return scb;
240}
241
242/* Return the open serial device for FD, if found, or NULL if FD
243   is not already opened.  */
244
245struct serial *
246serial_for_fd (int fd)
247{
248  struct serial *scb;
249  struct serial_ops *ops;
250
251  for (scb = scb_base; scb; scb = scb->next)
252    if (scb->fd == fd)
253      return scb;
254
255  return NULL;
256}
257
258struct serial *
259serial_fdopen (const int fd)
260{
261  struct serial *scb;
262  struct serial_ops *ops;
263
264  for (scb = scb_base; scb; scb = scb->next)
265    if (scb->fd == fd)
266      {
267	scb->refcnt++;
268	return scb;
269      }
270
271  ops = serial_interface_lookup ("terminal");
272  if (!ops)
273    ops = serial_interface_lookup ("hardwire");
274
275  if (!ops)
276    return NULL;
277
278  scb = XCALLOC (1, struct serial);
279
280  scb->ops = ops;
281
282  scb->bufcnt = 0;
283  scb->bufp = scb->buf;
284
285  scb->fd = fd;
286
287  scb->name = NULL;
288  scb->next = scb_base;
289  scb->refcnt = 1;
290  scb->debug_p = 0;
291  scb->async_state = 0;
292  scb->async_handler = NULL;
293  scb->async_context = NULL;
294  scb_base = scb;
295
296  last_serial_opened = scb;
297
298  return scb;
299}
300
301static void
302do_serial_close (struct serial *scb, int really_close)
303{
304  struct serial *tmp_scb;
305
306  last_serial_opened = NULL;
307
308  if (serial_logfp)
309    {
310      fputs_unfiltered ("\nEnd of log\n", serial_logfp);
311      serial_current_type = 0;
312
313      /* XXX - What if serial_logfp == gdb_stdout or gdb_stderr? */
314      ui_file_delete (serial_logfp);
315      serial_logfp = NULL;
316    }
317
318/* This is bogus.  It's not our fault if you pass us a bad scb...!  Rob, you
319   should fix your code instead.  */
320
321  if (!scb)
322    return;
323
324  scb->refcnt--;
325  if (scb->refcnt > 0)
326    return;
327
328  /* ensure that the FD has been taken out of async mode */
329  if (scb->async_handler != NULL)
330    serial_async (scb, NULL, NULL);
331
332  if (really_close)
333    scb->ops->close (scb);
334
335  if (scb->name)
336    xfree (scb->name);
337
338  if (scb_base == scb)
339    scb_base = scb_base->next;
340  else
341    for (tmp_scb = scb_base; tmp_scb; tmp_scb = tmp_scb->next)
342      {
343	if (tmp_scb->next != scb)
344	  continue;
345
346	tmp_scb->next = tmp_scb->next->next;
347	break;
348      }
349
350  xfree (scb);
351}
352
353void
354serial_close (struct serial *scb)
355{
356  do_serial_close (scb, 1);
357}
358
359void
360serial_un_fdopen (struct serial *scb)
361{
362  do_serial_close (scb, 0);
363}
364
365int
366serial_readchar (struct serial *scb, int timeout)
367{
368  int ch;
369
370  /* FIXME: cagney/1999-10-11: Don't enable this check until the ASYNC
371     code is finished. */
372  if (0 && serial_is_async_p (scb) && timeout < 0)
373    internal_error (__FILE__, __LINE__,
374		    _("serial_readchar: blocking read in async mode"));
375
376  ch = scb->ops->readchar (scb, timeout);
377  if (serial_logfp != NULL)
378    {
379      serial_logchar (serial_logfp, 'r', ch, timeout);
380
381      /* Make sure that the log file is as up-to-date as possible,
382         in case we are getting ready to dump core or something. */
383      gdb_flush (serial_logfp);
384    }
385  if (serial_debug_p (scb))
386    {
387      fprintf_unfiltered (gdb_stdlog, "[");
388      serial_logchar (gdb_stdlog, 'r', ch, timeout);
389      fprintf_unfiltered (gdb_stdlog, "]");
390      gdb_flush (gdb_stdlog);
391    }
392
393  return (ch);
394}
395
396int
397serial_write (struct serial *scb, const char *str, int len)
398{
399  if (serial_logfp != NULL)
400    {
401      int count;
402
403      for (count = 0; count < len; count++)
404	serial_logchar (serial_logfp, 'w', str[count] & 0xff, 0);
405
406      /* Make sure that the log file is as up-to-date as possible,
407         in case we are getting ready to dump core or something. */
408      gdb_flush (serial_logfp);
409    }
410
411  return (scb->ops->write (scb, str, len));
412}
413
414void
415serial_printf (struct serial *desc, const char *format,...)
416{
417  va_list args;
418  char *buf;
419  va_start (args, format);
420
421  buf = xstrvprintf (format, args);
422  serial_write (desc, buf, strlen (buf));
423
424  xfree (buf);
425  va_end (args);
426}
427
428int
429serial_drain_output (struct serial *scb)
430{
431  return scb->ops->drain_output (scb);
432}
433
434int
435serial_flush_output (struct serial *scb)
436{
437  return scb->ops->flush_output (scb);
438}
439
440int
441serial_flush_input (struct serial *scb)
442{
443  return scb->ops->flush_input (scb);
444}
445
446int
447serial_send_break (struct serial *scb)
448{
449  if (serial_logfp != NULL)
450    serial_logchar (serial_logfp, 'w', SERIAL_BREAK, 0);
451
452  return (scb->ops->send_break (scb));
453}
454
455void
456serial_raw (struct serial *scb)
457{
458  scb->ops->go_raw (scb);
459}
460
461serial_ttystate
462serial_get_tty_state (struct serial *scb)
463{
464  return scb->ops->get_tty_state (scb);
465}
466
467int
468serial_set_tty_state (struct serial *scb, serial_ttystate ttystate)
469{
470  return scb->ops->set_tty_state (scb, ttystate);
471}
472
473void
474serial_print_tty_state (struct serial *scb,
475			serial_ttystate ttystate,
476			struct ui_file *stream)
477{
478  scb->ops->print_tty_state (scb, ttystate, stream);
479}
480
481int
482serial_noflush_set_tty_state (struct serial *scb,
483			      serial_ttystate new_ttystate,
484			      serial_ttystate old_ttystate)
485{
486  return scb->ops->noflush_set_tty_state (scb, new_ttystate, old_ttystate);
487}
488
489int
490serial_setbaudrate (struct serial *scb, int rate)
491{
492  return scb->ops->setbaudrate (scb, rate);
493}
494
495int
496serial_setstopbits (struct serial *scb, int num)
497{
498  return scb->ops->setstopbits (scb, num);
499}
500
501int
502serial_can_async_p (struct serial *scb)
503{
504  return (scb->ops->async != NULL);
505}
506
507int
508serial_is_async_p (struct serial *scb)
509{
510  return (scb->ops->async != NULL) && (scb->async_handler != NULL);
511}
512
513void
514serial_async (struct serial *scb,
515	      serial_event_ftype *handler,
516	      void *context)
517{
518  /* Only change mode if there is a need. */
519  if ((scb->async_handler == NULL)
520      != (handler == NULL))
521    scb->ops->async (scb, handler != NULL);
522  scb->async_handler = handler;
523  scb->async_context = context;
524}
525
526int
527deprecated_serial_fd (struct serial *scb)
528{
529  /* FIXME: should this output a warning that deprecated code is being
530     called? */
531  if (scb->fd < 0)
532    {
533      internal_error (__FILE__, __LINE__,
534		      _("serial: FD not valid"));
535    }
536  return scb->fd; /* sigh */
537}
538
539void
540serial_debug (struct serial *scb, int debug_p)
541{
542  scb->debug_p = debug_p;
543}
544
545int
546serial_debug_p (struct serial *scb)
547{
548  return scb->debug_p || global_serial_debug_p;
549}
550
551#ifdef USE_WIN32API
552void
553serial_wait_handle (struct serial *scb, HANDLE *read, HANDLE *except)
554{
555  if (scb->ops->wait_handle)
556    scb->ops->wait_handle (scb, read, except);
557  else
558    {
559      *read = (HANDLE) _get_osfhandle (scb->fd);
560      *except = NULL;
561    }
562}
563
564void
565serial_done_wait_handle (struct serial *scb)
566{
567  if (scb->ops->done_wait_handle)
568    scb->ops->done_wait_handle (scb);
569}
570#endif
571
572#if 0
573/* The connect command is #if 0 because I hadn't thought of an elegant
574   way to wait for I/O on two `struct serial *'s simultaneously.  Two
575   solutions came to mind:
576
577   1) Fork, and have have one fork handle the to user direction,
578   and have the other hand the to target direction.  This
579   obviously won't cut it for MSDOS.
580
581   2) Use something like select.  This assumes that stdin and
582   the target side can both be waited on via the same
583   mechanism.  This may not be true for DOS, if GDB is
584   talking to the target via a TCP socket.
585   -grossman, 8 Jun 93 */
586
587/* Connect the user directly to the remote system.  This command acts just like
588   the 'cu' or 'tip' command.  Use <CR>~. or <CR>~^D to break out.  */
589
590static struct serial *tty_desc;	/* Controlling terminal */
591
592static void
593cleanup_tty (serial_ttystate ttystate)
594{
595  printf_unfiltered ("\r\n[Exiting connect mode]\r\n");
596  serial_set_tty_state (tty_desc, ttystate);
597  xfree (ttystate);
598  serial_close (tty_desc);
599}
600
601static void
602connect_command (char *args, int fromtty)
603{
604  int c;
605  char cur_esc = 0;
606  serial_ttystate ttystate;
607  struct serial *port_desc;		/* TTY port */
608
609  dont_repeat ();
610
611  if (args)
612    fprintf_unfiltered (gdb_stderr, "This command takes no args.  They have been ignored.\n");
613
614  printf_unfiltered ("[Entering connect mode.  Use ~. or ~^D to escape]\n");
615
616  tty_desc = serial_fdopen (0);
617  port_desc = last_serial_opened;
618
619  ttystate = serial_get_tty_state (tty_desc);
620
621  serial_raw (tty_desc);
622  serial_raw (port_desc);
623
624  make_cleanup (cleanup_tty, ttystate);
625
626  while (1)
627    {
628      int mask;
629
630      mask = serial_wait_2 (tty_desc, port_desc, -1);
631
632      if (mask & 2)
633	{			/* tty input */
634	  char cx;
635
636	  while (1)
637	    {
638	      c = serial_readchar (tty_desc, 0);
639
640	      if (c == SERIAL_TIMEOUT)
641		break;
642
643	      if (c < 0)
644		perror_with_name (_("connect"));
645
646	      cx = c;
647	      serial_write (port_desc, &cx, 1);
648
649	      switch (cur_esc)
650		{
651		case 0:
652		  if (c == '\r')
653		    cur_esc = c;
654		  break;
655		case '\r':
656		  if (c == '~')
657		    cur_esc = c;
658		  else
659		    cur_esc = 0;
660		  break;
661		case '~':
662		  if (c == '.' || c == '\004')
663		    return;
664		  else
665		    cur_esc = 0;
666		}
667	    }
668	}
669
670      if (mask & 1)
671	{			/* Port input */
672	  char cx;
673
674	  while (1)
675	    {
676	      c = serial_readchar (port_desc, 0);
677
678	      if (c == SERIAL_TIMEOUT)
679		break;
680
681	      if (c < 0)
682		perror_with_name (_("connect"));
683
684	      cx = c;
685
686	      serial_write (tty_desc, &cx, 1);
687	    }
688	}
689    }
690}
691#endif /* 0 */
692
693/* Serial set/show framework.  */
694
695static struct cmd_list_element *serial_set_cmdlist;
696static struct cmd_list_element *serial_show_cmdlist;
697
698static void
699serial_set_cmd (char *args, int from_tty)
700{
701  printf_unfiltered ("\"set serial\" must be followed by the name of a command.\n");
702  help_list (serial_set_cmdlist, "set serial ", -1, gdb_stdout);
703}
704
705static void
706serial_show_cmd (char *args, int from_tty)
707{
708  cmd_show_list (serial_show_cmdlist, from_tty, "");
709}
710
711
712void
713_initialize_serial (void)
714{
715#if 0
716  add_com ("connect", class_obscure, connect_command, _("\
717Connect the terminal directly up to the command monitor.\n\
718Use <CR>~. or <CR>~^D to break out."));
719#endif /* 0 */
720
721  add_prefix_cmd ("serial", class_maintenance, serial_set_cmd, _("\
722Set default serial/parallel port configuration."),
723		  &serial_set_cmdlist, "set serial ",
724		  0/*allow-unknown*/,
725		  &setlist);
726
727  add_prefix_cmd ("serial", class_maintenance, serial_show_cmd, _("\
728Show default serial/parallel port configuration."),
729		  &serial_show_cmdlist, "show serial ",
730		  0/*allow-unknown*/,
731		  &showlist);
732
733  add_setshow_filename_cmd ("remotelogfile", no_class, &serial_logfile, _("\
734Set filename for remote session recording."), _("\
735Show filename for remote session recording."), _("\
736This file is used to record the remote session for future playback\n\
737by gdbserver."),
738			    NULL,
739			    NULL, /* FIXME: i18n: */
740			    &setlist, &showlist);
741
742  add_setshow_enum_cmd ("remotelogbase", no_class, logbase_enums,
743			&serial_logbase, _("\
744Set numerical base for remote session logging"), _("\
745Show numerical base for remote session logging"), NULL,
746			NULL,
747			NULL, /* FIXME: i18n: */
748			&setlist, &showlist);
749
750  add_setshow_zinteger_cmd ("serial", class_maintenance,
751			    &global_serial_debug_p, _("\
752Set serial debugging."), _("\
753Show serial debugging."), _("\
754When non-zero, serial port debugging is enabled."),
755			    NULL,
756			    NULL, /* FIXME: i18n: */
757			    &setdebuglist, &showdebuglist);
758}
759