public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: Jacek Trzcinski <jacek@certum.pl>
To: cygwin@cygwin.com
Subject: Serial programming patch
Date: Tue, 22 May 2001 05:33:00 -0000	[thread overview]
Message-ID: <3B0A5B48.D8508D38@certum.pl> (raw)

Hi !,
Here is my patch to serial device. I implemented ioctl function which
makes possible
to get modem lines state (CTS,DSR,RI,CD) and set(get) modem control
lines (RTS and DTR)
It does not get(set) other signals from MCR register(there is no need).
It will be usefull for people (like me) who have to connect devices
requiring mentioned signals f.e. chip card readers.
I made changes in fhandler_serial.cc, fhandler.h and in termios.h where
I placed
proper constants taken directly from linux headers. I tested it in NT
and W2K environment
where there is nice way to get RTS and DTR state by DeviceIoControl
function. In
Windows 9x it is no possible and so far I do not know how to do it
without big gimnastics.
In consequence for 9x I keep mirror of this signals set by functions
which influence on state
of this signals (open, ioctl,tcsetattr) and in my ioctl simply return
it.
This patch was created on base of cygwin sources version 1.3.1-1
I have to send it as attachment because my post client is netscape and
inserted patch looks
horrible
Jacek
--- fhandler_serial.old.cc	Tue Apr 24 03:19:15 2001
+++ fhandler_serial.cc	Tue May 22 11:01:29 2001
@@ -32,6 +32,9 @@ fhandler_serial::fhandler_serial (const 
   vtime_ = 0;
   pgrp_ = myself->pgid;
   set_need_fork_fixup ();
+  osVersion=GetVersion();
+  dtr=0;
+  rts=0;
 }
 
 void
@@ -275,7 +278,8 @@ fhandler_serial::open (const char *name,
       if (!SetCommState (get_handle (), &state))
 	system_printf ("couldn't set initial state for %s, %E", get_name ());
     }
-
+  rts=TIOCM_RTS;
+  dtr=TIOCM_DTR;
   SetCommMask (get_handle (), EV_RXCHAR);
   set_open_status ();
   syscall_printf ("%p = fhandler_serial::open (%s, %p, %p)",
@@ -366,6 +370,93 @@ fhandler_serial::tcflow (int action)
   return 0;
 }
 
+
+/* ioctl: POSIX  */
+int
+fhandler_serial::ioctl (unsigned int cmd,void * buffer)
+{
+ 
+  DCB dcb;
+  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_RNG | TIOCM_RI;
+	if(modemLines&MS_RLSD_ON) modemStatus|=TIOCM_CAR | TIOCM_CD;
+	if(!(osVersion&0x80000000))
+	{
+	// here is Windows NT or Windows 2000
+	  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
+	  modemStatus|=rts|dtr;
+	  
+	}
+	*(int*)buffer=modemStatus;
+	return 0;
+      case TIOCMSET:
+        //if(request & ~(TIOCM_RTS | TIOCM_DTR)) return -1;
+	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 */
 int
 fhandler_serial::tcflush (int queue)
@@ -373,7 +464,7 @@ fhandler_serial::tcflush (int queue)
   if (queue == TCOFLUSH || queue == TCIOFLUSH)
     PurgeComm (get_handle (), PURGE_TXABORT | PURGE_TXCLEAR);
 
-  if (queue == TCIFLUSH | queue == TCIOFLUSH)
+  if (queue == TCIFLUSH || queue == TCIOFLUSH)
     /* Input flushing by polling until nothing turns up
        (we stop after 1000 chars anyway) */
     for (int max = 1000; max > 0; max--)
@@ -404,6 +495,8 @@ fhandler_serial::tcsetattr (int action, 
   COMMTIMEOUTS to;
   DCB ostate, state;
   unsigned int ovtime = vtime_, ovmin = vmin_;
+  int tmpDtr,tmpRts;
+  tmpDtr=tmpRts=0;
 
   termios_printf ("action %d", action);
   if ((action == TCSADRAIN) || (action == TCSAFLUSH))
@@ -569,6 +662,7 @@ fhandler_serial::tcsetattr (int action, 
     {							/* disable */
       state.fRtsControl = RTS_CONTROL_ENABLE;
       state.fOutxCtsFlow = FALSE;
+      tmpRts=TIOCM_RTS;
     }
 
   if (t->c_cflag & CRTSXOFF)
@@ -601,7 +695,10 @@ fhandler_serial::tcsetattr (int action, 
   set_w_binary ((t->c_oflag & ONLCR) ? 0 : 1);
 
   if (dropDTR == TRUE)
+  {
     EscapeCommFunction (get_handle (), CLRDTR);
+    tmpDtr=0;
+  }
   else
     {
       /* FIXME: Sometimes when CLRDTR is set, setting
@@ -610,7 +707,11 @@ fhandler_serial::tcsetattr (int action, 
       parameters while DTR is still down. */
 
       EscapeCommFunction (get_handle (), SETDTR);
+      tmpDtr=TIOCM_DTR;
     }
+    
+  rts=tmpRts;
+  dtr=tmpDtr;
 
   /*
   The following documentation on was taken from "Linux Serial Programming
--- fhandler.old.h	Tue Apr 24 03:19:14 2001
+++ fhandler.h	Tue May 22 10:34:58 2001
@@ -529,6 +529,9 @@ private:
   unsigned int vmin_;			/* from termios */
   unsigned int vtime_;			/* from termios */
   pid_t pgrp_;
+  unsigned int osVersion;
+  int	rts;
+  int	dtr;
 
 public:
   int overlapped_armed;
@@ -547,6 +550,7 @@ public:
   int tcsendbreak (int);
   int tcdrain ();
   int tcflow (int);
+  int ioctl (unsigned int cmd, void *);
   int tcsetattr (int a, const struct termios *t);
   int tcgetattr (struct termios *t);
   off_t lseek (off_t, int) { return 0; }
--- ./include/sys/termios.old.h	Sun Mar 25 21:09:52 2001
+++ ./include/sys/termios.h	Tue May 22 12:03:16 2001
@@ -13,6 +13,22 @@ details. */
 #ifndef	_SYS_TERMIOS_H
 #define _SYS_TERMIOS_H
 
+
+#define	TIOCMGET	0x5415
+#define TIOCMSET	0x5418
+#define TIOCINQ		0x541B
+
+#define	TIOCM_LE	0x001
+#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 TCOON		1
 #define TCIOFF		2

             reply	other threads:[~2001-05-22  5:33 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2001-05-22  5:33 Jacek Trzcinski [this message]
2001-05-22 13:09 ` Corinna Vinschen
2001-05-23  1:03   ` Jacek Trzcinski
2001-05-23  1:33     ` Corinna Vinschen
2001-05-23  5:21       ` Jacek Trzcinski
2001-05-23  7:29         ` Corinna Vinschen
2001-05-23 13:00           ` Christopher Faylor
2001-05-22 18:21 J. J. Farrell
2002-04-11  9:51 briseida deyanira maytorena sanchez
2002-04-11 10:04 ` Christopher Faylor

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=3B0A5B48.D8508D38@certum.pl \
    --to=jacek@certum.pl \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).