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
next 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).