diff --git a/CHANGES.md b/CHANGES.md index c38195d2ff..26dd51b148 100755 --- a/CHANGES.md +++ b/CHANGES.md @@ -7,6 +7,7 @@ Next Release (4.2.1) Features -------- +* [#510](https://github.com/java-native-access/jna/pull/510): Added `GetCommState`, `GetCommTimeouts` `SetCommState` and `SetCommTimeouts` to `com.sun.jna.platform.win32.Kernel32`. Added `DCB` structure to `com.sun.jna.platform.win32.WinBase` - [@MBollig](https://github.com/MBollig) Bug Fixes --------- diff --git a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java index 106a654e0c..87af3296d5 100644 --- a/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/Kernel32.java @@ -14,6 +14,7 @@ import com.sun.jna.Native; import com.sun.jna.Pointer; +import com.sun.jna.platform.win32.WinNT.HANDLE; import com.sun.jna.ptr.IntByReference; import com.sun.jna.ptr.PointerByReference; import com.sun.jna.win32.W32APIOptions; @@ -2729,4 +2730,87 @@ boolean GetVolumePathNamesForVolumeName(String lpszVolumeName, * @see FindVolumeClose */ boolean FindVolumeClose(HANDLE hFindVolume); + + /** + * Retrieves the current control settings for a specified communications + * device. + * + * @param hFile + * [in] A handle to the communications device.
+ * The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this {@link HANDLE}. + * @param lpDCB + * [in, out] A pointer to a {@link WinBase.DCB} structure that + * receives the control settings information. + * + * @return If the function succeeds, the return value is nonzero.
+ * If the function fails, the return value is zero. To get extended + * error information, call {@link Kernel32#GetLastError()}. + * + */ + boolean GetCommState(HANDLE hFile, WinBase.DCB lpDCB); + + /** + * + * Retrieves the time-out parameters for all read and write operations on a + * specified communications device.
+ *
+ * For more information about time-out values for communications devices, + * see the {@link Kernel32#SetCommTimeouts} function. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * + * @param lpCommTimeouts + * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure in + * which the time-out information is returned. + * @return If the function succeeds, the return value is nonzero. + * + * If the function fails, the return value is zero. To get extended + * error information, call {@link Kernel32#GetLastError()}. + * + * + * + */ + boolean GetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); + + /** + * Configures a communications device according to the specifications in a + * device-control block (a {@link WinBase.DCB} structure). The function + * reinitializes all hardware and control settings, but it does not empty + * output or input queues. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * @param lpDCB + * [in] A pointer to a {@link WinBase.DCB} structure that + * contains the configuration information for the specified + * communications device. + * @return If the function succeeds, the return value is nonzero. If the + * function fails, the return value is zero. To get extended error + * information, call {@link Kernel32#GetLastError()}. + */ + boolean SetCommState(HANDLE hFile, WinBase.DCB lpDCB); + + /** + * Sets the time-out parameters for all read and write operations on a + * specified communications device. + * + * @param hFile + * [in] A handle to the communications device. The + * {@link com.sun.jna.platform.win32.Kernel32#CreateFile(String, int, int, com.sun.jna.platform.win32.WinBase.SECURITY_ATTRIBUTES, int, int, com.sun.jna.platform.win32.WinNT.HANDLE)} + * function returns this handle. + * @param LPCOMMTIMEOUTS + * [in] A pointer to a {@link WinBase.COMMTIMEOUTS} structure + * that contains the new time-out values. + * @return If the function succeeds, the return value is nonzero.
+ * If the function fails, the return value is zero. To get extended + * error information, call {@link Kernel32#GetLastError()}. + */ + boolean SetCommTimeouts(HANDLE hFile, WinBase.COMMTIMEOUTS lpCommTimeouts); } diff --git a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java index 2a47213bc8..545ddacbb4 100755 --- a/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java +++ b/contrib/platform/src/com/sun/jna/platform/win32/WinBase.java @@ -1057,4 +1057,650 @@ public DWORD callback(ByteByReference pbData, Pointer pvCallbackContext, int NMPWAIT_USE_DEFAULT_WAIT=0x00000000; int NMPWAIT_NOWAIT=0x00000001; int NMPWAIT_WAIT_FOREVER=0xffffffff; + + + + /** + * + * Contains the time-out parameters for a communications device. The + * parameters determine the behavior of + * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} + * , {@link Kernel32#WriteFile(com.sun.jna.platform.win32.WinNT.HANDLE, + * byte[], int, com.sun.jna.ptr.IntByReference, + * com.sun.jna.platform.win32.WinBase.OVERLAPPED))}, ReadFileEx, and + * WriteFileEx operations on the device.
+ *
+ * + * Remarks
+ * If an application sets ReadIntervalTimeout and ReadTotalTimeoutMultiplier + * to MAXDWORD and sets ReadTotalTimeoutConstant to a value greater than + * zero and less than MAXDWORD, one of the following occurs when the + * ReadFile function is called: + *
  • If there are any bytes in the input buffer, ReadFile returns + * immediately with the bytes in the buffer.
  • + *
  • If there are no bytes in the input buffer, ReadFile waits until a + * byte arrives and then returns immediately.
  • + *
  • If no bytes arrive within the time specified by + * ReadTotalTimeoutConstant, ReadFile times out.
  • + * + * @author Markus + * + */ + public static class COMMTIMEOUTS extends Structure { + /** + * + * The maximum time allowed to elapse before the arrival of the next + * byte on the communications line, in milliseconds. If the interval + * between the arrival of any two bytes exceeds this amount, the + * {@link Kernel32#ReadFile(com.sun.jna.platform.win32.WinNT.HANDLE, java.nio.Buffer, int, com.sun.jna.ptr.IntByReference, com.sun.jna.platform.win32.WinBase.OVERLAPPED)} + * operation is completed and any buffered data is returned. A value of + * zero indicates that interval time-outs are not used. + * + * A value of MAXDWORD, combined with zero values for both the + * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} and + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} members, specifies + * that the read operation is to return immediately with the bytes that + * have already been received, even if no bytes have been received. + * + */ + public DWORD ReadIntervalTimeout; + + /** + * The multiplier used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * multiplied by the requested number of bytes to be read. + */ + public DWORD ReadTotalTimeoutMultiplier; + + /** + * A constant used to calculate the total time-out period for read + * operations, in milliseconds. For each read operation, this value is + * added to the product of the + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} member and the + * requested number of bytes. + * + * A value of zero for both the + * {@link COMMTIMEOUTS#ReadTotalTimeoutMultiplier} and + * {@link COMMTIMEOUTS#ReadTotalTimeoutConstant} members indicates that + * total time-outs are not used for read operations. + */ + public DWORD ReadTotalTimeoutConstant; + + /** + * The multiplier used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * multiplied by the number of bytes to be written. + */ + public DWORD WriteTotalTimeoutMultiplier; + + /** + * A constant used to calculate the total time-out period for write + * operations, in milliseconds. For each write operation, this value is + * added to the product of the + * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} member and the + * number of bytes to be written. + * + * A value of zero for both the + * {@link COMMTIMEOUTS#WriteTotalTimeoutMultiplier} and + * {@link COMMTIMEOUTS#WriteTotalTimeoutConstant} members indicates that + * total time-outs are not used for write operations. + * + */ + public DWORD WriteTotalTimeoutConstant; + + protected List getFieldOrder() { + return Arrays.asList(new String[] { "ReadIntervalTimeout", "ReadTotalTimeoutMultiplier", + "ReadTotalTimeoutConstant", "WriteTotalTimeoutMultiplier", "WriteTotalTimeoutConstant" }); + } + } + + + + /** + * Defines the control setting for a serial communications device. + */ + public static class DCB extends Structure { + + /** + * Type is used to handle the bitfield of the DBC structure. + */ + public static class DCBControllBits extends DWORD { + private static final long serialVersionUID = 8574966619718078579L; + + @Override + public String toString() { + final StringBuilder stringBuilder = new StringBuilder(); + stringBuilder.append('<'); + stringBuilder.append("fBinary:1="); + stringBuilder.append(getfBinary() ? '1' : '0'); + stringBuilder.append(", fParity:1="); + stringBuilder.append(getfParity() ? '1' : '0'); + stringBuilder.append(", fOutxCtsFlow:1="); + stringBuilder.append(getfOutxCtsFlow() ? '1' : '0'); + stringBuilder.append(", fOutxDsrFlow:1="); + stringBuilder.append(getfOutxDsrFlow() ? '1' : '0'); + stringBuilder.append(", fDtrControl:2="); + stringBuilder.append(getfDtrControl()); + stringBuilder.append(", fDsrSensitivity:1="); + stringBuilder.append(getfDsrSensitivity() ? '1' : '0'); + stringBuilder.append(", fTXContinueOnXoff:1="); + stringBuilder.append(getfTXContinueOnXoff() ? '1' : '0'); + stringBuilder.append(", fOutX:1="); + stringBuilder.append(getfOutX() ? '1' : '0'); + stringBuilder.append(", fInX:1="); + stringBuilder.append(getfInX() ? '1' : '0'); + stringBuilder.append(", fErrorChar:1="); + stringBuilder.append(getfErrorChar() ? '1' : '0'); + stringBuilder.append(", fNull:1="); + stringBuilder.append(getfNull() ? '1' : '0'); + stringBuilder.append(", fRtsControl:2="); + stringBuilder.append(getfRtsControl()); + stringBuilder.append(", fAbortOnError:1="); + stringBuilder.append(getfAbortOnError() ? '1' : '0'); + stringBuilder.append(", fDummy2:17="); + stringBuilder.append(getfDummy2()); + stringBuilder.append('>'); + return stringBuilder.toString(); + } + + public boolean getfAbortOnError() { + return (this.intValue() & (0x01 << 14)) != 0x00; + } + + public boolean getfBinary() { + return (this.intValue() & 0x01) != 0x00; + } + + public boolean getfDsrSensitivity() { + return (this.intValue() & (0x01 << 6)) != 0x00; + } + + public int getfDtrControl() { + return (this.intValue() >>> 4) & 0x03; + } + + public boolean getfErrorChar() { + return (this.intValue() & (0x01 << 10)) != 0x00; + } + + public boolean getfInX() { + return (this.intValue() & (0x01 << 9)) != 0x00; + } + + public boolean getfNull() { + return (this.intValue() & (0x01 << 11)) != 0x00; + } + + public boolean getfOutX() { + return (this.intValue() & (0x01 << 8)) != 0x00; + } + + public boolean getfOutxCtsFlow() { + return (this.intValue() & (0x01 << 2)) != 0x00; + } + + public boolean getfOutxDsrFlow() { + return (this.intValue() & (0x01 << 3)) != 0x00; + } + + public boolean getfParity() { + return (this.intValue() & (0x01 << 1)) != 0x00; + } + + public int getfRtsControl() { + return (this.intValue() >>> 12) & 0x03; + } + + public int getfDummy2() { + return (this.intValue()>>>15) & 0x1FFFF; + } + + public boolean getfTXContinueOnXoff() { + return (this.intValue() & (0x01 << 7)) != 0x00; + } + + /** + * If this member is TRUE, the driver terminates all read and write + * operations with an error status if an error occurs.
    + * The driver will not accept any further communications operations + * until the application has acknowledged the error by calling the + * ClearCommError function. + * + * @param fAbortOnError + */ + public void setfAbortOnError(boolean fAbortOnError) { + int tmp = leftShiftMask(fAbortOnError ? 1 : 0, (byte)14, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, binary mode is enabled.
    + * Windows does not support nonbinary mode transfers, so this member + * must be TRUE. + * + * @param fBinary + */ + public void setfBinary(boolean fBinary) { + int tmp = leftShiftMask(fBinary ? 1 : 0, (byte)0, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the communications driver is sensitive to the + * state of the DSR signal.
    + * The driver ignores any bytes received, unless the DSR modem input + * line is high. + * + * @param fDsrSensitivity + */ + public void setfDsrSensitivity(boolean fDsrSensitivity) { + int tmp = leftShiftMask(fDsrSensitivity ? 1 : 0, (byte)6, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * The DTR (data-terminal-ready) flow control. This member can be one of + * the following values. + *
  • {@link WinBase#DTR_CONTROL_DISABLE}
  • + *
  • {@link WinBase#DTR_CONTROL_ENABLE}
  • + *
  • {@link WinBase#DTR_CONTROL_HANDSHAKE}
  • + * + * @param fOutxDsrFlow + * value to set + */ + public void setfDtrControl(int fOutxDsrFlow) { + int tmp = leftShiftMask(fOutxDsrFlow, (byte)4, 0x03, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether bytes received with parity errors are replaced with + * the character specified by the ErrorChar member.
    + * If this member is TRUE and the fParity member is TRUE, replacement + * occurs. + * + * @param fErrorChar + */ + public void setfErrorChar(boolean fErrorChar) { + int tmp = leftShiftMask(fErrorChar ? 1 : 0, (byte)10, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether XON/XOFF flow control is used during reception.
    + * If this member is TRUE, the XoffChar character is sent when the input + * buffer comes within XoffLim bytes of being full, and the XonChar + * character is sent when the input buffer comes within XonLim bytes of + * being empty. + * + * @param fInX + */ + public void setfInX(boolean fInX) { + int tmp = leftShiftMask(fInX ? 1 : 0, (byte)9, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, null bytes are discarded when received. + * + * @param fNull + */ + public void setfNull(boolean fNull) { + int tmp = leftShiftMask(fNull ? 1 : 0, (byte)11, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * Indicates whether XON/XOFF flow control is used during transmission. + *
    + * If this member is TRUE, transmission stops when the XoffChar + * character is received and starts again when the XonChar character is + * received. + * + * @param fOutX + */ + public void setfOutX(boolean fOutX) { + int tmp = leftShiftMask(fOutX ? 1 : 0, (byte)8, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the CTS (clear-to-send) signal is monitored + * for output flow control.
    + * If this member is TRUE and CTS is turned off, output is suspended + * until CTS is sent again. + * + * @param fOutxCtsFlow + */ + public void setfOutxCtsFlow(boolean fOutxCtsFlow) { + int tmp = leftShiftMask(fOutxCtsFlow ? 1 : 0, (byte)2, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, the DSR (data-set-ready) signal is monitored + * for output flow control.
    + * If this member is TRUE and DSR is turned off, output is suspended + * until DSR is sent again. + * + * @param fOutxDsrFlow + */ + public void setfOutxDsrFlow(boolean fOutxDsrFlow) { + int tmp = leftShiftMask(fOutxDsrFlow ? 1 : 0, (byte)3, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, parity checking is performed and errors are + * reported. + * + * @param fParity + */ + public void setfParity(boolean fParity) { + int tmp = leftShiftMask(fParity ? 1 : 0, (byte)1, 0x01, this.intValue()); + this.setValue(tmp); + } + + /** + * + * The RTS (request-to-send) flow control. This member can be one of the + * following values. + *
  • {@link WinBase#RTS_CONTROL_DISABLE}
  • + *
  • {@link WinBase#RTS_CONTROL_ENABLE}
  • + *
  • {@link WinBase#RTS_CONTROL_HANDSHAKE}
  • + *
  • {@link WinBase#RTS_CONTROL_TOGGLE}
  • + * + * @param fRtsControl + */ + public void setfRtsControl(int fRtsControl) { + int tmp = leftShiftMask(fRtsControl, (byte)12, 0x03, this.intValue()); + this.setValue(tmp); + } + + /** + * If this member is TRUE, transmission continues after the input buffer + * has come within XoffLim bytes of being full and the driver has + * transmitted the XoffChar character to stop receiving bytes.
    + * If this member is FALSE, transmission does not continue until the + * input buffer is within XonLim bytes of being empty and the driver has + * transmitted the XonChar character to resume reception. + * + * @param fTXContinueOnXoff + */ + public void setfTXContinueOnXoff(boolean fTXContinueOnXoff) { + int tmp = leftShiftMask(fTXContinueOnXoff ? 1 : 0, (byte)7, 0x01, this.intValue()); + this.setValue(tmp); + } + + + private static int leftShiftMask(int valuetoset, byte shift, int mask, int storage) { + int tmp = storage; + tmp &= ~(mask << shift); + tmp |= ((valuetoset & mask) << shift); + return tmp; + } + } + /** + * The length of the structure, in bytes. The caller must set this + * member to sizeof(DCB). + */ + public DWORD DCBlength; + + /** + * + * The baud rate at which the communications device operates. This + * member can be an actual baud rate value, or one of the following + * indexes. + *
  • {@link WinBase#CBR_110}
  • + *
  • {@link WinBase#CBR_300}
  • + *
  • {@link WinBase#CBR_600}
  • + *
  • {@link WinBase#CBR_1200}
  • + *
  • {@link WinBase#CBR_2400}
  • + *
  • {@link WinBase#CBR_4800}
  • + *
  • {@link WinBase#CBR_9600}
  • + *
  • {@link WinBase#CBR_14400}
  • + *
  • {@link WinBase#CBR_19200}
  • + *
  • {@link WinBase#CBR_38400}
  • + *
  • {@link WinBase#CBR_56000}
  • + *
  • {@link WinBase#CBR_128000}
  • + *
  • {@link WinBase#CBR_256000}
  • + * + */ + public DWORD BaudRate; + + /** + * Contains all the bit wise setting entries. + */ + public DCBControllBits controllBits; + + /** + * Reserved; must be zero. + */ + public WORD wReserved; + + /** + * The minimum number of bytes in use allowed in the input buffer before + * flow control is activated to allow transmission by the sender. This + * assumes that either XON/XOFF, RTS, or DTR input flow control is + * specified in the fInX, fRtsControl, or fDtrControl members. + */ + public WORD XonLim; + + /** + * The minimum number of free bytes allowed in the input buffer before + * flow control is activated to inhibit the sender. Note that the sender + * may transmit characters after the flow control signal has been + * activated, so this value should never be zero. This assumes that + * either XON/XOFF, RTS, or DTR input flow control is specified in the + * fInX, fRtsControl, or fDtrControl members. The maximum number of + * bytes in use allowed is calculated by subtracting this value from the + * size, in bytes, of the input buffer. + */ + public WORD XoffLim; + + /** + * The number of bits in the bytes transmitted and received. + */ + public BYTE ByteSize; + + /** + * + * The parity scheme to be used. This member can be one of the following + * values. + *
  • {@link WinBase#EVENPARITY}
  • + *
  • {@link WinBase#ODDPARITY}
  • + *
  • {@link WinBase#NOPARITY}
  • + *
  • {@link WinBase#SPACEPARITY}
  • + *
  • {@link WinBase#MARKPARITY}
  • + */ + public BYTE Parity; + + /** + * The number of stop bits to be used. This member can be one of the + * following values. + *
  • {@link WinBase#ONESTOPBIT}
  • + *
  • {@link WinBase#ONE5STOPBITS}
  • + *
  • {@link WinBase#TWOSTOPBITS}
  • + */ + public BYTE StopBits; + + /** + * The value of the XON character for both transmission and reception. + */ + public char XonChar; + + /** + * The value of the XOFF character for both transmission and reception. + */ + public char XoffChar; + + /** + * The value of the character used to replace bytes received with a + * parity error. + */ + public char ErrorChar; + + /** + * The value of the character used to signal the end of data. + */ + public char EofChar; + + /** + * The value of the character used to signal an event. + */ + public char EvtChar; + + /** + * Reserved; do not use. + */ + public WORD wReserved1; + + public DCB() { + DCBlength = new DWORD(size()); + } + + protected List getFieldOrder() { + return Arrays.asList(new String[] { "DCBlength", "BaudRate", "controllBits", "wReserved", "XonLim", + "XoffLim", "ByteSize", "Parity", "StopBits", "XonChar", "XoffChar", "ErrorChar", "EofChar", + "EvtChar", "wReserved1" }); + } + } + + /** + * No parity. + */ + int NOPARITY = 0; + + /** + * Odd parity. + */ + int ODDPARITY = 1; + + /** + * Even parity. + */ + int EVENPARITY = 2; + + /** + * Mark parity. + */ + int MARKPARITY = 3; + + /** + * Space parity. + */ + int SPACEPARITY = 4; + + /** + * 1 stop bit. + */ + int ONESTOPBIT = 0; + + /** + * 1.5 stop bits. + */ + int ONE5STOPBITS = 1; + /** + * 2 stop bits. + */ + int TWOSTOPBITS = 2; + /** + * 110 bps. + */ + int CBR_110 = 110; + /** + * 300 bps. + */ + int CBR_300 = 300; + /** + * 600 bps. + */ + int CBR_600 = 600; + /** + * 1200 bps. + */ + int CBR_1200 = 1200; + /** + * 2400 bps. + */ + int CBR_2400 = 2400; + /** + * 4800 bps. + */ + int CBR_4800 = 4800; + /** + * 9600 bps. + */ + int CBR_9600 = 9600; + /** + * 14400 bps. + */ + int CBR_14400 = 14400; + /** + * 19200 bps. + */ + int CBR_19200 = 19200; + /** + * 38400 bps. + */ + int CBR_38400 = 38400; + /** + * 56000 bps. + */ + int CBR_56000 = 56000; + + /** + * 128000 bps. + */ + int CBR_128000 = 128000; + + /** + * 256000 bps. + */ + int CBR_256000 = 256000; + + /** + * Disables the DTR line when the device is opened and leaves it disabled. + */ + int DTR_CONTROL_DISABLE = 0; + + /** + * Enables the DTR line when the device is opened and leaves it on. + */ + int DTR_CONTROL_ENABLE = 1; + + /** + * Enables DTR handshaking.
    + * If handshaking is enabled, it is an error for the application to adjust + * the line by using the EscapeCommFunction function. + */ + int DTR_CONTROL_HANDSHAKE = 2; + + /** + * Disables the RTS line when the device is opened and leaves it disabled. + */ + int RTS_CONTROL_DISABLE = 0; + + /** + * Enables the RTS line when the device is opened and leaves it on. + */ + int RTS_CONTROL_ENABLE = 1; + + /** + * Enables RTS handshaking.
    + * The driver raises the RTS line when the "type-ahead" (input) buffer is + * less than one-half full and lowers the RTS line when the buffer is more + * than three-quarters full.
    + * If handshaking is enabled, it is an error for the application to adjust + * the line by using the EscapeCommFunction function. + */ + int RTS_CONTROL_HANDSHAKE = 2; + + /** + * Specifies that the RTS line will be high if bytes are available for + * transmission.
    + * After all buffered bytes have been sent, the RTS line will be low. + */ + int RTS_CONTROL_TOGGLE = 3;; + } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java index 97cb7e1407..1b4e743859 100644 --- a/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java +++ b/contrib/platform/test/com/sun/jna/platform/win32/Kernel32Test.java @@ -767,4 +767,167 @@ public void testVirtualQueryEx() { SIZE_T bytesRead = Kernel32.INSTANCE.VirtualQueryEx(selfHandle, Pointer.NULL, mbi, new SIZE_T(mbi.size())); assertTrue(bytesRead.intValue() > 0); } + + public void testGetCommState() { + WinBase.DCB lpDCB = new WinBase.DCB(); + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + //try to read the com port state using the invalid handle + assertFalse(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + switch (lpDCB.BaudRate.intValue()) { + case WinBase.CBR_110: + case WinBase.CBR_1200: + case WinBase.CBR_128000: + case WinBase.CBR_14400: + case WinBase.CBR_19200: + case WinBase.CBR_2400: + case WinBase.CBR_256000: + case WinBase.CBR_300: + case WinBase.CBR_38400: + case WinBase.CBR_4800: + case WinBase.CBR_56000: + case WinBase.CBR_600: + case WinBase.CBR_9600: + break; + default: + fail("Received value of WinBase.DCB.BaudRate is not valid"); + } + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testSetCommState() { + WinBase.DCB lpDCB = new WinBase.DCB(); + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to read the com port state using the invalid handle + assertFalse(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpDCB)); + DWORD oldBaudRate = new DWORD(lpDCB.BaudRate.longValue()); + + lpDCB.BaudRate = new DWORD(WinBase.CBR_110); + + assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + WinBase.DCB lpNewDCB = new WinBase.DCB(); + assertTrue(Kernel32.INSTANCE.GetCommState(handleSerialPort, lpNewDCB)); + + assertEquals(WinBase.CBR_110, lpNewDCB.BaudRate.intValue()); + + lpDCB.BaudRate = oldBaudRate; + assertTrue(Kernel32.INSTANCE.SetCommState(handleSerialPort, lpDCB)); + + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testGetCommTimeouts() { + WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to read the com port timeouts using the invalid handle + assertFalse(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + // Check if we can open a connection to com port1 + // If yes, we try to read the com state + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } + + public void testSetCommTimeouts() { + WinBase.COMMTIMEOUTS lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + + // Here we test a com port that definitely does not exist! + HANDLE handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\comDummy", + WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, + null); + + int lastError = Kernel32.INSTANCE.GetLastError(); + assertEquals(lastError, WinNT.ERROR_FILE_NOT_FOUND); + // try to store the com port timeouts using the invalid handle + assertFalse(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + // Check if we can open a connection to com port1 + // If yes, we try to store the com timeouts + // If no com port exists we have to skip this test + handleSerialPort = Kernel32.INSTANCE.CreateFile("\\\\.\\com1", WinNT.GENERIC_READ | WinNT.GENERIC_WRITE, 0, + null, WinNT.OPEN_EXISTING, WinNT.FILE_ATTRIBUTE_NORMAL, null); + lastError = Kernel32.INSTANCE.GetLastError(); + if (WinNT.NO_ERROR == lastError) { + assertFalse(WinNT.INVALID_HANDLE_VALUE.equals(handleSerialPort)); + try { + lpCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + DWORD oldReadIntervalTimeout = new DWORD(lpCommTimeouts.ReadIntervalTimeout.longValue()); + + lpCommTimeouts.ReadIntervalTimeout = new DWORD(20); + + assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + WinBase.COMMTIMEOUTS lpNewCommTimeouts = new WinBase.COMMTIMEOUTS(); + assertTrue(Kernel32.INSTANCE.GetCommTimeouts(handleSerialPort, lpNewCommTimeouts)); + + assertEquals(20, lpNewCommTimeouts.ReadIntervalTimeout.intValue()); + + lpCommTimeouts.ReadIntervalTimeout = oldReadIntervalTimeout; + + assertTrue(Kernel32.INSTANCE.SetCommTimeouts(handleSerialPort, lpCommTimeouts)); + + } finally { + Kernel32.INSTANCE.CloseHandle(handleSerialPort); + } + } + } } diff --git a/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java new file mode 100644 index 0000000000..cecb4b3b7d --- /dev/null +++ b/contrib/platform/test/com/sun/jna/platform/win32/WinBaseTest.java @@ -0,0 +1,136 @@ +/* Copyright (c) 2015 Markus Bollig, All Rights Reserved + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + */ +package com.sun.jna.platform.win32; + +import com.sun.jna.platform.win32.WinBase.DCB; + +import junit.framework.TestCase; + +public class WinBaseTest extends TestCase { + + /** + * Test the mapping of the {@link DCB} structure. + * Particularly the mapping of the bit field is tested. + */ + public void testDCBStructureMapping() { + //first we test if the WinBase.DCB bitfiled mapping works as expected. + WinBase.DCB lpDCB = new WinBase.DCB(); + lpDCB.controllBits.setValue(0); + + lpDCB.controllBits.setfBinary(true); + assertEquals(1, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfBinary()); + lpDCB.controllBits.setfBinary(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfBinary()); + + lpDCB.controllBits.setfParity(true); + assertEquals(2, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfParity()); + lpDCB.controllBits.setfParity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfParity()); + + lpDCB.controllBits.setfOutxCtsFlow(true); + assertEquals(4, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxCtsFlow()); + lpDCB.controllBits.setfOutxCtsFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxCtsFlow()); + + lpDCB.controllBits.setfOutxDsrFlow(true); + assertEquals(8, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutxDsrFlow()); + lpDCB.controllBits.setfOutxDsrFlow(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutxDsrFlow()); + + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_ENABLE); + assertEquals(16, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_ENABLE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_HANDSHAKE); + assertEquals(32, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_HANDSHAKE, lpDCB.controllBits.getfDtrControl()); + lpDCB.controllBits.setfDtrControl(WinBase.DTR_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.DTR_CONTROL_DISABLE, lpDCB.controllBits.getfDtrControl()); + + lpDCB.controllBits.setfDsrSensitivity(true); + assertEquals(64, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfDsrSensitivity()); + lpDCB.controllBits.setfDsrSensitivity(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfDsrSensitivity()); + + lpDCB.controllBits.setfTXContinueOnXoff(true); + assertEquals(128, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfTXContinueOnXoff()); + lpDCB.controllBits.setfTXContinueOnXoff(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfTXContinueOnXoff()); + + lpDCB.controllBits.setfOutX(true); + assertEquals(256, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfOutX()); + lpDCB.controllBits.setfOutX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfOutX()); + + lpDCB.controllBits.setfInX(true); + assertEquals(512, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfInX()); + lpDCB.controllBits.setfInX(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfInX()); + + lpDCB.controllBits.setfErrorChar(true); + assertEquals(1024, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfErrorChar()); + lpDCB.controllBits.setfErrorChar(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfErrorChar()); + + lpDCB.controllBits.setfNull(true); + assertEquals(2048, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfNull()); + lpDCB.controllBits.setfNull(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfNull()); + + + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_ENABLE); + assertEquals(4096, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_ENABLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_HANDSHAKE); + assertEquals(8192, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_HANDSHAKE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_TOGGLE); + assertEquals(12288, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_TOGGLE, lpDCB.controllBits.getfRtsControl()); + lpDCB.controllBits.setfRtsControl(WinBase.RTS_CONTROL_DISABLE); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(WinBase.RTS_CONTROL_DISABLE, lpDCB.controllBits.getfRtsControl()); + + + lpDCB.controllBits.setfAbortOnError(true); + assertEquals(16384, lpDCB.controllBits.longValue()); + assertEquals(true, lpDCB.controllBits.getfAbortOnError()); + lpDCB.controllBits.setfAbortOnError(false); + assertEquals(0, lpDCB.controllBits.longValue()); + assertEquals(false, lpDCB.controllBits.getfAbortOnError()); + } + + public static void main(String[] args) { + junit.textui.TestRunner.run(WinBaseTest.class); + } +} diff --git a/native/libffi/autogen.sh b/native/libffi/autogen.sh index d270b984c1..822ff97d88 100755 --- a/native/libffi/autogen.sh +++ b/native/libffi/autogen.sh @@ -1,2 +1,2 @@ #!/bin/sh -exec autoreconf -v -f -i +exec autoreconf -v -f -i \ No newline at end of file