2 * DEC 93 Erik Bos <erik@xs4all.nl>
13 #if defined(__NetBSD__) || defined(__FreeBSD__)
15 #include <sys/ioctl.h>
23 /* #define DEBUG_COMM */
24 /* #undef DEBUG_COMM */
27 int commerror
= 0, eventmask
= 0;
29 struct DosDeviceStruct COM
[MAX_PORTS
];
30 struct DosDeviceStruct LPT
[MAX_PORTS
];
35 char option
[10], temp
[256], *btemp
;
38 for (x
=0; x
!=MAX_PORTS
; x
++) {
39 strcpy(option
,"COMx");
43 GetPrivateProfileString("serialports", option
, "*", temp
, sizeof(temp
), WINE_INI
);
44 if (!strcmp(temp
, "*") || *temp
== '\0')
45 COM
[x
].devicename
= NULL
;
47 btemp
= index(temp
,',');
50 COM
[x
].baudrate
= atoi(btemp
);
55 if (!S_ISCHR(st
.st_mode
))
56 fprintf(stderr
,"comm: can 't use `%s' as %s !\n", temp
, option
);
58 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
59 fprintf(stderr
,"comm: can't malloc for device info!\n");
62 strcpy(COM
[x
].devicename
, temp
);
65 "Comm_Init: %s = %s\n", option
, COM
[x
].devicename
);
68 strcpy(option
, "LPTx");
72 GetPrivateProfileString("parallelports", option
, "*", temp
, sizeof(temp
), WINE_INI
);
73 if (!strcmp(temp
, "*") || *temp
== '\0')
74 LPT
[x
].devicename
= NULL
;
77 if (!S_ISCHR(st
.st_mode
))
78 fprintf(stderr
,"comm: can 't use `%s' as %s !\n", temp
, option
);
80 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
81 fprintf(stderr
,"comm: can't malloc for device info!\n");
84 strcpy(LPT
[x
].devicename
, temp
);
87 "Comm_Init: %s = %s\n", option
, LPT
[x
].devicename
);
94 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
98 for (x
=0; x
!=MAX_PORTS
; x
++) {
108 int ValidCOMPort(int x
)
110 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
113 int ValidLPTPort(int x
)
115 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
120 dprintf_comm(stddeb
, "WinError: errno = %d\n", errno
);
127 int BuildCommDCB(LPSTR device
, DCB FAR
*lpdcb
)
129 /* "COM1:9600,n,8,1" */
133 char *ptr
, temp
[256];
136 "BuildCommDCB: (%s), ptr %p\n", device
, lpdcb
);
139 if (!strncasecmp(device
,"COM",3)) {
140 port
= device
[3] - '0';
144 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
145 commerror
= IE_BADID
;
148 if (!ValidCOMPort(port
)) {
149 commerror
= IE_BADID
;
154 OpenComm(device
, 0, 0);
156 lpdcb
->Id
= COM
[port
].fd
;
161 if (*(device
+4) != ':')
164 strcpy(temp
,device
+5);
165 ptr
= strtok(temp
, ",");
167 if (COM
[port
].baudrate
> 0)
168 lpdcb
->BaudRate
= COM
[port
].baudrate
;
170 lpdcb
->BaudRate
= atoi(ptr
);
171 dprintf_comm(stddeb
,"BuildCommDCB: baudrate (%d)\n", lpdcb
->BaudRate
);
173 ptr
= strtok(NULL
, ",");
175 *ptr
= toupper(*ptr
);
177 dprintf_comm(stddeb
,"BuildCommDCB: parity (%c)\n", *ptr
);
180 lpdcb
->Parity
= NOPARITY
;
187 lpdcb
->Parity
= EVENPARITY
;
190 lpdcb
->Parity
= MARKPARITY
;
193 lpdcb
->Parity
= ODDPARITY
;
196 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
200 ptr
= strtok(NULL
, ",");
201 dprintf_comm(stddeb
, "BuildCommDCB: charsize (%c)\n", *ptr
);
202 lpdcb
->ByteSize
= *ptr
- '0';
204 ptr
= strtok(NULL
, ",");
205 dprintf_comm(stddeb
, "BuildCommDCB: stopbits (%c)\n", *ptr
);
208 lpdcb
->StopBits
= ONESTOPBIT
;
211 lpdcb
->StopBits
= TWOSTOPBITS
;
214 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
222 int OpenComm(LPSTR device
, UINT cbInQueue
, UINT cbOutQueue
)
227 "OpenComm: %s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
230 if (!strncasecmp(device
,"COM",3)) {
231 port
= device
[3] - '0';
234 fprintf(stderr
, "comm: BUG ! COM0 doesn't exists!.\n");
235 commerror
= IE_BADID
;
239 "OpenComm: %s = %s\n", device
, COM
[port
].devicename
);
241 if (!ValidCOMPort(port
)) {
242 commerror
= IE_BADID
;
249 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
251 commerror
= WinError();
259 if (!strncasecmp(device
,"LPT",3)) {
260 port
= device
[3] - '0';
262 if (!ValidLPTPort(port
)) {
263 commerror
= IE_BADID
;
271 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
273 commerror
= WinError();
283 int CloseComm(int fd
)
285 dprintf_comm(stddeb
,"CloseComm: fd %d\n", fd
);
286 if (close(fd
) == -1) {
287 commerror
= WinError();
295 int SetCommBreak(int fd
)
297 struct DosDeviceStruct
*ptr
;
299 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
300 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
301 commerror
= IE_BADID
;
310 int ClearCommBreak(int fd
)
312 struct DosDeviceStruct
*ptr
;
314 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
315 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
316 commerror
= IE_BADID
;
325 LONG
EscapeCommFunction(int fd
, int nFunction
)
331 "EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
332 if (tcgetattr(fd
, &port
) == -1) {
333 commerror
= WinError();
342 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
348 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
354 port
.c_cflag
&= TIOCM_DTR
;
358 port
.c_cflag
&= TIOCM_RTS
;
363 port
.c_cflag
|= CRTSCTS
;
367 port
.c_cflag
|= CRTSCTS
;
372 port
.c_iflag
|= IXOFF
;
376 port
.c_iflag
|= IXON
;
381 "EscapeCommFunction fd: %d, unknown function: %d\n",
386 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
387 commerror
= WinError();
395 int FlushComm(int fd
, int fnQueue
)
399 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
409 "FlushComm fd: %d, UNKNOWN queue: %d\n",
414 if (tcflush(fd
, fnQueue
)) {
415 commerror
= WinError();
423 int GetCommError(int fd
, COMSTAT FAR
*lpStat
)
428 "GetCommError: fd %d (current error %d)\n", fd
, commerror
);
429 temperror
= commerror
;
434 UINT FAR
* SetCommEventMask(int fd
, UINT fuEvtMask
)
437 "SetCommEventMask: fd %d, mask %d\n", fd
, fuEvtMask
);
438 eventmask
|= fuEvtMask
;
439 return (UINT
*)&eventmask
;
442 UINT
GetCommEventMask(int fd
, int fnEvtClear
)
445 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
446 eventmask
&= ~fnEvtClear
;
450 int SetCommState(DCB FAR
*lpdcb
)
453 struct DosDeviceStruct
*ptr
;
456 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
457 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
458 commerror
= WinError();
463 port
.c_cc
[VTIME
] = 1;
465 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
466 port
.c_iflag
|= (IGNBRK
);
468 port
.c_oflag
&= ~(OPOST
);
470 port
.c_cflag
&= ~(HUPCL
);
471 port
.c_cflag
|= CLOCAL
| CREAD
;
473 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
474 port
.c_lflag
|= NOFLSH
;
476 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
477 commerror
= IE_BADID
;
480 if (ptr
->baudrate
> 0)
481 lpdcb
->BaudRate
= ptr
->baudrate
;
482 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
484 port
.c_cflag
&= ~CBAUD
;
485 switch (lpdcb
->BaudRate
) {
488 port
.c_cflag
|= B110
;
492 port
.c_cflag
|= B300
;
496 port
.c_cflag
|= B600
;
500 port
.c_cflag
|= B1200
;
504 port
.c_cflag
|= B2400
;
508 port
.c_cflag
|= B4800
;
512 port
.c_cflag
|= B9600
;
516 port
.c_cflag
|= B19200
;
520 port
.c_cflag
|= B38400
;
523 commerror
= IE_BAUDRATE
;
527 switch (lpdcb
->BaudRate
) {
530 port
.c_ospeed
= B110
;
534 port
.c_ospeed
= B300
;
538 port
.c_ospeed
= B600
;
542 port
.c_ospeed
= B1200
;
546 port
.c_ospeed
= B2400
;
550 port
.c_ospeed
= B4800
;
554 port
.c_ospeed
= B9600
;
558 port
.c_ospeed
= B19200
;
562 port
.c_ospeed
= B38400
;
565 commerror
= IE_BAUDRATE
;
568 port
.c_ispeed
= port
.c_ospeed
;
570 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
571 port
.c_cflag
&= ~CSIZE
;
572 switch (lpdcb
->ByteSize
) {
586 commerror
= IE_BYTESIZE
;
590 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
591 port
.c_cflag
&= ~(PARENB
| PARODD
);
593 switch (lpdcb
->Parity
) {
595 port
.c_iflag
&= ~INPCK
;
598 port
.c_cflag
|= (PARENB
| PARODD
);
599 port
.c_iflag
|= INPCK
;
602 port
.c_cflag
|= PARENB
;
603 port
.c_iflag
|= INPCK
;
606 commerror
= IE_BYTESIZE
;
611 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
612 switch (lpdcb
->StopBits
) {
614 port
.c_cflag
&= ~CSTOPB
;
617 port
.c_cflag
|= CSTOPB
;
620 commerror
= IE_BYTESIZE
;
625 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
626 port
.c_cflag
|= CRTSCTS
;
628 if (lpdcb
->fDtrDisable
)
630 port
.c_cflag
&= ~CRTSCTS
;
633 port
.c_iflag
|= IXON
;
635 port
.c_iflag
|= IXOFF
;
637 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
638 commerror
= WinError();
646 int GetCommState(int fd
, DCB FAR
*lpdcb
)
650 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
651 if (tcgetattr(fd
, &port
) == -1) {
652 commerror
= WinError();
659 switch (port
.c_cflag
& CBAUD
) {
661 switch (port
.c_ospeed
) {
664 lpdcb
->BaudRate
= 110;
667 lpdcb
->BaudRate
= 300;
670 lpdcb
->BaudRate
= 600;
673 lpdcb
->BaudRate
= 1200;
676 lpdcb
->BaudRate
= 2400;
679 lpdcb
->BaudRate
= 4800;
682 lpdcb
->BaudRate
= 9600;
685 lpdcb
->BaudRate
= 19200;
688 lpdcb
->BaudRate
= 38400;
692 switch (port
.c_cflag
& CSIZE
) {
707 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
709 lpdcb
->fParity
= NOPARITY
;
712 lpdcb
->fParity
= EVENPARITY
;
714 case (PARENB
| PARODD
):
715 lpdcb
->fParity
= ODDPARITY
;
719 if (port
.c_cflag
& CSTOPB
)
720 lpdcb
->StopBits
= TWOSTOPBITS
;
722 lpdcb
->StopBits
= ONESTOPBIT
;
724 lpdcb
->RlsTimeout
= 50;
725 lpdcb
->CtsTimeout
= 50;
726 lpdcb
->DsrTimeout
= 50;
732 lpdcb
->fDtrDisable
= 0;
733 if (port
.c_cflag
& CRTSCTS
) {
736 lpdcb
->fOutxCtsFlow
= 1;
737 lpdcb
->fOutxDsrFlow
= 1;
740 lpdcb
->fDtrDisable
= 1;
742 if (port
.c_iflag
& IXON
)
747 if (port
.c_iflag
& IXOFF
)
762 int TransmitCommChar(int fd
, char chTransmit
)
764 struct DosDeviceStruct
*ptr
;
767 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
768 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
769 commerror
= IE_BADID
;
773 if (ptr
->suspended
) {
774 commerror
= IE_HARDWARE
;
778 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
779 commerror
= WinError();
787 int UngetCommChar(int fd
, char chUnget
)
789 struct DosDeviceStruct
*ptr
;
791 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
792 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
793 commerror
= IE_BADID
;
797 if (ptr
->suspended
) {
798 commerror
= IE_HARDWARE
;
803 ptr
->unget_byte
= chUnget
;
809 int ReadComm(int fd
, LPSTR lpvBuf
, int cbRead
)
812 struct DosDeviceStruct
*ptr
;
815 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
816 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
817 commerror
= IE_BADID
;
821 if (ptr
->suspended
) {
822 commerror
= IE_HARDWARE
;
827 *lpvBuf
= ptr
->unget_byte
;
835 status
= read(fd
, (void *) lpvBuf
, cbRead
);
838 if (errno
!= EAGAIN
) {
839 commerror
= WinError();
847 return length
+ status
;
851 int WriteComm(int fd
, LPSTR lpvBuf
, int cbWrite
)
854 struct DosDeviceStruct
*ptr
;
856 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
857 fd
, lpvBuf
, cbWrite
);
858 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
859 commerror
= IE_BADID
;
863 if (ptr
->suspended
) {
864 commerror
= IE_HARDWARE
;
868 for (x
=0; x
!= cbWrite
; x
++)
869 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
871 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
874 commerror
= WinError();