/* * Copyright (c) 2011, Kustaa Nyholm / SpareTimeLabs * All rights reserved. * * Redistribution and use in source and binary forms, with or without modification, * are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this list * of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, this * list of conditions and the following disclaimer in the documentation and/or other * materials provided with the distribution. * * Neither the name of the Kustaa Nyholm or SpareTimeLabs nor the names of its * contributors may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY * OF SUCH DAMAGE. */ package jtermios.windows.testsuite; import static jtermios.windows.WinAPI.CBR_1200; import static jtermios.windows.WinAPI.CloseHandle; import static jtermios.windows.WinAPI.CreateEvent; import static jtermios.windows.WinAPI.CreateFile; import static jtermios.windows.WinAPI.ERROR_IO_INCOMPLETE; import static jtermios.windows.WinAPI.ERROR_IO_PENDING; import static jtermios.windows.WinAPI.FILE_FLAG_OVERLAPPED; import static jtermios.windows.WinAPI.GENERIC_READ; import static jtermios.windows.WinAPI.GENERIC_WRITE; import static jtermios.windows.WinAPI.GetLastError; import static jtermios.windows.WinAPI.GetOverlappedResult; import static jtermios.windows.WinAPI.INVALID_HANDLE_VALUE; import static jtermios.windows.WinAPI.NOPARITY; import static jtermios.windows.WinAPI.ONESTOPBIT; import static jtermios.windows.WinAPI.OPEN_EXISTING; import static jtermios.windows.WinAPI.ReadFile; import static jtermios.windows.WinAPI.ResetEvent; import static jtermios.windows.WinAPI.SetCommState; import static jtermios.windows.WinAPI.SetCommTimeouts; import static jtermios.windows.WinAPI.SetupComm; import static jtermios.windows.WinAPI.WAIT_OBJECT_0; import static jtermios.windows.WinAPI.WAIT_TIMEOUT; import static jtermios.windows.WinAPI.WaitForSingleObject; import static jtermios.windows.WinAPI.WriteFile; import jtermios.windows.WinAPI.COMMTIMEOUTS; import jtermios.windows.WinAPI.DCB; import jtermios.windows.WinAPI.HANDLE; import jtermios.windows.WinAPI.OVERLAPPED; import com.sun.jna.Memory; public class TestSuite { private void check(boolean ok, String what) { if (!ok) { System.err.println(what + " failed, error " + GetLastError()); System.exit(0); } } public void test1() { System.out.println("A contorted loopback test with overlapped IO for WinAPI"); String COM = "COM5:"; HANDLE hComm = CreateFile(COM, GENERIC_READ | GENERIC_WRITE, 0, null, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, null); check(SetupComm(hComm, 2048, 2048), "SetupComm "); DCB dcb = new DCB(); dcb.DCBlength = dcb.size(); dcb.BaudRate = CBR_1200; dcb.ByteSize = 8; dcb.fFlags = 0; dcb.Parity = NOPARITY; dcb.XonChar = 0x11; dcb.StopBits = ONESTOPBIT; dcb.XonChar = 0x13; check(SetCommState(hComm, dcb), "SetCommState "); COMMTIMEOUTS touts = new COMMTIMEOUTS(); check(SetCommTimeouts(hComm, touts), "SetCommTimeouts "); check(!INVALID_HANDLE_VALUE.equals(hComm), "CreateFile " + COM); String send = "Hello World"; int tlen = send.getBytes().length; int[] txn = { 0 }; Memory txm = new Memory(tlen + 1); txm.clear(); txm.write(0, send.getBytes(), 0, tlen); int[] rxn = { 0 }; Memory rxm = new Memory(tlen); OVERLAPPED osReader = new OVERLAPPED(); osReader.writeField("hEvent", CreateEvent(null, true, false, null)); check(osReader.hEvent != null, "CreateEvent/osReader"); OVERLAPPED osWriter = new OVERLAPPED(); osWriter.writeField("hEvent", CreateEvent(null, true, false, null)); check(osWriter.hEvent != null, "CreateEvent/osWriter"); boolean first = true; // First time through here send some stuff first = false; check(ResetEvent(osWriter.hEvent), "ResetEvent/osWriter.hEvent"); boolean write = WriteFile(hComm, txm, tlen, txn, osWriter); if (!write) { check(GetLastError() == ERROR_IO_PENDING, "WriteFile"); System.out.println("Write pending"); } while (!write) { System.out.println("WaitForSingleObject/write"); int dwRes = WaitForSingleObject(osWriter.hEvent, 1000); switch (dwRes) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hComm, osWriter, txn, true)) check(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult/osWriter"); else write = true; break; case WAIT_TIMEOUT: System.out.println("write TIMEOT"); break; default: check(false, "WaitForSingleObject/write"); break; } } System.out.println("Transmit: '" + txm.getString(0) + "' , len=" + txn[0]); // First set up the read so that we actually get some overlap check(ResetEvent(osReader.hEvent), "ResetEvent/osReader.hEvent "); boolean read = ReadFile(hComm, rxm, tlen, rxn, osReader); if (!read) { check(GetLastError() == ERROR_IO_PENDING, "ReadFile"); System.out.println("Read pending"); } while (!read) { if (first) { } System.out.println("WaitForSingleObject/read"); check(ResetEvent(osReader.hEvent), "ResetEvent/osReader.hEvent"); int dwRes = WaitForSingleObject(osReader.hEvent, 1000); switch (dwRes) { case WAIT_OBJECT_0: if (!GetOverlappedResult(hComm, osReader, rxn, false)) check(GetLastError() == ERROR_IO_INCOMPLETE, "GetOverlappedResult/osReader"); else read = true; break; case WAIT_TIMEOUT: System.out.println("WAIT_TIMEOUT"); break; default: check(false, "WaitForSingleObject/osReader.hEvent"); break; } } System.out.println("Received: '" + rxm.getString(0) + "' , len=" + rxn[0]); check(CloseHandle(osWriter.hEvent), "CloseHandle/osWriter.hEvent"); check(CloseHandle(osReader.hEvent), "CloseHandle/osReader.hEvent"); check(CloseHandle(hComm), "CloseHandle/hComm"); System.out.println("All done"); } private void run() { test1(); } public static void main(String[] args) { TestSuite ts = new TestSuite(); ts.run(); } }