Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WriteBytes does not return how many bytes were not written #129

Open
danielgruber opened this issue Sep 20, 2022 · 4 comments
Open

WriteBytes does not return how many bytes were not written #129

danielgruber opened this issue Sep 20, 2022 · 4 comments
Labels
enhancement New feature or request help wanted Extra attention is needed language:cxx Needs changes to c/cpp sources. language:java Needs changes to java sources.

Comments

@danielgruber
Copy link

Hello,
At the moment we encountered that writeBytes does not return how many bytes were written. For a CTS / RTS flow, this is absolutly necessary. Is there a reason why this is not needed / or how we use this library correctly with hardware CTS / RTS without losing data in the middle?

Thanks a lot!

Best

Daniel

@tresf
Copy link

tresf commented Sep 21, 2022

Hi,

I don't believe this is possible currently. To support this without breaking backwards compatibility, a new function (e.g. write(bytes[])) would have to be written and the old boolean functions would have to be update to check the return length.

This would require Windows and Unix C++ code to be updated to return jint and the current functions would be wrapped to still return a boolean.

Disclaimer, this library is mostly in maintenance mode, so any features would have to be authored by the vested/interested parties.

Relevant functions:

Unix:

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);
env->ReleaseByteArrayElements(buffer, jBuffer, 0);
return result == bufferSize ? JNI_TRUE : JNI_FALSE;
}

Windows:

JNIEXPORT jboolean JNICALL Java_jssc_SerialNativeInterface_writeBytes
(JNIEnv *env, jobject, 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;
}

@tresf tresf added help wanted Extra attention is needed enhancement New feature or request language:cxx Needs changes to c/cpp sources. language:java Needs changes to java sources. labels Sep 21, 2022
@danielgruber
Copy link
Author

Hi @tresf,

Thanks for your update! I’m happy to implement the changes, still I would first want to know if there was a reason behind it not to implement it like this from the beginning?
So is this at all possible with the C stack being used? Or do I have to try?
Thanks!
Best
Daniel

@tresf
Copy link

tresf commented Sep 21, 2022

I would first want to know if there was a reason behind it not to implement it like this from the beginning?

Hi, this project is a fork of the original from https://github.com/scream3r/java-simple-serial-connector, so the history behind this decision likely lies there.

So is this at all possible with the C stack being used? Or do I have to try?

I think the Unix code makes it relatively easy, but I'm not sure about the win32 API. Perhaps the answer lies in GetOverlappedResult returning a zero? I'm not very familiar with hardware flow control and only partially familiar with the C++ portions of the codebase. We do have some other volunteers here as well as a Slack channel if interested. @hiddenalpha has been very helpful with the C++ portions as well.

@hiddenalpha
Copy link

Looks related to issue #96

hiddenalpha added a commit to hiddenalpha/jssc that referenced this issue Oct 3, 2022
Some thoughts about java-native#129

What this commit does:

- Make native impls return numberOfBytesWritten.
- Throw SerialPortException in case write fails in some way.
- Expose new 'write()' method to java which returns
  numberOfBytesWritten and uses exceptions for error handling.
- Keep old 'writeBytes()' method and translate to the old behavior.

What this commit does NOT:

THIS CODE IS NOT TESTED! It even was not launched at all. Nevertheless
it did compile fine for x86_64-linux-gnu (debian) and mingw
(cross-compile). So we need to do:

- Testing!
- Review if the change in the API (adding a 'write()' method) is the
  thing we should do or if we should do it differently somehow.

(wip @ 36ee5d8)
hiddenalpha added a commit to hiddenalpha/jssc that referenced this issue Oct 3, 2022
Some thoughts about
java-native#129
and
java-native#96

What this commit does:

- Make native impls return numberOfBytesWritten.
- Throw SerialPortException in case write fails in some way.
- Expose new 'write()' method to java which returns
  numberOfBytesWritten and uses exceptions for error handling.
- Keep old 'writeBytes()' method and translate to the old behavior.

What this commit does NOT:

THIS CODE IS NOT TESTED! It even was not launched at all. Nevertheless
it did compile fine for x86_64-linux-gnu (debian) and mingw
(cross-compile). So we need to do:

- Testing!
- Review if the change in the API (adding a 'write()' method) is the
  thing we should do or if we should do it differently somehow.

(wip @ 36ee5d8)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed language:cxx Needs changes to c/cpp sources. language:java Needs changes to java sources.
Projects
None yet
Development

No branches or pull requests

3 participants