2 * DEC 93 Erik Bos (erik@trashcan.hacktic.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
);
93 void Comm_DeInit(void)
97 for (x
=0; x
!=MAX_PORTS
; x
++) {
99 if (COM
[x
].devicename
) {
102 free(COM
[x
].devicename
);
104 if (LPT
[x
].devicename
) {
107 free(LPT
[x
].devicename
);
112 struct DosDeviceStruct
*GetDeviceStruct(int fd
)
116 for (x
=0; x
!=MAX_PORTS
; x
++) {
126 int ValidCOMPort(int x
)
128 return(x
< MAX_PORTS
? (int) COM
[x
].devicename
: 0);
131 int ValidLPTPort(int x
)
133 return(x
< MAX_PORTS
? (int) LPT
[x
].devicename
: 0);
138 dprintf_comm(stddeb
, "WinError: errno = %d\n", errno
);
145 int BuildCommDCB(LPSTR device
, DCB FAR
*lpdcb
)
147 /* "COM1:9600,n,8,1" */
151 char *ptr
, temp
[256];
154 "BuildCommDCB: (%s), ptr %d\n", device
, (long) lpdcb
);
157 if (!strncasecmp(device
,"COM",3)) {
158 port
= device
[3] - '0';
162 fprintf(stderr
, "comm: BUG ! COM0 can't exists!.\n");
163 commerror
= IE_BADID
;
166 if (!ValidCOMPort(port
)) {
167 commerror
= IE_BADID
;
172 OpenComm(device
, 0, 0);
174 lpdcb
->Id
= COM
[port
].fd
;
179 if (*(device
+4) != ':')
182 strcpy(temp
,device
+5);
183 ptr
= strtok(temp
, ",");
185 if (COM
[port
].baudrate
> 0)
186 lpdcb
->BaudRate
= COM
[port
].baudrate
;
188 lpdcb
->BaudRate
= atoi(ptr
);
189 dprintf_comm(stddeb
,"BuildCommDCB: baudrate (%d)\n", lpdcb
->BaudRate
);
191 ptr
= strtok(NULL
, ",");
193 *ptr
= toupper(*ptr
);
195 dprintf_comm(stddeb
,"BuildCommDCB: parity (%c)\n", *ptr
);
198 lpdcb
->Parity
= NOPARITY
;
205 lpdcb
->Parity
= EVENPARITY
;
208 lpdcb
->Parity
= MARKPARITY
;
211 lpdcb
->Parity
= ODDPARITY
;
214 fprintf(stderr
,"comm: unknown parity `%c'!\n", *ptr
);
218 ptr
= strtok(NULL
, ",");
219 dprintf_comm(stddeb
, "BuildCommDCB: charsize (%c)\n", *ptr
);
220 lpdcb
->ByteSize
= *ptr
- '0';
222 ptr
= strtok(NULL
, ",");
223 dprintf_comm(stddeb
, "BuildCommDCB: stopbits (%c)\n", *ptr
);
226 lpdcb
->StopBits
= ONESTOPBIT
;
229 lpdcb
->StopBits
= TWOSTOPBITS
;
232 fprintf(stderr
,"comm: unknown # of stopbits `%c'!\n", *ptr
);
240 int OpenComm(LPSTR device
, UINT cbInQueue
, UINT cbOutQueue
)
245 "OpenComm: %s, %d, %d\n", device
, cbInQueue
, cbOutQueue
);
248 if (!strncasecmp(device
,"COM",3)) {
249 port
= device
[3] - '0';
252 fprintf(stderr
, "comm: BUG ! COM0 doesn't exists!.\n");
253 commerror
= IE_BADID
;
257 "OpenComm: %s = %s\n", device
, COM
[port
].devicename
);
259 if (!ValidCOMPort(port
)) {
260 commerror
= IE_BADID
;
267 fd
= open(COM
[port
].devicename
, O_RDWR
| O_NONBLOCK
);
269 commerror
= WinError();
277 if (!strncasecmp(device
,"LPT",3)) {
278 port
= device
[3] - '0';
280 if (!ValidLPTPort(port
)) {
281 commerror
= IE_BADID
;
289 fd
= open(LPT
[port
].devicename
, O_RDWR
| O_NONBLOCK
, 0);
291 commerror
= WinError();
301 int CloseComm(int fd
)
303 dprintf_comm(stddeb
,"CloseComm: fd %d\n", fd
);
304 if (close(fd
) == -1) {
305 commerror
= WinError();
313 int SetCommBreak(int fd
)
315 struct DosDeviceStruct
*ptr
;
317 dprintf_comm(stddeb
,"SetCommBreak: fd: %d\n", fd
);
318 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
319 commerror
= IE_BADID
;
328 int ClearCommBreak(int fd
)
330 struct DosDeviceStruct
*ptr
;
332 dprintf_comm(stddeb
,"ClearCommBreak: fd: %d\n", fd
);
333 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
334 commerror
= IE_BADID
;
343 LONG
EscapeCommFunction(int fd
, int nFunction
)
349 "EscapeCommFunction fd: %d, function: %d\n", fd
, nFunction
);
350 if (tcgetattr(fd
, &port
) == -1) {
351 commerror
= WinError();
360 for (max
= MAX_PORTS
;!COM
[max
].devicename
;max
--)
366 for (max
= MAX_PORTS
;!LPT
[max
].devicename
;max
--)
372 port
.c_cflag
&= TIOCM_DTR
;
376 port
.c_cflag
&= TIOCM_RTS
;
380 port
.c_cflag
|= CRTSCTS
;
384 port
.c_cflag
|= CRTSCTS
;
388 port
.c_iflag
|= IXOFF
;
392 port
.c_iflag
|= IXON
;
397 "EscapeCommFunction fd: %d, unknown function: %d\n",
402 if (tcsetattr(fd
, TCSADRAIN
, &port
) == -1) {
403 commerror
= WinError();
411 int FlushComm(int fd
, int fnQueue
)
415 dprintf_comm(stddeb
,"FlushComm fd: %d, queue: %d\n", fd
, fnQueue
);
425 "FlushComm fd: %d, UNKNOWN queue: %d\n",
430 if (tcflush(fd
, fnQueue
)) {
431 commerror
= WinError();
439 int GetCommError(int fd
, COMSTAT FAR
*lpStat
)
444 "GetCommError: fd %d (current error %d)\n", fd
, commerror
);
445 temperror
= commerror
;
450 UINT FAR
* SetCommEventMask(int fd
, UINT fuEvtMask
)
453 "SetCommEventMask: fd %d, mask %d\n", fd
, fuEvtMask
);
454 eventmask
|= fuEvtMask
;
455 return (UINT
*)&eventmask
;
458 UINT
GetCommEventMask(int fd
, int fnEvtClear
)
461 "GetCommEventMask: fd %d, mask %d\n", fd
, fnEvtClear
);
462 eventmask
&= ~fnEvtClear
;
466 int SetCommState(DCB FAR
*lpdcb
)
469 struct DosDeviceStruct
*ptr
;
472 "SetCommState: fd %d, ptr %d\n", lpdcb
->Id
, (long) lpdcb
);
473 if (tcgetattr(lpdcb
->Id
, &port
) == -1) {
474 commerror
= WinError();
479 port
.c_cc
[VTIME
] = 1;
481 port
.c_iflag
&= ~(ISTRIP
|BRKINT
|IGNCR
|ICRNL
|INLCR
|IMAXBEL
);
482 port
.c_iflag
|= (IGNBRK
);
484 port
.c_oflag
&= ~(OPOST
);
486 port
.c_cflag
&= ~(HUPCL
);
487 port
.c_cflag
|= CLOCAL
| CREAD
;
489 port
.c_lflag
&= ~(ICANON
|ECHO
|ISIG
);
490 port
.c_lflag
|= NOFLSH
;
492 if ((ptr
= GetDeviceStruct(lpdcb
->Id
)) == NULL
) {
493 commerror
= IE_BADID
;
496 if (ptr
->baudrate
> 0)
497 lpdcb
->BaudRate
= ptr
->baudrate
;
498 dprintf_comm(stddeb
,"SetCommState: baudrate %d\n",lpdcb
->BaudRate
);
500 port
.c_cflag
&= ~CBAUD
;
501 switch (lpdcb
->BaudRate
) {
504 port
.c_cflag
|= B110
;
508 port
.c_cflag
|= B300
;
512 port
.c_cflag
|= B600
;
516 port
.c_cflag
|= B1200
;
520 port
.c_cflag
|= B2400
;
524 port
.c_cflag
|= B4800
;
528 port
.c_cflag
|= B9600
;
532 port
.c_cflag
|= B19200
;
536 port
.c_cflag
|= B38400
;
539 commerror
= IE_BAUDRATE
;
543 switch (lpdcb
->BaudRate
) {
546 port
.c_ospeed
= B110
;
550 port
.c_ospeed
= B300
;
554 port
.c_ospeed
= B600
;
558 port
.c_ospeed
= B1200
;
562 port
.c_ospeed
= B2400
;
566 port
.c_ospeed
= B4800
;
570 port
.c_ospeed
= B9600
;
574 port
.c_ospeed
= B19200
;
578 port
.c_ospeed
= B38400
;
581 commerror
= IE_BAUDRATE
;
584 port
.c_ispeed
= port
.c_ospeed
;
586 dprintf_comm(stddeb
,"SetCommState: bytesize %d\n",lpdcb
->ByteSize
);
587 port
.c_cflag
&= ~CSIZE
;
588 switch (lpdcb
->ByteSize
) {
602 commerror
= IE_BYTESIZE
;
606 dprintf_comm(stddeb
,"SetCommState: parity %d\n",lpdcb
->Parity
);
607 port
.c_cflag
&= ~(PARENB
| PARODD
);
609 switch (lpdcb
->Parity
) {
611 port
.c_iflag
&= ~INPCK
;
614 port
.c_cflag
|= (PARENB
| PARODD
);
615 port
.c_iflag
|= INPCK
;
618 port
.c_cflag
|= PARENB
;
619 port
.c_iflag
|= INPCK
;
622 commerror
= IE_BYTESIZE
;
627 dprintf_comm(stddeb
,"SetCommState: stopbits %d\n",lpdcb
->StopBits
);
628 switch (lpdcb
->StopBits
) {
630 port
.c_cflag
&= ~CSTOPB
;
633 port
.c_cflag
|= CSTOPB
;
636 commerror
= IE_BYTESIZE
;
640 if (lpdcb
->fDtrflow
|| lpdcb
->fRtsflow
|| lpdcb
->fOutxCtsFlow
)
641 port
.c_cflag
|= CRTSCTS
;
643 if (lpdcb
->fDtrDisable
)
644 port
.c_cflag
&= ~CRTSCTS
;
647 port
.c_iflag
|= IXON
;
649 port
.c_iflag
|= IXOFF
;
651 if (tcsetattr(lpdcb
->Id
, TCSADRAIN
, &port
) == -1) {
652 commerror
= WinError();
660 int GetCommState(int fd
, DCB FAR
*lpdcb
)
664 dprintf_comm(stddeb
,"GetCommState: fd %d, ptr %d\n", fd
, (long) lpdcb
);
665 if (tcgetattr(fd
, &port
) == -1) {
666 commerror
= WinError();
673 switch (port
.c_cflag
& CBAUD
) {
675 switch (port
.c_ospeed
) {
678 lpdcb
->BaudRate
= 110;
681 lpdcb
->BaudRate
= 300;
684 lpdcb
->BaudRate
= 600;
687 lpdcb
->BaudRate
= 1200;
690 lpdcb
->BaudRate
= 2400;
693 lpdcb
->BaudRate
= 4800;
696 lpdcb
->BaudRate
= 9600;
699 lpdcb
->BaudRate
= 19200;
702 lpdcb
->BaudRate
= 38400;
706 switch (port
.c_cflag
& CSIZE
) {
721 switch (port
.c_cflag
& ~(PARENB
| PARODD
)) {
723 lpdcb
->fParity
= NOPARITY
;
726 lpdcb
->fParity
= EVENPARITY
;
728 case (PARENB
| PARODD
):
729 lpdcb
->fParity
= ODDPARITY
;
733 if (port
.c_cflag
& CSTOPB
)
734 lpdcb
->StopBits
= TWOSTOPBITS
;
736 lpdcb
->StopBits
= ONESTOPBIT
;
738 lpdcb
->RlsTimeout
= 50;
739 lpdcb
->CtsTimeout
= 50;
740 lpdcb
->DsrTimeout
= 50;
745 lpdcb
->fDtrDisable
= 0;
746 if (port
.c_cflag
& CRTSCTS
) {
749 lpdcb
->fOutxCtsFlow
= 1;
750 lpdcb
->fOutxDsrFlow
= 1;
752 lpdcb
->fDtrDisable
= 1;
754 if (port
.c_iflag
& IXON
)
759 if (port
.c_iflag
& IXOFF
)
774 int TransmitCommChar(int fd
, char chTransmit
)
776 struct DosDeviceStruct
*ptr
;
779 "TransmitCommChar: fd %d, data %d \n", fd
, chTransmit
);
780 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
781 commerror
= IE_BADID
;
785 if (ptr
->suspended
) {
786 commerror
= IE_HARDWARE
;
790 if (write(fd
, (void *) &chTransmit
, 1) == -1) {
791 commerror
= WinError();
799 int UngetCommChar(int fd
, char chUnget
)
801 struct DosDeviceStruct
*ptr
;
803 dprintf_comm(stddeb
,"UngetCommChar: fd %d (char %d)\n", fd
, chUnget
);
804 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
805 commerror
= IE_BADID
;
809 if (ptr
->suspended
) {
810 commerror
= IE_HARDWARE
;
815 ptr
->unget_byte
= chUnget
;
821 int ReadComm(int fd
, LPSTR lpvBuf
, int cbRead
)
824 struct DosDeviceStruct
*ptr
;
827 "ReadComm: fd %d, ptr %d, length %d\n", fd
, (long) lpvBuf
, cbRead
);
828 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
829 commerror
= IE_BADID
;
833 if (ptr
->suspended
) {
834 commerror
= IE_HARDWARE
;
839 *lpvBuf
= ptr
->unget_byte
;
847 status
= read(fd
, (void *) lpvBuf
, cbRead
);
850 if (errno
!= EAGAIN
) {
851 commerror
= WinError();
859 return length
+ status
;
863 int WriteComm(int fd
, LPSTR lpvBuf
, int cbWrite
)
866 struct DosDeviceStruct
*ptr
;
868 dprintf_comm(stddeb
,"WriteComm: fd %d, ptr %d, length %d\n",
869 fd
, (long) lpvBuf
, cbWrite
);
870 if ((ptr
= GetDeviceStruct(fd
)) == NULL
) {
871 commerror
= IE_BADID
;
875 if (ptr
->suspended
) {
876 commerror
= IE_HARDWARE
;
880 for (x
=0; x
!= cbWrite
; x
++)
881 dprintf_comm(stddeb
,"%c", *(lpvBuf
+ x
) );
883 length
= write(fd
, (void *) lpvBuf
, cbWrite
);
886 commerror
= WinError();