diff --git a/INSTALL b/INSTALL index 8b52ef6..7e55e2b 100644 --- a/INSTALL +++ b/INSTALL @@ -106,31 +106,31 @@ Maven: com.fazecast jSerialComm - 1.2.0 + 1.2.2 Ivy: - + Grape: @Grapes( - @Grab(group='com.fazecast', module='jSerialComm', version='1.2.0') + @Grab(group='com.fazecast', module='jSerialComm', version='1.2.2') ) Gradle: -'com.fazecast:jSerialComm:1.2.0' +'com.fazecast:jSerialComm:1.2.2' Buildr: -'com.fazecast:jSerialComm:jar:1.2.0' +'com.fazecast:jSerialComm:jar:1.2.2' SBT: -libraryDependencies += "com.fazecast" % "jSerialComm" % "1.2.0" +libraryDependencies += "com.fazecast" % "jSerialComm" % "1.2.2" Leiningen: -[com.fazecast/jSerialComm "1.2.0"] +[com.fazecast/jSerialComm "1.2.2"] diff --git a/build.gradle b/build.gradle index ccf4169..a61aead 100644 --- a/build.gradle +++ b/build.gradle @@ -4,7 +4,7 @@ apply plugin: 'maven' group = 'com.fazecast' archivesBaseName = 'jSerialComm' -version = '1.1.1' +version = '1.2.2' sourceCompatibility = 1.6 targetCompatibility = 1.6 diff --git a/src/main/cpp/Android/jni/AndroidHelperFunctions.c b/src/main/cpp/Android/jni/AndroidHelperFunctions.c index 20ba28a..9aa44f6 100644 --- a/src/main/cpp/Android/jni/AndroidHelperFunctions.c +++ b/src/main/cpp/Android/jni/AndroidHelperFunctions.c @@ -74,6 +74,39 @@ void getFriendlyName(const char* productFile, char* friendlyName) } } +void getDriverName(const char* directoryToSearch, char* friendlyName) +{ + friendlyName[0] = '\0'; + + // Open the directory + DIR *directoryIterator = opendir(directoryToSearch); + if (!directoryIterator) + return; + + // Read all sub-directories in the current directory + struct dirent *directoryEntry = readdir(directoryIterator); + while (directoryEntry) + { + // Check if entry is a valid sub-directory + if (directoryEntry->d_name[0] != '.') + { + // Get the readable part of the driver name + strcpy(friendlyName, "USB-to-Serial Port ("); + char *startingPoint = strchr(directoryEntry->d_name, ':'); + if (startingPoint != NULL) + strcat(friendlyName, startingPoint+1); + else + strcat(friendlyName, directoryEntry->d_name); + strcat(friendlyName, ")"); + break; + } + directoryEntry = readdir(directoryIterator); + } + + // Close the directory + closedir(directoryIterator); +} + void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathToSearch) { // Open the directory @@ -106,7 +139,17 @@ void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathTo strcat(productFile, directoryEntry->d_name); strcat(productFile, "/device/../product"); getFriendlyName(productFile, friendlyName); - if (friendlyName[0] != '\0') + if (friendlyName[0] == '\0') + { + // Get friendly name based on the driver loaded + strcpy(productFile, fullPathToSearch); + strcat(productFile, directoryEntry->d_name); + strcat(productFile, "/driver/module/drivers"); + getDriverName(productFile, friendlyName); + if (friendlyName[0] != '\0') + push_back(comPorts, systemName, friendlyName); + } + else push_back(comPorts, systemName, friendlyName); // Clean up memory diff --git a/src/main/cpp/Android/jni/AndroidHelperFunctions.h b/src/main/cpp/Android/jni/AndroidHelperFunctions.h index 492f5dd..ea00fe7 100644 --- a/src/main/cpp/Android/jni/AndroidHelperFunctions.h +++ b/src/main/cpp/Android/jni/AndroidHelperFunctions.h @@ -33,6 +33,7 @@ typedef struct charPairVector } charPairVector; void push_back(struct charPairVector* vector, const char* firstString, const char* secondString); +void getDriverName(const char* directoryToSearch, char* friendlyName); void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathToSearch); void getFriendlyName(const char* productFile, char* friendlyName); unsigned int getBaudRateCode(int baudRate); diff --git a/src/main/cpp/Linux/LinuxHelperFunctions.c b/src/main/cpp/Linux/LinuxHelperFunctions.c index d076e7a..524cd7f 100644 --- a/src/main/cpp/Linux/LinuxHelperFunctions.c +++ b/src/main/cpp/Linux/LinuxHelperFunctions.c @@ -72,6 +72,39 @@ void getFriendlyName(const char* productFile, char* friendlyName) } } +void getDriverName(const char* directoryToSearch, char* friendlyName) +{ + friendlyName[0] = '\0'; + + // Open the directory + DIR *directoryIterator = opendir(directoryToSearch); + if (!directoryIterator) + return; + + // Read all sub-directories in the current directory + struct dirent *directoryEntry = readdir(directoryIterator); + while (directoryEntry) + { + // Check if entry is a valid sub-directory + if (directoryEntry->d_name[0] != '.') + { + // Get the readable part of the driver name + strcpy(friendlyName, "USB-to-Serial Port ("); + char *startingPoint = strchr(directoryEntry->d_name, ':'); + if (startingPoint != NULL) + strcat(friendlyName, startingPoint+1); + else + strcat(friendlyName, directoryEntry->d_name); + strcat(friendlyName, ")"); + break; + } + directoryEntry = readdir(directoryIterator); + } + + // Close the directory + closedir(directoryIterator); +} + void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathToSearch) { // Open the directory @@ -104,21 +137,31 @@ void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathTo strcat(productFile, directoryEntry->d_name); strcat(productFile, "/device/../product"); getFriendlyName(productFile, friendlyName); - if (friendlyName[0] == '\0') // Must be a physical platform port + if (friendlyName[0] == '\0') // Must be a physical (or emulated) port { - // Ensure that the platform port is actually open - struct serial_struct serialInfo = { 0 }; - int fd = open(systemName, O_RDWR | O_NONBLOCK | O_NOCTTY); - if (fd >= 0) + // See if this is a USB-to-Serial converter based on the driver loaded + strcpy(productFile, fullPathToSearch); + strcat(productFile, directoryEntry->d_name); + strcat(productFile, "/driver/module/drivers"); + getDriverName(productFile, friendlyName); + if (friendlyName[0] == '\0') // Must be a physical port { - if ((ioctl(fd, TIOCGSERIAL, &serialInfo) == 0) && (serialInfo.type != PORT_UNKNOWN)) + // Ensure that the platform port is actually open + struct serial_struct serialInfo = { 0 }; + int fd = open(systemName, O_RDWR | O_NONBLOCK | O_NOCTTY); + if (fd >= 0) { - strcpy(friendlyName, "Physical Port "); - strcat(friendlyName, directoryEntry->d_name+3); - push_back(comPorts, systemName, friendlyName); + if ((ioctl(fd, TIOCGSERIAL, &serialInfo) == 0) && (serialInfo.type != PORT_UNKNOWN)) + { + strcpy(friendlyName, "Physical Port "); + strcat(friendlyName, directoryEntry->d_name+3); + push_back(comPorts, systemName, friendlyName); + } + close(fd); } - close(fd); } + else + push_back(comPorts, systemName, friendlyName); } else push_back(comPorts, systemName, friendlyName); diff --git a/src/main/cpp/Linux/LinuxHelperFunctions.h b/src/main/cpp/Linux/LinuxHelperFunctions.h index 6a66d38..e92ad5a 100644 --- a/src/main/cpp/Linux/LinuxHelperFunctions.h +++ b/src/main/cpp/Linux/LinuxHelperFunctions.h @@ -33,6 +33,7 @@ typedef struct charPairVector } charPairVector; void push_back(struct charPairVector* vector, const char* firstString, const char* secondString); +void getDriverName(const char* directoryToSearch, char* friendlyName); void recursiveSearchForComPorts(charPairVector* comPorts, const char* fullPathToSearch); void getFriendlyName(const char* productFile, char* friendlyName); unsigned int getBaudRateCode(int baudRate); diff --git a/src/main/java/com/fazecast/jSerialComm/SerialPort.java b/src/main/java/com/fazecast/jSerialComm/SerialPort.java index 727b434..c2f7ab6 100644 --- a/src/main/java/com/fazecast/jSerialComm/SerialPort.java +++ b/src/main/java/com/fazecast/jSerialComm/SerialPort.java @@ -38,13 +38,14 @@ import java.util.Date; * This class provides native access to serial ports and devices without requiring external libraries or tools. * * @author Will Hedgecock <will.hedgecock@fazecast.com> - * @version 1.2.0 + * @version 1.2.2 * @see java.io.InputStream * @see java.io.OutputStream */ public final class SerialPort { // Static initializer loads correct native library for this machine + private static boolean isAndroid = false; static { String OS = System.getProperty("os.name").toLowerCase(); @@ -75,6 +76,7 @@ public final class SerialPort } catch (Exception e) { e.printStackTrace(); } + isAndroid = true; if (libraryPath.isEmpty()) libraryPath = "Android/armeabi"; fileName = "libjSerialComm.so"; @@ -249,6 +251,17 @@ public final class SerialPort */ public final boolean openPort() { + // If this is an Android application, we must explicitly allow serial port access to this library + if (isAndroid) + { + try + { + String grantPermissions = "chmod 666 " + getSystemPortName() + "\nexit\n"; + Process process = Runtime.getRuntime().exec("su -c " + grantPermissions); + process.waitFor(); + } catch (Exception e) { return false; } + } + try { Thread.sleep(500); } catch (Exception e) {} if (!isOpened && openPortNative()) { diff --git a/src/main/resources/Android/arm64-v8a/libjSerialComm.so b/src/main/resources/Android/arm64-v8a/libjSerialComm.so index 3bf425e..605affe 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 106bd4b..f65875e 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/armeabi/libjSerialComm.so b/src/main/resources/Android/armeabi/libjSerialComm.so index c648306..303d2bd 100644 Binary files a/src/main/resources/Android/armeabi/libjSerialComm.so and b/src/main/resources/Android/armeabi/libjSerialComm.so differ diff --git a/src/main/resources/Android/mips/libjSerialComm.so b/src/main/resources/Android/mips/libjSerialComm.so index ae2dc06..738ab9c 100644 Binary files a/src/main/resources/Android/mips/libjSerialComm.so and b/src/main/resources/Android/mips/libjSerialComm.so differ diff --git a/src/main/resources/Android/mips64/libjSerialComm.so b/src/main/resources/Android/mips64/libjSerialComm.so index 58ff893..7019795 100644 Binary files a/src/main/resources/Android/mips64/libjSerialComm.so and b/src/main/resources/Android/mips64/libjSerialComm.so differ diff --git a/src/main/resources/Android/x86/libjSerialComm.so b/src/main/resources/Android/x86/libjSerialComm.so index 2eb1bbd..bfe439c 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 f1e391c..5feda2d 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/Linux/armv5/libjSerialComm.so b/src/main/resources/Linux/armv5/libjSerialComm.so index 42e56d5..3a2ad59 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-hf/libjSerialComm.so b/src/main/resources/Linux/armv6-hf/libjSerialComm.so index e8888ce..e8f7999 100644 Binary files a/src/main/resources/Linux/armv6-hf/libjSerialComm.so and b/src/main/resources/Linux/armv6-hf/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv6/libjSerialComm.so b/src/main/resources/Linux/armv6/libjSerialComm.so index a7e8a25..9dc860b 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/armv7-hf/libjSerialComm.so b/src/main/resources/Linux/armv7-hf/libjSerialComm.so index bebb818..aa0e913 100644 Binary files a/src/main/resources/Linux/armv7-hf/libjSerialComm.so and b/src/main/resources/Linux/armv7-hf/libjSerialComm.so differ diff --git a/src/main/resources/Linux/armv7/libjSerialComm.so b/src/main/resources/Linux/armv7/libjSerialComm.so index 6587507..83f8827 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/x86/libjSerialComm.so b/src/main/resources/Linux/x86/libjSerialComm.so index 027b0ad..01ec489 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 93b19f7..905edc4 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/test/java/com/fazecast/jSerialComm/SerialPortTest.java b/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java index 30fc2e9..99223c2 100644 --- a/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java +++ b/src/test/java/com/fazecast/jSerialComm/SerialPortTest.java @@ -32,7 +32,7 @@ import java.util.Scanner; * This class provides a test case for the jSerialComm library. * * @author Will Hedgecock <will.hedgecock@gmail.com> - * @version 1.0 + * @version 2.0 * @see java.io.InputStream * @see java.io.OutputStream */