delorie.com/archives/browse.cgi   search  
Mail Archives: cygwin/2001/05/22/08:34:44

Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm
List-Subscribe: <mailto:cygwin-subscribe AT sources DOT redhat DOT com>
List-Archive: <http://sources.redhat.com/ml/cygwin/>
List-Post: <mailto:cygwin AT sources DOT redhat DOT com>
List-Help: <mailto:cygwin-help AT sources DOT redhat DOT com>, <http://sources.redhat.com/ml/#faqs>
Sender: cygwin-owner AT sources DOT redhat DOT com
Delivered-To: mailing list cygwin AT sources DOT redhat DOT com
Message-ID: <3B0A5B48.D8508D38@certum.pl>
Date: Tue, 22 May 2001 14:27:52 +0200
From: Jacek Trzcinski <jacek AT certum DOT pl>
Reply-To: jacek AT certum DOT pl
X-Mailer: Mozilla 4.7 [en] (WinNT; U)
X-Accept-Language: en,pdf
MIME-Version: 1.0
To: cygwin AT cygwin DOT com
Subject: Serial programming patch

--------------256B4E686CF2F8F9A2DD2BE2
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

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
--------------256B4E686CF2F8F9A2DD2BE2
Content-Type: text/plain; charset=us-ascii;
 name="serial.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="serial.patch"

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


--------------256B4E686CF2F8F9A2DD2BE2
Content-Type: text/plain; charset=us-ascii

--
Want to unsubscribe from this list?
Check out: http://cygwin.com/ml/#unsubscribe-simple
--------------256B4E686CF2F8F9A2DD2BE2--

- Raw text -


  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019