diff --git a/core/org.eclipse.cdt.core.win32/library/cdt-win32.sln b/core/org.eclipse.cdt.core.win32/library/cdt-win32.sln index da36400d228..5367a43acb8 100644 --- a/core/org.eclipse.cdt.core.win32/library/cdt-win32.sln +++ b/core/org.eclipse.cdt.core.win32/library/cdt-win32.sln @@ -3,8 +3,6 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 2013 VisualStudioVersion = 12.0.31101.0 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serial", "serial\serial.vcxproj", "{2E2DB53A-62BE-4690-8FCB-209885DD9B3C}" -EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "winreg", "winreg\winreg.vcxproj", "{4CA57EA3-42F2-4CC1-8E95-5C707A8E7363}" EndProject Global @@ -17,18 +15,6 @@ Global Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Debug|Mixed Platforms.Build.0 = Debug|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Debug|Win32.ActiveCfg = Debug|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Debug|Win32.Build.0 = Debug|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Debug|x64.ActiveCfg = Debug|x64 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Debug|x64.Build.0 = Debug|x64 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Release|Mixed Platforms.ActiveCfg = Release|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Release|Mixed Platforms.Build.0 = Release|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Release|Win32.ActiveCfg = Release|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Release|Win32.Build.0 = Release|Win32 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Release|x64.ActiveCfg = Release|x64 - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C}.Release|x64.Build.0 = Release|x64 {4CA57EA3-42F2-4CC1-8E95-5C707A8E7363}.Debug|Mixed Platforms.ActiveCfg = Debug|Win32 {4CA57EA3-42F2-4CC1-8E95-5C707A8E7363}.Debug|Mixed Platforms.Build.0 = Debug|Win32 {4CA57EA3-42F2-4CC1-8E95-5C707A8E7363}.Debug|Win32.ActiveCfg = Debug|Win32 diff --git a/core/org.eclipse.cdt.core.win32/library/serial/.gitignore b/core/org.eclipse.cdt.core.win32/library/serial/.gitignore deleted file mode 100644 index 5d72c45d207..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/serial/.gitignore +++ /dev/null @@ -1,2 +0,0 @@ -/serial.tlog/ -/serial.vcxproj.user diff --git a/core/org.eclipse.cdt.core.win32/library/serial/dllmain.cpp b/core/org.eclipse.cdt.core.win32/library/serial/dllmain.cpp deleted file mode 100644 index 6e297985f3b..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/serial/dllmain.cpp +++ /dev/null @@ -1,28 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -#include "stdafx.h" - -BOOL APIENTRY DllMain( HMODULE hModule, - DWORD ul_reason_for_call, - LPVOID lpReserved - ) -{ - switch (ul_reason_for_call) - { - case DLL_PROCESS_ATTACH: - case DLL_THREAD_ATTACH: - case DLL_THREAD_DETACH: - case DLL_PROCESS_DETACH: - break; - } - return TRUE; -} - diff --git a/core/org.eclipse.cdt.core.win32/library/serial/serial.cpp b/core/org.eclipse.cdt.core.win32/library/serial/serial.cpp deleted file mode 100644 index 69a1de31a31..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/serial/serial.cpp +++ /dev/null @@ -1,149 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -#include "stdafx.h" - -extern "C" -JNIEXPORT jlong JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_open0 -(JNIEnv *env, jobject jobj, jstring portName, jint baudRate, jint byteSize, jint parity, jint stopBits) -{ - const wchar_t * cportName = (const wchar_t *) env->GetStringChars(portName, NULL); - HANDLE handle = CreateFile(cportName, - GENERIC_READ | GENERIC_WRITE, - 0, - NULL, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - NULL); - - if (handle != INVALID_HANDLE_VALUE) { - DCB dcb = { 0 }; - - if (!GetCommState(handle, &dcb)) { - fprintf(stderr, "Error getting DCB: %S\n", cportName); - return -1; - } - - dcb.BaudRate = baudRate; - dcb.ByteSize = (BYTE) byteSize; - - switch (parity) { - case 0: // None - dcb.fParity = FALSE; - break; - case 1: // Even - dcb.fParity = TRUE; - dcb.Parity = EVENPARITY; - break; - case 2: // Odd - dcb.fParity = TRUE; - dcb.Parity = ODDPARITY; - break; - } - - switch (stopBits) { - case 0: - dcb.StopBits = ONESTOPBIT; - break; - case 1: - dcb.StopBits = TWOSTOPBITS; - break; - } - - if (!SetCommState(handle, &dcb)) { - fprintf(stderr, "Error setting DCB: %S\n", cportName); - return -1; - } - } - - return (jlong) handle; -} - -extern "C" -JNIEXPORT void JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_close0 -(JNIEnv *env, jobject jobj, jlong handle) -{ - CloseHandle((HANDLE) handle); -} - -extern "C" -JNIEXPORT jint JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_read0 -(JNIEnv *env, jobject jobj, jlong jhandle) -{ - OVERLAPPED olp = { 0 }; - - olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (olp.hEvent == NULL) { - fprintf(stderr, "Error creating event\n"); - fflush(stderr); - return -1; - } - - char buff; - DWORD nwritten; - HANDLE handle = (HANDLE)jhandle; - - if (!ReadFile(handle, &buff, sizeof(buff), &nwritten, &olp)) { - if (GetLastError() != ERROR_IO_PENDING) { - fprintf(stderr, "Error reading from port: %d\n", GetLastError()); - fflush(stderr); - return -1; - } - else { - switch (WaitForSingleObject(olp.hEvent, INFINITE)) { - case WAIT_OBJECT_0: - if (!GetOverlappedResult(handle, &olp, &nwritten, FALSE)) { - if (GetLastError() != ERROR_OPERATION_ABORTED) { - fprintf(stderr, "Error waiting for read: %d\n", GetLastError()); - fflush(stderr); - } - return -1; - } - break; - } - } - } - - CloseHandle(olp.hEvent); - return buff; -} - -extern "C" -JNIEXPORT void JNICALL Java_org_eclipse_cdt_utils_serial_SerialPort_write0 -(JNIEnv *env, jobject jobj, jlong jhandle, jint b) -{ - OVERLAPPED olp = { 0 }; - - olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); - if (olp.hEvent == NULL) { - fprintf(stderr, "Error creating event\n"); - return; - } - - char buff = (char) b; - DWORD nwritten; - HANDLE handle = (HANDLE) jhandle; - - if (!WriteFile(handle, &buff, sizeof(buff), &nwritten, &olp)) { - if (GetLastError() != ERROR_IO_PENDING) { - fprintf(stderr, "Error writing to port\n"); - } - else { - switch (WaitForSingleObject(olp.hEvent, INFINITE)) { - case WAIT_OBJECT_0: - if (!GetOverlappedResult(handle, &olp, &nwritten, FALSE)) { - fprintf(stderr, "Error waiting for write\n"); - } - } - } - } - - CloseHandle(olp.hEvent); -} diff --git a/core/org.eclipse.cdt.core.win32/library/serial/stdafx.cpp b/core/org.eclipse.cdt.core.win32/library/serial/stdafx.cpp deleted file mode 100644 index c97de4cd232..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/serial/stdafx.cpp +++ /dev/null @@ -1,14 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -#include "stdafx.h" - -// TODO: reference any additional headers you need in STDAFX.H -// and not in this file diff --git a/core/org.eclipse.cdt.core.win32/library/serial/stdafx.h b/core/org.eclipse.cdt.core.win32/library/serial/stdafx.h deleted file mode 100644 index 0babced30e7..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/serial/stdafx.h +++ /dev/null @@ -1,22 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -#pragma once - -#include "targetver.h" - -#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers -// Windows Header Files: -#include -#include - - - -// TODO: reference additional headers your program requires here diff --git a/core/org.eclipse.cdt.core.win32/library/serial/targetver.h b/core/org.eclipse.cdt.core.win32/library/serial/targetver.h deleted file mode 100644 index d27181a16d6..00000000000 --- a/core/org.eclipse.cdt.core.win32/library/serial/targetver.h +++ /dev/null @@ -1,18 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2015 QNX Software Systems and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Eclipse Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/epl-v10.html - * - * Contributors: - * QNX Software Systems - Initial API and implementation - *******************************************************************************/ -#pragma once - -// Including SDKDDKVer.h defines the highest available Windows platform. - -// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and -// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. - -#include diff --git a/native/org.eclipse.cdt.native.serial/jni/.gitignore b/native/org.eclipse.cdt.native.serial/jni/posix/.gitignore similarity index 100% rename from native/org.eclipse.cdt.native.serial/jni/.gitignore rename to native/org.eclipse.cdt.native.serial/jni/posix/.gitignore diff --git a/native/org.eclipse.cdt.native.serial/jni/posix/Makefile b/native/org.eclipse.cdt.native.serial/jni/posix/Makefile index 9952967f322..8dbea9ad859 100644 --- a/native/org.eclipse.cdt.native.serial/jni/posix/Makefile +++ b/native/org.eclipse.cdt.native.serial/jni/posix/Makefile @@ -10,13 +10,29 @@ # Alex Blewitt - MacOSX with a 64-bit vm #*******************************************************************************/ -JAVA_HOME = $(shell echo /Library/Java/JavaVirtualMachines/jdk1.8.0_*.jdk/Contents/Home) UNAME = $(shell uname) # Defaults which can be overridden. ifeq ($(UNAME),Darwin) +JAVA_HOME = $(shell echo /Library/Java/JavaVirtualMachines/jdk1.8.0_*.jdk/Contents/Home) OS = macosx +JNI_OS = darwin ARCHS = x86_64 +ARCH_FLAG_X86 = -arch i386 +ARCH_FLAG_X86_64 = -arch x86_64 +LDFLAGS = -dynamiclib +LIBEXT = jnilib +else +ifeq ($(UNAME),Linux) +JAVA_HOME = /usr/lib/jvm/java-8-oracle +OS = linux +JNI_OS = linux +ARCHS = x86 x86_64 +ARCH_FLAG_X86 = -m32 +ARCH_FLAG_X86_64 = -m64 +LDFLAGS = -shared +LIBEXT = so +endif endif ARCH_X86 = x86 @@ -24,17 +40,14 @@ ARCH_X86_64 = x86_64 CC=gcc LD=libtool -CPPFLAGS = -I. -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/darwin +CPPFLAGS = -I. -I$(JAVA_HOME)/include -I$(JAVA_HOME)/include/$(JNI_OS) CFLAGS +=-fPIC -D_REENTRANT -ARCH_FLAG_X86 = -arch i386 -ARCH_FLAG_X86_64 = -arch x86_64 - INSTALL_DIR_X86 = ../../os/$(OS)/$(ARCH_X86) INSTALL_DIR_X86_64 = ../../os/$(OS)/$(ARCH_X86_64) -LIB_NAME_FULL_SERIAL_X86 = $(INSTALL_DIR_X86)/libserial.jnilib -LIB_NAME_FULL_SERIAL_X86_64 = $(INSTALL_DIR_X86_64)/libserial.jnilib +LIB_NAME_FULL_SERIAL_X86 = $(INSTALL_DIR_X86)/libserial.$(LIBEXT) +LIB_NAME_FULL_SERIAL_X86_64 = $(INSTALL_DIR_X86_64)/libserial.$(LIBEXT) OBJS_SERIAL_X86 = serial_$(ARCH_X86).o OBJS_SERIAL_X86_64 = serial_$(ARCH_X86_64).o @@ -52,11 +65,11 @@ rebuild: clean all $(LIB_NAME_FULL_SERIAL_X86): $(OBJS_SERIAL_X86) mkdir -p $(INSTALL_DIR_X86) - $(CC) -dynamiclib $(ARCH_FLAG_X86) -o $(LIB_NAME_FULL_SERIAL_X86) $(OBJS_SERIAL_X86) -lc -framework JavaVM + $(CC) $(LDFLAGS) $(ARCH_FLAG_X86) -o $(LIB_NAME_FULL_SERIAL_X86) $(OBJS_SERIAL_X86) $(LIB_NAME_FULL_SERIAL_X86_64): $(OBJS_SERIAL_X86_64) mkdir -p $(INSTALL_DIR_X86_64) - $(CC) -dynamiclib $(ARCH_FLAG_X86_64) -o $(LIB_NAME_FULL_SERIAL_X86_64) $(OBJS_SERIAL_X86_64) -lc -framework JavaVM + $(CC) $(LDFLAGS) $(ARCH_FLAG_X86_64) -o $(LIB_NAME_FULL_SERIAL_X86_64) $(OBJS_SERIAL_X86_64) serial_$(ARCH_X86).o: serial.c $(CC) $(CFLAGS) $(ARCH_FLAG_X86) $(CPPFLAGS) -c -o $@ serial.c diff --git a/native/org.eclipse.cdt.native.serial/jni/posix/serial.c b/native/org.eclipse.cdt.native.serial/jni/posix/serial.c index bf1e51da279..3bc71e493ef 100644 --- a/native/org.eclipse.cdt.native.serial/jni/posix/serial.c +++ b/native/org.eclipse.cdt.native.serial/jni/posix/serial.c @@ -8,9 +8,11 @@ * Contributors: * QNX Software Systems - initial API and implementation *******************************************************************************/ +#ifdef __APPLE__ #include #include #include +#endif #include #include #include @@ -26,6 +28,7 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName, const char * cportName = (*env)->GetStringUTFChars(env, portName, NULL); int fd = open(cportName, O_RDWR | O_NOCTTY | O_NDELAY); if (fd < 0) { + perror(cportName); return fd; } @@ -88,7 +91,7 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName, options.c_iflag |= IGNPAR; options.c_cc[VMIN] = 0; // min chars to read - options.c_cc[VTIME] = 10; // 10ths second timeout + options.c_cc[VTIME] = 2; // 10ths second timeout tcflush(fd, TCIFLUSH); tcsetattr(fd, TCSANOW, &options); @@ -97,18 +100,12 @@ JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName, } JNIEXPORT void JNICALL FUNC(close0)(JNIEnv *env, jobject jobj, jlong handle) - { +{ close(handle); - } +} -JNIEXPORT jint JNICALL FUNC(read0)(JNIEnv *env, jobject jobj, jlong handle) - { - char buff; - int res = read(handle, &buff, 1); - return res < 0 ? -1 : buff; - } - -JNIEXPORT jint JNICALL FUNC(read1)(JNIEnv * env, jobject jobj, jlong handle, jbyteArray bytes, jint offset, jint size) { +JNIEXPORT jint JNICALL FUNC(read1)(JNIEnv * env, jobject jobj, jlong handle, jbyteArray bytes, jint offset, jint size) +{ jbyte buff[256]; int n = size < sizeof(buff) ? size : sizeof(buff); n = read(handle, buff, n); @@ -119,7 +116,22 @@ JNIEXPORT jint JNICALL FUNC(read1)(JNIEnv * env, jobject jobj, jlong handle, jby } JNIEXPORT void JNICALL FUNC(write0)(JNIEnv *env, jobject jobj, jlong handle, jint b) - { +{ char buff = b; write(handle, &buff, 1); +} + +JNIEXPORT void JNICALL FUNC(write1)(JNIEnv *env, jobject jobj, jlong handle, jbyteArray bytes, jint offset, jint size) +{ + while (size > 0) { + jbyte buff[256]; + int n = size < sizeof(buff) ? size : sizeof(buff); + (*env)->GetByteArrayRegion(env, bytes, offset, n, buff); + n = write(handle, buff, n); + if (n < 0) { + return; } + size -= n; + offset += n; + } +} diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/.gitignore b/native/org.eclipse.cdt.native.serial/jni/win32/serial/.gitignore new file mode 100644 index 00000000000..8f10bd00b58 --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/.gitignore @@ -0,0 +1,6 @@ +/ipch/ +/Release/ +/x64/ +/serial.opensdf +/serial.sdf +/serial.v12.suo diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/dllmain.cpp b/native/org.eclipse.cdt.native.serial/jni/win32/serial/dllmain.cpp new file mode 100644 index 00000000000..8a4edd3105c --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/dllmain.cpp @@ -0,0 +1,19 @@ +// dllmain.cpp : Defines the entry point for the DLL application. +#include "stdafx.h" + +BOOL APIENTRY DllMain( HMODULE hModule, + DWORD ul_reason_for_call, + LPVOID lpReserved + ) +{ + switch (ul_reason_for_call) + { + case DLL_PROCESS_ATTACH: + case DLL_THREAD_ATTACH: + case DLL_THREAD_DETACH: + case DLL_PROCESS_DETACH: + break; + } + return TRUE; +} + diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.cpp b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.cpp new file mode 100644 index 00000000000..6bbc8c4d68a --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.cpp @@ -0,0 +1,242 @@ +/******************************************************************************* +* Copyright (c) 2015 QNX Software Systems and others. +* All rights reserved. This program and the accompanying materials +* are made available under the terms of the Eclipse Public License v1.0 +* which accompanies this distribution, and is available at +* http://www.eclipse.org/legal/epl-v10.html +* +* Contributors: +* QNX Software Systems - Initial API and implementation +*******************************************************************************/ +#include "stdafx.h" + +#define FUNC(x) Java_org_eclipse_cdt_serial_SerialPort_ ## x + +static void throwIOException(JNIEnv *env, char *msg) { + char buff[256]; + sprintf_s(buff, sizeof(buff), "%s: %d", msg, GetLastError()); + jclass cls = env->FindClass("java/io/IOException"); + env->ThrowNew(cls, buff); +} + +extern "C" +JNIEXPORT jlong JNICALL FUNC(open0)(JNIEnv *env, jobject jobj, jstring portName, jint baudRate, jint byteSize, jint parity, jint stopBits) +{ + const wchar_t * cportName = (const wchar_t *)env->GetStringChars(portName, NULL); + HANDLE handle = CreateFile(cportName, + GENERIC_READ | GENERIC_WRITE, + 0, + NULL, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + NULL); + + if (handle == INVALID_HANDLE_VALUE) { + throwIOException(env, "Error opening serial port"); + return -1; + } + + DCB dcb = { 0 }; + + if (!GetCommState(handle, &dcb)) { + throwIOException(env, "Error getting DCB"); + return -1; + } + + dcb.BaudRate = baudRate; + dcb.ByteSize = (BYTE)byteSize; + + switch (parity) { + case 0: // None + dcb.fParity = FALSE; + break; + case 1: // Even + dcb.fParity = TRUE; + dcb.Parity = EVENPARITY; + break; + case 2: // Odd + dcb.fParity = TRUE; + dcb.Parity = ODDPARITY; + break; + } + + switch (stopBits) { + case 0: + dcb.StopBits = ONESTOPBIT; + break; + case 1: + dcb.StopBits = TWOSTOPBITS; + break; + } + + if (!SetCommState(handle, &dcb)) { + throwIOException(env, "Error setting DCB"); + return -1; + } + + COMMTIMEOUTS timeouts = { 0 }; + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + timeouts.ReadTotalTimeoutConstant = 200; + if (!SetCommTimeouts(handle, &timeouts)) { + throwIOException(env, "Error setting timeouts"); + return -1; + } + + return (jlong)handle; +} + +extern "C" +JNIEXPORT void JNICALL FUNC(close0)(JNIEnv *env, jobject jobj, jlong handle) +{ + CloseHandle((HANDLE)handle); +} + +extern "C" +JNIEXPORT jint JNICALL FUNC(read1)(JNIEnv * env, jobject jobj, jlong jhandle, jbyteArray bytes, jint offset, jint size) +{ + OVERLAPPED olp = { 0 }; + + olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (olp.hEvent == NULL) { + throwIOException(env, "Error creating event"); + return -1; + } + + char buff[256]; + DWORD nread = sizeof(buff) < size ? sizeof(buff) : size; + HANDLE handle = (HANDLE)jhandle; + + if (!ReadFile(handle, buff, sizeof(buff), &nread, &olp)) { + if (GetLastError() != ERROR_IO_PENDING) { + throwIOException(env, "Error reading from port"); + CloseHandle(olp.hEvent); + return -1; + } + else { + switch (WaitForSingleObject(olp.hEvent, INFINITE)) { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(handle, &olp, &nread, FALSE)) { + if (GetLastError() != ERROR_OPERATION_ABORTED) { + throwIOException(env, "Error waiting for read"); + } + CloseHandle(olp.hEvent); + return -1; + } + break; + } + } + } + + if (nread > 0) { + env->SetByteArrayRegion(bytes, offset, nread, (jbyte *)buff); + } + CloseHandle(olp.hEvent); + return nread; +} + +extern "C" +JNIEXPORT void JNICALL FUNC(write0)(JNIEnv *env, jobject jobj, jlong jhandle, jint b) +{ + OVERLAPPED olp = { 0 }; + + olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (olp.hEvent == NULL) { + throwIOException(env, "Error creating event"); + return; + } + + char buff = (char)b; + DWORD nwritten; + HANDLE handle = (HANDLE)jhandle; + + if (!WriteFile(handle, &buff, sizeof(buff), &nwritten, &olp)) { + if (GetLastError() != ERROR_IO_PENDING) { + throwIOException(env, "Error writing to port"); + } + else { + switch (WaitForSingleObject(olp.hEvent, INFINITE)) { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(handle, &olp, &nwritten, FALSE)) { + throwIOException(env, "Error waiting for write"); + } + } + } + } + + CloseHandle(olp.hEvent); +} + +extern "C" +JNIEXPORT void JNICALL FUNC(write1)(JNIEnv *env, jobject jobj, jlong jhandle, jbyteArray bytes, jint offset, jint size) +{ + OVERLAPPED olp = { 0 }; + + olp.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + if (olp.hEvent == NULL) { + throwIOException(env, "Error creating event"); + return; + } + + while (size > 0) { + char buff[256]; + DWORD nwritten = sizeof(buff) < size ? sizeof(buff) : size; + env->GetByteArrayRegion(bytes, offset, nwritten, (jbyte *)buff); + HANDLE handle = (HANDLE)jhandle; + + if (!WriteFile(handle, buff, nwritten, &nwritten, &olp)) { + if (GetLastError() != ERROR_IO_PENDING) { + throwIOException(env, "Error writing to port"); + return; + } + else { + switch (WaitForSingleObject(olp.hEvent, INFINITE)) { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(handle, &olp, &nwritten, FALSE)) { + throwIOException(env, "Error waiting for write"); + return; + } + } + } + } + size -= nwritten; + offset += nwritten; + } + + CloseHandle(olp.hEvent); +} + +extern "C" +JNIEXPORT jstring FUNC(getPortName)(JNIEnv *env, jclass cls, jint i) +{ + HKEY key; + + if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"HARDWARE\\DEVICEMAP\\SERIALCOMM", 0, KEY_READ, &key) != ERROR_SUCCESS) { + throwIOException(env, "Can not find registry key"); + return NULL; + } + + wchar_t name[256]; + DWORD len = sizeof(name); + LONG rc = RegEnumValue(key, (DWORD)i, name, &len, NULL, NULL, NULL, NULL); + if (rc != ERROR_SUCCESS) { + if (rc != ERROR_NO_MORE_ITEMS) { + throwIOException(env, "Can not enum value"); + } + RegCloseKey(key); + return NULL; + } + + wchar_t value[256]; + DWORD type; + len = sizeof(value); + if (RegQueryValueEx(key, name, NULL, &type, (BYTE *)value, &len) != ERROR_SUCCESS) { + throwIOException(env, "Can not query value"); + RegCloseKey(key); + return NULL; + } + + jstring result = env->NewString((jchar *)value, (jsize) wcslen(value)); + RegCloseKey(key); + return result; +} diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.sln b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.sln new file mode 100644 index 00000000000..0a828bdd3bd --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.sln @@ -0,0 +1,28 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio 2013 +VisualStudioVersion = 12.0.31101.0 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "serial", "serial.vcxproj", "{48ED88D3-77CF-4E77-9554-10719E633142}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Win32 = Debug|Win32 + Debug|x64 = Debug|x64 + Release|Win32 = Release|Win32 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {48ED88D3-77CF-4E77-9554-10719E633142}.Debug|Win32.ActiveCfg = Debug|Win32 + {48ED88D3-77CF-4E77-9554-10719E633142}.Debug|Win32.Build.0 = Debug|Win32 + {48ED88D3-77CF-4E77-9554-10719E633142}.Debug|x64.ActiveCfg = Debug|x64 + {48ED88D3-77CF-4E77-9554-10719E633142}.Debug|x64.Build.0 = Debug|x64 + {48ED88D3-77CF-4E77-9554-10719E633142}.Release|Win32.ActiveCfg = Release|Win32 + {48ED88D3-77CF-4E77-9554-10719E633142}.Release|Win32.Build.0 = Release|Win32 + {48ED88D3-77CF-4E77-9554-10719E633142}.Release|x64.ActiveCfg = Release|x64 + {48ED88D3-77CF-4E77-9554-10719E633142}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection +EndGlobal diff --git a/core/org.eclipse.cdt.core.win32/library/serial/serial.vcxproj b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.vcxproj similarity index 91% rename from core/org.eclipse.cdt.core.win32/library/serial/serial.vcxproj rename to native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.vcxproj index 8e8c5b153d1..4009c5fec7e 100644 --- a/core/org.eclipse.cdt.core.win32/library/serial/serial.vcxproj +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.vcxproj @@ -19,7 +19,7 @@ - {2E2DB53A-62BE-4690-8FCB-209885DD9B3C} + {48ED88D3-77CF-4E77-9554-10719E633142} Win32Proj serial @@ -74,13 +74,11 @@ false - $(SolutionDir)..\..\org.eclipse.cdt.core.win32.x86\os\win32\x86\ - + $(SolutionDir)..\..\..\os\win32\x86\ false - $(SolutionDir)..\..\org.eclipse.cdt.core.win32.x86_64\os\win32\x86_64\ - + $(SolutionDir)..\..\..\os\win32\x86_64\ @@ -88,8 +86,6 @@ Level3 Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;SERIAL_EXPORTS;%(PreprocessorDefinitions) - true - MultiThreadedDebug Windows @@ -102,8 +98,6 @@ Level3 Disabled WIN32;_DEBUG;_WINDOWS;_USRDLL;SERIAL_EXPORTS;%(PreprocessorDefinitions) - true - MultiThreadedDebug Windows @@ -118,8 +112,7 @@ true true WIN32;NDEBUG;_WINDOWS;_USRDLL;SERIAL_EXPORTS;%(PreprocessorDefinitions) - true - C:\Program Files\Java\jdk1.8.0_31\include;C:\Program Files\Java\jdk1.8.0_31\include\win32;%(AdditionalIncludeDirectories) + C:\Program Files\Java\jdk1.8.0_31\include\win32;C:\Program Files\Java\jdk1.8.0_31\include;%(AdditionalIncludeDirectories) MultiThreaded @@ -137,7 +130,7 @@ true true WIN32;NDEBUG;_WINDOWS;_USRDLL;SERIAL_EXPORTS;%(PreprocessorDefinitions) - C:\Program Files\Java\jdk1.8.0_31\include;C:\Program Files\Java\jdk1.8.0_31\include\win32;%(AdditionalIncludeDirectories) + C:\Program Files\Java\jdk1.8.0_31\include\win32;C:\Program Files\Java\jdk1.8.0_31\include;%(AdditionalIncludeDirectories) MultiThreaded @@ -147,6 +140,9 @@ true + + + diff --git a/core/org.eclipse.cdt.core.win32/library/serial/serial.vcxproj.filters b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.vcxproj.filters similarity index 92% rename from core/org.eclipse.cdt.core.win32/library/serial/serial.vcxproj.filters rename to native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.vcxproj.filters index 240d00d0c19..b6e39963926 100644 --- a/core/org.eclipse.cdt.core.win32/library/serial/serial.vcxproj.filters +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.vcxproj.filters @@ -14,6 +14,9 @@ rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + Header Files diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.cpp b/native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.cpp new file mode 100644 index 00000000000..4a32c69d470 --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.cpp @@ -0,0 +1,8 @@ +// stdafx.cpp : source file that includes just the standard includes +// serial.pch will be the pre-compiled header +// stdafx.obj will contain the pre-compiled type information + +#include "stdafx.h" + +// TODO: reference any additional headers you need in STDAFX.H +// and not in this file diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.h b/native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.h new file mode 100644 index 00000000000..935ddb49a46 --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.h @@ -0,0 +1,17 @@ +// stdafx.h : include file for standard system include files, +// or project specific include files that are used frequently, but +// are changed infrequently +// + +#pragma once + +#include "targetver.h" + +#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +// Windows Header Files: +#include + + + +// TODO: reference additional headers your program requires here +#include diff --git a/native/org.eclipse.cdt.native.serial/jni/win32/serial/targetver.h b/native/org.eclipse.cdt.native.serial/jni/win32/serial/targetver.h new file mode 100644 index 00000000000..90e767bfce7 --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/jni/win32/serial/targetver.h @@ -0,0 +1,8 @@ +#pragma once + +// Including SDKDDKVer.h defines the highest available Windows platform. + +// If you wish to build your application for a previous Windows platform, include WinSDKVer.h and +// set the _WIN32_WINNT macro to the platform you wish to support before including SDKDDKVer.h. + +#include diff --git a/native/org.eclipse.cdt.native.serial/os/linux/x86/libserial.so b/native/org.eclipse.cdt.native.serial/os/linux/x86/libserial.so new file mode 100755 index 00000000000..a42fdfbdb1b Binary files /dev/null and b/native/org.eclipse.cdt.native.serial/os/linux/x86/libserial.so differ diff --git a/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so b/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so new file mode 100755 index 00000000000..cd5e3455ce4 Binary files /dev/null and b/native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so differ diff --git a/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib b/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib index bf96f91430c..a8eefeeb4a6 100755 Binary files a/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib and b/native/org.eclipse.cdt.native.serial/os/macosx/x86_64/libserial.jnilib differ diff --git a/native/org.eclipse.cdt.native.serial/os/win32/x86/.gitignore b/native/org.eclipse.cdt.native.serial/os/win32/x86/.gitignore new file mode 100644 index 00000000000..141e13b4a72 --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/os/win32/x86/.gitignore @@ -0,0 +1,3 @@ +/serial.exp +/serial.lib +/serial.pdb diff --git a/native/org.eclipse.cdt.native.serial/os/win32/x86/serial.dll b/native/org.eclipse.cdt.native.serial/os/win32/x86/serial.dll new file mode 100644 index 00000000000..3ac1554c02b Binary files /dev/null and b/native/org.eclipse.cdt.native.serial/os/win32/x86/serial.dll differ diff --git a/native/org.eclipse.cdt.native.serial/os/win32/x86_64/.gitignore b/native/org.eclipse.cdt.native.serial/os/win32/x86_64/.gitignore new file mode 100644 index 00000000000..141e13b4a72 --- /dev/null +++ b/native/org.eclipse.cdt.native.serial/os/win32/x86_64/.gitignore @@ -0,0 +1,3 @@ +/serial.exp +/serial.lib +/serial.pdb diff --git a/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll b/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll new file mode 100644 index 00000000000..331384f0a7b Binary files /dev/null and b/native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll differ diff --git a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java index 62c7a9bdabb..fc0f9f23833 100644 --- a/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java +++ b/native/org.eclipse.cdt.native.serial/src/org/eclipse/cdt/serial/SerialPort.java @@ -15,6 +15,8 @@ import java.io.FilenameFilter; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Pattern; import org.eclipse.cdt.serial.internal.Messages; @@ -32,7 +34,6 @@ public class SerialPort { private StopBits stopBits = StopBits.S1; private long handle; - private static final String SERIAL_KEY = "HARDWARE\\DEVICEMAP\\SERIALCOMM"; //$NON-NLS-1$ private static final String PORT_OPEN = Messages.getString("SerialPort.PortIsOpen"); //$NON-NLS-1$ static { @@ -44,10 +45,24 @@ public class SerialPort { } private InputStream inputStream = new InputStream() { + private byte[] rbuff = new byte[256]; + private int rpos = 0; + private int rlen = 0; + @Override public int read() throws IOException { if (isOpen()) { - return read0(handle); + if (rpos >= rlen) { + while (true) { + rlen = read1(handle, rbuff, 0, rbuff.length); + if (rlen < 0) { + return -1; + } else if (rlen > 0) { + break; + } + } + } + return rbuff[rpos++]; } else { return -1; } @@ -56,7 +71,17 @@ public class SerialPort { @Override public int read(byte[] b, int off, int len) throws IOException { if (isOpen()) { - return read1(handle, b, off, len); + int n = rlen - rpos; + if (n > 0) { + if (len < n) { + n = len; + } + System.arraycopy(rbuff, rpos, b, off, n); + rpos += n; + return n; + } else { + return read1(handle, b, off, len); + } } else { return -1; } @@ -76,6 +101,13 @@ public class SerialPort { } } + @Override + public void write(byte[] buff, int off, int len) throws IOException { + if (isOpen()) { + write1(handle, buff, off, len); + } + } + @Override public void close() throws IOException { SerialPort.this.close(); @@ -91,62 +123,61 @@ public class SerialPort { this.portName = portName; } + private native long open0(String portName, int baudRate, int byteSize, int parity, int stopBits) throws IOException; + + private native void close0(long handle) throws IOException; + + private native int read1(long handle, byte[] b, int off, int len) throws IOException; + + private native void write0(long handle, int b) throws IOException; + + private native void write1(long handle, byte[] b, int off, int len) throws IOException; + + private static native String getPortName(int i) throws IOException; + + private static String[] listDevs(final Pattern pattern) { + File dev = new File("/dev"); //$NON-NLS-1$ + File[] files = dev.listFiles(new FilenameFilter() { + @Override + public boolean accept(File dir, String name) { + return pattern.matcher(name).matches(); + } + }); + + if (files == null) { + return new String[0]; + } + + String[] names = new String[files.length]; + for (int i = 0; i < files.length; i++) { + names[i] = files[i].getAbsolutePath(); + } + return names; + } + /** * List the available serial ports. * * @return serial ports */ - public static String[] list() { - if (System.getProperty("os.name").equals("Mac OS X")) { //$NON-NLS-1$//$NON-NLS-2$ - File dev = new File("/dev"); //$NON-NLS-1$ - final Pattern pattern = Pattern.compile("tty\\.(usbserial|usbmodem).*"); //$NON-NLS-1$ - File[] files = dev.listFiles(new FilenameFilter() { - @Override - public boolean accept(File dir, String name) { - return pattern.matcher(name).matches(); - } - }); - - if (files == null) { - return new String[0]; + public static String[] list() throws IOException { + String osName = System.getProperty("os.name"); //$NON-NLS-1$ + if (osName.equals("Mac OS X")) { //$NON-NLS-1$ + return listDevs(Pattern.compile("tty\\.(usbserial|usbmodem).*")); //$NON-NLS-1$ + } else if (osName.equals("Linux")) { //$NON-NLS-1$ + return listDevs(Pattern.compile("ttyUSB.*")); //$NON-NLS-1$ + } else if (osName.startsWith("Windows")) { //$NON-NLS-1$ + List ports = new ArrayList<>(); + int i = 0; + for (String name = getPortName(i++); name != null; name = getPortName(i++)) { + ports.add(name); } - String[] names = new String[files.length]; - for (int i = 0; i < files.length; i++) { - names[i] = files[i].getAbsolutePath(); - } - return names; - } else if (System.getProperty("os.name").equals("Windows NT")) { //$NON-NLS-1$//$NON-NLS-2$ -// WindowsRegistry reg = WindowsRegistry.getRegistry(); -// if (reg != null) { -// List ports = new ArrayList<>(); -// int i = 0; -// String name = reg.getLocalMachineValueName(SERIAL_KEY, i); -// while (name != null) { -// String value = reg.getLocalMachineValue(SERIAL_KEY, name); -// ports.add(value); -// i++; -// name = reg.getLocalMachineValueName(SERIAL_KEY, i); -// } -// return ports.toArray(new String[ports.size()]); -// } else { -// return new String[0]; -// } - return new String[0]; + return ports.toArray(new String[ports.size()]); } else { return new String[0]; } } - private native long open0(String portName, int baudRate, int byteSize, int parity, int stopBits) throws IOException; - - private native void close0(long handle) throws IOException; - - private native int read0(long handle) throws IOException; - - private native int read1(long handle, byte[] b, int off, int len); - - private native void write0(long handle, int b) throws IOException; - /** * Return the name for this serial port. *