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
--)
356 port
.c_cflag
&= TIOCM_DTR
;
360 port
.c_cflag
&= TIOCM_RTS
;
365 port
.c_cflag
|= CRTSCTS
;
369 port
.c_cflag
|= CRTSCTS
;
374 port
.c_iflag
|= IXOFF
;
378 port
.c_iflag
|= IXON
;
383 "EscapeCommFunction fd: %d, unknown function: %d\n",
388 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
389 commerror
= WinError();
397 int FlushComm(int fd
, int fnQueue
)
401 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
411 "FlushComm fd: %d, UNKNOWN queue: %d\n",
416 if (tcflush(fd
, fnQueue
)) {
417 commerror
= WinError();
425 int GetCommError(int fd
, COMSTAT FAR
*lpStat
)
430 "GetCommError: fd %d (current error %d)\n", fd
, commerror
);
431 temperror
= commerror
;
436 UINT FAR
* SetCommEventMask(int fd
, UINT fuEvtMask
)
439 "SetCommEventMask: fd %d, mask %d\n", fd
, fuEvtMask
);
440 eventmask
|= fuEvtMask
;
441 return (UINT
*)&eventmask
;
444 UINT
GetCommEventMask(int fd
, int fnEvtClear
)
447 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
448 eventmask
&= ~fnEvtClear
;
452 int SetCommState(DCB FAR
*lpdcb
)
455 struct DosDeviceStruct
*ptr
;
458 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
459 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
460 commerror
= WinError();
465 port
.c_cc
[VTIME
] = 1;
467 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
468 port
.c_iflag
|= (IGNBRK
);
470 port
.c_oflag
&= ~(OPOST
);
472 port
.c_cflag
&= ~(HUPCL
);
473 port
.c_cflag
|= CLOCAL
| CREAD
;
475 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
476 port
.c_lflag
|= NOFLSH
;
478 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
479 commerror
= IE_BADID
;
482 if (ptr
->baudrate
> 0)
483 lpdcb
->BaudRate
= ptr
->baudrate
;
484 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
486 port
.c_cflag
&= ~CBAUD
;
487 switch (lpdcb
->BaudRate
) {
490 port
.c_cflag
|= B110
;
494 port
.c_cflag
|= B300
;
498 port
.c_cflag
|= B600
;
502 port
.c_cflag
|= B1200
;
506 port
.c_cflag
|= B2400
;
510 port
.c_cflag
|= B4800
;
514 port
.c_cflag
|= B9600
;
518 port
.c_cflag
|= B19200
;
522 port
.c_cflag
|= B38400
;
525 commerror
= IE_BAUDRATE
;
529 switch (lpdcb
->BaudRate
) {
532 port
.c_ospeed
= B110
;
536 port
.c_ospeed
= B300
;
540 port
.c_ospeed
= B600
;
544 port
.c_ospeed
= B1200
;
548 port
.c_ospeed
= B2400
;
552 port
.c_ospeed
= B4800
;
556 port
.c_ospeed
= B9600
;
560 port
.c_ospeed
= B19200
;
564 port
.c_ospeed
= B38400
;
567 commerror
= IE_BAUDRATE
;
570 port
.c_ispeed
= port
.c_ospeed
;
572 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
573 port
.c_cflag
&= ~CSIZE
;
574 switch (lpdcb
->ByteSize
) {
588 commerror
= IE_BYTESIZE
;
592 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
593 port
.c_cflag
&= ~(PARENB
| PARODD
);
595 switch (lpdcb
->Parity
) {
597 port
.c_iflag
&= ~INPCK
;
600 port
.c_cflag
|= (PARENB
| PARODD
);
601 port
.c_iflag
|= INPCK
;
604 port
.c_cflag
|= PARENB
;
605 port
.c_iflag
|= INPCK
;
608 commerror
= IE_BYTESIZE
;
613 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
614 switch (lpdcb
->StopBits
) {
616 port
.c_cflag
&= ~CSTOPB
;
619 port
.c_cflag
|= CSTOPB
;
622 commerror
= IE_BYTESIZE
;
627 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
628 port
.c_cflag
|= CRTSCTS
;
630 if (lpdcb
->fDtrDisable
)
631 port
.c_cflag
&= ~CRTSCTS
;
634 port
.c_iflag
|= IXON
;
636 port
.c_iflag
|= IXOFF
;
638 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
639 commerror
= WinError();
647 int GetCommState(int fd
, DCB FAR
*lpdcb
)
651 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
652 if (tcgetattr(fd
, &port
) == -1) {
653 commerror
= WinError();
660 switch (port
.c_cflag
& CBAUD
) {
662 switch (port
.c_ospeed
) {
665 lpdcb
->BaudRate
= 110;
668 lpdcb
->BaudRate
= 300;
671 lpdcb
->BaudRate
= 600;
674 lpdcb
->BaudRate
= 1200;
677 lpdcb
->BaudRate
= 2400;
680 lpdcb
->BaudRate
= 4800;
683 lpdcb
->BaudRate
= 9600;
686 lpdcb
->BaudRate
= 19200;
689 lpdcb
->BaudRate
= 38400;
693 switch (port
.c_cflag
& CSIZE
) {
708 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
710 lpdcb
->fParity
= NOPARITY
;
713 lpdcb
->fParity
= EVENPARITY
;
715 case (PARENB
| PARODD
):
716 lpdcb
->fParity
= ODDPARITY
;
720 if (port
.c_cflag
& CSTOPB
)
721 lpdcb
->StopBits
= TWOSTOPBITS
;
723 lpdcb
->StopBits
= ONESTOPBIT
;
725 lpdcb
->RlsTimeout
= 50;
726 lpdcb
->CtsTimeout
= 50;
727 lpdcb
->DsrTimeout
= 50;
731 lpdcb
->fDtrDisable
= 0;
735 if (port
.c_cflag
& CRTSCTS
) {
738 lpdcb
->fOutxCtsFlow
= 1;
739 lpdcb
->fOutxDsrFlow
= 1;
742 lpdcb
->fDtrDisable
= 1;
744 if (port
.c_iflag
& IXON
)
749 if (port
.c_iflag
& IXOFF
)
764 int TransmitCommChar(int fd
, char chTransmit
)
766 struct DosDeviceStruct
*ptr
;
769 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
770 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
771 commerror
= IE_BADID
;
775 if (ptr
->suspended
) {
776 commerror
= IE_HARDWARE
;
780 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
781 commerror
= WinError();
789 int UngetCommChar(int fd
, char chUnget
)
791 struct DosDeviceStruct
*ptr
;
793 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
794 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
795 commerror
= IE_BADID
;
799 if (ptr
->suspended
) {
800 commerror
= IE_HARDWARE
;
805 ptr
->unget_byte
= chUnget
;
811 int ReadComm(int fd
, LPSTR lpvBuf
, int cbRead
)
814 struct DosDeviceStruct
*ptr
;
817 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
818 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
819 commerror
= IE_BADID
;
823 if (ptr
->suspended
) {
824 commerror
= IE_HARDWARE
;
829 *lpvBuf
= ptr
->unget_byte
;
837 status
= read(fd
, (void *) lpvBuf
, cbRead
);
840 if (errno
!= EAGAIN
) {
841 commerror
= WinError();
849 return length
+ status
;
853 int WriteComm(int fd
, LPSTR lpvBuf
, int cbWrite
)
856 struct DosDeviceStruct
*ptr
;
858 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
859 fd
, lpvBuf
, cbWrite
);
860 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
861 commerror
= IE_BADID
;
865 if (ptr
->suspended
) {
866 commerror
= IE_HARDWARE
;
870 for (x
=0; x
!= cbWrite
; x
++)
871 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
873 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
876 commerror
= WinError();