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 PROFILE_GetWineIniString( "serialports", option
, "*",
45 if (!strcmp(temp
, "*") || *temp
== '\0')
46 COM
[x
].devicename
= NULL
;
48 btemp
= strchr(temp
,',');
51 COM
[x
].baudrate
= atoi(btemp
);
56 if (!S_ISCHR(st
.st_mode
))
57 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
59 if ((COM
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
60 fprintf(stderr
,"comm: can't malloc for device info!\n");
63 strcpy(COM
[x
].devicename
, temp
);
66 "Comm_Init: %s = %s\n", option
, COM
[x
].devicename
);
69 strcpy(option
, "LPTx");
73 PROFILE_GetWineIniString( "parallelports", option
, "*",
75 if (!strcmp(temp
, "*") || *temp
== '\0')
76 LPT
[x
].devicename
= NULL
;
79 if (!S_ISCHR(st
.st_mode
))
80 fprintf(stderr
,"comm: can't use `%s' as %s !\n", temp
, option
);
82 if ((LPT
[x
].devicename
= malloc(strlen(temp
)+1)) == NULL
)
83 fprintf(stderr
,"comm: can't malloc for device info!\n");
86 strcpy(LPT
[x
].devicename
, temp
);
89 "Comm_Init: %s = %s\n", option
, LPT
[x
].devicename
);
96 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
100 for (x
=0; x
!=MAX_PORTS
; x
++) {
110 int ValidCOMPort(int x
)
112 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
115 int ValidLPTPort(int x
)
117 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
122 dprintf_comm(stddeb
, "WinError: errno = %d\n", errno
);
129 BOOL
BuildCommDCB(LPCSTR device
, LPDCB lpdcb
)
131 /* "COM1:9600,n,8,1" */
135 char *ptr
, temp
[256];
138 "BuildCommDCB: (%s), ptr %p\n", device
, lpdcb
);
141 if (!lstrncmpi(device
,"COM",3)) {
142 port
= device
[3] - '0';
146 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
147 commerror
= IE_BADID
;
150 if (!ValidCOMPort(port
)) {
151 commerror
= IE_BADID
;
156 OpenComm(device
, 0, 0);
158 lpdcb
->Id
= COM
[port
].fd
;
163 if (*(device
+4) != ':')
166 strcpy(temp
,device
+5);
167 ptr
= strtok(temp
, ", ");
169 if (COM
[port
].baudrate
> 0)
170 lpdcb
->BaudRate
= COM
[port
].baudrate
;
172 lpdcb
->BaudRate
= atoi(ptr
);
173 dprintf_comm(stddeb
,"BuildCommDCB: baudrate (%d)\n", lpdcb
->BaudRate
);
175 ptr
= strtok(NULL
, ", ");
177 *ptr
= toupper(*ptr
);
179 dprintf_comm(stddeb
,"BuildCommDCB: parity (%c)\n", *ptr
);
182 lpdcb
->Parity
= NOPARITY
;
189 lpdcb
->Parity
= EVENPARITY
;
192 lpdcb
->Parity
= MARKPARITY
;
195 lpdcb
->Parity
= ODDPARITY
;
198 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
202 ptr
= strtok(NULL
, ", ");
203 dprintf_comm(stddeb
, "BuildCommDCB: charsize (%c)\n", *ptr
);
204 lpdcb
->ByteSize
= *ptr
- '0';
206 ptr
= strtok(NULL
, ", ");
207 dprintf_comm(stddeb
, "BuildCommDCB: stopbits (%c)\n", *ptr
);
210 lpdcb
->StopBits
= ONESTOPBIT
;
213 lpdcb
->StopBits
= TWOSTOPBITS
;
216 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
224 int OpenComm(LPCSTR device
, UINT cbInQueue
, UINT cbOutQueue
)
229 "OpenComm: %s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
232 if (!lstrncmpi(device
,"COM",3)) {
233 port
= device
[3] - '0';
236 fprintf(stderr
, "comm: BUG ! COM0 doesn't exists!.\n");
237 commerror
= IE_BADID
;
241 "OpenComm: %s = %s\n", device
, COM
[port
].devicename
);
243 if (!ValidCOMPort(port
)) {
244 commerror
= IE_BADID
;
251 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
253 commerror
= WinError();
261 if (!lstrncmpi(device
,"LPT",3)) {
262 port
= device
[3] - '0';
264 if (!ValidLPTPort(port
)) {
265 commerror
= IE_BADID
;
273 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
275 commerror
= WinError();
285 int CloseComm(int fd
)
287 dprintf_comm(stddeb
,"CloseComm: fd %d\n", fd
);
288 if (close(fd
) == -1) {
289 commerror
= WinError();
297 int SetCommBreak(int fd
)
299 struct DosDeviceStruct
*ptr
;
301 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
302 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
303 commerror
= IE_BADID
;
312 int ClearCommBreak(int fd
)
314 struct DosDeviceStruct
*ptr
;
316 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
317 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
318 commerror
= IE_BADID
;
327 LONG
EscapeCommFunction(int fd
, int nFunction
)
333 "EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
334 if (tcgetattr(fd
, &port
) == -1) {
335 commerror
= WinError();
344 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
350 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
357 port
.c_cflag
&= TIOCM_DTR
;
363 port
.c_cflag
&= TIOCM_RTS
;
369 port
.c_cflag
|= CRTSCTS
;
373 port
.c_cflag
|= CRTSCTS
;
378 port
.c_iflag
|= IXOFF
;
382 port
.c_iflag
|= IXON
;
387 "EscapeCommFunction fd: %d, unknown function: %d\n",
392 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
393 commerror
= WinError();
401 int FlushComm(int fd
, int fnQueue
)
405 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
415 "FlushComm fd: %d, UNKNOWN queue: %d\n",
420 if (tcflush(fd
, fnQueue
)) {
421 commerror
= WinError();
429 int GetCommError(int fd
, COMSTAT
*lpStat
)
434 "GetCommError: fd %d (current error %d)\n", fd
, commerror
);
435 temperror
= commerror
;
440 UINT
* SetCommEventMask(int fd
, UINT fuEvtMask
)
443 "SetCommEventMask: fd %d, mask %d\n", fd
, fuEvtMask
);
444 eventmask
|= fuEvtMask
;
445 return (UINT
*)&eventmask
;
448 UINT
GetCommEventMask(int fd
, int fnEvtClear
)
451 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
452 eventmask
&= ~fnEvtClear
;
456 int SetCommState(DCB
*lpdcb
)
459 struct DosDeviceStruct
*ptr
;
462 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
463 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
464 commerror
= WinError();
469 port
.c_cc
[VTIME
] = 1;
472 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
474 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
);
476 port
.c_iflag
|= (IGNBRK
);
478 port
.c_oflag
&= ~(OPOST
);
480 port
.c_cflag
&= ~(HUPCL
);
481 port
.c_cflag
|= CLOCAL
| CREAD
;
483 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
484 port
.c_lflag
|= NOFLSH
;
486 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
487 commerror
= IE_BADID
;
490 if (ptr
->baudrate
> 0)
491 lpdcb
->BaudRate
= ptr
->baudrate
;
492 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
494 port
.c_cflag
&= ~CBAUD
;
495 switch (lpdcb
->BaudRate
) {
498 port
.c_cflag
|= B110
;
502 port
.c_cflag
|= B300
;
506 port
.c_cflag
|= B600
;
510 port
.c_cflag
|= B1200
;
514 port
.c_cflag
|= B2400
;
518 port
.c_cflag
|= B4800
;
522 port
.c_cflag
|= B9600
;
526 port
.c_cflag
|= B19200
;
530 port
.c_cflag
|= B38400
;
533 commerror
= IE_BAUDRATE
;
537 switch (lpdcb
->BaudRate
) {
540 port
.c_ospeed
= B110
;
544 port
.c_ospeed
= B300
;
548 port
.c_ospeed
= B600
;
552 port
.c_ospeed
= B1200
;
556 port
.c_ospeed
= B2400
;
560 port
.c_ospeed
= B4800
;
564 port
.c_ospeed
= B9600
;
568 port
.c_ospeed
= B19200
;
572 port
.c_ospeed
= B38400
;
575 commerror
= IE_BAUDRATE
;
578 port
.c_ispeed
= port
.c_ospeed
;
580 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
581 port
.c_cflag
&= ~CSIZE
;
582 switch (lpdcb
->ByteSize
) {
596 commerror
= IE_BYTESIZE
;
600 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
601 port
.c_cflag
&= ~(PARENB
| PARODD
);
603 switch (lpdcb
->Parity
) {
605 port
.c_iflag
&= ~INPCK
;
608 port
.c_cflag
|= (PARENB
| PARODD
);
609 port
.c_iflag
|= INPCK
;
612 port
.c_cflag
|= PARENB
;
613 port
.c_iflag
|= INPCK
;
616 commerror
= IE_BYTESIZE
;
621 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
622 switch (lpdcb
->StopBits
) {
624 port
.c_cflag
&= ~CSTOPB
;
627 port
.c_cflag
|= CSTOPB
;
630 commerror
= IE_BYTESIZE
;
635 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
636 port
.c_cflag
|= CRTSCTS
;
638 if (lpdcb
->fDtrDisable
)
639 port
.c_cflag
&= ~CRTSCTS
;
642 port
.c_iflag
|= IXON
;
644 port
.c_iflag
|= IXOFF
;
646 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
647 commerror
= WinError();
655 int GetCommState(int fd
, DCB
*lpdcb
)
659 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
660 if (tcgetattr(fd
, &port
) == -1) {
661 commerror
= WinError();
668 switch (port
.c_cflag
& CBAUD
) {
670 switch (port
.c_ospeed
) {
673 lpdcb
->BaudRate
= 110;
676 lpdcb
->BaudRate
= 300;
679 lpdcb
->BaudRate
= 600;
682 lpdcb
->BaudRate
= 1200;
685 lpdcb
->BaudRate
= 2400;
688 lpdcb
->BaudRate
= 4800;
691 lpdcb
->BaudRate
= 9600;
694 lpdcb
->BaudRate
= 19200;
697 lpdcb
->BaudRate
= 38400;
701 switch (port
.c_cflag
& CSIZE
) {
716 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
718 lpdcb
->fParity
= NOPARITY
;
721 lpdcb
->fParity
= EVENPARITY
;
723 case (PARENB
| PARODD
):
724 lpdcb
->fParity
= ODDPARITY
;
728 if (port
.c_cflag
& CSTOPB
)
729 lpdcb
->StopBits
= TWOSTOPBITS
;
731 lpdcb
->StopBits
= ONESTOPBIT
;
733 lpdcb
->RlsTimeout
= 50;
734 lpdcb
->CtsTimeout
= 50;
735 lpdcb
->DsrTimeout
= 50;
739 lpdcb
->fDtrDisable
= 0;
743 if (port
.c_cflag
& CRTSCTS
) {
746 lpdcb
->fOutxCtsFlow
= 1;
747 lpdcb
->fOutxDsrFlow
= 1;
750 lpdcb
->fDtrDisable
= 1;
752 if (port
.c_iflag
& IXON
)
757 if (port
.c_iflag
& IXOFF
)
772 int TransmitCommChar(int fd
, char chTransmit
)
774 struct DosDeviceStruct
*ptr
;
777 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
778 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
779 commerror
= IE_BADID
;
783 if (ptr
->suspended
) {
784 commerror
= IE_HARDWARE
;
788 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
789 commerror
= WinError();
797 int UngetCommChar(int fd
, char chUnget
)
799 struct DosDeviceStruct
*ptr
;
801 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
802 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
803 commerror
= IE_BADID
;
807 if (ptr
->suspended
) {
808 commerror
= IE_HARDWARE
;
813 ptr
->unget_byte
= chUnget
;
819 int ReadComm(int fd
, LPSTR lpvBuf
, int cbRead
)
822 struct DosDeviceStruct
*ptr
;
825 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
826 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
827 commerror
= IE_BADID
;
831 if (ptr
->suspended
) {
832 commerror
= IE_HARDWARE
;
837 *lpvBuf
= ptr
->unget_byte
;
845 status
= read(fd
, (void *) lpvBuf
, cbRead
);
848 if (errno
!= EAGAIN
) {
849 commerror
= WinError();
857 return length
+ status
;
861 int WriteComm(int fd
, LPSTR lpvBuf
, int cbWrite
)
864 struct DosDeviceStruct
*ptr
;
866 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
867 fd
, lpvBuf
, cbWrite
);
868 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
869 commerror
= IE_BADID
;
873 if (ptr
->suspended
) {
874 commerror
= IE_HARDWARE
;
878 for (x
=0; x
!= cbWrite
; x
++)
879 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
881 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
884 commerror
= WinError();