From bc7cd0fe79953af39ec183c1ae64a55dfb46451f Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 14 Feb 2014 12:17:41 -0800 Subject: [PATCH 01/16] Support cu.* devices on OS X Opening /dev/cu.* doesn't require DCD to be asserted and succeeds immediately. --- src/java/jssc/SerialPortList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 5af9a95ea..89d134e2e 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -53,7 +53,7 @@ public class SerialPortList { break; } case SerialNativeInterface.OS_MAC_OS_X: { - PORTNAMES_REGEXP = Pattern.compile("tty.(serial|usbserial|usbmodem).*"); + PORTNAMES_REGEXP = Pattern.compile("(cu|tty).(serial|usbserial|usbmodem).*"); PORTNAMES_PATH = "/dev/"; break; } From ec95367f5fdab32ad0173faba89999005243ced1 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 14 Feb 2014 12:20:07 -0800 Subject: [PATCH 02/16] Support all cu.* & tty.* devices on OS X This includes /dev/tty.Bluetooth-Modem and friends. --- src/java/jssc/SerialPortList.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 89d134e2e..188905737 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -53,7 +53,7 @@ public class SerialPortList { break; } case SerialNativeInterface.OS_MAC_OS_X: { - PORTNAMES_REGEXP = Pattern.compile("(cu|tty).(serial|usbserial|usbmodem).*"); + PORTNAMES_REGEXP = Pattern.compile("(cu|tty)\\..+"); PORTNAMES_PATH = "/dev/"; break; } From 6c55bb04cf6271ec89d5878ef945c1c22da49ffa Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 14 Feb 2014 12:22:46 -0800 Subject: [PATCH 03/16] Don't open ports for getPortNames() Opening certain devices, such as serial endpoints over Bluetooth, can take a long time before they fail. Moreover, it's better to show devices even when the user currently doesn't have permissions to access them - else one might think of a problem with the device or driver, when a "sudo chmod 666" would do the trick. --- src/java/jssc/SerialPortList.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 188905737..8da724f0a 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -330,6 +330,7 @@ private static String[] getUnixBasedPortNames(String searchPath, Pattern pattern String fileName = file.getName(); if(!file.isDirectory() && !file.isFile() && pattern.matcher(fileName).find()){ String portName = searchPath + fileName; + /* long portHandle = serialInterface.openPort(portName, false);//Open port without TIOCEXCL if(portHandle < 0 && portHandle != SerialNativeInterface.ERR_PORT_BUSY){ continue; @@ -337,6 +338,7 @@ private static String[] getUnixBasedPortNames(String searchPath, Pattern pattern else if(portHandle != SerialNativeInterface.ERR_PORT_BUSY) { serialInterface.closePort(portHandle); } + */ portsTree.add(portName); } } From 4aa2399e20efcf9a4d994deeb4f64dfda94c2c90 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 14 Feb 2014 12:29:04 -0800 Subject: [PATCH 04/16] Try to load native libraries without modifying the host system Before dynamically extracting the matching native library, first try to load it using System.loadLibrary(). This is helpful when it's not desired to modify the host system (but rather make changes to java.library.path). --- src/java/jssc/SerialNativeInterface.java | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/src/java/jssc/SerialNativeInterface.java b/src/java/jssc/SerialNativeInterface.java index c5264f5e8..4979dc225 100644 --- a/src/java/jssc/SerialNativeInterface.java +++ b/src/java/jssc/SerialNativeInterface.java @@ -150,7 +150,9 @@ else if(architecture.equals("arm")) {//since 2.1.0 boolean loadLib = false; - if(isLibFolderExist(libFolderPath)){ + if(loadLibFromPath("jSSC-"+libVersion)) { + // nothing more to do + } else if(isLibFolderExist(libFolderPath)){ if(isLibFileExist(libFolderPath + fileSeparator + libName)){ loadLib = true; } @@ -303,6 +305,21 @@ public static String getLibraryMinorSuffix() { */ public static native String getNativeLibraryVersion(); + /** + * Attempt to load a library using System.loadLibrary + * + * @param lib name of the library + * @return true if sucessful, false if not + */ + public static boolean loadLibFromPath(String lib) { + try { + System.loadLibrary(lib); + return true; + } catch (UnsatisfiedLinkError e) { + return false; + } + } + /** * Open port * From 475f912da6f3b8e084e0af1cc2cf592f663f6aab Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 14 Feb 2014 12:37:40 -0800 Subject: [PATCH 05/16] Add a Universal binary for OS X The command used to compile this on 10.9.1: g++ -shared -arch i386 -arch x86_64 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -I"/System/Library/Frameworks/IOKit.framework/Headers" -o libjSSC-2.8_universal.jnilib jssc.cpp --- .../libs/mac_os_x/libjSSC-2.8_universal.jnilib | Bin 0 -> 50204 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 src/java/libs/mac_os_x/libjSSC-2.8_universal.jnilib diff --git a/src/java/libs/mac_os_x/libjSSC-2.8_universal.jnilib b/src/java/libs/mac_os_x/libjSSC-2.8_universal.jnilib new file mode 100755 index 0000000000000000000000000000000000000000..bd3467f9038086fb8eea612c63b5e33a1661b42c GIT binary patch literal 50204 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 Date: Fri, 14 Feb 2014 13:44:11 -0800 Subject: [PATCH 06/16] Allow querying of USB properties getPortProperties() returns a map with keys and values as string. The currently available properties are: idProduct (lowercase hexadecimal zero-padded to four digits), idVendor (same as idProduct), manufacturer, product, serial. This is currently implemented for Linux and OS X (only in the Universal binary). The command used to compile this on 10.9.1: g++ -shared -arch i386 -arch x86_64 -I"$JAVA_HOME/include" -I"$JAVA_HOME/include/darwin" -I"/System/Library/Frameworks/IOKit.framework/Headers" -framework CoreFoundation -framework IOKit -o libjSSC-2.8_universal.jnilib jssc.cpp --- src/cpp/_nix_based/jssc.cpp | 135 ++++++++++++++++++ src/cpp/jssc_SerialNativeInterface.h | 8 ++ src/java/jssc/SerialNativeInterface.java | 2 + src/java/jssc/SerialPortList.java | 75 ++++++++++ .../mac_os_x/libjSSC-2.8_universal.jnilib | Bin 50204 -> 59932 bytes 5 files changed, 220 insertions(+) diff --git a/src/cpp/_nix_based/jssc.cpp b/src/cpp/_nix_based/jssc.cpp index 634b62018..b12889b28 100644 --- a/src/cpp/_nix_based/jssc.cpp +++ b/src/cpp/_nix_based/jssc.cpp @@ -40,7 +40,12 @@ #include //Needed for select() function #endif #ifdef __APPLE__ + #include + #include + #include + #include #include //Needed for IOSSIOSPEED in Mac OS X (Non standard baudrate) + #include // Needed for MAXPATHLEN #endif #include @@ -872,3 +877,133 @@ JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus env->SetIntArrayRegion(returnArray, 0, 4, returnValues); return returnArray; } + +JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties + (JNIEnv *env, jclass cls, jstring portName) { + const char* portNameChar = (const char*)env->GetStringUTFChars(portName, NULL); + jclass stringClass = env->FindClass("Ljava/lang/String;"); + jobjectArray ret = env->NewObjectArray(5, stringClass, NULL); + +#ifdef __APPLE__ + + // this code is based on QtSerialPort + CFMutableDictionaryRef matching = IOServiceMatching(kIOSerialBSDServiceValue); + io_iterator_t iter = 0; + kern_return_t kr = IOServiceGetMatchingServices(kIOMasterPortDefault, matching, &iter); + if (kr != kIOReturnSuccess) { + env->ReleaseStringUTFChars(portName, portNameChar); + return ret; + } + + io_registry_entry_t service; + while ((service = IOIteratorNext(iter))) { + + // compare portName against cu and tty devices + bool found = false; + + CFTypeRef cu = 0; + cu = IORegistryEntrySearchCFProperty(service, kIOServicePlane, CFSTR(kIOCalloutDeviceKey), kCFAllocatorDefault, 0); + if (cu) { + char buffer[MAXPATHLEN]; + CFStringGetCString(CFStringRef(cu), buffer, sizeof(buffer), kCFStringEncodingUTF8); + //fprintf(stdout, "getPortProperties: %s\n", buffer); + //fflush(stdout); + if (strcmp(portNameChar, buffer) == 0) { + found = true; + } + CFRelease(cu); + } + + CFTypeRef tty = 0; + tty = IORegistryEntrySearchCFProperty(service, kIOServicePlane, CFSTR(kIODialinDeviceKey), kCFAllocatorDefault, 0); + if (tty) { + char buffer[MAXPATHLEN]; + CFStringGetCString(CFStringRef(tty), buffer, sizeof(buffer), kCFStringEncodingUTF8); + //fprintf(stdout, "getPortProperties: %s\n", buffer); + //fflush(stdout); + if (strcmp(portNameChar, buffer) == 0) { + found = true; + } + CFRelease(tty); + } + + if (!found) { + // not port we're looking for + //fprintf(stderr, "getPortProperties: %s not found", portNameChar); + //fflush(stderr); + IOObjectRelease(service); + continue; + } + + io_registry_entry_t entry = service; + do { + int val = 0; + char buffer[255]; + + CFTypeRef idProduct = 0; + idProduct = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBProductID), kCFAllocatorDefault, 0); + if (idProduct && !env->GetObjectArrayElement(ret, 0)) { + CFNumberGetValue(CFNumberRef(idProduct), kCFNumberIntType, &val); + sprintf(buffer, "%04x", val); + jstring tmp = env->NewStringUTF(buffer); + env->SetObjectArrayElement(ret, 0, tmp); + env->DeleteLocalRef(tmp); + CFRelease(idProduct); + } + + CFTypeRef idVendor = 0; + idVendor = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBVendorID), kCFAllocatorDefault, 0); + if (idVendor && !env->GetObjectArrayElement(ret, 1)) { + CFNumberGetValue(CFNumberRef(idVendor), kCFNumberIntType, &val); + sprintf(buffer, "%04x", val); + jstring tmp = env->NewStringUTF(buffer); + env->SetObjectArrayElement(ret, 1, tmp); + env->DeleteLocalRef(tmp); + CFRelease(idVendor); + } + + CFTypeRef manufacturer = 0; + manufacturer = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBVendorString), kCFAllocatorDefault, 0); + if (manufacturer && !env->GetObjectArrayElement(ret, 2)) { + CFStringGetCString(CFStringRef(manufacturer), buffer, sizeof(buffer), kCFStringEncodingUTF8); + jstring tmp = env->NewStringUTF(buffer); + env->SetObjectArrayElement(ret, 2, tmp); + env->DeleteLocalRef(tmp); + CFRelease(manufacturer); + } + + CFTypeRef product = 0; + product = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBProductString), kCFAllocatorDefault, 0); + if (product && !env->GetObjectArrayElement(ret, 3)) { + CFStringGetCString(CFStringRef(product), buffer, sizeof(buffer), kCFStringEncodingUTF8); + jstring tmp = env->NewStringUTF(buffer); + env->SetObjectArrayElement(ret, 3, tmp); + env->DeleteLocalRef(tmp); + CFRelease(product); + } + + CFTypeRef serial = 0; + serial = IORegistryEntrySearchCFProperty(entry, kIOServicePlane, CFSTR(kUSBSerialNumberString), kCFAllocatorDefault, 0); + if (serial && !env->GetObjectArrayElement(ret, 4)) { + CFStringGetCString(CFStringRef(serial), buffer, sizeof(buffer), kCFStringEncodingUTF8); + jstring tmp = env->NewStringUTF(buffer); + env->SetObjectArrayElement(ret, 4, tmp); + env->DeleteLocalRef(tmp); + CFRelease(serial); + } + + kr = IORegistryEntryGetParentEntry(entry, kIOServicePlane, &entry); + } while (kr == kIOReturnSuccess); + + IOObjectRelease(entry); + + IOObjectRelease(service); + } + + IOObjectRelease(iter); + +#endif // __APPLE__ + + env->ReleaseStringUTFChars(portName, portNameChar); + return ret; +} diff --git a/src/cpp/jssc_SerialNativeInterface.h b/src/cpp/jssc_SerialNativeInterface.h index 7029b1bbe..969da1e84 100644 --- a/src/cpp/jssc_SerialNativeInterface.h +++ b/src/cpp/jssc_SerialNativeInterface.h @@ -195,6 +195,14 @@ JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak (JNIEnv *, jobject, jlong, jint); +/* + * Class: jssc_SerialNativeInterface + * Method: getPortProperties + * Signature: (Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties + (JNIEnv *, jclass, jstring); + #ifdef __cplusplus } #endif diff --git a/src/java/jssc/SerialNativeInterface.java b/src/java/jssc/SerialNativeInterface.java index 4979dc225..aba50cdf5 100644 --- a/src/java/jssc/SerialNativeInterface.java +++ b/src/java/jssc/SerialNativeInterface.java @@ -500,4 +500,6 @@ public static boolean loadLibFromPath(String lib) { * @since 0.8 */ public native boolean sendBreak(long handle, int duration); + + public static native String[] getPortProperties(String portName); } diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 8da724f0a..38bb20085 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -25,7 +25,11 @@ package jssc; import java.io.File; +import java.io.FileReader; import java.util.Comparator; +import java.util.HashMap; +import java.util.Map; +import java.util.Scanner; import java.util.TreeSet; import java.util.regex.Pattern; @@ -347,4 +351,75 @@ else if(portHandle != SerialNativeInterface.ERR_PORT_BUSY) { } return returnArray; } + + public static Map getPortProperties(String portName) { + if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_LINUX) { + return getLinuxPortProperties(portName); + } else if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_MAC_OS_X) { + return getNativePortProperties(portName); + } else if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_WINDOWS){ + // TODO + return new HashMap(); + } else { + return new HashMap(); + } + } + + public static Map getLinuxPortProperties(String portName) { + Map props = new HashMap(); + try { + // portName has the format /dev/ttyUSB0 + String dev = portName.split("/")[2]; + File sysfsNode = new File("/sys/bus/usb-serial/devices/"+dev); + + // resolve the symbolic link and store the resulting components in an array + String[] sysfsPath = sysfsNode.getCanonicalPath().split("/"); + + // walk the tree to the root + for (int i=sysfsPath.length-2; 0 < i; i--) { + String curPath = "/"; + for (int j=1; j <= i; j++) { + curPath += sysfsPath[j]+"/"; + } + + // look for specific attributes + String[] attribs = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; + for (int j=0; j < attribs.length; j++) { + try { + Scanner in = new Scanner(new FileReader(curPath+attribs[j])); + // we treat the values just as strings + props.put(attribs[j], in.next()); + } catch (Exception e) { + // ignore the attribute + } + } + + // stop once we have at least one attribute + if (0 < props.size()) { + break; + } + } + } catch (Exception e) { + // nothing to do, return what we have so far + } + return props; + } + + public static Map getNativePortProperties(String portName) { + Map props = new HashMap(); + try { + // use JNI functions to read those properties + String[] names = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; + String[] values = SerialNativeInterface.getPortProperties(portName); + + for (int i=0; i < names.length; i++) { + if (values[i] != null) { + props.put(names[i], values[i]); + } + } + } catch (Exception e) { + // nothing to do, return what we have so far + } + return props; + } } diff --git a/src/java/libs/mac_os_x/libjSSC-2.8_universal.jnilib b/src/java/libs/mac_os_x/libjSSC-2.8_universal.jnilib index bd3467f9038086fb8eea612c63b5e33a1661b42c..012a1684bc300a2e4abe8d636e710c974647c6f2 100755 GIT binary patch literal 59932 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 delta 8314 zcmd5=3s{uZx?Zzp29(e{pwyof%Y|$yhHI7H7gM+F4_>7`u#KNEQTy&kVYX zF5Tj47A!#5gRTi(PZm6au6`tBPKNrlV^eW(eU z9y8j`2v`zPwiH<;1|rc`p>?3$h}RAlF;;*hIb|+hpz<|GkKna1b_?3hVgzhA7>yM( zC9E!TDp~{PsGZsI>fN_9HfLvc1QbM$(Z)ZXw6C=(f6lHqtc~A-sRXQB4KO{bHmw+& zosO4G#H_{aM4!@R%(7p5E;}gz+=-Df|Au#PRea|v8R{tc&J|*C%{8dJx2M40B`$~x zPr)+tC$0}&ic5v602~MJniPmjn#eUN@ZmHo>`Bsao&qP6rtxFRa4jj7uS?#gH$*Q= zrVB3)B;YMO%>C4WH$NF>>L-VMsAp`zg>mnI9#-p9_&@4l51J!-cwWDVr|Nq`lMB^c z6)$eknXcjA#KF1r4Bin3*V5y;Bd%vCJ%RJb#zD-)*?ht{xNG7JJ{SX!Ol;$gF`${0 z&xfOX=1)>9_@ZdAPOj9x5rw@d@zTSYKk@cNVK5%vpWM$cN5ZpHO8JIJP-Sl7-$uZe z%u;?P0^ZHE$K24-BlLHe2RlkWaDC)jpmK5VMIBhP;a!;C<2u-vwUW=*fqLpf zK1BzMr!M24gu{iYS-dM8yi+&veOjnB-pU`)!jr~SzEKOW8;kg59cZ&};b%2)dv+X; z(ZY)CWPVcv4`+5L8N>?!4pnA|o# z_iq0CAn3{c_2l#TU+9Q;{d&;#z~`=3udCz}SB0me4{8+drFPSs^f9Dza`(xpF-s!j}sA9#1uQb}tk0Jd^6K?J%=h0wTk$)FI7TnXD z{}@j^M%7B%sr3-UCH&g(AHrN)4a393-mPkAon_)H)Np=QVtl2V#=@9Rk-0+$hi~aErip#9Ec04AEVSqrwKR7}0?`W;oJp*USP8M?#HxwyC$^rLo7gsD+lcKZwvkvDv1VfbK&+NnKe1)R zZV)Rc_5-m6#I*Pd2TUpQyHU~axjLeOyd}@8pjmw1jf4)m_nO`lXDVNF+I-n zdZu)u?bc&F8RN-J(TTP%nOcO;?#OBzoQ%^p=0Th|J(IBN6r8Tn>e0F}-if>lGsE6! z(RX5e94=QWn5SUQ#caa70CPF!WteL*H)Gz2c^hUo=KYwDWA4Iy0rM-EU(aIaa#}Sr z!jnU)^g8{UOPoo(Nzud?;_bpsm6c1D*IU=Hg{w_&avE%_n2)SQqJt-@qWHyOINLWq z_$H35ND4RnOO;*`vdd=e*oC}2ueVn_eiGh@ zVMldMeQQfCHSJUge}&y)b2!8!Zt+F%)^ensB5RxLLLL4chY$W>ob$1Q1>&`A74^y5 z*z90`RJ7PxKW}PnUSSu3V@mPJf}c{ZWiKnKt3~S__7>(*vH-Z_YE;{M3iBF!gQKOy z*0Pd4qbzEzsj)Y=h)Q!BTN@ngQ{}w+#U=vO+MG=uocxguxBFh4p*|lIJ}2574P9- zUf!_02p?}HyQySqtF76#s)Zd^`aRpz%0=a6?7VVr`671l&z|YJQpwx~Y_B`B4Y6-3 zLa&k9&!!-Oa~j^MxsLioBX~_|t8@6;XAj{M_f5w-?p&%p6QQqwE-_K8h+H#5=RAa7 zfGWnNvw@;UXkmX;W^_4aDEa|~1Gl-k#_KdJKAVfA#@4UM%E z^Bx?Njlua1j>6_<+j?^y`;1;?|b~VD-Hd6i-3;dzq@CK-_YA?lmY+2A08*x6|R#_kzO?U}aA^!z(KA z=^^aCSpM&U@Wp$E?7dV{fhF!c5j+I$yATEmIu|22??&h*a4x|Q0#4qSHqmG@nT%Fr z75=R3+dqcj%E@S1ptY3}ZQK=@O^|=B7yECw5tV{K2o}MM~CX6>qTp!HX;}Y-25B9eb*Tyq;L&4g_#WWMgVIQd> zXDnky633aGt(Leok+BmJ*W#wEPvYHJXGpG(U#mgsYsVUgyJ(5`r7&ifcvC1&!xDFf zx8bBOIr>zbiv@QwS_3XioYsPWmE*W31mMu&E!TYoL!oat5dE~i$Uhxe%=+BrF# zZsebgu*jLKv*IU6X`x;iW(~#jaU4ABH0X}v`=`_^kg=ngaNRjOYB~N(DZS}4jC>B8 zwJ}h>*`Ujr>I>u9QKX!y@bKo_BBf}t6g8o*!s8hksl8P-##uSbURYc?n~$Vb_B(X2nd2dP6xCvjMX>ty}N~jGWdl zracyWw0Y)@XOv-EHdW=DtW8N)vs$8vK&mi2ct?`l1$cc5aS~TEPRV>t)v! zyusNdIJ?^r;}TW62WXtIHBstqNP_FTCx*mg*}!Tn@Fpig(w^~LnFP0@`7{yk*>fA; zkl1r@PqaE=8&3Z}+ef$eKrCF@AHz?^f_J}x&yIz#1JQg+Y)|@uJ2{VzflY@B_^D{P zc*w}tM8lVdHt=twPzTV%!-vQ7ZBcOQ@YmcM37ta&ML=953+==@34fhlachV=nW%7E%>(*joE7 z)fMl$E_r9`VCm6V{!}=uJ-U|94Tr&_1-u{}vX0gB&$MvxST=uJ3s;V9%KGH({i8S6525=&mH-^FQPsGM=5oP8+U+?LmsjIFl-bce=_{3HI_o47lCv$je zCLK*%8q&G$%E+yYr)$6Sd z27cPe3xZ+#=@fo72o|3n&%Z>In*@8X;7|};I-RF24WWC{=nh$SsB3~D>`XN0L6CkX zkv}sQ=AFslH^)NLnRNd8SlD;wK+OCgx`(;b(xIN`qo+DT=LW%or%JghsAvCEyLnUt z&HEsbNl6>a>HnUXo8^*HO`K>Damsk4hHT%U)V}JIw8p($GHe z1u6}AkLLp6@vbcXfEs?+mBSYX!uMTw@Leh>J-c&kDozbJ@HGM8J)5S;>-qBhJIXfq za9R_-rQx(@fewLd1g;afK_H2O!)coY(v<_MpHm0=Efl7x=Ki?E)VW=oYw3;BJ9? z1@1#cfn&dL4hlRhuv6esfyV`&6nIMD8G*kM*o8=6Si&Kk%L>be({`YhbcWAxq-v>n z;DZtN_6U28m=-s6Y~V$rG?@)NOYBx+XNWB%)=8|A*j{3*h;1i!Kd}diJxq*VOzlBp z4a80pTTbk6i7g>^nV6N>`^4rUOR4>wXaNO(AeMvdN1Xv9KCPkbrMtsuEv9*wGA_0+ zytJ&%IE8B9!Jp<{Odfg+Otc@PG$@tRMvqdJeNR%_1cSF5;9n zNw(c*+t@BCa8R-*CEG387bN>z$-XJse#w3$+0P~WwPcyJwg*X8-XSDPeul8;W?T=O z6rMb;N{@Z>7ag36zoa@ShM=o213XnpigErz1AYjUR_~*Owx8P2>GS_wZa75+qx6RE zk=T!d!vzr|#evTHz2wzYH~1um*U0k;4kRq}k^7_M&`)lIt)a1{-fnNAt34Ev5;*ZV@K;oY-aM=`m`@dN zMexifC`9O+LyWY9&R-#P6QH1g4Ck-^6IH?U-%}L^Nmc0mIaNUj3VkFfbd#3gA?PMS z!9ySfg+Wpk`j)W1IJocqv`mxLYBiyvU_=yu=wGBPR7tZ+7+yjLdpGXvDBXft9P|@~ zJEAh^@xV^$FlH+E=*jz0ZRpPM`Lg05pQ2>dfz${}jd(3y-^QFcwNsMi2a+);$r3~p zsUetd_%0v~SR`4AVE9jY%JhRN;=6(ugV{&J?mTfpecpxv!X=aoQWoSDOqMU?l}wf}}yfpet9n=ATxr2Ov z$%A}<*@JwPKHBIcCU!Cu@Yg@c_t!wk_m@G)_m@J*FY{9($X_zbw~g}a0`UF&cfc{K z!iG`4bCkbhl)rbBe`J*Zn^As`c2r=L2J*kHpX7f0i}aI(fl7FCU<#zIH^7+dk@&v; E6Kde_LjV8( From c0d2c800daa5116728e93964846ca4ae6a857055 Mon Sep 17 00:00:00 2001 From: gohai Date: Fri, 6 Feb 2015 23:16:32 +0100 Subject: [PATCH 07/16] Recompile for armv6 hard float Command used to compile on a current Raspbian: g++ -shared -march=armv6 -mfpu=vfp -mfloat-abi=hard -I/usr/lib/jvm/jdk-7 -oracle-armhf/include -I/usr/lib/jvm/jdk-7-oracle-armhf/include/linux -o libjSSC-2.8_armhf.so jssc.cpp --- src/java/libs/linux/libjSSC-2.8_armhf.so | Bin 10631 -> 23090 bytes 1 file changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 src/java/libs/linux/libjSSC-2.8_armhf.so diff --git a/src/java/libs/linux/libjSSC-2.8_armhf.so b/src/java/libs/linux/libjSSC-2.8_armhf.so old mode 100644 new mode 100755 index 3742fbe08f4313d2b997ce0acaf96dffad5602b4..41680a417ffce8add436f91f2b98caf6dc464f99 GIT binary patch literal 23090 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 From 598c80b7c989b3bfb8f9b822eca24e3383574b29 Mon Sep 17 00:00:00 2001 From: gohai Date: Tue, 11 Apr 2017 14:16:12 +0200 Subject: [PATCH 08/16] Add aarch64 native library This was built with: g++ -shared -I /usr/lib/jdk1.8.0_121/include -I/usr/lib/jdk1.8.0_121/include/linux -o libjSSC-2.8_aarch64.so jssc.cpp --- src/java/libs/linux/libjSSC-2.8_aarch64.so | Bin 0 -> 25176 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100755 src/java/libs/linux/libjSSC-2.8_aarch64.so diff --git a/src/java/libs/linux/libjSSC-2.8_aarch64.so b/src/java/libs/linux/libjSSC-2.8_aarch64.so new file mode 100755 index 0000000000000000000000000000000000000000..38813ae5fa672737415ab07ce4a5912a75665737 GIT binary patch literal 25176 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 I{x|3UzaZ;>)c^nh literal 0 HcmV?d00001 From f6cd08c1433427b8ea60eac8c178e1c3e25f5d2d Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Sat, 8 Jul 2017 12:25:13 +0300 Subject: [PATCH 09/16] refactors getPortProperties, adds Win support to Java code --- src/java/jssc/SerialPortList.java | 30 ++++++++++++++---------------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 38bb20085..452eebe0c 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -353,19 +353,17 @@ else if(portHandle != SerialNativeInterface.ERR_PORT_BUSY) { } public static Map getPortProperties(String portName) { - if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_LINUX) { + int osType = SerialNativeInterface.getOsType(); + if(osType == SerialNativeInterface.OS_LINUX) { return getLinuxPortProperties(portName); - } else if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_MAC_OS_X) { + } else if(osType == SerialNativeInterface.OS_MAC_OS_X || osType == SerialNativeInterface.OS_WINDOWS) { return getNativePortProperties(portName); - } else if(SerialNativeInterface.getOsType() == SerialNativeInterface.OS_WINDOWS){ - // TODO - return new HashMap(); } else { return new HashMap(); } } - public static Map getLinuxPortProperties(String portName) { + private static Map getLinuxPortProperties(String portName) { Map props = new HashMap(); try { // portName has the format /dev/ttyUSB0 @@ -376,19 +374,19 @@ public static Map getLinuxPortProperties(String portName) { String[] sysfsPath = sysfsNode.getCanonicalPath().split("/"); // walk the tree to the root - for (int i=sysfsPath.length-2; 0 < i; i--) { - String curPath = "/"; - for (int j=1; j <= i; j++) { - curPath += sysfsPath[j]+"/"; + for (int i = sysfsPath.length-2; 0 < i; i--) { + StringBuilder curPath = new StringBuilder("/"); + for (int j = 1; j <= i; j++) { + curPath.append(sysfsPath[j]).append("/"); } // look for specific attributes - String[] attribs = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; - for (int j=0; j < attribs.length; j++) { + String[] attributes = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; + for (String attribute : attributes) { try { - Scanner in = new Scanner(new FileReader(curPath+attribs[j])); + Scanner in = new Scanner(new FileReader(curPath + attribute)); // we treat the values just as strings - props.put(attribs[j], in.next()); + props.put(attribute, in.next()); } catch (Exception e) { // ignore the attribute } @@ -405,14 +403,14 @@ public static Map getLinuxPortProperties(String portName) { return props; } - public static Map getNativePortProperties(String portName) { + private static Map getNativePortProperties(String portName) { Map props = new HashMap(); try { // use JNI functions to read those properties String[] names = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; String[] values = SerialNativeInterface.getPortProperties(portName); - for (int i=0; i < names.length; i++) { + for (int i = 0; i < names.length; i++) { if (values[i] != null) { props.put(names[i], values[i]); } From e832aec68b4d48a5c48439bb794a9e6074fd02d2 Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Sat, 8 Jul 2017 12:43:03 +0300 Subject: [PATCH 10/16] adds Win cpp code with getPortProperties support also made a few changes so that MS compiler would be able to compile --- src/cpp/windows/jssc.c++ | 1409 ++++++++++++++++++++++-------------- src/cpp/windows/jssc_win.h | 78 ++ 2 files changed, 935 insertions(+), 552 deletions(-) create mode 100644 src/cpp/windows/jssc_win.h diff --git a/src/cpp/windows/jssc.c++ b/src/cpp/windows/jssc.c++ index 08428ded3..b08b56c39 100644 --- a/src/cpp/windows/jssc.c++ +++ b/src/cpp/windows/jssc.c++ @@ -1,287 +1,289 @@ /* jSSC (Java Simple Serial Connector) - serial port communication library. - * © Alexey Sokolov (scream3r), 2010-2014. - * - * This file is part of jSSC. - * - * jSSC is free software: you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * jSSC is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public License - * along with jSSC. If not, see . - * - * If you use jSSC in public project you can inform me about this by e-mail, - * of course if you want it. - * - * e-mail: scream3r.org@gmail.com - * web-site: http://scream3r.org | http://code.google.com/p/java-simple-serial-connector/ - */ -#include -#include -#include -#include "../jssc_SerialNativeInterface.h" +* © Alexey Sokolov (scream3r), 2010-2014. +* Roman Belkov , 2017 +* +* This file is part of jSSC. +* +* jSSC is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* jSSC is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with jSSC. If not, see . +* +* If you use jSSC in public project you can inform me about this by e-mail, +* of course if you want it. +* +* e-mail: scream3r.org@gmail.com +* web-site: http://scream3r.org | https://github.com/scream3r/java-simple-serial-connector +*/ + +#include +#include +#include -//#include +#include "../jssc_SerialNativeInterface.h" +#include "jssc_win.h" /* - * Get native library version - */ +* Get native library version +*/ JNIEXPORT jstring JNICALL Java_jssc_SerialNativeInterface_getNativeLibraryVersion(JNIEnv *env, jobject object) { - return env->NewStringUTF(jSSC_NATIVE_LIB_VERSION); + return env->NewStringUTF(jSSC_NATIVE_LIB_VERSION); } /* - * Port opening. - * - * In 2.2.0 added useTIOCEXCL (not used in Windows, only for compatibility with _nix version) - */ -JNIEXPORT jlong JNICALL Java_jssc_SerialNativeInterface_openPort(JNIEnv *env, jobject object, jstring portName, jboolean useTIOCEXCL){ - char prefix[] = "\\\\.\\"; - const char* port = env->GetStringUTFChars(portName, JNI_FALSE); - - //since 2.1.0 -> string concat fix - char portFullName[strlen(prefix) + strlen(port) + 1]; - strcpy(portFullName, prefix); - strcat(portFullName, port); - //<- since 2.1.0 - - HANDLE hComm = CreateFile(portFullName, - GENERIC_READ | GENERIC_WRITE, - 0, - 0, - OPEN_EXISTING, - FILE_FLAG_OVERLAPPED, - 0); - env->ReleaseStringUTFChars(portName, port); - - //since 2.3.0 -> - if(hComm != INVALID_HANDLE_VALUE){ - DCB *dcb = new DCB(); - if(!GetCommState(hComm, dcb)){ - CloseHandle(hComm);//since 2.7.0 - hComm = (HANDLE)jssc_SerialNativeInterface_ERR_INCORRECT_SERIAL_PORT;//(-4)Incorrect serial port - } - delete dcb; - } - else { - DWORD errorValue = GetLastError(); - if(errorValue == ERROR_ACCESS_DENIED){ - hComm = (HANDLE)jssc_SerialNativeInterface_ERR_PORT_BUSY;//(-1)Port busy - } - else if(errorValue == ERROR_FILE_NOT_FOUND){ - hComm = (HANDLE)jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND;//(-2)Port not found - } - } - //<- since 2.3.0 - return (jlong)hComm;//since 2.4.0 changed to jlong +* Port opening. +* +* In 2.2.0 added useTIOCEXCL (not used in Windows, only for compatibility with _nix version) +*/ +JNIEXPORT jlong JNICALL Java_jssc_SerialNativeInterface_openPort(JNIEnv *env, jobject object, jstring portName, jboolean useTIOCEXCL) { + char prefix[] = "\\\\.\\"; + const char* port = env->GetStringUTFChars(portName, JNI_FALSE); + + //since 2.1.0 -> string concat fix + char *portFullName = new char[strlen(prefix) + strlen(port) + 1]; + strcpy(portFullName, prefix); + strcat(portFullName, port); + //<- since 2.1.0 + + HANDLE hComm = CreateFile(convertCharArrayToLPCWSTR(portFullName), + GENERIC_READ | GENERIC_WRITE, + 0, + 0, + OPEN_EXISTING, + FILE_FLAG_OVERLAPPED, + 0); + env->ReleaseStringUTFChars(portName, port); + + //since 2.3.0 -> + if (hComm != INVALID_HANDLE_VALUE) { + DCB *dcb = new DCB(); + if (!GetCommState(hComm, dcb)) { + CloseHandle(hComm);//since 2.7.0 + hComm = (HANDLE)jssc_SerialNativeInterface_ERR_INCORRECT_SERIAL_PORT;//(-4)Incorrect serial port + } + delete dcb; + } + else { + DWORD errorValue = GetLastError(); + if (errorValue == ERROR_ACCESS_DENIED) { + hComm = (HANDLE)jssc_SerialNativeInterface_ERR_PORT_BUSY;//(-1)Port busy + } + else if (errorValue == ERROR_FILE_NOT_FOUND) { + hComm = (HANDLE)jssc_SerialNativeInterface_ERR_PORT_NOT_FOUND;//(-2)Port not found + } + } + //<- since 2.3.0 + return (jlong)hComm;//since 2.4.0 changed to jlong }; /* - * Setting serial port params. - * - * In 2.6.0 added flags (not used in Windows, only for compatibility with _nix version) - */ +* Setting serial port params. +* +* In 2.6.0 added flags (not used in Windows, only for compatibility with _nix version) +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setParams - (JNIEnv *env, jobject object, jlong portHandle, jint baudRate, jint byteSize, jint stopBits, jint parity, jboolean setRTS, jboolean setDTR, jint flags){ - HANDLE hComm = (HANDLE)portHandle; - DCB *dcb = new DCB(); - jboolean returnValue = JNI_FALSE; - if(GetCommState(hComm, dcb)){ - dcb->BaudRate = baudRate; - dcb->ByteSize = byteSize; - dcb->StopBits = stopBits; - dcb->Parity = parity; - - //since 0.8 -> - if(setRTS == JNI_TRUE){ - dcb->fRtsControl = RTS_CONTROL_ENABLE; - } - else { - dcb->fRtsControl = RTS_CONTROL_DISABLE; - } - if(setDTR == JNI_TRUE){ - dcb->fDtrControl = DTR_CONTROL_ENABLE; - } - else { - dcb->fDtrControl = DTR_CONTROL_DISABLE; - } - dcb->fOutxCtsFlow = FALSE; - dcb->fOutxDsrFlow = FALSE; - dcb->fDsrSensitivity = FALSE; - dcb->fTXContinueOnXoff = TRUE; - dcb->fOutX = FALSE; - dcb->fInX = FALSE; - dcb->fErrorChar = FALSE; - dcb->fNull = FALSE; - dcb->fAbortOnError = FALSE; - dcb->XonLim = 2048; - dcb->XoffLim = 512; - dcb->XonChar = (char)17; //DC1 - dcb->XoffChar = (char)19; //DC3 - //<- since 0.8 - - if(SetCommState(hComm, dcb)){ - - //since 2.1.0 -> previously setted timeouts by another application should be cleared - COMMTIMEOUTS *lpCommTimeouts = new COMMTIMEOUTS(); - lpCommTimeouts->ReadIntervalTimeout = 0; - lpCommTimeouts->ReadTotalTimeoutConstant = 0; - lpCommTimeouts->ReadTotalTimeoutMultiplier = 0; - lpCommTimeouts->WriteTotalTimeoutConstant = 0; - lpCommTimeouts->WriteTotalTimeoutMultiplier = 0; - if(SetCommTimeouts(hComm, lpCommTimeouts)){ - returnValue = JNI_TRUE; - } - delete lpCommTimeouts; - //<- since 2.1.0 - } - } - delete dcb; - return returnValue; +(JNIEnv *env, jobject object, jlong portHandle, jint baudRate, jint byteSize, jint stopBits, jint parity, jboolean setRTS, jboolean setDTR, jint flags) { + HANDLE hComm = (HANDLE)portHandle; + DCB *dcb = new DCB(); + jboolean returnValue = JNI_FALSE; + if (GetCommState(hComm, dcb)) { + dcb->BaudRate = baudRate; + dcb->ByteSize = byteSize; + dcb->StopBits = stopBits; + dcb->Parity = parity; + + //since 0.8 -> + if (setRTS == JNI_TRUE) { + dcb->fRtsControl = RTS_CONTROL_ENABLE; + } + else { + dcb->fRtsControl = RTS_CONTROL_DISABLE; + } + if (setDTR == JNI_TRUE) { + dcb->fDtrControl = DTR_CONTROL_ENABLE; + } + else { + dcb->fDtrControl = DTR_CONTROL_DISABLE; + } + dcb->fOutxCtsFlow = FALSE; + dcb->fOutxDsrFlow = FALSE; + dcb->fDsrSensitivity = FALSE; + dcb->fTXContinueOnXoff = TRUE; + dcb->fOutX = FALSE; + dcb->fInX = FALSE; + dcb->fErrorChar = FALSE; + dcb->fNull = FALSE; + dcb->fAbortOnError = FALSE; + dcb->XonLim = 2048; + dcb->XoffLim = 512; + dcb->XonChar = (char)17; //DC1 + dcb->XoffChar = (char)19; //DC3 + //<- since 0.8 + + if (SetCommState(hComm, dcb)) { + + //since 2.1.0 -> previously setted timeouts by another application should be cleared + COMMTIMEOUTS *lpCommTimeouts = new COMMTIMEOUTS(); + lpCommTimeouts->ReadIntervalTimeout = 0; + lpCommTimeouts->ReadTotalTimeoutConstant = 0; + lpCommTimeouts->ReadTotalTimeoutMultiplier = 0; + lpCommTimeouts->WriteTotalTimeoutConstant = 0; + lpCommTimeouts->WriteTotalTimeoutMultiplier = 0; + if (SetCommTimeouts(hComm, lpCommTimeouts)) { + returnValue = JNI_TRUE; + } + delete lpCommTimeouts; + //<- since 2.1.0 + } + } + delete dcb; + return returnValue; } /* - * PurgeComm - */ +* PurgeComm +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_purgePort - (JNIEnv *env, jobject object, jlong portHandle, jint flags){ - HANDLE hComm = (HANDLE)portHandle; - DWORD dwFlags = (DWORD)flags; - return (PurgeComm(hComm, dwFlags) ? JNI_TRUE : JNI_FALSE); +(JNIEnv *env, jobject object, jlong portHandle, jint flags) { + HANDLE hComm = (HANDLE)portHandle; + DWORD dwFlags = (DWORD)flags; + return (PurgeComm(hComm, dwFlags) ? JNI_TRUE : JNI_FALSE); } /* - * Port closing - */ +* Port closing +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_closePort - (JNIEnv *env, jobject object, jlong portHandle){ - HANDLE hComm = (HANDLE)portHandle; - return (CloseHandle(hComm) ? JNI_TRUE : JNI_FALSE); +(JNIEnv *env, jobject object, jlong portHandle) { + HANDLE hComm = (HANDLE)portHandle; + return (CloseHandle(hComm) ? JNI_TRUE : JNI_FALSE); } /* - * Set events mask - */ +* Set events mask +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setEventsMask - (JNIEnv *env, jobject object, jlong portHandle, jint mask){ - HANDLE hComm = (HANDLE)portHandle; - DWORD dwEvtMask = (DWORD)mask; - return (SetCommMask(hComm, dwEvtMask) ? JNI_TRUE : JNI_FALSE); +(JNIEnv *env, jobject object, jlong portHandle, jint mask) { + HANDLE hComm = (HANDLE)portHandle; + DWORD dwEvtMask = (DWORD)mask; + return (SetCommMask(hComm, dwEvtMask) ? JNI_TRUE : JNI_FALSE); } /* - * Get events mask - */ +* Get events mask +*/ JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getEventsMask - (JNIEnv *env, jobject object, jlong portHandle){ - HANDLE hComm = (HANDLE)portHandle; - DWORD lpEvtMask; - if(GetCommMask(hComm, &lpEvtMask)){ - return (jint)lpEvtMask; - } - else { - return -1; - } +(JNIEnv *env, jobject object, jlong portHandle) { + HANDLE hComm = (HANDLE)portHandle; + DWORD lpEvtMask; + if (GetCommMask(hComm, &lpEvtMask)) { + return (jint)lpEvtMask; + } + else { + return -1; + } } /* - * Change RTS line state (ON || OFF) - */ +* Change RTS line state (ON || OFF) +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setRTS - (JNIEnv *env, jobject object, jlong portHandle, jboolean enabled){ - HANDLE hComm = (HANDLE)portHandle; - if(enabled == JNI_TRUE){ - return (EscapeCommFunction(hComm, SETRTS) ? JNI_TRUE : JNI_FALSE); - } - else { - return (EscapeCommFunction(hComm, CLRRTS) ? JNI_TRUE : JNI_FALSE); - } +(JNIEnv *env, jobject object, jlong portHandle, jboolean enabled) { + HANDLE hComm = (HANDLE)portHandle; + if (enabled == JNI_TRUE) { + return (EscapeCommFunction(hComm, SETRTS) ? JNI_TRUE : JNI_FALSE); + } + else { + return (EscapeCommFunction(hComm, CLRRTS) ? JNI_TRUE : JNI_FALSE); + } } /* - * Change DTR line state (ON || OFF) - */ +* Change DTR line state (ON || OFF) +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR - (JNIEnv *env, jobject object, jlong portHandle, jboolean enabled){ - HANDLE hComm = (HANDLE)portHandle; - if(enabled == JNI_TRUE){ - return (EscapeCommFunction(hComm, SETDTR) ? JNI_TRUE : JNI_FALSE); - } - else { - return (EscapeCommFunction(hComm, CLRDTR) ? JNI_TRUE : JNI_FALSE); - } +(JNIEnv *env, jobject object, jlong portHandle, jboolean enabled) { + HANDLE hComm = (HANDLE)portHandle; + if (enabled == JNI_TRUE) { + return (EscapeCommFunction(hComm, SETDTR) ? JNI_TRUE : JNI_FALSE); + } + else { + return (EscapeCommFunction(hComm, CLRDTR) ? JNI_TRUE : JNI_FALSE); + } } /* - * Write data to port - * portHandle - port handle - * buffer - byte array for sending - */ +* Write data to port +* portHandle - port handle +* buffer - byte array for sending +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes - (JNIEnv *env, jobject object, jlong portHandle, jbyteArray buffer){ - HANDLE hComm = (HANDLE)portHandle; - DWORD lpNumberOfBytesTransferred; - DWORD lpNumberOfBytesWritten; - OVERLAPPED *overlapped = new OVERLAPPED(); - jboolean returnValue = JNI_FALSE; - jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); - overlapped->hEvent = CreateEventA(NULL, true, false, NULL); - if(WriteFile(hComm, jBuffer, (DWORD)env->GetArrayLength(buffer), &lpNumberOfBytesWritten, overlapped)){ - returnValue = JNI_TRUE; - } - else if(GetLastError() == ERROR_IO_PENDING){ - if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){ - if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){ - returnValue = JNI_TRUE; - } - } - } - env->ReleaseByteArrayElements(buffer, jBuffer, 0); - CloseHandle(overlapped->hEvent); - delete overlapped; - return returnValue; +(JNIEnv *env, jobject object, jlong portHandle, jbyteArray buffer) { + HANDLE hComm = (HANDLE)portHandle; + DWORD lpNumberOfBytesTransferred; + DWORD lpNumberOfBytesWritten; + OVERLAPPED *overlapped = new OVERLAPPED(); + jboolean returnValue = JNI_FALSE; + jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); + overlapped->hEvent = CreateEventA(NULL, true, false, NULL); + if (WriteFile(hComm, jBuffer, (DWORD)env->GetArrayLength(buffer), &lpNumberOfBytesWritten, overlapped)) { + returnValue = JNI_TRUE; + } + else if (GetLastError() == ERROR_IO_PENDING) { + if (WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0) { + if (GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)) { + returnValue = JNI_TRUE; + } + } + } + env->ReleaseByteArrayElements(buffer, jBuffer, 0); + CloseHandle(overlapped->hEvent); + delete overlapped; + return returnValue; } /* - * Read data from port - * portHandle - port handle - * byteCount - count of bytes for reading - */ +* Read data from port +* portHandle - port handle +* byteCount - count of bytes for reading +*/ JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes - (JNIEnv *env, jobject object, jlong portHandle, jint byteCount){ - HANDLE hComm = (HANDLE)portHandle; - DWORD lpNumberOfBytesTransferred; - DWORD lpNumberOfBytesRead; - OVERLAPPED *overlapped = new OVERLAPPED(); - jbyte lpBuffer[byteCount]; - jbyteArray returnArray = env->NewByteArray(byteCount); - overlapped->hEvent = CreateEventA(NULL, true, false, NULL); - if(ReadFile(hComm, lpBuffer, (DWORD)byteCount, &lpNumberOfBytesRead, overlapped)){ - env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer); - } - else if(GetLastError() == ERROR_IO_PENDING){ - if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){ - if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){ - env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer); - } - } - } - CloseHandle(overlapped->hEvent); - delete overlapped; - return returnArray; +(JNIEnv *env, jobject object, jlong portHandle, jint byteCount) { + HANDLE hComm = (HANDLE)portHandle; + DWORD lpNumberOfBytesTransferred; + DWORD lpNumberOfBytesRead; + OVERLAPPED *overlapped = new OVERLAPPED(); + jbyte *lpBuffer = new jbyte [byteCount]; + jbyteArray returnArray = env->NewByteArray(byteCount); + overlapped->hEvent = CreateEventA(NULL, true, false, NULL); + if (ReadFile(hComm, lpBuffer, (DWORD)byteCount, &lpNumberOfBytesRead, overlapped)) { + env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer); + } + else if (GetLastError() == ERROR_IO_PENDING) { + if (WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0) { + if (GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)) { + env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer); + } + } + } + CloseHandle(overlapped->hEvent); + delete overlapped; + return returnArray; } /* - * Get bytes count in serial port buffers (Input and Output) - */ +* Get bytes count in serial port buffers (Input and Output) +*/ JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getBuffersBytesCount - (JNIEnv *env, jobject object, jlong portHandle){ +(JNIEnv *env, jobject object, jlong portHandle) { HANDLE hComm = (HANDLE)portHandle; jint returnValues[2]; returnValues[0] = -1; @@ -289,7 +291,7 @@ JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getBuffersBytesCount jintArray returnArray = env->NewIntArray(2); DWORD lpErrors; COMSTAT *comstat = new COMSTAT(); - if(ClearCommError(hComm, &lpErrors, comstat)){ + if (ClearCommError(hComm, &lpErrors, comstat)) { returnValues[0] = (jint)comstat->cbInQue; returnValues[1] = (jint)comstat->cbOutQue; } @@ -311,35 +313,35 @@ const jint FLOWCONTROL_XONXOFF_OUT = 8; //<- since 0.8 /* - * Setting flow control mode - * - * since 0.8 - */ +* Setting flow control mode +* +* since 0.8 +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setFlowControlMode - (JNIEnv *env, jobject object, jlong portHandle, jint mask){ +(JNIEnv *env, jobject object, jlong portHandle, jint mask) { HANDLE hComm = (HANDLE)portHandle; jboolean returnValue = JNI_FALSE; DCB *dcb = new DCB(); - if(GetCommState(hComm, dcb)){ + if (GetCommState(hComm, dcb)) { dcb->fRtsControl = RTS_CONTROL_ENABLE; dcb->fOutxCtsFlow = FALSE; dcb->fOutX = FALSE; dcb->fInX = FALSE; - if(mask != FLOWCONTROL_NONE){ - if((mask & FLOWCONTROL_RTSCTS_IN) == FLOWCONTROL_RTSCTS_IN){ + if (mask != FLOWCONTROL_NONE) { + if ((mask & FLOWCONTROL_RTSCTS_IN) == FLOWCONTROL_RTSCTS_IN) { dcb->fRtsControl = RTS_CONTROL_HANDSHAKE; } - if((mask & FLOWCONTROL_RTSCTS_OUT) == FLOWCONTROL_RTSCTS_OUT){ + if ((mask & FLOWCONTROL_RTSCTS_OUT) == FLOWCONTROL_RTSCTS_OUT) { dcb->fOutxCtsFlow = TRUE; } - if((mask & FLOWCONTROL_XONXOFF_IN) == FLOWCONTROL_XONXOFF_IN){ + if ((mask & FLOWCONTROL_XONXOFF_IN) == FLOWCONTROL_XONXOFF_IN) { dcb->fInX = TRUE; } - if((mask & FLOWCONTROL_XONXOFF_OUT) == FLOWCONTROL_XONXOFF_OUT){ + if ((mask & FLOWCONTROL_XONXOFF_OUT) == FLOWCONTROL_XONXOFF_OUT) { dcb->fOutX = TRUE; } } - if(SetCommState(hComm, dcb)){ + if (SetCommState(hComm, dcb)) { returnValue = JNI_TRUE; } } @@ -348,26 +350,26 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setFlowControlMode } /* - * Getting flow control mode - * - * since 0.8 - */ +* Getting flow control mode +* +* since 0.8 +*/ JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getFlowControlMode - (JNIEnv *env, jobject object, jlong portHandle){ +(JNIEnv *env, jobject object, jlong portHandle) { HANDLE hComm = (HANDLE)portHandle; jint returnValue = 0; DCB *dcb = new DCB(); - if(GetCommState(hComm, dcb)){ - if(dcb->fRtsControl == RTS_CONTROL_HANDSHAKE){ + if (GetCommState(hComm, dcb)) { + if (dcb->fRtsControl == RTS_CONTROL_HANDSHAKE) { returnValue |= FLOWCONTROL_RTSCTS_IN; } - if(dcb->fOutxCtsFlow == TRUE){ + if (dcb->fOutxCtsFlow == TRUE) { returnValue |= FLOWCONTROL_RTSCTS_OUT; } - if(dcb->fInX == TRUE){ + if (dcb->fInX == TRUE) { returnValue |= FLOWCONTROL_XONXOFF_IN; } - if(dcb->fOutX == TRUE){ + if (dcb->fOutX == TRUE) { returnValue |= FLOWCONTROL_XONXOFF_OUT; } } @@ -376,18 +378,18 @@ JNIEXPORT jint JNICALL Java_jssc_SerialNativeInterface_getFlowControlMode } /* - * Send break for setted duration - * - * since 0.8 - */ +* Send break for setted duration +* +* since 0.8 +*/ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak - (JNIEnv *env, jobject object, jlong portHandle, jint duration){ +(JNIEnv *env, jobject object, jlong portHandle, jint duration) { HANDLE hComm = (HANDLE)portHandle; jboolean returnValue = JNI_FALSE; - if(duration > 0){ - if(SetCommBreak(hComm) > 0){ + if (duration > 0) { + if (SetCommBreak(hComm) > 0) { Sleep(duration); - if(ClearCommBreak(hComm) > 0){ + if (ClearCommBreak(hComm) > 0) { returnValue = JNI_TRUE; } } @@ -396,298 +398,601 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak } /* - * Wait event - * portHandle - port handle - */ +* Wait event +* portHandle - port handle +*/ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_waitEvents - (JNIEnv *env, jobject object, jlong portHandle) { - HANDLE hComm = (HANDLE)portHandle; - DWORD lpEvtMask = 0; - DWORD lpNumberOfBytesTransferred = 0; - OVERLAPPED *overlapped = new OVERLAPPED(); - jclass intClass = env->FindClass("[I"); - jobjectArray returnArray; - boolean functionSuccessful = false; - overlapped->hEvent = CreateEventA(NULL, true, false, NULL); - if(WaitCommEvent(hComm, &lpEvtMask, overlapped)){ - functionSuccessful = true; - } - else if(GetLastError() == ERROR_IO_PENDING){ - if(WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0){ - if(GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)){ - functionSuccessful = true; - } - } - } - if(functionSuccessful){ - boolean executeGetCommModemStatus = false; - boolean executeClearCommError = false; - DWORD events[9];//fixed since 0.8 (old value is 8) - jint eventsCount = 0; - if((EV_BREAK & lpEvtMask) == EV_BREAK){ - events[eventsCount] = EV_BREAK; - eventsCount++; - } - if((EV_CTS & lpEvtMask) == EV_CTS){ - events[eventsCount] = EV_CTS; - eventsCount++; - executeGetCommModemStatus = true; - } - if((EV_DSR & lpEvtMask) == EV_DSR){ - events[eventsCount] = EV_DSR; - eventsCount++; - executeGetCommModemStatus = true; - } - if((EV_ERR & lpEvtMask) == EV_ERR){ - events[eventsCount] = EV_ERR; - eventsCount++; - executeClearCommError = true; - } - if((EV_RING & lpEvtMask) == EV_RING){ - events[eventsCount] = EV_RING; - eventsCount++; - executeGetCommModemStatus = true; - } - if((EV_RLSD & lpEvtMask) == EV_RLSD){ - events[eventsCount] = EV_RLSD; - eventsCount++; - executeGetCommModemStatus = true; - } - if((EV_RXCHAR & lpEvtMask) == EV_RXCHAR){ - events[eventsCount] = EV_RXCHAR; - eventsCount++; - executeClearCommError = true; - } - if((EV_RXFLAG & lpEvtMask) == EV_RXFLAG){ - events[eventsCount] = EV_RXFLAG; - eventsCount++; - executeClearCommError = true; - } - if((EV_TXEMPTY & lpEvtMask) == EV_TXEMPTY){ - events[eventsCount] = EV_TXEMPTY; - eventsCount++; - executeClearCommError = true; - } - /* - * Execute GetCommModemStatus function if it's needed (get lines status) - */ - jint statusCTS = 0; - jint statusDSR = 0; - jint statusRING = 0; - jint statusRLSD = 0; - boolean successGetCommModemStatus = false; - if(executeGetCommModemStatus){ - DWORD lpModemStat; - if(GetCommModemStatus(hComm, &lpModemStat)){ - successGetCommModemStatus = true; - if((MS_CTS_ON & lpModemStat) == MS_CTS_ON){ - statusCTS = 1; - } - if((MS_DSR_ON & lpModemStat) == MS_DSR_ON){ - statusDSR = 1; - } - if((MS_RING_ON & lpModemStat) == MS_RING_ON){ - statusRING = 1; - } - if((MS_RLSD_ON & lpModemStat) == MS_RLSD_ON){ - statusRLSD = 1; - } - } - else { - jint lastError = (jint)GetLastError(); - statusCTS = lastError; - statusDSR = lastError; - statusRING = lastError; - statusRLSD = lastError; - } - } - /* - * Execute ClearCommError function if it's needed (get count of bytes in buffers and errors) - */ - jint bytesCountIn = 0; - jint bytesCountOut = 0; - jint communicationsErrors = 0; - boolean successClearCommError = false; - if(executeClearCommError){ - DWORD lpErrors; - COMSTAT *comstat = new COMSTAT(); - if(ClearCommError(hComm, &lpErrors, comstat)){ - successClearCommError = true; - bytesCountIn = (jint)comstat->cbInQue; - bytesCountOut = (jint)comstat->cbOutQue; - communicationsErrors = (jint)lpErrors; - } - else { - jint lastError = (jint)GetLastError(); - bytesCountIn = lastError; - bytesCountOut = lastError; - communicationsErrors = lastError; - } - delete comstat; - } - /* - * Create int[][] for events values - */ - returnArray = env->NewObjectArray(eventsCount, intClass, NULL); - /* - * Set events values - */ - for(jint i = 0; i < eventsCount; i++){ - jint returnValues[2]; - switch(events[i]){ - case EV_BREAK: - returnValues[0] = (jint)events[i]; - returnValues[1] = 0; - goto forEnd; - case EV_CTS: - returnValues[1] = statusCTS; - goto modemStatus; - case EV_DSR: - returnValues[1] = statusDSR; - goto modemStatus; - case EV_ERR: - returnValues[1] = communicationsErrors; - goto bytesAndErrors; - case EV_RING: - returnValues[1] = statusRING; - goto modemStatus; - case EV_RLSD: - returnValues[1] = statusRLSD; - goto modemStatus; - case EV_RXCHAR: - returnValues[1] = bytesCountIn; - goto bytesAndErrors; - case EV_RXFLAG: - returnValues[1] = bytesCountIn; - goto bytesAndErrors; - case EV_TXEMPTY: - returnValues[1] = bytesCountOut; - goto bytesAndErrors; - default: - returnValues[0] = (jint)events[i]; - returnValues[1] = 0; - goto forEnd; - }; - modemStatus: { - if(successGetCommModemStatus){ - returnValues[0] = (jint)events[i]; - } - else { - returnValues[0] = -1; - } - goto forEnd; - } - bytesAndErrors: { - if(successClearCommError){ - returnValues[0] = (jint)events[i]; - } - else { - returnValues[0] = -1; - } - goto forEnd; - } - forEnd: { - jintArray singleResultArray = env->NewIntArray(2); - env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues); - env->SetObjectArrayElement(returnArray, i, singleResultArray); - }; - } - } - else { - returnArray = env->NewObjectArray(1, intClass, NULL); - jint returnValues[2]; - returnValues[0] = -1; - returnValues[1] = (jint)GetLastError(); - jintArray singleResultArray = env->NewIntArray(2); - env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues); - env->SetObjectArrayElement(returnArray, 0, singleResultArray); - }; - CloseHandle(overlapped->hEvent); - delete overlapped; - return returnArray; +(JNIEnv *env, jobject object, jlong portHandle) { + HANDLE hComm = (HANDLE)portHandle; + DWORD lpEvtMask = 0; + DWORD lpNumberOfBytesTransferred = 0; + OVERLAPPED *overlapped = new OVERLAPPED(); + jclass intClass = env->FindClass("[I"); + jobjectArray returnArray; + boolean functionSuccessful = false; + overlapped->hEvent = CreateEventA(NULL, true, false, NULL); + if (WaitCommEvent(hComm, &lpEvtMask, overlapped)) { + functionSuccessful = true; + } + else if (GetLastError() == ERROR_IO_PENDING) { + if (WaitForSingleObject(overlapped->hEvent, INFINITE) == WAIT_OBJECT_0) { + if (GetOverlappedResult(hComm, overlapped, &lpNumberOfBytesTransferred, false)) { + functionSuccessful = true; + } + } + } + if (functionSuccessful) { + boolean executeGetCommModemStatus = false; + boolean executeClearCommError = false; + DWORD events[9];//fixed since 0.8 (old value is 8) + jint eventsCount = 0; + if ((EV_BREAK & lpEvtMask) == EV_BREAK) { + events[eventsCount] = EV_BREAK; + eventsCount++; + } + if ((EV_CTS & lpEvtMask) == EV_CTS) { + events[eventsCount] = EV_CTS; + eventsCount++; + executeGetCommModemStatus = true; + } + if ((EV_DSR & lpEvtMask) == EV_DSR) { + events[eventsCount] = EV_DSR; + eventsCount++; + executeGetCommModemStatus = true; + } + if ((EV_ERR & lpEvtMask) == EV_ERR) { + events[eventsCount] = EV_ERR; + eventsCount++; + executeClearCommError = true; + } + if ((EV_RING & lpEvtMask) == EV_RING) { + events[eventsCount] = EV_RING; + eventsCount++; + executeGetCommModemStatus = true; + } + if ((EV_RLSD & lpEvtMask) == EV_RLSD) { + events[eventsCount] = EV_RLSD; + eventsCount++; + executeGetCommModemStatus = true; + } + if ((EV_RXCHAR & lpEvtMask) == EV_RXCHAR) { + events[eventsCount] = EV_RXCHAR; + eventsCount++; + executeClearCommError = true; + } + if ((EV_RXFLAG & lpEvtMask) == EV_RXFLAG) { + events[eventsCount] = EV_RXFLAG; + eventsCount++; + executeClearCommError = true; + } + if ((EV_TXEMPTY & lpEvtMask) == EV_TXEMPTY) { + events[eventsCount] = EV_TXEMPTY; + eventsCount++; + executeClearCommError = true; + } + /* + * Execute GetCommModemStatus function if it's needed (get lines status) + */ + jint statusCTS = 0; + jint statusDSR = 0; + jint statusRING = 0; + jint statusRLSD = 0; + boolean successGetCommModemStatus = false; + if (executeGetCommModemStatus) { + DWORD lpModemStat; + if (GetCommModemStatus(hComm, &lpModemStat)) { + successGetCommModemStatus = true; + if ((MS_CTS_ON & lpModemStat) == MS_CTS_ON) { + statusCTS = 1; + } + if ((MS_DSR_ON & lpModemStat) == MS_DSR_ON) { + statusDSR = 1; + } + if ((MS_RING_ON & lpModemStat) == MS_RING_ON) { + statusRING = 1; + } + if ((MS_RLSD_ON & lpModemStat) == MS_RLSD_ON) { + statusRLSD = 1; + } + } + else { + jint lastError = (jint)GetLastError(); + statusCTS = lastError; + statusDSR = lastError; + statusRING = lastError; + statusRLSD = lastError; + } + } + /* + * Execute ClearCommError function if it's needed (get count of bytes in buffers and errors) + */ + jint bytesCountIn = 0; + jint bytesCountOut = 0; + jint communicationsErrors = 0; + boolean successClearCommError = false; + if (executeClearCommError) { + DWORD lpErrors; + COMSTAT *comstat = new COMSTAT(); + if (ClearCommError(hComm, &lpErrors, comstat)) { + successClearCommError = true; + bytesCountIn = (jint)comstat->cbInQue; + bytesCountOut = (jint)comstat->cbOutQue; + communicationsErrors = (jint)lpErrors; + } + else { + jint lastError = (jint)GetLastError(); + bytesCountIn = lastError; + bytesCountOut = lastError; + communicationsErrors = lastError; + } + delete comstat; + } + /* + * Create int[][] for events values + */ + returnArray = env->NewObjectArray(eventsCount, intClass, NULL); + /* + * Set events values + */ + for (jint i = 0; i < eventsCount; i++) { + jint returnValues[2]; + switch (events[i]) { + case EV_BREAK: + returnValues[0] = (jint)events[i]; + returnValues[1] = 0; + goto forEnd; + case EV_CTS: + returnValues[1] = statusCTS; + goto modemStatus; + case EV_DSR: + returnValues[1] = statusDSR; + goto modemStatus; + case EV_ERR: + returnValues[1] = communicationsErrors; + goto bytesAndErrors; + case EV_RING: + returnValues[1] = statusRING; + goto modemStatus; + case EV_RLSD: + returnValues[1] = statusRLSD; + goto modemStatus; + case EV_RXCHAR: + returnValues[1] = bytesCountIn; + goto bytesAndErrors; + case EV_RXFLAG: + returnValues[1] = bytesCountIn; + goto bytesAndErrors; + case EV_TXEMPTY: + returnValues[1] = bytesCountOut; + goto bytesAndErrors; + default: + returnValues[0] = (jint)events[i]; + returnValues[1] = 0; + goto forEnd; + }; + modemStatus: { + if (successGetCommModemStatus) { + returnValues[0] = (jint)events[i]; + } + else { + returnValues[0] = -1; + } + goto forEnd; + } + bytesAndErrors: { + if (successClearCommError) { + returnValues[0] = (jint)events[i]; + } + else { + returnValues[0] = -1; + } + goto forEnd; + } + forEnd: { + jintArray singleResultArray = env->NewIntArray(2); + env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues); + env->SetObjectArrayElement(returnArray, i, singleResultArray); + }; + } + } + else { + returnArray = env->NewObjectArray(1, intClass, NULL); + jint returnValues[2]; + returnValues[0] = -1; + returnValues[1] = (jint)GetLastError(); + jintArray singleResultArray = env->NewIntArray(2); + env->SetIntArrayRegion(singleResultArray, 0, 2, returnValues); + env->SetObjectArrayElement(returnArray, 0, singleResultArray); + }; + CloseHandle(overlapped->hEvent); + delete overlapped; + return returnArray; } /* - * Get serial port names - */ +* Get serial port names +*/ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getSerialPortNames - (JNIEnv *env, jobject object){ - HKEY phkResult; - LPCSTR lpSubKey = "HARDWARE\\DEVICEMAP\\SERIALCOMM\\"; - jobjectArray returnArray = NULL; - if(RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &phkResult) == ERROR_SUCCESS){ - boolean hasMoreElements = true; - DWORD keysCount = 0; - char valueName[256]; - DWORD valueNameSize; - DWORD enumResult; - while(hasMoreElements){ - valueNameSize = 256; - enumResult = RegEnumValueA(phkResult, keysCount, valueName, &valueNameSize, NULL, NULL, NULL, NULL); - if(enumResult == ERROR_SUCCESS){ - keysCount++; - } - else if(enumResult == ERROR_NO_MORE_ITEMS){ - hasMoreElements = false; - } - else { - hasMoreElements = false; - } - } - if(keysCount > 0){ - jclass stringClass = env->FindClass("java/lang/String"); - returnArray = env->NewObjectArray((jsize)keysCount, stringClass, NULL); - char lpValueName[256]; - DWORD lpcchValueName; - byte lpData[256]; - DWORD lpcbData; - DWORD result; - for(DWORD i = 0; i < keysCount; i++){ - lpcchValueName = 256; - lpcbData = 256; - result = RegEnumValueA(phkResult, i, lpValueName, &lpcchValueName, NULL, NULL, lpData, &lpcbData); - if(result == ERROR_SUCCESS){ - env->SetObjectArrayElement(returnArray, i, env->NewStringUTF((char*)lpData)); - } - } - } - CloseHandle(phkResult); - } - return returnArray; +(JNIEnv *env, jobject object) { + HKEY phkResult; + LPCSTR lpSubKey = "HARDWARE\\DEVICEMAP\\SERIALCOMM\\"; + jobjectArray returnArray = NULL; + if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, lpSubKey, 0, KEY_READ, &phkResult) == ERROR_SUCCESS) { + boolean hasMoreElements = true; + DWORD keysCount = 0; + char valueName[256]; + DWORD valueNameSize; + DWORD enumResult; + while (hasMoreElements) { + valueNameSize = 256; + enumResult = RegEnumValueA(phkResult, keysCount, valueName, &valueNameSize, NULL, NULL, NULL, NULL); + if (enumResult == ERROR_SUCCESS) { + keysCount++; + } + else if (enumResult == ERROR_NO_MORE_ITEMS) { + hasMoreElements = false; + } + else { + hasMoreElements = false; + } + } + if (keysCount > 0) { + jclass stringClass = env->FindClass("java/lang/String"); + returnArray = env->NewObjectArray((jsize)keysCount, stringClass, NULL); + char lpValueName[256]; + DWORD lpcchValueName; + byte lpData[256]; + DWORD lpcbData; + DWORD result; + for (DWORD i = 0; i < keysCount; i++) { + lpcchValueName = 256; + lpcbData = 256; + result = RegEnumValueA(phkResult, i, lpValueName, &lpcchValueName, NULL, NULL, lpData, &lpcbData); + if (result == ERROR_SUCCESS) { + env->SetObjectArrayElement(returnArray, i, env->NewStringUTF((char*)lpData)); + } + } + } + CloseHandle(phkResult); + } + return returnArray; } /* - * Get lines status - * - * returnValues[0] - CTS - * returnValues[1] - DSR - * returnValues[2] - RING - * returnValues[3] - RLSD - * - */ +* Get lines status +* +* returnValues[0] - CTS +* returnValues[1] - DSR +* returnValues[2] - RING +* returnValues[3] - RLSD +* +*/ JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus - (JNIEnv *env, jobject object, jlong portHandle){ - HANDLE hComm = (HANDLE)portHandle; - DWORD lpModemStat; - jint returnValues[4]; - for(jint i = 0; i < 4; i++){ - returnValues[i] = 0; - } - jintArray returnArray = env->NewIntArray(4); - if(GetCommModemStatus(hComm, &lpModemStat)){ - if((MS_CTS_ON & lpModemStat) == MS_CTS_ON){ - returnValues[0] = 1; - } - if((MS_DSR_ON & lpModemStat) == MS_DSR_ON){ - returnValues[1] = 1; - } - if((MS_RING_ON & lpModemStat) == MS_RING_ON){ - returnValues[2] = 1; - } - if((MS_RLSD_ON & lpModemStat) == MS_RLSD_ON){ - returnValues[3] = 1; - } - } - env->SetIntArrayRegion(returnArray, 0, 4, returnValues); - return returnArray; +(JNIEnv *env, jobject object, jlong portHandle) { + HANDLE hComm = (HANDLE)portHandle; + DWORD lpModemStat; + jint returnValues[4]; + for (jint i = 0; i < 4; i++) { + returnValues[i] = 0; + } + jintArray returnArray = env->NewIntArray(4); + if (GetCommModemStatus(hComm, &lpModemStat)) { + if ((MS_CTS_ON & lpModemStat) == MS_CTS_ON) { + returnValues[0] = 1; + } + if ((MS_DSR_ON & lpModemStat) == MS_DSR_ON) { + returnValues[1] = 1; + } + if ((MS_RING_ON & lpModemStat) == MS_RING_ON) { + returnValues[2] = 1; + } + if ((MS_RLSD_ON & lpModemStat) == MS_RLSD_ON) { + returnValues[3] = 1; + } + } + env->SetIntArrayRegion(returnArray, 0, 4, returnValues); + return returnArray; +} + +JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties +(JNIEnv *env, jclass cls, jstring portName) { + std::wstring wantedPortName = convertCharArrayToLPCWSTR((const char*)env->GetStringUTFChars(portName, NULL)); + jclass stringClass = env->FindClass("Ljava/lang/String;"); + int itemsCount = 5; + int retPos = 0; + jobjectArray ret = env->NewObjectArray(itemsCount, stringClass, NULL); + + std::vector ports; + + static const struct { + GUID guid; DWORD flags; + } setupTokens[] = { + { GUID_DEVCLASS_PORTS, DIGCF_PRESENT }, + { GUID_DEVCLASS_MODEM, DIGCF_PRESENT }, + { GUID_DEVINTERFACE_COMPORT, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE }, + { GUID_DEVINTERFACE_MODEM, DIGCF_PRESENT | DIGCF_DEVICEINTERFACE } + }; + + enum { SetupTokensCount = sizeof(setupTokens) / sizeof(setupTokens[0]) }; + + for (int i = 0; i < SetupTokensCount; ++i) { + const HDEVINFO deviceInfoSet = ::SetupDiGetClassDevs(&setupTokens[i].guid, nullptr, nullptr, setupTokens[i].flags); + if (deviceInfoSet == INVALID_HANDLE_VALUE) + return ret; + + SP_DEVINFO_DATA deviceInfoData; + ::memset(&deviceInfoData, 0, sizeof(deviceInfoData)); + deviceInfoData.cbSize = sizeof(deviceInfoData); + + DWORD index = 0; + while (::SetupDiEnumDeviceInfo(deviceInfoSet, index++, &deviceInfoData)) { + const std::wstring devicePort = devicePortName(deviceInfoSet, &deviceInfoData); + if (devicePort.empty() || (devicePort.find(L"LPT") != std::string::npos) || devicePort.compare(wantedPortName) != 0) + continue; + + if (anyOfPorts(ports, devicePort)) + continue; + + const std::wstring instanceIdentifier = deviceInstanceIdentifier(deviceInfoData.DevInst); + + bool ok = false; + const uint16_t productIdentifier = + deviceProductIdentifier(instanceIdentifier, ok); + addWStringToJavaArray(env, ret, retPos, intToString(instanceIdentifier)); + retPos++; + + ok = false; + const uint16_t vendorIdentifier = + deviceVendorIdentifier(instanceIdentifier, ok); + addWStringToJavaArray(env, ret, retPos, intToString(vendorIdentifier)); + retPos++; + + const std::wstring manufacturer = deviceManufacturer(deviceInfoSet, &deviceInfoData); + addWStringToJavaArray(env, ret, retPos, manufacturer); + retPos++; + + const std::wstring description = deviceDescription(deviceInfoSet, &deviceInfoData); + addWStringToJavaArray(env, ret, retPos, description); + retPos++; + + const std::wstring serialNumber = deviceSerialNumber(instanceIdentifier, deviceInfoData.DevInst); + addWStringToJavaArray(env, ret, retPos, serialNumber); + retPos++; + + ports.push_back(devicePort); + } + ::SetupDiDestroyDeviceInfoList(deviceInfoSet); + } + return ret; +} + +static std::wstring deviceRegistryProperty(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData, + DWORD property) { + + DWORD dataType = 0; + std::vector outputBuffer(MAX_PATH + 1, 0); + DWORD bytesRequired = MAX_PATH; + for (;;) { + if (::SetupDiGetDeviceRegistryProperty(deviceInfoSet, deviceInfoData, property, &dataType, + reinterpret_cast(&outputBuffer[0]), + bytesRequired, &bytesRequired)) { + break; + } + + if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER + || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) { + return NULL; + } + outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0); + } + return std::wstring(outputBuffer.begin(), outputBuffer.end()); +} +static std::wstring deviceDescription(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData) { + return deviceRegistryProperty(deviceInfoSet, deviceInfoData, SPDRP_DEVICEDESC); +} + +static std::wstring deviceManufacturer(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData) { + return deviceRegistryProperty(deviceInfoSet, deviceInfoData, SPDRP_MFG); +} + +static std::wstring deviceInstanceIdentifier(DEVINST deviceInstanceNumber) { + std::vector outputBuffer(MAX_DEVICE_ID_LEN + 1, 0); + if (::CM_Get_Device_ID( + deviceInstanceNumber, + &outputBuffer[0], + MAX_DEVICE_ID_LEN, + 0) != CR_SUCCESS) { + return NULL; + } + return std::wstring(outputBuffer.begin(), outputBuffer.end()); +} + +static DEVINST parentDeviceInstanceNumber(DEVINST childDeviceInstanceNumber) { + ULONG nodeStatus = 0; + ULONG problemNumber = 0; + if (::CM_Get_DevNode_Status(&nodeStatus, &problemNumber, + childDeviceInstanceNumber, 0) != CR_SUCCESS) { + return 0; + } + DEVINST parentInstanceNumber = 0; + if (::CM_Get_Parent(&parentInstanceNumber, childDeviceInstanceNumber, 0) != CR_SUCCESS) + return 0; + return parentInstanceNumber; +} + +static std::wstring parseDeviceSerialNumber(const std::wstring &instanceIdentifier) { + int firstbound = instanceIdentifier.rfind('\\'); + int lastbound = instanceIdentifier.find('_', firstbound); + if (instanceIdentifier.find(L"USB\\") == 0) { + if (lastbound != instanceIdentifier.size() - 3) + lastbound = instanceIdentifier.size(); + int ampersand = instanceIdentifier.find('&', firstbound); + if (ampersand != -1 && ampersand < lastbound) + return NULL; + } + else if (instanceIdentifier.find(L"FTDIBUS\\") == 0) { + firstbound = instanceIdentifier.rfind('+'); + lastbound = instanceIdentifier.find('\\', firstbound); + if (lastbound == -1) + return NULL; + } + else { + return NULL; + } + + return instanceIdentifier.substr(firstbound + 1, lastbound - firstbound - 1); +} + +static std::wstring deviceSerialNumber(std::wstring instanceIdentifier, + DEVINST deviceInstanceNumber) { + for (;;) { + const std::wstring result = parseDeviceSerialNumber(instanceIdentifier); + if (!result.empty()) + return result; + deviceInstanceNumber = parentDeviceInstanceNumber(deviceInstanceNumber); + if (deviceInstanceNumber == 0) + break; + instanceIdentifier = deviceInstanceIdentifier(deviceInstanceNumber); + if (instanceIdentifier.empty()) + break; + } + + return NULL; +} + +static uint16_t parseDeviceIdentifier(const std::wstring &instanceIdentifier, + const std::wstring &identifierPrefix, + int identifierSize, bool &ok) { + + uint16_t result; + const int index = instanceIdentifier.find(identifierPrefix); + if (index == -1) + return uint16_t(0); + try + { + result = std::stoi(instanceIdentifier.substr(index + identifierPrefix.size(), identifierSize), nullptr, 16); + ok = true; + } + catch (std::invalid_argument const & ex) + { + ok = false; + } + catch (std::out_of_range const & ex) + { + ok = false; + } + return result; +} + +static uint16_t deviceVendorIdentifier(const std::wstring &instanceIdentifier, bool &ok) { + static const int vendorIdentifierSize = 4; + uint16_t result = parseDeviceIdentifier( + instanceIdentifier, L"VID_", vendorIdentifierSize, ok); + if (!ok) + result = parseDeviceIdentifier( + instanceIdentifier, L"VEN_", vendorIdentifierSize, ok); + return result; +} + +static uint16_t deviceProductIdentifier(const std::wstring &instanceIdentifier, bool &ok) { + static const int productIdentifierSize = 4; + uint16_t result = parseDeviceIdentifier( + instanceIdentifier, L"PID_", productIdentifierSize, ok); + if (!ok) + result = parseDeviceIdentifier( + instanceIdentifier, L"DEV_", productIdentifierSize, ok); + return result; +} + +static bool anyOfPorts(const std::vector &ports, const std::wstring &portName) { + const auto end = ports.end(); + auto isPortNamesEquals = [&portName](const std::wstring &port) { + return port == portName; + }; + return std::find_if(ports.begin(), end, isPortNamesEquals) != end; +} + +static std::wstring devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) { + const HKEY key = ::SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, + 0, DIREG_DEV, KEY_READ); + if (key == INVALID_HANDLE_VALUE) + return NULL; + + static const wchar_t * const keyTokens[] = { + L"PortName\0", + L"PortNumber\0" + }; + + enum { KeyTokensCount = sizeof(keyTokens) / sizeof(keyTokens[0]) }; + + std::wstring portName; + for (int i = 0; i < KeyTokensCount; ++i) { + DWORD dataType = 0; + std::vector outputBuffer(MAX_PATH + 1, 0); + DWORD bytesRequired = MAX_PATH; + for (;;) { + const LONG ret = ::RegQueryValueEx(key, keyTokens[i], nullptr, &dataType, + reinterpret_cast(&outputBuffer[0]), &bytesRequired); + if (ret == ERROR_MORE_DATA) { + outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0); + continue; + } + else if (ret == ERROR_SUCCESS) { + if (dataType == REG_SZ) + portName = std::wstring(outputBuffer.begin(), outputBuffer.end()); + else if (dataType == REG_DWORD) + portName = L"COM" + std::to_wstring(DWORD(&outputBuffer[0])); + } + break; + } + + if (!portName.empty()) + break; + } + ::RegCloseKey(key); + return portName; +} + +// std::wstring to jstring +static jstring wstr2jstr(JNIEnv *env, std::wstring cstr) { + jstring result = nullptr; + try + { + int len = cstr.size(); + jchar* raw = new jchar[len]; + memcpy(raw, cstr.c_str(), len * sizeof(wchar_t)); + result = env->NewString(raw, len); + delete[] raw; + return result; + } + catch (const std::exception ex) + { + // TODO + //std::wcout << L"EXCEPTION in wsz2jstr translating string input " << cstr << std::endl; + //cout << "exception: " << ex.what() << std::endl; + } + + return result; +} + +static wchar_t *convertCharArrayToLPCWSTR(const char* charArray) { + wchar_t* wString = new wchar_t[4096]; + MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096); + return wString; +} + +static void addWStringToJavaArray(JNIEnv *env, jobjectArray objArray, int pos, std::wstring str) { + jstring tmp = wstr2jstr(env, str); + env->SetObjectArrayElement(objArray, 0, tmp); + env->DeleteLocalRef(tmp); +} + +template std::wstring intToString(I num) { + std::wstringstream sstream; + sstream << std::hex << num; + std::wstring result = sstream.str(); + return result; } diff --git a/src/cpp/windows/jssc_win.h b/src/cpp/windows/jssc_win.h new file mode 100644 index 000000000..34158cb18 --- /dev/null +++ b/src/cpp/windows/jssc_win.h @@ -0,0 +1,78 @@ +/* jSSC (Java Simple Serial Connector) - serial port communication library. +* Roman Belkov , 2017 +* +* This file is part of jSSC. +* +* jSSC is free software: you can redistribute it and/or modify +* it under the terms of the GNU Lesser General Public License as published by +* the Free Software Foundation, either version 3 of the License, or +* (at your option) any later version. +* +* jSSC is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public License +* along with jSSC. If not, see . +* +* If you use jSSC in public project you can inform me about this by e-mail, +* of course if you want it. +* +* e-mail: scream3r.org@gmail.com +* web-site: http://scream3r.org | https://github.com/scream3r/java-simple-serial-connector +*/ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +static std::wstring deviceRegistryProperty(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData, + DWORD property); + +static std::wstring deviceDescription(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData); + +static std::wstring deviceManufacturer(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData); + +static std::wstring deviceInstanceIdentifier(DEVINST deviceInstanceNumber); + +static DEVINST parentDeviceInstanceNumber(DEVINST childDeviceInstanceNumber); + +static std::wstring parseDeviceSerialNumber(const std::wstring &instanceIdentifier); + +static std::wstring deviceSerialNumber(std::wstring instanceIdentifier, + DEVINST deviceInstanceNumber); + +static uint16_t parseDeviceIdentifier(const std::wstring &instanceIdentifier, + const std::wstring &identifierPrefix, + int identifierSize, bool &ok); + +static uint16_t deviceVendorIdentifier(const std::wstring &instanceIdentifier, bool &ok); + +static uint16_t deviceProductIdentifier(const std::wstring &instanceIdentifier, bool &ok); + +static bool anyOfPorts(const std::vector &ports, const std::wstring &portName); + +static std::wstring devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData); + +// std::wstring to jstring +static jstring wstr2jstr(JNIEnv *env, std::wstring cstr); + +static wchar_t *convertCharArrayToLPCWSTR(const char* charArray); + +static void addWStringToJavaArray(JNIEnv *env, jobjectArray objArray, int pos, std::wstring str); + +template std::wstring intToString(I num); \ No newline at end of file From f6944b1d638d50fd2e985369406ab3acb1e50639 Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Mon, 10 Jul 2017 15:26:42 +0300 Subject: [PATCH 11/16] multiple fixes for Win native getPortProperties --- src/cpp/windows/jssc.c++ | 75 ++++++++++++++++++++++++++++---------- src/cpp/windows/jssc_win.h | 5 ++- 2 files changed, 58 insertions(+), 22 deletions(-) diff --git a/src/cpp/windows/jssc.c++ b/src/cpp/windows/jssc.c++ index b08b56c39..2a811a8fb 100644 --- a/src/cpp/windows/jssc.c++ +++ b/src/cpp/windows/jssc.c++ @@ -27,6 +27,7 @@ #include #include #include +#include #include "../jssc_SerialNativeInterface.h" #include "jssc_win.h" @@ -42,25 +43,23 @@ JNIEXPORT jstring JNICALL Java_jssc_SerialNativeInterface_getNativeLibraryVersio * Port opening. * * In 2.2.0 added useTIOCEXCL (not used in Windows, only for compatibility with _nix version) +* Usage of wstring added by Roman Belkov in post-2.8.0 */ JNIEXPORT jlong JNICALL Java_jssc_SerialNativeInterface_openPort(JNIEnv *env, jobject object, jstring portName, jboolean useTIOCEXCL) { - char prefix[] = "\\\\.\\"; - const char* port = env->GetStringUTFChars(portName, JNI_FALSE); + const std::wstring prefix = L"\\\\.\\"; + //const char* port = env->GetStringUTFChars(portName, JNI_FALSE); + const std::wstring port = jstr2wstr(env, portName); - //since 2.1.0 -> string concat fix - char *portFullName = new char[strlen(prefix) + strlen(port) + 1]; - strcpy(portFullName, prefix); - strcat(portFullName, port); - //<- since 2.1.0 + std::wstring portFullName = std::wstring(prefix); + portFullName += port; - HANDLE hComm = CreateFile(convertCharArrayToLPCWSTR(portFullName), + HANDLE hComm = CreateFile(portFullName.c_str(), GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0); - env->ReleaseStringUTFChars(portName, port); //since 2.3.0 -> if (hComm != INVALID_HANDLE_VALUE) { @@ -694,9 +693,25 @@ JNIEXPORT jintArray JNICALL Java_jssc_SerialNativeInterface_getLinesStatus return returnArray; } +/* +* Gets properties of given port +* +* Returns a string array of port's properties +* +* ret[0] - product ID (in hex) +* ret[1] - vendor ID (in hex) +* ret[2] - manufacturer +* ret[3] - description +* ret[4] - serial number +* +* NOTE: parts of this code are based on Qt's serialport. +* Since JSSC is already LGPL-licensed, this does not seem like a violation of LGPL rules +* +*/ + JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties (JNIEnv *env, jclass cls, jstring portName) { - std::wstring wantedPortName = convertCharArrayToLPCWSTR((const char*)env->GetStringUTFChars(portName, NULL)); + std::wstring wantedPortName = jstr2wstr(env, portName); jclass stringClass = env->FindClass("Ljava/lang/String;"); int itemsCount = 5; int retPos = 0; @@ -726,7 +741,7 @@ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties DWORD index = 0; while (::SetupDiEnumDeviceInfo(deviceInfoSet, index++, &deviceInfoData)) { - const std::wstring devicePort = devicePortName(deviceInfoSet, &deviceInfoData); + const std::wstring devicePort = std::wstring(devicePortName(deviceInfoSet, &deviceInfoData).c_str()); if (devicePort.empty() || (devicePort.find(L"LPT") != std::string::npos) || devicePort.compare(wantedPortName) != 0) continue; @@ -738,7 +753,7 @@ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties bool ok = false; const uint16_t productIdentifier = deviceProductIdentifier(instanceIdentifier, ok); - addWStringToJavaArray(env, ret, retPos, intToString(instanceIdentifier)); + addWStringToJavaArray(env, ret, retPos, intToString(productIdentifier)); retPos++; ok = false; @@ -747,15 +762,15 @@ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties addWStringToJavaArray(env, ret, retPos, intToString(vendorIdentifier)); retPos++; - const std::wstring manufacturer = deviceManufacturer(deviceInfoSet, &deviceInfoData); + const std::wstring manufacturer = trimAfterFirstNull(deviceManufacturer(deviceInfoSet, &deviceInfoData)); addWStringToJavaArray(env, ret, retPos, manufacturer); retPos++; - const std::wstring description = deviceDescription(deviceInfoSet, &deviceInfoData); + const std::wstring description = trimAfterFirstNull(deviceDescription(deviceInfoSet, &deviceInfoData)); addWStringToJavaArray(env, ret, retPos, description); retPos++; - const std::wstring serialNumber = deviceSerialNumber(instanceIdentifier, deviceInfoData.DevInst); + const std::wstring serialNumber = trimAfterFirstNull(deviceSerialNumber(instanceIdentifier, deviceInfoData.DevInst)); addWStringToJavaArray(env, ret, retPos, serialNumber); retPos++; @@ -766,6 +781,10 @@ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties return ret; } +/* +* Functions below are helper methods. Mainly they are for getSerialPorts (as of 10.07.2017) +*/ + static std::wstring deviceRegistryProperty(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData, DWORD property) { @@ -978,15 +997,31 @@ static jstring wstr2jstr(JNIEnv *env, std::wstring cstr) { return result; } -static wchar_t *convertCharArrayToLPCWSTR(const char* charArray) { - wchar_t* wString = new wchar_t[4096]; - MultiByteToWideChar(CP_ACP, 0, charArray, -1, wString, 4096); - return wString; +static std::wstring jstr2wstr(JNIEnv *env, jstring string) +{ + std::wstring value; + + const jchar *raw = env->GetStringChars(string, 0); + jsize len = env->GetStringLength(string); + + value.assign(raw, raw + len); + + env->ReleaseStringChars(string, raw); + + return value; +} + +static std::wstring trimAfterFirstNull(std::wstring str) { + size_t index = str.find_first_of(L'\0'); + if (index != std::string::npos) { + str.erase(index, str.length()); + } + return str; } static void addWStringToJavaArray(JNIEnv *env, jobjectArray objArray, int pos, std::wstring str) { jstring tmp = wstr2jstr(env, str); - env->SetObjectArrayElement(objArray, 0, tmp); + env->SetObjectArrayElement(objArray, pos, tmp); env->DeleteLocalRef(tmp); } diff --git a/src/cpp/windows/jssc_win.h b/src/cpp/windows/jssc_win.h index 34158cb18..7e2dfc438 100644 --- a/src/cpp/windows/jssc_win.h +++ b/src/cpp/windows/jssc_win.h @@ -68,10 +68,11 @@ static bool anyOfPorts(const std::vector &ports, const std::wstrin static std::wstring devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData); -// std::wstring to jstring static jstring wstr2jstr(JNIEnv *env, std::wstring cstr); -static wchar_t *convertCharArrayToLPCWSTR(const char* charArray); +std::wstring jstr2wstr(JNIEnv *env, jstring string); + +static std::wstring trimAfterFirstNull(std::wstring str); static void addWStringToJavaArray(JNIEnv *env, jobjectArray objArray, int pos, std::wstring str); From fcaf44c80c34c0b859870a9beff9e54dd3a805dd Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Mon, 10 Jul 2017 15:32:18 +0300 Subject: [PATCH 12/16] adds new Win .dll's with getSerialPortProperties Compiled in MSVC 2017. Needs to add setupapi.lib for linker & give path to JDK includes. --- src/java/libs/windows/jSSC-2.8_x86.dll | Bin 67072 -> 37376 bytes src/java/libs/windows/jSSC-2.8_x86_64.dll | Bin 122880 -> 45568 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/src/java/libs/windows/jSSC-2.8_x86.dll b/src/java/libs/windows/jSSC-2.8_x86.dll index 8ff7541a02b896b3ec9c151875ad04570ffaa306..b097fad7283d9327e811538286ad1e98f746789c 100644 GIT binary patch literal 37376 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 diff --git a/src/java/libs/windows/jSSC-2.8_x86_64.dll b/src/java/libs/windows/jSSC-2.8_x86_64.dll index d4e19e069ffb54a74a00dd10f1108dcc0b5a5d06..abc1e0ade76c76361408c48b1dd9a0d522d12d29 100644 GIT binary patch literal 45568 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 literal 122880 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

TZf%ad_#p0qV5L9BgPsgvWAa8 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 CohQct From 647731c0776aadf7428153f8e92cce72baec10a6 Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Mon, 10 Jul 2017 17:29:38 +0300 Subject: [PATCH 13/16] Adds 230400 baudrate to available rates Tested on Win & Linux --- src/java/jssc/SerialPort.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java/jssc/SerialPort.java b/src/java/jssc/SerialPort.java index e5f43b402..3344f0f22 100644 --- a/src/java/jssc/SerialPort.java +++ b/src/java/jssc/SerialPort.java @@ -58,6 +58,7 @@ public class SerialPort { public static final int BAUDRATE_57600 = 57600; public static final int BAUDRATE_115200 = 115200; public static final int BAUDRATE_128000 = 128000; + public static final int BAUDRATE_230400 = 230400; public static final int BAUDRATE_256000 = 256000; From 0f0851d63f3eeec27209d398818c3303f8fed3d1 Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Thu, 27 Jul 2017 16:18:19 +0300 Subject: [PATCH 14/16] reads string instead of just part before the first space in LinuxPortProps --- src/java/jssc/SerialPortList.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 452eebe0c..5ce7bfff8 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -385,6 +385,7 @@ private static Map getLinuxPortProperties(String portName) { for (String attribute : attributes) { try { Scanner in = new Scanner(new FileReader(curPath + attribute)); + in.useDelimiter(System.getProperty("line.separator")); // we treat the values just as strings props.put(attribute, in.next()); } catch (Exception e) { From 794b114166196cf9ae727908ea735a9832cc0705 Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Wed, 2 Aug 2017 13:32:31 +0300 Subject: [PATCH 15/16] Adds Windows provided by bus description to port properties It appeared, that if you change device description (CP2102 in my case), you'll still get default description given by Windows where the new, changed device description is expected. Luckily, in Windows 7 and above there is a way to do so. Note that this commit will probably break everything on XP & Vista. --- src/cpp/windows/jssc.c++ | 31 +++++++++++++++++++++- src/cpp/windows/jssc_win.h | 3 +++ src/java/jssc/SerialPortList.java | 8 +++++- src/java/libs/windows/jSSC-2.8_x86.dll | Bin 37376 -> 38400 bytes src/java/libs/windows/jSSC-2.8_x86_64.dll | Bin 45568 -> 47104 bytes 5 files changed, 40 insertions(+), 2 deletions(-) diff --git a/src/cpp/windows/jssc.c++ b/src/cpp/windows/jssc.c++ index 2a811a8fb..e9d5a7fba 100644 --- a/src/cpp/windows/jssc.c++ +++ b/src/cpp/windows/jssc.c++ @@ -32,6 +32,8 @@ #include "../jssc_SerialNativeInterface.h" #include "jssc_win.h" +#include + /* * Get native library version */ @@ -713,7 +715,7 @@ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties (JNIEnv *env, jclass cls, jstring portName) { std::wstring wantedPortName = jstr2wstr(env, portName); jclass stringClass = env->FindClass("Ljava/lang/String;"); - int itemsCount = 5; + int itemsCount = 6; int retPos = 0; jobjectArray ret = env->NewObjectArray(itemsCount, stringClass, NULL); @@ -770,6 +772,10 @@ JNIEXPORT jobjectArray JNICALL Java_jssc_SerialNativeInterface_getPortProperties addWStringToJavaArray(env, ret, retPos, description); retPos++; + const std::wstring busProvidedDesc = trimAfterFirstNull(busProvidedDescription(deviceInfoSet, &deviceInfoData)); + addWStringToJavaArray(env, ret, retPos, busProvidedDesc); + retPos++; + const std::wstring serialNumber = trimAfterFirstNull(deviceSerialNumber(instanceIdentifier, deviceInfoData.DevInst)); addWStringToJavaArray(env, ret, retPos, serialNumber); retPos++; @@ -807,6 +813,29 @@ static std::wstring deviceRegistryProperty(HDEVINFO deviceInfoSet, } return std::wstring(outputBuffer.begin(), outputBuffer.end()); } + +static std::wstring busProvidedDescription(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData) +{ + DWORD dataType = 0; + std::vector outputBuffer(MAX_PATH + 1, 0); + DWORD bytesRequired = MAX_PATH; + for (;;) { + if (::SetupDiGetDeviceProperty(deviceInfoSet, deviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc, &dataType, + reinterpret_cast(&outputBuffer[0]), + bytesRequired, &bytesRequired, 0)) { + break; + } + + if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER + || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) { + return NULL; + } + outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0); + } + return std::wstring(outputBuffer.begin(), outputBuffer.end()); +} + static std::wstring deviceDescription(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData) { return deviceRegistryProperty(deviceInfoSet, deviceInfoData, SPDRP_DEVICEDESC); diff --git a/src/cpp/windows/jssc_win.h b/src/cpp/windows/jssc_win.h index 7e2dfc438..5056e3555 100644 --- a/src/cpp/windows/jssc_win.h +++ b/src/cpp/windows/jssc_win.h @@ -44,6 +44,9 @@ static std::wstring deviceRegistryProperty(HDEVINFO deviceInfoSet, static std::wstring deviceDescription(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData); +static std::wstring busProvidedDescription(HDEVINFO deviceInfoSet, + PSP_DEVINFO_DATA deviceInfoData); + static std::wstring deviceManufacturer(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA deviceInfoData); diff --git a/src/java/jssc/SerialPortList.java b/src/java/jssc/SerialPortList.java index 5ce7bfff8..21aed25cc 100644 --- a/src/java/jssc/SerialPortList.java +++ b/src/java/jssc/SerialPortList.java @@ -407,8 +407,14 @@ private static Map getLinuxPortProperties(String portName) { private static Map getNativePortProperties(String portName) { Map props = new HashMap(); try { + String[] names; + if (SerialNativeInterface.getOsType() == SerialNativeInterface.OS_WINDOWS) { + names = new String[] { "idProduct", "idVendor", "manufacturer", "product", "busProvidedProduct", "serial" }; + } else { + names = new String[] { "idProduct", "idVendor", "manufacturer", "product", "serial" }; + } + // use JNI functions to read those properties - String[] names = { "idProduct", "idVendor", "manufacturer", "product", "serial" }; String[] values = SerialNativeInterface.getPortProperties(portName); for (int i = 0; i < names.length; i++) { diff --git a/src/java/libs/windows/jSSC-2.8_x86.dll b/src/java/libs/windows/jSSC-2.8_x86.dll index b097fad7283d9327e811538286ad1e98f746789c..a6c54119b94d6898556e5c35193d68572b988d7f 100644 GIT binary patch delta 8829 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 diff --git a/src/java/libs/windows/jSSC-2.8_x86_64.dll b/src/java/libs/windows/jSSC-2.8_x86_64.dll index abc1e0ade76c76361408c48b1dd9a0d522d12d29..1c40908677254f7d2501fb61b03d48d90ef04b5d 100644 GIT binary patch delta 15198 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 AlK=n! delta 14293 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 Wr1MD6k%1#ukFaNT9ZOz*Qu9A~db>~n From dfa336a3c0bc4d1c9ccc745c0a7e53360d2d6953 Mon Sep 17 00:00:00 2001 From: Roman Belkov Date: Wed, 2 Aug 2017 15:37:51 +0300 Subject: [PATCH 16/16] NULL is not a valid return from functions with wstring ret type --- src/cpp/windows/jssc.c++ | 16 ++++++++-------- src/java/libs/windows/jSSC-2.8_x86.dll | Bin 38400 -> 37888 bytes src/java/libs/windows/jSSC-2.8_x86_64.dll | Bin 47104 -> 46592 bytes 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/cpp/windows/jssc.c++ b/src/cpp/windows/jssc.c++ index e9d5a7fba..4e466c1a1 100644 --- a/src/cpp/windows/jssc.c++ +++ b/src/cpp/windows/jssc.c++ @@ -807,7 +807,7 @@ static std::wstring deviceRegistryProperty(HDEVINFO deviceInfoSet, if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) { - return NULL; + return std::wstring(); } outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0); } @@ -829,7 +829,7 @@ static std::wstring busProvidedDescription(HDEVINFO deviceInfoSet, if (::GetLastError() != ERROR_INSUFFICIENT_BUFFER || (dataType != REG_SZ && dataType != REG_EXPAND_SZ)) { - return NULL; + return std::wstring(); } outputBuffer.resize(bytesRequired / sizeof(wchar_t) + 2, 0); } @@ -853,7 +853,7 @@ static std::wstring deviceInstanceIdentifier(DEVINST deviceInstanceNumber) { &outputBuffer[0], MAX_DEVICE_ID_LEN, 0) != CR_SUCCESS) { - return NULL; + return std::wstring(); } return std::wstring(outputBuffer.begin(), outputBuffer.end()); } @@ -879,16 +879,16 @@ static std::wstring parseDeviceSerialNumber(const std::wstring &instanceIdentifi lastbound = instanceIdentifier.size(); int ampersand = instanceIdentifier.find('&', firstbound); if (ampersand != -1 && ampersand < lastbound) - return NULL; + return std::wstring(); } else if (instanceIdentifier.find(L"FTDIBUS\\") == 0) { firstbound = instanceIdentifier.rfind('+'); lastbound = instanceIdentifier.find('\\', firstbound); if (lastbound == -1) - return NULL; + return std::wstring(); } else { - return NULL; + return std::wstring(); } return instanceIdentifier.substr(firstbound + 1, lastbound - firstbound - 1); @@ -908,7 +908,7 @@ static std::wstring deviceSerialNumber(std::wstring instanceIdentifier, break; } - return NULL; + return std::wstring(); } static uint16_t parseDeviceIdentifier(const std::wstring &instanceIdentifier, @@ -967,7 +967,7 @@ static std::wstring devicePortName(HDEVINFO deviceInfoSet, PSP_DEVINFO_DATA devi const HKEY key = ::SetupDiOpenDevRegKey(deviceInfoSet, deviceInfoData, DICS_FLAG_GLOBAL, 0, DIREG_DEV, KEY_READ); if (key == INVALID_HANDLE_VALUE) - return NULL; + return std::wstring(); static const wchar_t * const keyTokens[] = { L"PortName\0", diff --git a/src/java/libs/windows/jSSC-2.8_x86.dll b/src/java/libs/windows/jSSC-2.8_x86.dll index a6c54119b94d6898556e5c35193d68572b988d7f..2b0f60203606bdd27b95a2af4097f4deeb116d51 100644 GIT binary patch delta 3545 zcmaJ@2~<;O7XIJQ7WS}(5ZMI+K_$sc-g^lzc_@MwLF0~qSShktMMapZ9mOePi!o}w zVx6wm)}>XC)>x%=thj+z>Qb%y^kAt@ERNfFEVXLpe+hVcdd|!{=jPu3zxRIk{`cPZ zzbxH>mu|zmB~;?a?SGqs`kpR?6a1+lKU73EjPA|z#h{`t`dt%^q=bsV52sV5z+fe{ z97@UW3RsSn(1b(b5SCG^>=*HD3Kx!q9M5TZ!(iCrSsnOHiO?kLC0l+{mV<(5FICvB zG=v)ONNmHChLhcJi{rQorg+i#QZB6W(&NjyaNJ9ov@r!CqUIg%xP>IgDk50(lO|Z( zri60Mo)HB=h$^V9EE?)h8oF1JU1H# z`^MqOY#8k;!#UYd;R|@vF!3T8wPLs(fG5W@DIP0c>GYv^N+{BWx*`} zS8!(*obzwN&jfo_fCt9CCYT*G0be!2(V*uMS9y|J!BZ00nsb8wZdz%vLuRyJ3@*pA z-7HbvoO(ne8d%#)>Fd?nr{g?-_I zU!btE{$m3YfQNR3!O+MFRC(lfK^>2s&EF3eVN%yB?Q!hGQAbUJVIo>z}K_n#G!_e6tDmKgM$1hRhMAb8eOq))tT$iPGb z`Df1&j;8@HTs1CN-^HTqDaY~u=}1h+u24`%C4f588$XT| z2kUzg+Te>w5Q<+Ihz8+l$+$_xABhLddb>paddn2!Q_iDUM?7kC|ex)ZlF{* zkj4d+I_`e~-S+4MDi?u@AtNeLB8nErCYdXtC1L?jIo=Ew6T;iV;Ff%FOq96kDy8+b zW2KJ>A-CE7DnhK1k|Qbc4-qc!FCtvtUk8ca4c9_n94F_P#b)azWp!MPCgpVd9w2&~ z&6UY+m*_g(W|!!y*Sn%f`n1-?k2zKl?(S|+xSNYTuM>9sj=C3dH~Fh9i;T3+bWuUdZJv+ zn$wkexh^pMsP)XbUdwpLax%W+>@Ep}LuoRfzGUFvv0wVnj1rp^(9~A{8hjBqpyUBb z+2&cB{$ud6TVnQ&TuNPFV;gSlq3R#rK2Nrq+JcvzB0T-bx!%TJXYjIb$Re{N*tU;w zYfdkHlDy6xS>gqVIsi@@WwOFMkj$QAQdOC ze)@A;E@iFn9W&W7$?=9CLet1)P%OeUIqS}+_nve1ob80N1SNi@608ZssE^=u!t{{E zPl{k>d>6v5l9A{rVZ26EzLmKzHp| zh>B4XS4eAzwct^CGtnS4Wm>7V;12zrqk~+~Bn@kK@lnych}c`}_YxPnts~cc>KC1N z@S?W8r?tQT?%r>xMAGt)MN~`U9o@&0jYtYF4a}tE&@?cO8Unipjv=27=fD^|HUnal zVqzM^tDGF&n$y{iQ0v$XBt6>c#yVRGg-N-T89quP#H z+Vk=Wit>bn8DVQZ!r}h(R=lqeJ}-;K@n!IBnSwC;t+Jn}hBf&}dUpnrJ|ZN|L(+{e zA?Xt$s|iOHNa{@}fKb*5B<;#U(oiDH3B?jxaGNPe?miuI=&%H(-|IwTDzG;#rw z-kRw8?u(6m@$~;`z+`6up{0vZHd&r!jS8VQ8gNMX%fPq;ouj&JJV@f=m)Tw*207A;2tH8&0{b3DN^cS7Jo4gKvT2-&%i|_In6E^=9>T&2O4OtwO8RYPDOm zt=bjzr}Pqii~bXR!w&sEeE@TS-N-%RIDQmAg)if0@*DWg{7?Kn-qWx}pHGA4r=#*AlPW-6F@%xlaWOf$2J zd53wQ+01;!9A+*sUCce^5#!4Sv*B!913QG}*j#orYh{7`oZZdtV-K?@+4Jm8wugPd z{>naMeYg-VnoHr*xqNOMcZAC@lp1Obs}1W6I}LjbhYSJ6G$U;sY8+20x7&Ec_}9!` zna?u4`4C>tbG(@!&gbzKeiA>GFXvz7Yx#xzQvOYTHUAF(5#O+#-^+i+AL38)=lO2_ zKfH%2z%vvIF;z?rQ^zb~mNLtkmCRaZ y1M?yCDYKio%J{KHwt4q_eWriJw?+u&Q;r{~Y1OT)E delta 3790 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 diff --git a/src/java/libs/windows/jSSC-2.8_x86_64.dll b/src/java/libs/windows/jSSC-2.8_x86_64.dll index 1c40908677254f7d2501fb61b03d48d90ef04b5d..a6579cebf19697ff991b0d478db9650a204897b3 100644 GIT binary patch delta 10240 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 spO?Tti~&#v+BKw`j&ulXb()Z_uVze!@GX?1`