From ebc8caa425cefbe1d642a2186e057d069830cda6 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Tue, 7 Apr 2015 14:36:56 -0400 Subject: [PATCH] Windows and Linux serial port support. Also played with I/O streams. Added buffered writes as well as non-native unbuffered reads. Change-Id: I3577746ed8215844e02601608f4a9173d1639aa1 --- .../library/cdt-win32.sln | 14 - .../library/serial/.gitignore | 2 - .../library/serial/dllmain.cpp | 28 -- .../library/serial/serial.cpp | 149 ----------- .../library/serial/stdafx.cpp | 14 - .../library/serial/stdafx.h | 22 -- .../library/serial/targetver.h | 18 -- .../jni/{ => posix}/.gitignore | 0 .../jni/posix/Makefile | 31 ++- .../jni/posix/serial.c | 36 ++- .../jni/win32/serial/.gitignore | 6 + .../jni/win32/serial/dllmain.cpp | 19 ++ .../jni/win32/serial/serial.cpp | 242 ++++++++++++++++++ .../jni/win32/serial/serial.sln | 28 ++ .../jni/win32}/serial/serial.vcxproj | 20 +- .../jni/win32}/serial/serial.vcxproj.filters | 3 + .../jni/win32/serial/stdafx.cpp | 8 + .../jni/win32/serial/stdafx.h | 17 ++ .../jni/win32/serial/targetver.h | 8 + .../os/linux/x86/libserial.so | Bin 0 -> 7589 bytes .../os/linux/x86_64/libserial.so | Bin 0 -> 12906 bytes .../os/macosx/x86_64/libserial.jnilib | Bin 9492 -> 9492 bytes .../os/win32/x86/.gitignore | 3 + .../os/win32/x86/serial.dll | Bin 0 -> 77312 bytes .../os/win32/x86_64/.gitignore | 3 + .../os/win32/x86_64/serial.dll | Bin 0 -> 90112 bytes .../org/eclipse/cdt/serial/SerialPort.java | 127 +++++---- 27 files changed, 470 insertions(+), 328 deletions(-) delete mode 100644 core/org.eclipse.cdt.core.win32/library/serial/.gitignore delete mode 100644 core/org.eclipse.cdt.core.win32/library/serial/dllmain.cpp delete mode 100644 core/org.eclipse.cdt.core.win32/library/serial/serial.cpp delete mode 100644 core/org.eclipse.cdt.core.win32/library/serial/stdafx.cpp delete mode 100644 core/org.eclipse.cdt.core.win32/library/serial/stdafx.h delete mode 100644 core/org.eclipse.cdt.core.win32/library/serial/targetver.h rename native/org.eclipse.cdt.native.serial/jni/{ => posix}/.gitignore (100%) create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/.gitignore create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/dllmain.cpp create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.cpp create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/serial.sln rename {core/org.eclipse.cdt.core.win32/library => native/org.eclipse.cdt.native.serial/jni/win32}/serial/serial.vcxproj (91%) rename {core/org.eclipse.cdt.core.win32/library => native/org.eclipse.cdt.native.serial/jni/win32}/serial/serial.vcxproj.filters (92%) create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.cpp create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/stdafx.h create mode 100644 native/org.eclipse.cdt.native.serial/jni/win32/serial/targetver.h create mode 100755 native/org.eclipse.cdt.native.serial/os/linux/x86/libserial.so create mode 100755 native/org.eclipse.cdt.native.serial/os/linux/x86_64/libserial.so create mode 100644 native/org.eclipse.cdt.native.serial/os/win32/x86/.gitignore create mode 100644 native/org.eclipse.cdt.native.serial/os/win32/x86/serial.dll create mode 100644 native/org.eclipse.cdt.native.serial/os/win32/x86_64/.gitignore create mode 100644 native/org.eclipse.cdt.native.serial/os/win32/x86_64/serial.dll 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 0000000000000000000000000000000000000000..a42fdfbdb1bdb7580590786a035711068d4f3a82 GIT binary patch literal 7589 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 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..cd5e3455ce43a81c928286ee90ff94baa76307f9 GIT binary patch literal 12906 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 GqyGT*F*Wr7 delta 808 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 P1>R}Cnh?JJzu*1= 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. *