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
;
362 port
.c_cflag
|= CRTSCTS
;
366 port
.c_cflag
|= CRTSCTS
;
370 port
.c_iflag
|= IXOFF
;
374 port
.c_iflag
|= IXON
;
379 "EscapeCommFunction fd: %d, unknown function: %d\n",
384 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
385 commerror
= WinError();
393 int FlushComm(int fd
, int fnQueue
)
397 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
407 "FlushComm fd: %d, UNKNOWN queue: %d\n",
412 if (tcflush(fd
, fnQueue
)) {
413 commerror
= WinError();
421 int GetCommError(int fd
, COMSTAT FAR
*lpStat
)
426 "GetCommError: fd %d (current error %d)\n", fd
, commerror
);
427 temperror
= commerror
;
432 UINT FAR
* SetCommEventMask(int fd
, UINT fuEvtMask
)
435 "SetCommEventMask: fd %d, mask %d\n", fd
, fuEvtMask
);
436 eventmask
|= fuEvtMask
;
437 return (UINT
*)&eventmask
;
440 UINT
GetCommEventMask(int fd
, int fnEvtClear
)
443 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
444 eventmask
&= ~fnEvtClear
;
448 int SetCommState(DCB FAR
*lpdcb
)
451 struct DosDeviceStruct
*ptr
;
454 "SetCommState: fd %d, ptr %p\n", lpdcb
->Id
, lpdcb
);
455 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
456 commerror
= WinError();
461 port
.c_cc
[VTIME
] = 1;
463 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
464 port
.c_iflag
|= (IGNBRK
);
466 port
.c_oflag
&= ~(OPOST
);
468 port
.c_cflag
&= ~(HUPCL
);
469 port
.c_cflag
|= CLOCAL
| CREAD
;
471 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
472 port
.c_lflag
|= NOFLSH
;
474 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
475 commerror
= IE_BADID
;
478 if (ptr
->baudrate
> 0)
479 lpdcb
->BaudRate
= ptr
->baudrate
;
480 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
482 port
.c_cflag
&= ~CBAUD
;
483 switch (lpdcb
->BaudRate
) {
486 port
.c_cflag
|= B110
;
490 port
.c_cflag
|= B300
;
494 port
.c_cflag
|= B600
;
498 port
.c_cflag
|= B1200
;
502 port
.c_cflag
|= B2400
;
506 port
.c_cflag
|= B4800
;
510 port
.c_cflag
|= B9600
;
514 port
.c_cflag
|= B19200
;
518 port
.c_cflag
|= B38400
;
521 commerror
= IE_BAUDRATE
;
525 switch (lpdcb
->BaudRate
) {
528 port
.c_ospeed
= B110
;
532 port
.c_ospeed
= B300
;
536 port
.c_ospeed
= B600
;
540 port
.c_ospeed
= B1200
;
544 port
.c_ospeed
= B2400
;
548 port
.c_ospeed
= B4800
;
552 port
.c_ospeed
= B9600
;
556 port
.c_ospeed
= B19200
;
560 port
.c_ospeed
= B38400
;
563 commerror
= IE_BAUDRATE
;
566 port
.c_ispeed
= port
.c_ospeed
;
568 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
569 port
.c_cflag
&= ~CSIZE
;
570 switch (lpdcb
->ByteSize
) {
584 commerror
= IE_BYTESIZE
;
588 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
589 port
.c_cflag
&= ~(PARENB
| PARODD
);
591 switch (lpdcb
->Parity
) {
593 port
.c_iflag
&= ~INPCK
;
596 port
.c_cflag
|= (PARENB
| PARODD
);
597 port
.c_iflag
|= INPCK
;
600 port
.c_cflag
|= PARENB
;
601 port
.c_iflag
|= INPCK
;
604 commerror
= IE_BYTESIZE
;
609 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
610 switch (lpdcb
->StopBits
) {
612 port
.c_cflag
&= ~CSTOPB
;
615 port
.c_cflag
|= CSTOPB
;
618 commerror
= IE_BYTESIZE
;
622 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
623 port
.c_cflag
|= CRTSCTS
;
625 if (lpdcb
->fDtrDisable
)
626 port
.c_cflag
&= ~CRTSCTS
;
629 port
.c_iflag
|= IXON
;
631 port
.c_iflag
|= IXOFF
;
633 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
634 commerror
= WinError();
642 int GetCommState(int fd
, DCB FAR
*lpdcb
)
646 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %p\n", fd
, lpdcb
);
647 if (tcgetattr(fd
, &port
) == -1) {
648 commerror
= WinError();
655 switch (port
.c_cflag
& CBAUD
) {
657 switch (port
.c_ospeed
) {
660 lpdcb
->BaudRate
= 110;
663 lpdcb
->BaudRate
= 300;
666 lpdcb
->BaudRate
= 600;
669 lpdcb
->BaudRate
= 1200;
672 lpdcb
->BaudRate
= 2400;
675 lpdcb
->BaudRate
= 4800;
678 lpdcb
->BaudRate
= 9600;
681 lpdcb
->BaudRate
= 19200;
684 lpdcb
->BaudRate
= 38400;
688 switch (port
.c_cflag
& CSIZE
) {
703 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
705 lpdcb
->fParity
= NOPARITY
;
708 lpdcb
->fParity
= EVENPARITY
;
710 case (PARENB
| PARODD
):
711 lpdcb
->fParity
= ODDPARITY
;
715 if (port
.c_cflag
& CSTOPB
)
716 lpdcb
->StopBits
= TWOSTOPBITS
;
718 lpdcb
->StopBits
= ONESTOPBIT
;
720 lpdcb
->RlsTimeout
= 50;
721 lpdcb
->CtsTimeout
= 50;
722 lpdcb
->DsrTimeout
= 50;
727 lpdcb
->fDtrDisable
= 0;
728 if (port
.c_cflag
& CRTSCTS
) {
731 lpdcb
->fOutxCtsFlow
= 1;
732 lpdcb
->fOutxDsrFlow
= 1;
734 lpdcb
->fDtrDisable
= 1;
736 if (port
.c_iflag
& IXON
)
741 if (port
.c_iflag
& IXOFF
)
756 int TransmitCommChar(int fd
, char chTransmit
)
758 struct DosDeviceStruct
*ptr
;
761 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
762 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
763 commerror
= IE_BADID
;
767 if (ptr
->suspended
) {
768 commerror
= IE_HARDWARE
;
772 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
773 commerror
= WinError();
781 int UngetCommChar(int fd
, char chUnget
)
783 struct DosDeviceStruct
*ptr
;
785 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
786 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
787 commerror
= IE_BADID
;
791 if (ptr
->suspended
) {
792 commerror
= IE_HARDWARE
;
797 ptr
->unget_byte
= chUnget
;
803 int ReadComm(int fd
, LPSTR lpvBuf
, int cbRead
)
806 struct DosDeviceStruct
*ptr
;
809 "ReadComm: fd %d, ptr %p, length %d\n", fd
, lpvBuf
, cbRead
);
810 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
811 commerror
= IE_BADID
;
815 if (ptr
->suspended
) {
816 commerror
= IE_HARDWARE
;
821 *lpvBuf
= ptr
->unget_byte
;
829 status
= read(fd
, (void *) lpvBuf
, cbRead
);
832 if (errno
!= EAGAIN
) {
833 commerror
= WinError();
841 return length
+ status
;
845 int WriteComm(int fd
, LPSTR lpvBuf
, int cbWrite
)
848 struct DosDeviceStruct
*ptr
;
850 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %p, length %d\n",
851 fd
, lpvBuf
, cbWrite
);
852 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
853 commerror
= IE_BADID
;
857 if (ptr
->suspended
) {
858 commerror
= IE_HARDWARE
;
862 for (x
=0; x
!= cbWrite
; x
++)
863 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
865 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
868 commerror
= WinError();