From 06d21645a5e3f44ef03555fb673c45a807abf887 Mon Sep 17 00:00:00 2001 From: Roel Date: Mon, 30 May 2022 22:46:16 +0200 Subject: [PATCH 1/6] added newline to get rid of compiler warning --- src/main/cpp/jssc_SerialNativeInterface.h | 3 ++- .../natives/osx_64/libjssc.dylib | Bin 35872 -> 52368 bytes 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/cpp/jssc_SerialNativeInterface.h b/src/main/cpp/jssc_SerialNativeInterface.h index afde9b032..7bb4bef89 100644 --- a/src/main/cpp/jssc_SerialNativeInterface.h +++ b/src/main/cpp/jssc_SerialNativeInterface.h @@ -170,4 +170,5 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_sendBreak #ifdef __cplusplus } #endif -#endif \ No newline at end of file +#endif + diff --git a/src/main/resources-precompiled/natives/osx_64/libjssc.dylib b/src/main/resources-precompiled/natives/osx_64/libjssc.dylib index a4dbbdbe6b5444c50428c5c067ed8e99d74d45bf..710acf18fa11e3935d342d427fc3819b5537d90c 100755 GIT binary patch delta 4029 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 b@L57kOQ6Z6_eK`WwiBO4&M4{Nd++@hqAW^1 From 400872c37fd7f729e6adbd84957ee4efc1d6ab69 Mon Sep 17 00:00:00 2001 From: Roel Date: Mon, 30 May 2022 22:55:40 +0200 Subject: [PATCH 2/6] pushed proposed code changes in cloned library --- src/main/cpp/_nix_based/jssc.cpp | 107 ++++++++++++++---- .../natives/osx_64/libjssc.dylib | Bin 52368 -> 52368 bytes 2 files changed, 83 insertions(+), 24 deletions(-) diff --git a/src/main/cpp/_nix_based/jssc.cpp b/src/main/cpp/_nix_based/jssc.cpp index 6887a0b6a..6df7ebfe7 100644 --- a/src/main/cpp/_nix_based/jssc.cpp +++ b/src/main/cpp/_nix_based/jssc.cpp @@ -529,14 +529,57 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes (JNIEnv *env, jobject, jlong portHandle, jbyteArray buffer){ jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); jint bufferSize = env->GetArrayLength(buffer); - jint result = write(portHandle, jBuffer, (size_t)bufferSize); + fd_set write_fd_set; + int byteRemains = bufferSize; + struct timeval timeout; + int result; + jclass threadClass = env->FindClass("java/lang/Thread"); + jmethodID areWeInterruptedMethod = env->GetStaticMethodID(threadClass, "interrupted", "()Z"); + + while(byteRemains > 0) { + + // Check if the java thread has been interrupted, and if so, throw the exception + if (env->CallStaticBooleanMethod(threadClass, areWeInterruptedMethod)) { + jclass excClass = env->FindClass("java/lang/InterruptedException"); + env->ThrowNew(excClass, "Interrupted while writing to serial port"); + // It shouldn't matter what we return, the exception will be thrown right away + break; + } + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; // 100 ms + FD_ZERO(&write_fd_set); + FD_SET(portHandle, &write_fd_set); + + result = select(portHandle + 1, NULL, &write_fd_set, NULL, &timeout); + if (result < 0) { + env->ThrowNew(env->FindClass("java/io/IOException"), "Waiting for serial port to become writable failed"); + // Return value is ignored anyway, exception is handled immidiatly + break; + } else if (result == 0) { + // timeout + continue; + } + + result = write(portHandle, jBuffer + (bufferSize - byteRemains), byteRemains); + if(result < 0){ + env->ThrowNew(env->FindClass("java/io/IOException"), "Error writing to serial port"); + break; + } else if (result == 0) { + env->ThrowNew(env->FindClass("java/io/IOException"), "Serial port was closed unexpectedly"); + break; + } else { // result > 0 + byteRemains -= result; + } + } env->ReleaseByteArrayElements(buffer, jBuffer, 0); - return result == bufferSize ? JNI_TRUE : JNI_FALSE; + return JNI_TRUE; //result == bufferSize ? JNI_TRUE : JNI_FALSE; } /** * Waits until 'read()' has something to tell for the specified filedescriptor. */ +/* static void awaitReadReady(JNIEnv*, jlong fd){ #if HAVE_POLL == 0 // Alternative impl using 'select' as 'poll' isn't available (or broken). @@ -579,7 +622,8 @@ static void awaitReadReady(JNIEnv*, jlong fd){ #endif } - +*/ + /* OK */ /* * Reading data from the port @@ -588,36 +632,51 @@ static void awaitReadReady(JNIEnv*, jlong fd){ */ JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes (JNIEnv *env, jobject, jlong portHandle, jint byteCount){ - - // TODO: Errors should be communicated by raising java exceptions; Will break - // backwards compatibility. - + fd_set read_fd_set; jbyte *lpBuffer = new jbyte[byteCount]; - jbyteArray returnArray = NULL; int byteRemains = byteCount; - + struct timeval timeout; + int result; + jclass threadClass = env->FindClass("java/lang/Thread"); + jmethodID areWeInterruptedMethod = env->GetStaticMethodID(threadClass, "interrupted", "()Z"); + while(byteRemains > 0) { - int result = 0; - - awaitReadReady(env, portHandle); - errno = 0; - result = read(portHandle, lpBuffer + (byteCount - byteRemains), byteRemains); - if (result < 0) { - // man read: On error, -1 is returned, and errno is set to indicate the error. - // TODO: May candidate for raising a java exception. See comment at begin of function. + // Check if the java thread has been interrupted, and if so, throw the exception + if (env->CallStaticBooleanMethod(threadClass, areWeInterruptedMethod)) { + jclass excClass = env->FindClass("java/lang/InterruptedException"); + env->ThrowNew(excClass, "Interrupted while reading from serial port"); + // It shouldn't matter what we return, the exception will be thrown right away + break; } - else if (result == 0) { - // AFAIK this happens either on EOF or on EWOULDBLOCK (see 'man read'). - // TODO: Is "just continue" really the right thing to do? I will keep it that - // way because the old code did so and I don't know better. + + timeout.tv_sec = 0; + timeout.tv_usec = 100000; // 100 ms + FD_ZERO(&read_fd_set); + FD_SET(portHandle, &read_fd_set); + + result = select(portHandle + 1, &read_fd_set, NULL, NULL, &timeout); + if (result < 0) { + env->ThrowNew(env->FindClass("java/io/IOException"), "Error while waiting for input from serial port"); + // Return value is ignored anyway, exception is handled immidiatly + break; + } else if (result == 0) { + // timeout + continue; } - else { + + result = read(portHandle, lpBuffer + (byteCount - byteRemains), byteRemains); + if(result < 0){ + env->ThrowNew(env->FindClass("java/io/IOException"), "Error reading from serial port"); + break; + } else if (result == 0) { + env->ThrowNew(env->FindClass("java/io/IOException"), "Serial port was closed unexpectedly"); + break; + } else { // result > 0 byteRemains -= result; } } - - returnArray = env->NewByteArray(byteCount); + jbyteArray returnArray = env->NewByteArray(byteCount); env->SetByteArrayRegion(returnArray, 0, byteCount, lpBuffer); delete[] lpBuffer; return returnArray; diff --git a/src/main/resources-precompiled/natives/osx_64/libjssc.dylib b/src/main/resources-precompiled/natives/osx_64/libjssc.dylib index 710acf18fa11e3935d342d427fc3819b5537d90c..3f9de134c9c94dccec122e3e70bf5203c6a38331 100755 GIT binary patch delta 3235 zcma)84R9036<(brz`^EZQ4*j~M9PmHQY--mL-3CpA3e=TK*lyWaU3jUnFwS{k)_y7 zlaYw+l&cUNy)*?%I_l4K9MX2wD9L!zHa%)1$t2Tis5@>lnM9qCR>e)Kv?(Q&`1*El zZG$N@z0tjI-_O2%_x8KhiKn$9{FZ1UCzo~^3+0GhPZ?D#l%G6PWAtuUwO$pFcl*gJ zHO9--nxNLp+of%qnnm$yRi|Erb)EEc{THP{jmh{f^?qHWM!j1ty#te)YgIL_0>V0j zCnb626k~X5p82hbrrMP!>aSPIj*mY3VL`WAimxwa#urM-^>vH8q1?V}N^qxDxWEgo z*7fnJFo#*`4;#M0lr4}R+ql`3 zD#5Y6Eu7^lA8Q(W<6ux%XOBLesTUMjXRt(iW#d*uCke8$r&D;*FPBK4Z+w`!w?t~* zw618p7;1VyKT<3m+tkDyE|xynw2EmcmWnE?*d^eLa+ihkeSiAAFT+TMP4_VWoG*DQ zSB3c_e;b1Gc;QW6Xv)}x8+>#wFZ|YWNfBi|wsW#As#|3j{sMg-;)VAVu^H^pcWmZk zm7|awyvlB~O-QS@MJcfHv644cmtB}t#G}y1UtkXKQAg(YAJhw-S#IDXHhg>s7;Qqz z?&{3gg*<;guZJ}gR^>vJ%L?2WyP^)Kha7g{AJ7RA!uw@*;4Pdg&BXywnj4Hit3m8u znJphM!CnHGRj5;8w+d}4_z7?kwww!#d|&ml1&}0oHxKRRW3S=_mP`3#cM%rN=c8Pr z=qyPKTaS0=+azMt9^>NqK@!#5#`ZVEG$=Xh7%R{4t^%(O$-+gPGJlrDut%e?3echd z`+zv?yxteOmQh7Sa}XLLeLpgSH@e08sI}Glm~~(4FpjQ*9SqLS`66ENCA#9C+1^3yjY&^z zTZqY%g`E9za1FFv?QTr%ZWDC3Rb-A#caFA$H?Bnu)xPS17MyXS`4e0;RY>-2^w?c6fqG7PVv!_7Babrf534qRLs66 z^G8N-RjtGM(Rm1Uuq*mOL#T-tKD6$&?y)vm8ylu+PdG0)vUb-ew!Xg;K$=V3O7rml&vQ)k`(fj5qxspn(=;ENruo08UjqxK z`CxvCM9rpo_*R}DCqeAdbFd8NxePeP^V?|tQ)n(dHdLA)f)-BGe0;XIS8ebuG>?W` zv-muUzgObXwN2D8 zYxUBu?c>Z&om5uc#k{ALPF3#+AAb-bWwl7;w}^a>$mfYXMdTSG&l34PBI88bhd9jIu0Jm7Y= zBTrY*9SDT{L3cYUD}Myd1lVRgT(8UR4|;rE=q977=W&nMZR!blf}XAerl8N%?GAXH zUX$M!2&#EJz6#r}naO*dVKuhH7q~eX&)x5K`8w5X&i#>buCjvkDI5it%&fiaP?n&YR1aT1&w zYq24O&*)`vYvC?~Tk_W~UWq@?>OjGFC;h;}V;oeBjHpq1v3BjfW?*Wr2x$t%h>=T> zu5JO+7T`b4%py%3zEBdS$t$&+>%yPX43iY+(Qh*&#bp%NP&8BAMzNmaPKwPG_fzyz ze3D{>;x|=HzNWuYmX!59cfTy(VCEJY;4#ETNjv=L-0U70=N^_ihHa+EBQTEa10iEk zz#`HHLd2rbCjD-Bc{uBYarOX+gcn4v6OVjY__6u~2r&R6j)mBRM?KIpaupg(G9zkD z5q+K6U}$U0>Jpk9+*wUTlhBwA1)YJ!wO1hY1*Ai|2M~$?o`KIk+_|rEPU+A{NmvFy zzA&(`edf(XMQ*B-e=Hb3NA<)O)t{ky9P;Ap8r*pP)VH_=##k4r-%WMHeIy*6Q1vj1 z&;nkk0ojdez=u>fSE;&zQ4{*{UnpEvR4>r^2dJK-5Aa>8qpzs(DXJUj{Evy=h>&Tk o8n6`jh%3(0fE`rN(E?hizI&Y-ADHsruj&HT4O^2JFQn%D7gFRPFaQ7m delta 2028 zcmYjSeQZ-z6u*7#*t(9j4$NQ#DQ07IxUJ=*ZgX^fOG{qOo6N9*II7bM;xKbUmrN4U zLO1lL4vH7$%a0OGBoa)aehg#a;l?)jLnbULIzSM}3sWh7fRiEh-1{!zOW*Hzf9ITg z?(IGI-WS`YkHK%M4s9!F&5M^I_EeiSj+brQ?aCWjsHqN((8$7V*IaoGE=?x5wZTQI zbgqXjHJYyGW~vS3V8%4EPiM`Oxi^n{Tm%opd@q+M({(6o_=B!V+Ak?$!)(nY`BP7t z=tRtK-GFczw+}+3jIXMPO=NHBCZRHi6qUUxsM+N6GN*NOHjV9Q@;Yuw-HpRXT7m|* z9NjSJ!D$$0bv7}SS6WJ0kZ9i3PY32yrV zfJMW7QdG}od^a6?1}t(w_29qZ56JkMx*0P1aR2=f8DDaoNXO6wSS-a`dDFaIks^Ir zP2vjCFFq$e@9$kzW}eXr3xQChgs+Ip#HC`R*brJGZTw>&7$w{Y>$4$&>xQMkSt&Ap zR~i_gg_6vR$JIlbG{W1{^{aVHjt(L5TL2_Q>juR$mm%JV&-sr1nUU`8p`|>dU~iw? z{iPk+QSY#b2S#lVhF=w1Wc=g+^+7p8_!boRgcsKM0~n)Ad86LEOflQMad>0!hRwFF zHi!jk)~H@1w?;IN6j^A4)knckC8(H8Q>qhLw)S^N_kh>Lym=42*I}Jti<+V#Z(r@q zPBt6$A{YlC4XxF%$2KMfQj)&Cr!J7zI^I@qvTlcIh*>%&+6K&97t`^h{)AQuPjthu z2SdTatc3UL12gjAe;}^MhkphyrUyI+S&&Tj))W^cj7SJ)BLgxaeFDyJ%7k>yaLU_q zlhiJZInMbr&R=jo!g-MMY0e{@uX0XtzO8ZctBk5bxDJb_ z9a8QHnQ=c%U-1)t?~2TDGqhs?vZ~i-O$4BwSPhV(5PyYA3JQgI3pv$0JrrI8?eMGA z@EX8S8*Qznu#U-(($*`J1_(X((cf-|5zZSLL7s#5viJ>;|)2AF>Go0!8<4mHJTqn4HJJ;4q z%|FPsg%@&+>w6zH2jrsp5cjX-T7gYKpRJk>Av+)7n|mFcTEG>q<9tAipe3{}(EJr# z$9eykxvsC!{Cl`gI5geQwZh~7V!8pLSd|t~0Q->6ILrrF#C1LQH*t;ZTKrnBV|)O7 NuYXnY Date: Mon, 30 May 2022 23:24:20 +0200 Subject: [PATCH 3/6] added SerialPortStream.java to the project --- .../natives/osx_64/libjssc.dylib | Bin 52368 -> 52368 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources-precompiled/natives/osx_64/libjssc.dylib b/src/main/resources-precompiled/natives/osx_64/libjssc.dylib index 3f9de134c9c94dccec122e3e70bf5203c6a38331..235c306bc5043d99fcd7830875b2d9a7c55ac049 100755 GIT binary patch delta 1251 zcmZ9LUr19?9LLYOZc}O2<{yew8ls7|^4fIyXKoXz=06COqW?26BTH)q`ml0TsO!4A za(pNax@1Dw%j!acV60|Y1h&U|iM>Qr5;qX)A+U4q`RT(B+xL4uzdvWcZTHCc(`5P@ z%|_)&U%_ndsC<0VZ4J6O4MH$D{@r6;g==3HJocgDdeOQtBAF2j)^Qdu6KhpY#)nLOoCL8~P2&QRsFK9T87bqO zp*0)hET?AsiB#u zNcBIX+FmPTyp?>Z`-I(OuD+iRUFte$zuttC)Aa>P@X#U3gz{cqX(ni}y)-XQ}#2%EvTffs?>!JXh<@D}h+ z@KfODzyshx@L_Nne3HBR!dO?V#*C%;&tv}tQ>YWAA%zI>lcwZhy46T`yu~ITqg(kj zl?0QJpCJ>4NvMl_j2F6-U38!9p%S}5MZ3s${Y)+~yi7$2P>C{82H0+Z{tWsGb&~SM zotalF5XwacluM2-?ifl?VvE@pdQH4e9Z@&1MdUmI9NWkF9dNXs^Izcg8(m4yV&^H4 z?*_KPjlauz2+1(OJQO4y{J^ik-Wtvpfgc!xfogyea1XEsUtkK@vYYq61-3!`FP%FO m5^H(E_B8$hNhmk~tib@sf&II9ePBIr=NtyMsqfz`nf?O=e+ps% delta 1262 zcmZ9LT}YEr7{||<+nl5{H3@Q(g0uX}*XHKebV{aEYzZr|M4Hj^!kH$KLXv}ST5C8v zMVSNxDJ)BtZ*}3-Kyzt9y9i8>*o6@x$t!eG5v_CH^XSE1w*UY9o{zI<+d2M;1V4S< zOq24F{EVb=m-5FS)~345oQAm}*Z6l!>IMXZ5ZoY@*pd;b;Rs2@SV>;0GRZW~PF;uW zHO#Bl$r|nHuy6`+LyQ%yN3<#)D6}IQ;lt)>OU_usA7kjmkKa?0Qa@L4BvH4Vj8LoR zTdYlJ_Jo_g%3P~2V~NJBzLfW*rSvh@5vkNGJleBc=1pcbGc>TN;|<1ee0GJ*9IY3w z#D|}^Q z)@y3@_Lx5FPR({wvE5eRX1AU^C2rST!o*=YoWjml9sP^hyHC7l@z#+5){Opyqw)`2 z17{=+TnC;9E`V2oH-Ou~JHXF_yTGr4yTNa97vHE_a>bBpf9721uR<-^Q3CQ4#X^@l z(oUCA;#_FScAuq7_c<(%IE z2dX*$0^YgYrF1X0pC9s0U~K`fALBfV+%UjA6hsWX;483D!C9-|8xFug6~Geo_W(!X z3rqr|V&1<5tcCt9ne7N=SMq`b3H$>hP|ye*g#kK&+X{L8;7-1Xvj Date: Mon, 30 May 2022 23:57:07 +0200 Subject: [PATCH 4/6] added missing file --- src/main/java/jssc/SerialPortStream.java | 221 +++++++++++++++++++++++ 1 file changed, 221 insertions(+) create mode 100644 src/main/java/jssc/SerialPortStream.java diff --git a/src/main/java/jssc/SerialPortStream.java b/src/main/java/jssc/SerialPortStream.java new file mode 100644 index 000000000..e64448e28 --- /dev/null +++ b/src/main/java/jssc/SerialPortStream.java @@ -0,0 +1,221 @@ +/* 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/ + * + * SerialPortStream.java is written and contributed under the same license + * to the jSSC project by FactorIT B.V. in 2022 (factoritbv on github) + * + */ +package jssc; + +import java.net.*; +import java.util.*; +import java.util.concurrent.*; +import java.io.*; + +public class SerialPortStream { + + private SerialPort m_serial_port; + private SerialPortInputStream m_serial_port_input_stream; + private SerialPortOutputStream m_serial_port_output_stream; + private volatile boolean m_closed; + + private class SerialPortInputStream extends InputStream { + private byte[] m_buffer; + private int m_buffer_pos = 0; + private int m_buffer_len = 0; + + public SerialPortInputStream() { + m_buffer_len = 0; + m_buffer_pos = 0; + } + + public void close() throws IOException { + SerialPortInputStream.this.close(); + } + + public int read() throws IOException { + try { + // See if we run out of available bytes, and try to re-fill the buffer + if (m_buffer_pos >= m_buffer_len) { + m_buffer_len = m_serial_port.getInputBufferBytesCount(); + if (m_buffer_len == 0) { + // Nothing available, just block until the first byte comes available and return directly + return (int)m_serial_port.readBytes(1)[0]; + } + // Fetch the available bytes at once + m_buffer = m_serial_port.readBytes(m_buffer_len); + // Reset the position in the buffer + m_buffer_pos = 0; + } + return m_buffer[m_buffer_pos++]; + } catch (SerialPortException ex) { + throw new IOException(ex); + } + } + + public int available() throws IOException { + try { + return m_serial_port.getInputBufferBytesCount(); + } catch (SerialPortException ex) { + throw new IOException(ex); + } + } + } + + private class SerialPortOutputStream extends OutputStream { + + public void close() throws IOException { + SerialPortStream.this.close(); + } + + public void write(byte[] b) throws IOException { + try { + m_serial_port.writeBytes(b); + } catch (Exception ex) { + throw new IOException(ex); + } + } + + public void write(byte[] b, int off, int len) throws IOException { + byte[] buffer = Arrays.copyOfRange(b,off,off+len); + try { + m_serial_port.writeBytes(buffer); + } catch (Exception ex) { + throw new IOException(ex); + } + } + + public void write(int b) throws IOException { + try { + m_serial_port.writeBytes(new byte[]{(byte)b}); + } catch (Exception ex) { + throw new IOException(ex); + } + } + } + + public SerialPortStream(SerialPort serial_port, int baudrate) throws IOException { + super(); + m_serial_port = serial_port; + try { + // Open the serial port if it is still closed + if (!m_serial_port.isOpened()) { + if (!m_serial_port.openPort()) { + throw new IOException("Could not open serial port [" + m_serial_port.getPortName() + "]"); + } + // For the USB CDC class seems to be mandatory to set the line coding. + // So we use the most common values (9600 baud, 8 bits chars, 1 close bit, no parity) + if (!m_serial_port.setParams(baudrate,8,1,0)) { + throw new IOException("Could not set params for serial port [" + m_serial_port.getPortName() + "]"); + } + } + } catch (SerialPortException ex) { + // Redirect exeption to an IO exception + throw new IOException(ex); + } + m_serial_port_input_stream = new SerialPortInputStream(); + m_serial_port_output_stream = new SerialPortOutputStream(); + } + + public SerialPortStream(SerialPort serial_port) throws IOException { + this(serial_port,9600); + } + + public SerialPortStream(String serial_port_name, int baudrate) throws IOException { + this(new SerialPort(serial_port_name),baudrate); + } + + public SerialPortStream(String serial_port_name) throws IOException { + this(serial_port_name,9600); + } + + public SerialPort getSerialPort() { + return m_serial_port; + } + + public String getName() { + return m_serial_port.getPortName(); + } + + public InputStream getInputStream() { + return m_serial_port_input_stream; + } + + public OutputStream getOutputStream() { + return m_serial_port_output_stream; + } + + public synchronized void close() throws IOException { + // Immidiatly return when connection was already lost and cleaned up in the past + if (m_closed) return; + + // Update the connection status + m_closed = true; + + boolean failure = false; + + // Try to close and clean up the input stream + try { + m_serial_port_input_stream.close(); + } catch (IOException ex) { + failure = true; + } + + // Try to close and clean up the output stream + try { + m_serial_port_output_stream.close(); + } catch (IOException ex) { + failure = true; + } + + if (failure) { + throw new IOException("Error occured while closing and cleaning up the in/output streams"); + } + + // Only try to close the serial port if it is still open + if (m_serial_port.isOpened()) { + try { + m_serial_port.closePort(); + } catch (SerialPortException ex) { + throw new IOException(ex); + } + } + } + + public synchronized boolean isClosed() { + if (!m_closed) { + try { + m_serial_port_input_stream.available(); + } catch (IOException ex) { + try { + this.close(); + } catch (IOException ex2) { + // ignore + } + } + } + return m_closed; + } +} + From 7da1377a527ec3ce72c8cd05c284438c49dde52a Mon Sep 17 00:00:00 2001 From: Roel Date: Tue, 31 May 2022 00:00:34 +0200 Subject: [PATCH 5/6] reverted to original precompiled binary in repo --- .../natives/osx_64/libjssc.dylib | Bin 52368 -> 35872 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/src/main/resources-precompiled/natives/osx_64/libjssc.dylib b/src/main/resources-precompiled/natives/osx_64/libjssc.dylib index 235c306bc5043d99fcd7830875b2d9a7c55ac049..a4dbbdbe6b5444c50428c5c067ed8e99d74d45bf 100755 GIT binary patch delta 5008 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 uyT;*-mpt1e{ literal 52368 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 JU6DJh{ue$N@k#&y From 17cc2f6c52f58c5237c8aff98fe67067363575f2 Mon Sep 17 00:00:00 2001 From: Andreas Fankhauser <23085769+hiddenalpha@users.noreply.github.com> Date: Mon, 20 Jun 2022 19:45:44 +0200 Subject: [PATCH 6/6] Suggest some fine-tuning for foreign PR In [PR_127] we got miscellaneous improvements. But we do no longer use poll and therefore are back to the FD_SETSIZE limit of *select*. This commit suggests some fine-tuning to [PR_127]. It does so by replacing a possible SEGFAULT (aka crashing the whole JVM) by throwing a java exception instead. This improves the reported error and even enables user code to react to the situation. Still not perfect. But IMHO good enough for now. We can still improve later (for example as soon there's enough time to do so). [PR_127]: https://github.com/java-native/jssc/pull/127 --- src/main/cpp/_nix_based/jssc.cpp | 87 ++++++++------------------------ 1 file changed, 22 insertions(+), 65 deletions(-) diff --git a/src/main/cpp/_nix_based/jssc.cpp b/src/main/cpp/_nix_based/jssc.cpp index 6df7ebfe7..32eef8b59 100644 --- a/src/main/cpp/_nix_based/jssc.cpp +++ b/src/main/cpp/_nix_based/jssc.cpp @@ -40,19 +40,9 @@ #endif #ifdef __APPLE__ #include //Needed for IOSSIOSPEED in Mac OS X (Non standard baudrate) -#elif !defined(HAVE_POLL) - // Seems as poll has some portability issues on OsX (Search for "poll" in - // "https://cr.yp.to/docs/unixport.html"). So we only make use of poll on - // all platforms except "__APPLE__". - // If you want to force usage of 'poll', pass "-DHAVE_POLL=1" to gcc. - #define HAVE_POLL 1 #endif -#if HAVE_POLL == 0 - #include -#else - #include -#endif +#include #include #include @@ -527,7 +517,7 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_setDTR */ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes (JNIEnv *env, jobject, jlong portHandle, jbyteArray buffer){ - jbyte* jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); + jbyte* jBuffer = NULL; jint bufferSize = env->GetArrayLength(buffer); fd_set write_fd_set; int byteRemains = bufferSize; @@ -535,7 +525,15 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes int result; jclass threadClass = env->FindClass("java/lang/Thread"); jmethodID areWeInterruptedMethod = env->GetStaticMethodID(threadClass, "interrupted", "()Z"); - + + if (portHandle < 0 || portHandle > FD_SETSIZE) { + char msg[95]; + snprintf(msg, sizeof msg, "select(): file descriptor %ld outside expected range 0..%d", portHandle, FD_SETSIZE); + return env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), msg); + } + + jBuffer = env->GetByteArrayElements(buffer, JNI_FALSE); + while(byteRemains > 0) { // Check if the java thread has been interrupted, and if so, throw the exception @@ -576,70 +574,29 @@ JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes return JNI_TRUE; //result == bufferSize ? JNI_TRUE : JNI_FALSE; } -/** - * Waits until 'read()' has something to tell for the specified filedescriptor. - */ -/* -static void awaitReadReady(JNIEnv*, jlong fd){ -#if HAVE_POLL == 0 - // Alternative impl using 'select' as 'poll' isn't available (or broken). - - //assert(fd < FD_SETSIZE); // <- Might help when hunting SEGFAULTs. - fd_set readFds; - while(true) { - FD_ZERO(&readFds); - FD_SET(fd, &readFds); - int result = select(fd + 1, &readFds, NULL, NULL, NULL); - if(result < 0){ - // man select: On error, -1 is returned, and errno is set to indicate the error - // TODO: Maybe a candidate to raise a java exception. But won't do - // yet for backward compatibility. - continue; - } - // Did wait successfully. - break; - } - FD_CLR(fd, &readFds); - -#else - // Default impl using 'poll'. This is more robust against fd>=1024 (eg - // SEGFAULT problems). - - struct pollfd fds[1]; - fds[0].fd = fd; - fds[0].events = POLLIN; - while(true){ - int result = poll(fds, 1, -1); - if(result < 0){ - // man poll: On error, -1 is returned, and errno is set to indicate the error. - // TODO: Maybe a candidate to raise a java exception. But won't do - // yet for backward compatibility. - continue; - } - // Did wait successfully. - break; - } -#endif -} -*/ - -/* OK */ /* * Reading data from the port - * - * Rewritten to use poll() instead of select() to handle fd>=1024 */ JNIEXPORT jbyteArray JNICALL Java_jssc_SerialNativeInterface_readBytes (JNIEnv *env, jobject, jlong portHandle, jint byteCount){ fd_set read_fd_set; - jbyte *lpBuffer = new jbyte[byteCount]; + jbyte *lpBuffer = NULL; int byteRemains = byteCount; struct timeval timeout; int result; jclass threadClass = env->FindClass("java/lang/Thread"); jmethodID areWeInterruptedMethod = env->GetStaticMethodID(threadClass, "interrupted", "()Z"); - + + if (portHandle < 0 || portHandle > FD_SETSIZE) { + char msg[95]; + snprintf(msg, sizeof msg, "select(): file descriptor %ld outside expected range 0..%d", portHandle, FD_SETSIZE); + env->ThrowNew(env->FindClass("java/lang/IndexOutOfBoundsException"), msg); + return NULL; + } + + lpBuffer = new jbyte[byteCount]; + while(byteRemains > 0) { // Check if the java thread has been interrupted, and if so, throw the exception