* fhandler.h (class fhandler_serial): Add new members of
the class - rts,dtr and method ioctl(). Variables rts and dtr important for Win 9x only. * fhandler_serial.cc (fhandler_serial::open): Add initial setting of dtr and rts. Important for Win 9x only. (fhandler_serial::ioctl): New function. Implements commands TIOCMGET, TIOCMSET and TIOCINQ. (fhandler_serial::tcflush): Fixed found error. (fhandler_serial::tcsetattr): Add settings of rts and dtr. Important for Win 9x only. * termios.h: Add new defines as a support for ioctl() function on serial device.
This commit is contained in:
		| @@ -1,3 +1,18 @@ | |||||||
|  | 2002-07-22  Jacek Trzcinski <jacek@certum.pl> | ||||||
|  |  | ||||||
|  | 	* fhandler.h (class fhandler_serial): Add new members of | ||||||
|  | 	the class - rts,dtr and method ioctl(). Variables rts and dtr | ||||||
|  | 	important for Win 9x only. | ||||||
|  | 	* fhandler_serial.cc (fhandler_serial::open): Add initial setting | ||||||
|  | 	of dtr and rts. Important for Win 9x only. | ||||||
|  | 	(fhandler_serial::ioctl): New function. Implements commands TIOCMGET, | ||||||
|  | 	TIOCMSET and TIOCINQ. | ||||||
|  | 	(fhandler_serial::tcflush): Fixed found error. | ||||||
|  | 	(fhandler_serial::tcsetattr): Add settings of rts and dtr. Important | ||||||
|  | 	for Win 9x only. | ||||||
|  | 	* termios.h: Add new defines as a support for ioctl() function   | ||||||
|  | 	on serial device. | ||||||
|  |  | ||||||
| 2002-07-20  Christopher Faylor  <cgf@redhat.com> | 2002-07-20  Christopher Faylor  <cgf@redhat.com> | ||||||
|  |  | ||||||
| 	* autoload.cc (LoadDLLprime): Add jmp call to allow streamlining of | 	* autoload.cc (LoadDLLprime): Add jmp call to allow streamlining of | ||||||
|   | |||||||
| @@ -629,6 +629,8 @@ class fhandler_serial: public fhandler_base | |||||||
|   unsigned int vmin_;			/* from termios */ |   unsigned int vmin_;			/* from termios */ | ||||||
|   unsigned int vtime_;			/* from termios */ |   unsigned int vtime_;			/* from termios */ | ||||||
|   pid_t pgrp_; |   pid_t pgrp_; | ||||||
|  |   int rts;				/* for Windows 9x purposes only */ | ||||||
|  |   int dtr;				/* for Windows 9x purposes only */ | ||||||
|  |  | ||||||
|  public: |  public: | ||||||
|   int overlapped_armed; |   int overlapped_armed; | ||||||
| @@ -648,6 +650,7 @@ class fhandler_serial: public fhandler_base | |||||||
|   int tcsendbreak (int); |   int tcsendbreak (int); | ||||||
|   int tcdrain (); |   int tcdrain (); | ||||||
|   int tcflow (int); |   int tcflow (int); | ||||||
|  |   int ioctl (unsigned int cmd, void *); | ||||||
|   int tcsetattr (int a, const struct termios *t); |   int tcsetattr (int a, const struct termios *t); | ||||||
|   int tcgetattr (struct termios *t); |   int tcgetattr (struct termios *t); | ||||||
|   __off64_t lseek (__off64_t, int) { return 0; } |   __off64_t lseek (__off64_t, int) { return 0; } | ||||||
|   | |||||||
| @@ -268,6 +268,23 @@ fhandler_serial::open (path_conv *, int flags, mode_t mode) | |||||||
| 	system_printf ("couldn't set initial state for %s, %E", get_name ()); | 	system_printf ("couldn't set initial state for %s, %E", get_name ()); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|  |   /* setting rts and dtr to known state so that ioctl() function with | ||||||
|  |   request TIOCMGET could return correct value of RTS and DTR lines.  | ||||||
|  |   Important only for Win 9x systems */ | ||||||
|  |    | ||||||
|  |   if (wincap.is_winnt() == false) | ||||||
|  |   { | ||||||
|  |     if (EscapeCommFunction (get_handle (), SETDTR) == 0) | ||||||
|  |       system_printf ("couldn't set initial state of DTR for %s, %E", get_name ()); | ||||||
|  |     if (EscapeCommFunction (get_handle (), SETRTS) == 0) | ||||||
|  |       system_printf ("couldn't set initial state of RTS for %s, %E", get_name ()); | ||||||
|  |        | ||||||
|  |     /* even though one of above functions fail I have to set rts and dtr | ||||||
|  |     variables to initial value. */ | ||||||
|  |     rts = TIOCM_RTS; | ||||||
|  |     dtr = TIOCM_DTR; | ||||||
|  |   } | ||||||
|  |    | ||||||
|   SetCommMask (get_handle (), EV_RXCHAR); |   SetCommMask (get_handle (), EV_RXCHAR); | ||||||
|   set_open_status (); |   set_open_status (); | ||||||
|   syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)", |   syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)", | ||||||
| @@ -358,6 +375,107 @@ fhandler_serial::tcflow (int action) | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
|  | /* ioctl: */ | ||||||
|  | int | ||||||
|  | fhandler_serial::ioctl (unsigned int cmd, void *buffer) | ||||||
|  | { | ||||||
|  |  | ||||||
|  |   DWORD ev; | ||||||
|  |   COMSTAT st; | ||||||
|  |   DWORD action; | ||||||
|  |   DWORD modemLines; | ||||||
|  |   DWORD mcr; | ||||||
|  |   DWORD cbReturned; | ||||||
|  |   bool result; | ||||||
|  |   int modemStatus; | ||||||
|  |   int request; | ||||||
|  |    | ||||||
|  |   request = *(int *) buffer; | ||||||
|  |   action = 0; | ||||||
|  |   modemStatus = 0; | ||||||
|  |   if (!ClearCommError (get_handle (), &ev, &st)) | ||||||
|  |     return -1; | ||||||
|  |   switch (cmd) | ||||||
|  |     { | ||||||
|  |     case TIOCMGET: | ||||||
|  |       if (GetCommModemStatus (get_handle (), &modemLines) == 0) | ||||||
|  |         return -1; | ||||||
|  |       if (modemLines & MS_CTS_ON) | ||||||
|  |         modemStatus |= TIOCM_CTS; | ||||||
|  |       if (modemLines & MS_DSR_ON) | ||||||
|  |         modemStatus |= TIOCM_DSR; | ||||||
|  |       if (modemLines & MS_RING_ON) | ||||||
|  |         modemStatus |= TIOCM_RI; | ||||||
|  |       if (modemLines & MS_RLSD_ON) | ||||||
|  |         modemStatus |= TIOCM_CD; | ||||||
|  |       if (wincap.is_winnt() == true) | ||||||
|  |         { | ||||||
|  | 	 | ||||||
|  | 	  /* here is Windows NT or Windows 2000 part */ | ||||||
|  | 	  result = DeviceIoControl (get_handle (), | ||||||
|  |                                     0x001B0078, | ||||||
|  | 				    NULL, 0, &mcr, 4, &cbReturned, 0); | ||||||
|  |           if (!result) | ||||||
|  | 	    return -1; | ||||||
|  |           if (cbReturned != 4) | ||||||
|  | 	    return -1; | ||||||
|  |           if (mcr & 2) | ||||||
|  | 	    modemStatus |= TIOCM_RTS; | ||||||
|  |           if (mcr & 1) | ||||||
|  | 	    modemStatus |= TIOCM_DTR; | ||||||
|  | 	     | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  |         { | ||||||
|  | 	 | ||||||
|  | 	  /* here is Windows 9x part */ | ||||||
|  | 	  modemStatus |= rts | dtr; | ||||||
|  | 	   | ||||||
|  | 	} | ||||||
|  |       *(int *) buffer = modemStatus; | ||||||
|  |       return 0; | ||||||
|  |     case TIOCMSET: | ||||||
|  |       if (request & TIOCM_RTS) | ||||||
|  |         { | ||||||
|  | 	  if (EscapeCommFunction (get_handle (), SETRTS) == 0) | ||||||
|  | 	    return -1; | ||||||
|  |           else | ||||||
|  | 	    rts = TIOCM_RTS; | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  |         { | ||||||
|  | 	  if (EscapeCommFunction (get_handle (), CLRRTS) == 0) | ||||||
|  | 	    return -1; | ||||||
|  |           else | ||||||
|  | 	    rts = 0; | ||||||
|  | 	} | ||||||
|  |       if (request & TIOCM_DTR) | ||||||
|  |         { | ||||||
|  | 	  if (EscapeCommFunction (get_handle (), SETDTR) == 0) | ||||||
|  | 	    return -1; | ||||||
|  |           else | ||||||
|  | 	    dtr = TIOCM_DTR; | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  |         { | ||||||
|  | 	  if (EscapeCommFunction (get_handle (), CLRDTR) == 0) | ||||||
|  | 	    return -1; | ||||||
|  |           else | ||||||
|  | 	    dtr = 0; | ||||||
|  | 	} | ||||||
|  |       return 0; | ||||||
|  |    case TIOCINQ: | ||||||
|  |      if (ev & CE_FRAME | ev & CE_IOE | ev & CE_OVERRUN | | ||||||
|  |          ev & CE_RXOVER | ev & CE_RXPARITY) | ||||||
|  |        return -1; | ||||||
|  |      *(int *) buffer = st.cbInQue; | ||||||
|  |      return 0; | ||||||
|  |    default: | ||||||
|  |      return -1; | ||||||
|  |    } | ||||||
|  | }     | ||||||
|  |  | ||||||
| /* tcflush: POSIX 7.2.2.1 */ | /* tcflush: POSIX 7.2.2.1 */ | ||||||
| int | int | ||||||
| fhandler_serial::tcflush (int queue) | fhandler_serial::tcflush (int queue) | ||||||
| @@ -395,6 +513,8 @@ fhandler_serial::tcsetattr (int action, const struct termios *t) | |||||||
|   COMMTIMEOUTS to; |   COMMTIMEOUTS to; | ||||||
|   DCB ostate, state; |   DCB ostate, state; | ||||||
|   unsigned int ovtime = vtime_, ovmin = vmin_; |   unsigned int ovtime = vtime_, ovmin = vmin_; | ||||||
|  |   int tmpDtr, tmpRts; | ||||||
|  |   tmpDtr = tmpRts = 0; | ||||||
|  |  | ||||||
|   termios_printf ("action %d", action); |   termios_printf ("action %d", action); | ||||||
|   if ((action == TCSADRAIN) || (action == TCSAFLUSH)) |   if ((action == TCSADRAIN) || (action == TCSAFLUSH)) | ||||||
| @@ -560,6 +680,7 @@ fhandler_serial::tcsetattr (int action, const struct termios *t) | |||||||
|     {							/* disable */ |     {							/* disable */ | ||||||
|       state.fRtsControl = RTS_CONTROL_ENABLE; |       state.fRtsControl = RTS_CONTROL_ENABLE; | ||||||
|       state.fOutxCtsFlow = FALSE; |       state.fOutxCtsFlow = FALSE; | ||||||
|  |       tmpRts = TIOCM_RTS; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   if (t->c_cflag & CRTSXOFF) |   if (t->c_cflag & CRTSXOFF) | ||||||
| @@ -592,7 +713,10 @@ fhandler_serial::tcsetattr (int action, const struct termios *t) | |||||||
|   set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1); |   set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1); | ||||||
|  |  | ||||||
|   if (dropDTR == TRUE) |   if (dropDTR == TRUE) | ||||||
|  |     { | ||||||
|       EscapeCommFunction (get_handle (), CLRDTR); |       EscapeCommFunction (get_handle (), CLRDTR); | ||||||
|  |       tmpDtr = 0; | ||||||
|  |     } | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       /* FIXME: Sometimes when CLRDTR is set, setting |       /* FIXME: Sometimes when CLRDTR is set, setting | ||||||
| @@ -601,8 +725,12 @@ fhandler_serial::tcsetattr (int action, const struct termios *t) | |||||||
|       parameters while DTR is still down. */ |       parameters while DTR is still down. */ | ||||||
|  |  | ||||||
|       EscapeCommFunction (get_handle (), SETDTR); |       EscapeCommFunction (get_handle (), SETDTR); | ||||||
|  |       tmpDtr = TIOCM_DTR; | ||||||
|     } |     } | ||||||
|      |      | ||||||
|  |   rts = tmpRts; | ||||||
|  |   dtr = tmpDtr; | ||||||
|  |  | ||||||
|   /* |   /* | ||||||
|   The following documentation on was taken from "Linux Serial Programming |   The following documentation on was taken from "Linux Serial Programming | ||||||
|   HOWTO".  It explains how MIN (t->c_cc[VMIN] || vmin_) and TIME |   HOWTO".  It explains how MIN (t->c_cc[VMIN] || vmin_) and TIME | ||||||
|   | |||||||
| @@ -13,6 +13,26 @@ details. */ | |||||||
| #ifndef	_SYS_TERMIOS_H | #ifndef	_SYS_TERMIOS_H | ||||||
| #define _SYS_TERMIOS_H | #define _SYS_TERMIOS_H | ||||||
|  |  | ||||||
|  | #define	TIOCMGET	0x5415 | ||||||
|  | #define	TIOCMSET	0x5418 | ||||||
|  | #define	TIOCINQ		0x541B	 | ||||||
|  |  | ||||||
|  | /* TIOCINQ is utilized instead of FIONREAD which has been | ||||||
|  | accupied for other purposes under CYGWIN. | ||||||
|  | Other UNIX ioctl requests has been omited because | ||||||
|  | effects of their work one can achive by standard | ||||||
|  | POSIX commands */ | ||||||
|  |  | ||||||
|  |  | ||||||
|  | #define	TIOCM_DTR	0x002 | ||||||
|  | #define	TIOCM_RTS	0x004 | ||||||
|  | #define	TIOCM_CTS	0x020 | ||||||
|  | #define	TIOCM_CAR	0x040 | ||||||
|  | #define	TIOCM_RNG	0x080 | ||||||
|  | #define	TIOCM_DSR	0x100 | ||||||
|  | #define	TIOCM_CD	TIOCM_CAR | ||||||
|  | #define	TIOCM_RI	TIOCM_RNG | ||||||
|  |  | ||||||
| #define TCOOFF		0 | #define TCOOFF		0 | ||||||
| #define TCOON		1 | #define TCOON		1 | ||||||
| #define TCIOFF		2 | #define TCIOFF		2 | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user