diff --git a/src/main/c/Posix/SerialPort_Posix.c b/src/main/c/Posix/SerialPort_Posix.c index ae8c616..d36f2a2 100644 --- a/src/main/c/Posix/SerialPort_Posix.c +++ b/src/main/c/Posix/SerialPort_Posix.c @@ -79,6 +79,7 @@ jfieldID writeTimeoutField; jfieldID eventFlagsField; // List of available serial ports +char portsEnumerated = 0; serialPortVector serialPorts = { NULL, 0, 0 }; // JNI exception handler @@ -98,6 +99,37 @@ static inline jboolean checkJniError(JNIEnv *env, int lineNumber) return JNI_FALSE; } +// Generalized port enumeration function +static void enumeratePorts(void) +{ + // Reset the enumerated flag on all non-open serial ports + for (int i = 0; i < serialPorts.length; ++i) + serialPorts.ports[i]->enumerated = (serialPorts.ports[i]->handle > 0); + + // Enumerate serial ports on this machine +#if defined(__linux__) + + recursiveSearchForComPorts(&serialPorts, "/sys/devices/"); + driverBasedSearchForComPorts(&serialPorts, "/proc/tty/driver/serial", "/dev/ttyS"); + driverBasedSearchForComPorts(&serialPorts, "/proc/tty/driver/mvebu_serial", "/dev/ttyMV"); + lastDitchSearchForComPorts(&serialPorts); + +#elif defined(__sun__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) + + searchForComPorts(&serialPorts); + +#endif + + // Remove all non-enumerated ports from the serial port listing + for (int i = 0; i < serialPorts.length; ++i) + if (!serialPorts.ports[i]->enumerated) + { + removePort(&serialPorts, serialPorts.ports[i]); + i--; + } + portsEnumerated = 1; +} + #if defined(__linux__) && !defined(__ANDROID__) // Event listening threads @@ -207,31 +239,8 @@ void* eventReadingThread2(void *serialPortPointer) JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommPorts(JNIEnv *env, jclass serialComm) { - // Reset the enumerated flag on all non-open serial ports - for (int i = 0; i < serialPorts.length; ++i) - serialPorts.ports[i]->enumerated = (serialPorts.ports[i]->handle > 0); - - // Enumerate serial ports on this machine -#if defined(__linux__) - - recursiveSearchForComPorts(&serialPorts, "/sys/devices/"); - driverBasedSearchForComPorts(&serialPorts, "/proc/tty/driver/serial", "/dev/ttyS"); - driverBasedSearchForComPorts(&serialPorts, "/proc/tty/driver/mvebu_serial", "/dev/ttyMV"); - lastDitchSearchForComPorts(&serialPorts); - -#elif defined(__sun__) || defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) - - searchForComPorts(&serialPorts); - -#endif - - // Remove all non-enumerated ports from the serial port listing - for (int i = 0; i < serialPorts.length; ++i) - if (!serialPorts.ports[i]->enumerated) - { - removePort(&serialPorts, serialPorts.ports[i]); - i--; - } + // Enumerate all ports on the current system + enumeratePorts(); // Create a Java-based port listing jobjectArray arrayObject = (*env)->NewObjectArray(env, serialPorts.length, serialCommClass, 0); @@ -356,6 +365,38 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_uninitializeLibr checkJniError(env, __LINE__ - 1); } +JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_retrievePortDetails(JNIEnv *env, jobject obj) +{ + // Retrieve the serial port parameter fields + jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); + if (checkJniError(env, __LINE__ - 1)) return; + const char *portName = (*env)->GetStringUTFChars(env, portNameJString, NULL); + if (checkJniError(env, __LINE__ - 1)) return; + + // Ensure that the serial port exists + if (!portsEnumerated) + enumeratePorts(); + serialPort *port = fetchPort(&serialPorts, portName); + if (!port) + { + (*env)->ReleaseStringUTFChars(env, portNameJString, portName); + checkJniError(env, __LINE__ - 1); + return; + } + + // Fill in the Java-side port details + (*env)->SetObjectField(env, obj, portDescriptionField, (*env)->NewStringUTF(env, port->portDescription)); + if (checkJniError(env, __LINE__ - 1)) return; + (*env)->SetObjectField(env, obj, friendlyNameField, (*env)->NewStringUTF(env, port->friendlyName)); + if (checkJniError(env, __LINE__ - 1)) return; + (*env)->SetObjectField(env, obj, portLocationField, (*env)->NewStringUTF(env, port->portLocation)); + if (checkJniError(env, __LINE__ - 1)) return; + + // Release all JNI structures + (*env)->ReleaseStringUTFChars(env, portNameJString, portName); + checkJniError(env, __LINE__ - 1); +} + JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(JNIEnv *env, jobject obj) { // Retrieve the serial port parameter fields diff --git a/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h b/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h index ebe6a2b..9500c5e 100644 --- a/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h +++ b/src/main/c/Posix/com_fazecast_jSerialComm_SerialPort.h @@ -99,6 +99,14 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_initializeLibrar JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_uninitializeLibrary (JNIEnv *, jclass); +/* + * Class: com_fazecast_jSerialComm_SerialPort + * Method: retrievePortDetails + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_retrievePortDetails + (JNIEnv *, jobject); + /* * Class: com_fazecast_jSerialComm_SerialPort * Method: openPortNative diff --git a/src/main/c/Windows/SerialPort_Windows.c b/src/main/c/Windows/SerialPort_Windows.c index 3ed7560..d39e60c 100644 --- a/src/main/c/Windows/SerialPort_Windows.c +++ b/src/main/c/Windows/SerialPort_Windows.c @@ -2,7 +2,7 @@ * SerialPort_Windows.c * * Created on: Feb 25, 2012 - * Last Updated on: Jan 21, 2022 + * Last Updated on: Jan 25, 2022 * Author: Will Hedgecock * * Copyright (C) 2012-2022 Fazecast, Inc. @@ -78,6 +78,7 @@ typedef int (__stdcall *FT_CreateDeviceInfoListFunction)(LPDWORD); typedef int (__stdcall *FT_GetDeviceInfoListFunction)(FT_DEVICE_LIST_INFO_NODE*, LPDWORD); // List of available serial ports +char portsEnumerated = 0; serialPortVector serialPorts = { NULL, 0, 0 }; // JNI exception handler @@ -97,7 +98,8 @@ static inline jboolean checkJniError(JNIEnv *env, int lineNumber) return JNI_FALSE; } -JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommPorts(JNIEnv *env, jclass serialComm) +// Generalized port enumeration function +static void enumeratePorts(void) { // Reset the enumerated flag on all non-open serial ports for (int i = 0; i < serialPorts.length; ++i) @@ -312,8 +314,16 @@ JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommP removePort(&serialPorts, serialPorts.ports[i]); i--; } + portsEnumerated = 1; +} + +JNIEXPORT jobjectArray JNICALL Java_com_fazecast_jSerialComm_SerialPort_getCommPorts(JNIEnv *env, jclass serialComm) +{ + // Enumerate all ports on the current system + enumeratePorts(); // Get relevant SerialComm methods and fill in com port array + wchar_t comPort[128]; jobjectArray arrayObject = (*env)->NewObjectArray(env, serialPorts.length, serialCommClass, 0); if (checkJniError(env, __LINE__ - 1)) return arrayObject; for (int i = 0; i < serialPorts.length; ++i) @@ -415,6 +425,38 @@ JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_uninitializeLibr checkJniError(env, __LINE__ - 1); } +JNIEXPORT void JNICALL Java_com_fazecast_jSerialComm_SerialPort_retrievePortDetails(JNIEnv *env, jobject obj) +{ + // Retrieve the serial port parameter fields + jstring portNameJString = (jstring)(*env)->GetObjectField(env, obj, comPortField); + if (checkJniError(env, __LINE__ - 1)) return; + const wchar_t *portName = (wchar_t*)(*env)->GetStringChars(env, portNameJString, NULL); + if (checkJniError(env, __LINE__ - 1)) return; + + // Ensure that the serial port exists + if (!portsEnumerated) + enumeratePorts(); + serialPort *port = fetchPort(&serialPorts, portName); + if (!port) + { + (*env)->ReleaseStringChars(env, portNameJString, (const jchar*)portName); + checkJniError(env, __LINE__ - 1); + return; + } + + // Fill in the Java-side port details + (*env)->SetObjectField(env, obj, friendlyNameField, (*env)->NewString(env, (jchar*)port->friendlyName, wcslen(port->friendlyName))); + if (checkJniError(env, __LINE__ - 1)) return; + (*env)->SetObjectField(env, obj, portDescriptionField, (*env)->NewString(env, (jchar*)port->portDescription, wcslen(port->portDescription))); + if (checkJniError(env, __LINE__ - 1)) return; + (*env)->SetObjectField(env, obj, portLocationField, (*env)->NewString(env, (jchar*)port->portLocation, wcslen(port->portLocation))); + if (checkJniError(env, __LINE__ - 1)) return; + + // Release all JNI structures + (*env)->ReleaseStringChars(env, portNameJString, (const jchar*)portName); + checkJniError(env, __LINE__ - 1); +} + JNIEXPORT jlong JNICALL Java_com_fazecast_jSerialComm_SerialPort_openPortNative(JNIEnv *env, jobject obj) { // Retrieve the serial port parameter fields diff --git a/src/main/c/Windows/WindowsHelperFunctions.c b/src/main/c/Windows/WindowsHelperFunctions.c index b0cb8b9..64fff1b 100644 --- a/src/main/c/Windows/WindowsHelperFunctions.c +++ b/src/main/c/Windows/WindowsHelperFunctions.c @@ -2,7 +2,7 @@ * WindowsHelperFunctions.c * * Created on: May 05, 2015 - * Last Updated on: Jan 22, 2022 + * Last Updated on: Jan 25, 2022 * Author: Will Hedgecock * * Copyright (C) 2012-2022 Fazecast, Inc. @@ -77,6 +77,11 @@ serialPort* pushBack(serialPortVector* vector, const wchar_t* key, const wchar_t serialPort* fetchPort(serialPortVector* vector, const wchar_t* key) { + // Move past any opening slashes + if ((key[0] == L'\\') && (key[1] == L'\\') && (key[2] == L'.') && (key[3] == L'\\')) + key += 4; + + // Retrieve the serial port specified by the passed-in key for (int i = 0; i < vector->length; ++i) if (wcscmp(key, vector->ports[i]->portPath) == 0) return vector->ports[i]; diff --git a/src/main/java/com/fazecast/jSerialComm/SerialPort.java b/src/main/java/com/fazecast/jSerialComm/SerialPort.java index 391c1b9..56478b9 100644 --- a/src/main/java/com/fazecast/jSerialComm/SerialPort.java +++ b/src/main/java/com/fazecast/jSerialComm/SerialPort.java @@ -2,7 +2,7 @@ * SerialPort.java * * Created on: Feb 25, 2012 - * Last Updated on: Jan 20, 2022 + * Last Updated on: Jan 25, 2022 * Author: Will Hedgecock * * Copyright (C) 2012-2022 Fazecast, Inc. @@ -460,7 +460,7 @@ public final class SerialPort * @return A {@link SerialPort} object. * @throws SerialPortInvalidPortException If a {@link SerialPort} object cannot be created due to a logical or formatting error in the portDescriptor parameter. */ - static public final SerialPort getCommPort(String portDescriptor) throws SerialPortInvalidPortException + static public final synchronized SerialPort getCommPort(String portDescriptor) throws SerialPortInvalidPortException { // Correct port descriptor, if needed try @@ -493,6 +493,8 @@ public final class SerialPort serialPort.comPort = portDescriptor; serialPort.friendlyName = "User-Specified Port"; serialPort.portDescription = "User-Specified Port"; + serialPort.portLocation = "0-0"; + serialPort.retrievePortDetails(); return serialPort; } @@ -552,7 +554,7 @@ public final class SerialPort private volatile String comPort, friendlyName, portDescription, portLocation; private volatile boolean eventListenerRunning = false, disableConfig = false, disableExclusiveLock = false; private volatile boolean rs485Mode = false, rs485ActiveHigh = true, rs485RxDuringTx = false, rs485EnableTermination = false; - private volatile boolean isRtsEnabled = true, isDtrEnabled = true, autoFlushIOBuffers = false; + private volatile boolean isRtsEnabled = true, isDtrEnabled = true, autoFlushIOBuffers = false, requestElevatedPermissions = false; private SerialPortInputStream inputStream = null; private SerialPortOutputStream outputStream = null; @@ -709,7 +711,7 @@ public final class SerialPort * exclusive locks on system resources. */ public final synchronized void disableExclusiveLock() { disableExclusiveLock = true; } - + /** * Returns the source code line location of the latest error encountered during execution of * the native code for this port. @@ -734,6 +736,7 @@ public final class SerialPort // Serial Port Setup Methods private static native void initializeLibrary(); // Initializes the JNI code private static native void uninitializeLibrary(); // Un-initializes the JNI code + private final native void retrievePortDetails(); // Retrieves port descriptions, names, and details private final native long openPortNative(); // Opens serial port private final native long closePortNative(long portHandle); // Closes serial port private final native boolean configPort(long portHandle); // Changes/sets serial port parameters as defined by this class diff --git a/src/main/resources/Android/arm64-v8a/libjSerialComm.so b/src/main/resources/Android/arm64-v8a/libjSerialComm.so index 6f2b5bc..627b691 100644 Binary files a/src/main/resources/Android/arm64-v8a/libjSerialComm.so and b/src/main/resources/Android/arm64-v8a/libjSerialComm.so differ diff --git a/src/main/resources/Android/armeabi-v7a/libjSerialComm.so b/src/main/resources/Android/armeabi-v7a/libjSerialComm.so index ea59048..30e669a 100644 Binary files a/src/main/resources/Android/armeabi-v7a/libjSerialComm.so and b/src/main/resources/Android/armeabi-v7a/libjSerialComm.so differ diff --git a/src/main/resources/Android/x86/libjSerialComm.so b/src/main/resources/Android/x86/libjSerialComm.so index c2fd04f..5733780 100644 Binary files a/src/main/resources/Android/x86/libjSerialComm.so and b/src/main/resources/Android/x86/libjSerialComm.so differ diff --git a/src/main/resources/Android/x86_64/libjSerialComm.so b/src/main/resources/Android/x86_64/libjSerialComm.so index 9f6a899..cd1898c 100644 Binary files a/src/main/resources/Android/x86_64/libjSerialComm.so and b/src/main/resources/Android/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/FreeBSD/arm64/libjSerialComm.so b/src/main/resources/FreeBSD/arm64/libjSerialComm.so index ea8ced7..103f47a 100644 Binary files a/src/main/resources/FreeBSD/arm64/libjSerialComm.so and b/src/main/resources/FreeBSD/arm64/libjSerialComm.so differ diff --git a/src/main/resources/FreeBSD/x86/libjSerialComm.so b/src/main/resources/FreeBSD/x86/libjSerialComm.so index 48721c2..be6f3f9 100644 Binary files a/src/main/resources/FreeBSD/x86/libjSerialComm.so and b/src/main/resources/FreeBSD/x86/libjSerialComm.so differ diff --git a/src/main/resources/FreeBSD/x86_64/libjSerialComm.so b/src/main/resources/FreeBSD/x86_64/libjSerialComm.so index 4e484e8..5196a98 100644 Binary files a/src/main/resources/FreeBSD/x86_64/libjSerialComm.so and b/src/main/resources/FreeBSD/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv5/libjSerialComm.so b/src/main/resources/Linux/armv5/libjSerialComm.so index 8045ed3..8fbfe76 100644 Binary files a/src/main/resources/Linux/armv5/libjSerialComm.so and b/src/main/resources/Linux/armv5/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv6/libjSerialComm.so b/src/main/resources/Linux/armv6/libjSerialComm.so index 10f767f..d1b7986 100644 Binary files a/src/main/resources/Linux/armv6/libjSerialComm.so and b/src/main/resources/Linux/armv6/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv6hf/libjSerialComm.so b/src/main/resources/Linux/armv6hf/libjSerialComm.so index 6b74bfe..36d2142 100644 Binary files a/src/main/resources/Linux/armv6hf/libjSerialComm.so and b/src/main/resources/Linux/armv6hf/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv7/libjSerialComm.so b/src/main/resources/Linux/armv7/libjSerialComm.so index 3dd8a57..9065d71 100644 Binary files a/src/main/resources/Linux/armv7/libjSerialComm.so and b/src/main/resources/Linux/armv7/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv7hf/libjSerialComm.so b/src/main/resources/Linux/armv7hf/libjSerialComm.so index 01c663e..6a97adc 100644 Binary files a/src/main/resources/Linux/armv7hf/libjSerialComm.so and b/src/main/resources/Linux/armv7hf/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv8_32/libjSerialComm.so b/src/main/resources/Linux/armv8_32/libjSerialComm.so index da1e4ac..3354c65 100644 Binary files a/src/main/resources/Linux/armv8_32/libjSerialComm.so and b/src/main/resources/Linux/armv8_32/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv8_64/libjSerialComm.so b/src/main/resources/Linux/armv8_64/libjSerialComm.so index 9ef0177..5ca23d3 100644 Binary files a/src/main/resources/Linux/armv8_64/libjSerialComm.so and b/src/main/resources/Linux/armv8_64/libjSerialComm.so differ diff --git a/src/main/resources/Linux/ppc64le/libjSerialComm.so b/src/main/resources/Linux/ppc64le/libjSerialComm.so index 3511578..bed9b8d 100644 Binary files a/src/main/resources/Linux/ppc64le/libjSerialComm.so and b/src/main/resources/Linux/ppc64le/libjSerialComm.so differ diff --git a/src/main/resources/Linux/x86/libjSerialComm.so b/src/main/resources/Linux/x86/libjSerialComm.so index 16e171d..9169598 100644 Binary files a/src/main/resources/Linux/x86/libjSerialComm.so and b/src/main/resources/Linux/x86/libjSerialComm.so differ diff --git a/src/main/resources/Linux/x86_64/libjSerialComm.so b/src/main/resources/Linux/x86_64/libjSerialComm.so index 34ef27e..de2b23e 100644 Binary files a/src/main/resources/Linux/x86_64/libjSerialComm.so and b/src/main/resources/Linux/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/OSX/aarch64/libjSerialComm.jnilib b/src/main/resources/OSX/aarch64/libjSerialComm.jnilib index 54edcdb..9adf5ce 100755 Binary files a/src/main/resources/OSX/aarch64/libjSerialComm.jnilib and b/src/main/resources/OSX/aarch64/libjSerialComm.jnilib differ diff --git a/src/main/resources/OSX/x86/libjSerialComm.jnilib b/src/main/resources/OSX/x86/libjSerialComm.jnilib index baa8cd5..98b8638 100644 Binary files a/src/main/resources/OSX/x86/libjSerialComm.jnilib and b/src/main/resources/OSX/x86/libjSerialComm.jnilib differ diff --git a/src/main/resources/OSX/x86_64/libjSerialComm.jnilib b/src/main/resources/OSX/x86_64/libjSerialComm.jnilib index de7f450..cda1ab1 100755 Binary files a/src/main/resources/OSX/x86_64/libjSerialComm.jnilib and b/src/main/resources/OSX/x86_64/libjSerialComm.jnilib differ diff --git a/src/main/resources/OpenBSD/amd64/libjSerialComm.so b/src/main/resources/OpenBSD/amd64/libjSerialComm.so index c98c882..52aa047 100644 Binary files a/src/main/resources/OpenBSD/amd64/libjSerialComm.so and b/src/main/resources/OpenBSD/amd64/libjSerialComm.so differ diff --git a/src/main/resources/OpenBSD/x86/libjSerialComm.so b/src/main/resources/OpenBSD/x86/libjSerialComm.so index b033c2e..e49ce86 100644 Binary files a/src/main/resources/OpenBSD/x86/libjSerialComm.so and b/src/main/resources/OpenBSD/x86/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so b/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so index a827fe0..ae54ee1 100644 Binary files a/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so and b/src/main/resources/Solaris/sparcv8plus_32/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so b/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so index 9138db5..91d45b5 100644 Binary files a/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so and b/src/main/resources/Solaris/sparcv9_64/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/x86/libjSerialComm.so b/src/main/resources/Solaris/x86/libjSerialComm.so index 48b9e09..2c42892 100644 Binary files a/src/main/resources/Solaris/x86/libjSerialComm.so and b/src/main/resources/Solaris/x86/libjSerialComm.so differ diff --git a/src/main/resources/Solaris/x86_64/libjSerialComm.so b/src/main/resources/Solaris/x86_64/libjSerialComm.so index b80756d..6d0add8 100644 Binary files a/src/main/resources/Solaris/x86_64/libjSerialComm.so and b/src/main/resources/Solaris/x86_64/libjSerialComm.so differ diff --git a/src/main/resources/Windows/aarch64/jSerialComm.dll b/src/main/resources/Windows/aarch64/jSerialComm.dll index b9f3ffb..bac600d 100644 Binary files a/src/main/resources/Windows/aarch64/jSerialComm.dll and b/src/main/resources/Windows/aarch64/jSerialComm.dll differ diff --git a/src/main/resources/Windows/armv7/jSerialComm.dll b/src/main/resources/Windows/armv7/jSerialComm.dll index eb58b2d..aee94dd 100644 Binary files a/src/main/resources/Windows/armv7/jSerialComm.dll and b/src/main/resources/Windows/armv7/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86/jSerialComm.dll b/src/main/resources/Windows/x86/jSerialComm.dll index 6c898b7..52b282e 100644 Binary files a/src/main/resources/Windows/x86/jSerialComm.dll and b/src/main/resources/Windows/x86/jSerialComm.dll differ diff --git a/src/main/resources/Windows/x86_64/jSerialComm.dll b/src/main/resources/Windows/x86_64/jSerialComm.dll index aee2e65..6bfe0b9 100644 Binary files a/src/main/resources/Windows/x86_64/jSerialComm.dll and b/src/main/resources/Windows/x86_64/jSerialComm.dll differ