mavlink / MAVSDK-Java

MAVSDK client for Java.
68 stars 40 forks source link

mavsdkserver stop method is not working in the last release #96

Closed jjcetraro closed 1 year ago

jjcetraro commented 2 years ago

I was testing the android-client example, and the mavsdkServer.stop() call in the onPause of the MapsActivity works fine. I mean, I am testing with a sim_vehicle, and I can see on the console that when I connect to the vehicle I see "New connection on serial port 0" on the console, and when I leave the MapsActivity, I see "Closed connection on serial port 0".

This example is using:

I tried to update to the last version (1.1.1), and the connection to the sim_vehicle works fine, but with this last version what is not working is the stop method. When I leave tha activity, I don't see the "Closed connection on serial port 0" on the console, and I have to close the app to see this message. I am using the same code, the only thing I did was to update the version of the mavsdk and the mavsdk-server.

  1. Is this a known bug?
  2. Are you working to solve it in the following release?

Thanks!

JonasVautherin commented 2 years ago

It is not known, it actually sounds like a regression.

Would you be willing to contribute a fix for that? I'm happy to help/review :blush:.

jjcetraro commented 2 years ago

It is not known, it actually sounds like a regression.

Would you be willing to contribute a fix for that? I'm happy to help/review 😊.

I can try :D

jjcetraro commented 2 years ago

Ok, I did a bit of research.. The last release without the bug is 'io.mavsdk:mavsdk-server:0.10.0'.. So, this bug was introduced in 'io.mavsdk:mavsdk-server:0.11.0'.

I saw the differences between both versions, and I think the change that introduced the bug was in the file 'mavsdk_server/build.gradle', and the problem is that you changed the mavsdk_server version you use, from v0.43.0 to v0.48.0.

I mean, with mavsdk_server_release v0.43.0 the code works, and with the v0.48.0 it doesn't.

I also saw the difference in the stop method between those two versions, and I saw that the difference is the following:

// v0.43.0
void stop() { _server->stop(); }

// v0.48.0
void stop()
    {
        _connection_initiator.cancel();

        if (_server != nullptr) {
            _server->stop();
        }
    }

do you know why this _connection_initiator.cancel() was introduced to the code? can we remove it to verify if it is the problem?

best regards!

JonasVautherin commented 2 years ago

I think that's because now, start() will block until the remote System is discovered. If you try to stop before that, then stop() has to cancel that blocking call.

BTW you mention "Closed connection on serial port 0". Are you using a serial connection on Android? Did you try with a UDP connection, just to see if that's different?

jjcetraro commented 2 years ago

The SITL I am using for testing, only exposes TCP endpoints to connect. I don't know why it says "serial" in the message, because I was connecting from the Android device using TCP.

Anyway, I tested using UPD instead of TCP. Because the SITL does not expose any UDP endpoint, I had to use mavproxy. So, I used mavproxy to redirect the telemetry from TCP to UDP. In my deploy, I have one computer with the SITL (192.168.250.147), and the Android device (192.168.250.148). My first try was to expose the telemetry (with mavproxy) using the SITL ip address, and try to connect from the android device to the SITL ip address using mavsdk_server. This didn't work:

2022-04-26 17:47:32.710 28124-28124/com.ksi.missionkeeper I/Mavsdk: MAVSDK version: v1.2.0
2022-04-26 17:47:32.711 28124-28124/com.ksi.missionkeeper D/MAVSDK-Server: Running mavsdk_server with connection url: udp://192.168.250.147:14540
2022-04-26 17:47:32.711 28124-28124/com.ksi.missionkeeper I/Mavsdk: Waiting to discover system on udp://192.168.250.147:14540...
2022-04-26 17:47:32.712 28124-28124/com.ksi.missionkeeper D/Mavsdk: Initializing connection to remote system...

Then I tried to redirect the telemetry to the android device ip, and connect with mavsdk_server using udp://:14540. This second try worked:

2022-04-26 17:54:36.644 30202-30202/com.ksi.missionkeeper I/Mavsdk: MAVSDK version: v1.2.0
2022-04-26 17:54:36.645 30202-30202/com.ksi.missionkeeper D/MAVSDK-Server: Running mavsdk_server with connection url: udp://:14540
2022-04-26 17:54:36.645 30202-30202/com.ksi.missionkeeper I/Mavsdk: Waiting to discover system on udp://:14540...
2022-04-26 17:54:36.765 30202-30429/com.ksi.missionkeeper I/Mavsdk: New system on: 192.168.250.147:41636 (with sysid: 1)
2022-04-26 17:54:36.765 30202-30429/com.ksi.missionkeeper D/Mavsdk: New: System ID: 1 Comp ID: 1
2022-04-26 17:54:36.765 30202-30429/com.ksi.missionkeeper D/Mavsdk: Component Autopilot (1) added.
2022-04-26 17:54:37.358 30202-30429/com.ksi.missionkeeper D/Mavsdk: Discovered 1 component(s)
2022-04-26 17:54:37.359 30202-30428/com.ksi.missionkeeper I/Mavsdk: System discovered
2022-04-26 17:54:37.363 30202-30202/com.ksi.missionkeeper I/Mavsdk: Server started
2022-04-26 17:54:37.363 30202-30202/com.ksi.missionkeeper I/Mavsdk: Server set to listen on 0.0.0.0:46567
2022-04-26 17:54:37.363 30202-30202/com.ksi.missionkeeper D/MAVSDK-Server: mavsdk_server is now running, listening on port 46567
2022-04-26 17:54:37.515 30202-30429/com.ksi.missionkeeper W/Mavsdk: command unsupported (512).

After this, I tried to stop the mavsdk_server and connect again, and I receive the following error:

2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper I/Mavsdk: MAVSDK version: v1.2.0
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper D/MAVSDK-Server: Running mavsdk_server with connection url: udp://:14540
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper I/Mavsdk: Waiting to discover system on udp://:14540...
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper E/Mavsdk: bind error: Address already in use
2022-04-26 17:55:44.493 30202-30202/com.ksi.missionkeeper E/Mavsdk: Connection failed: Bind error

All this executions were using the version 1.1.1. After this, I made the same test using version 0.7.0, and with this old version I can connect and disconnect all the times I want (so the stop method works fine in this old version using udp too).

JonasVautherin commented 2 years ago

So is it that _connection_initiator.cancel(); does not return correctly when you stop()?

jjcetraro commented 2 years ago

I don't really know because right now I only executed the android-client project, so I can't debug that part of the code.. I will try to execute the mavsdk_server in my laptop to see if I can debug that line and see what is happening there.. thanks!

jjcetraro commented 2 years ago

Another question.. I am trying to build the mavsdk_server, and I am using this command:

cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_MAVSDK_SERVER=ON -Bbuild/default -H.
cmake --build build/default -j8

https://mavsdk.mavlink.io/main/en/cpp/guide/build_mavsdk_server.html

Where should I execute it? in /MAVSDK or in /MAVSDK/src/mavsdk_server?

JonasVautherin commented 2 years ago

In the root of the repo (where the root CMakeLists.txt is), so what I guess you mean by "/MAVSDK" :+1:

jjcetraro commented 2 years ago

Thats what I thought... Have you ever seen this error?

-- Configuring done
-- Generating done
-- Build files have been written to: /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink
[ 12%] Performing download step (git clone) for 'mavlink'
Cloning into 'mavlink'...
fatal: reference is not a tree: 3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2
CMake Error at /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink/mavlink/tmp/mavlink-gitclone.cmake:49 (message):
  Failed to checkout tag: '3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2'

CMakeFiles/mavlink.dir/build.make:97: recipe for target 'mavlink/src/mavlink-stamp/mavlink-download' failed
make[2]: *** [mavlink/src/mavlink-stamp/mavlink-download] Error 1
CMakeFiles/Makefile2:82: recipe for target 'CMakeFiles/mavlink.dir/all' failed
make[1]: *** [CMakeFiles/mavlink.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2
CMake Error at third_party/cmake/build_target.cmake:51 (message):
  /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink
  failed to build!
Call Stack (most recent call first):
  third_party/CMakeLists.txt:31 (build_target)

-- Configuring incomplete, errors occurred!
See also "/home/dronedojo/github_repos/MAVSDK/build/default/CMakeFiles/CMakeOutput.log".
JonasVautherin commented 2 years ago

Seems like there is something wrong with the main branch. I'll have a look tomorrow :+1:

JonasVautherin commented 2 years ago

A fix is coming here: https://github.com/mavlink/MAVSDK/pull/1758

jjcetraro commented 2 years ago

I cloned the repo again and I am having the same error when I try to build the code.. do you think that maybe it is because of the ubuntu version I am using? (16.04.7 LTS)

JonasVautherin commented 2 years ago

Oh really? It solved the problem for me :thinking:. Is that a clean clone, or did you have the build/ folder remaining from the previous tries?

jjcetraro commented 2 years ago

No no, I remove the folder and clone the repo again using "git clone https://github.com/mavlink/MAVSDK.git"

After that, I enter to folder using "cd MAVSDK", and then I executed the command for linux:

cmake -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF -DBUILD_MAVSDK_SERVER=ON -Bbuild/default -H.

JonasVautherin commented 2 years ago

And you get the exact same issue? Can you try to edit that line (the one I removed) and change it to GIT_SHALLOW FALSE then?

jjcetraro commented 2 years ago

I added GIT_SHALLOW FALSE in that file and I have the same error :(

JonasVautherin commented 2 years ago

Would you mind removing the folder again, cloning again (and setting GIT_SHALLOW FALSE), then running cmake again and copy-pasting the error?

My question is whether the hash is the same: 3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2. Because that hash does exist in the repo, so unless it is a shallow clone, it should be there :thinking:.

jjcetraro commented 2 years ago

I recorded the whole process :)

https://www.youtube.com/watch?v=2JM-nwhAqc0

the error is the same I posted 8 days ago

JonasVautherin commented 2 years ago

I suspect it's related to the version of CMake you are using (it's quite old with Ubuntu 16). Can you update CMake? It should be on snap, for instance.

jjcetraro commented 2 years ago

but I am using the last version, 3.23.1 haha.. do you think it is not compatible with ubuntu 16? ... Which ubuntu version are you using?

JonasVautherin commented 2 years ago

Wait...

the error is the same I posted 8 days ago

What you posted back then said:

Cloning into 'mavlink'...
fatal: reference is not a tree: 3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2
CMake Error at /home/dronedojo/github_repos/MAVSDK/build/default/third_party/mavlink/mavlink/tmp/mavlink-gitclone.cmake:49 (message):
  Failed to checkout tag: '3b52eac09c2e37325e4bc49cd2667ea37bf1d7d2'

What I see in your video is:

ImportError: No module named 'future'

Am I missing something? At least you should solve that error, which is a python dependency that needs to be installed.

divyanshupundir commented 2 years ago

@jjcetraro did you read this line in the README?

divyanshupundir commented 2 years ago

@jjcetraro @JonasVautherin, I saw this issue just today. I'm not sure if it is due to the new API changes. Please let me know if you've figured it out. Otherwise, I'll rewrite the android-client example.

jjcetraro commented 2 years ago

@divyanshu1234 thanks for contacting.. I saw that line, and I tried to stop the mavsdk_server using that example, but that didn't work.

It is really easy to test.. if you use an old version, you can stop and reconnect the mavsdk_server anytime you want. With the last version, if you stop the mavsdk_server, when you try to reconnect it, you receive an error that says that the port is busy, so the stop method is not working.

Can you test it and see if you can fix it? :)

divyanshupundir commented 2 years ago

@jjcetraro, sure I'll go through the example. But please give me some time. I've been having quite busy weeks for some time.

divyanshupundir commented 2 years ago

This comment is just a suggestion based on my experience with using this library to build a GCS for over a year. I'll try to tell you why we designed our GCS as something vastly different from the android-client example.

jjcetraro commented 2 years ago

Thanks for the suggestion. The truth is we are not developing a GCS, we are only using the mavsdk lib to get the drone telemetry. Anyway, this suggestion is very relevant for our project.

Are you planning to update the android-client example to use the last version of the mavsdk lib?

I am not hurry about this, just need to know if you are planning to update that project. That would be really really helpful for me :)

Thanks!

divyanshupundir commented 2 years ago

@jjcetraro Sorry for not being able to respond. I'll try to have a look at the android-client in a few days.

emialonzo commented 2 years ago

I am trying to solve the problem, is it possible to see the c++ mavsdk_server logs

JonasVautherin commented 2 years ago

One easy way I like for debugging is to run mavsdk_server on my laptop and connect MAVSDK-Java to it from the phone :+1:

divyanshupundir commented 2 years ago

Even I tried to find and fix the issue from Java side and couldn't. Looks like it's a problem with the C++ server.

xumeng367 commented 2 years ago

Can someone fix this bug? and Update the java SDK?

JonasVautherin commented 2 years ago

So what's happening, exactly? When you call mavsdkServer.stop(), does it return, or does it hang? Did you try with a more recent of mavsdk_server, e.g. v1.4.2?

I tried to stop from C++, and it seems to work. Also the swift example app uses mavsdk_server_stop() and it seems fine there :thinking:.

xumeng367 commented 2 years ago

I‘m use tcp connection ,After successful connection, exit app, enter, The bug can appear

julianoes commented 2 years ago

It would be interesting to get a stack trace of where it hangs.

JonasVautherin commented 2 years ago

I‘m use tcp connection ,After successful connection, exit app, enter, The bug can appear

What is the bug? Does it crash? Does it hang? Does it just not stop mavsdk_server?

jjcetraro commented 2 years ago

Ok, I will try to give you all the info you need to reproduce the bug:

  1. I cloned the repo, and I tried to execute the android-client app. I couldn't because there was a compilation error, so I commented some code to fix it.
  2. Then I added to the app a run/stop button, to test the run and stop methods of the mavsdk server.
  3. I executed the app with this new button, and it works perfect. You can run and stop the mavsdk server all the times you want, and there is no problem.
  4. After that I updated the mavsdk and mavsdk-server used in the app, from 0.7.0 to 1.1.1. I executed the code and now, you can run the mavsdk server, stop it, but when you try to run it again, you cant:

bind error: Address already in use Connection failed: Bind error

  1. I updated the code to use the MavsdkEventQueue class (because you mention in the documentation you have to use it to run and stop the mavsdk server) and I tested again. Same result, you can run, stop, but you can't run again.

I forgot to tell that for testing I am using a sim_vehicle in a laptop, and I am using mavproxy in the same laptop to redirect the telemetry from the laptop to the android device.

For all these tests I created a new branch called jjcetraro in the cloned repo. I leave a link to download it in case you think it could be useful:

(https://github.com/jjcetraro/mavsdk-android-test)

jjcetraro commented 1 year ago

Hi! Any update? 😄

julianoes commented 1 year ago

I'm trying to run your test app. I'm not very familiar with Android and how to run things in it. Are you using it in an x64 emulator, or on an arm device?

julianoes commented 1 year ago

It's crashing for me, any idea? (I'm not very familiar with this stuff)

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: io.mavsdk.androidclient, PID: 22933
    java.lang.RuntimeException: Unable to start activity ComponentInfo{io.mavsdk.androidclient/io.mavsdk.androidclient.MapsActivity}: java.lang.SecurityException: getDataNetworkTypeForSubscriber
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3778)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3940)
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:109)
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2345)
        at android.os.Handler.dispatchMessage(Handler.java:106)
        at android.os.Looper.loopOnce(Looper.java:233)
        at android.os.Looper.loop(Looper.java:344)
        at android.app.ActivityThread.main(ActivityThread.java:8210)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
     Caused by: java.lang.SecurityException: getDataNetworkTypeForSubscriber
        at android.os.Parcel.createExceptionOrNull(Parcel.java:2441)
        at android.os.Parcel.createException(Parcel.java:2425)
        at android.os.Parcel.readException(Parcel.java:2408)
        at android.os.Parcel.readException(Parcel.java:2350)
        at com.android.internal.telephony.ITelephony$Stub$Proxy.getNetworkTypeForSubscriber(ITelephony.java:9300)
        at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:2990)
        at android.telephony.TelephonyManager.getNetworkType(TelephonyManager.java:2954)
        at com.mapbox.android.telemetry.TelemetryUtils.obtainCellularNetworkType(TelemetryUtils.java:165)
        at com.mapbox.mapboxsdk.module.telemetry.PhoneState.<init>(PhoneState.java:39)
        at com.mapbox.mapboxsdk.module.telemetry.TelemetryImpl.onAppUserTurnstileEvent(TelemetryImpl.java:46)
        at com.mapbox.mapboxsdk.maps.MapView.onCreate(MapView.java:303)
        at io.mavsdk.androidclient.MapsActivity.onCreate(MapsActivity.java:77)
        at android.app.Activity.performCreate(Activity.java:8129)
        at android.app.Activity.performCreate(Activity.java:8109)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1344)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3747)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3940) 
        at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:109) 
        at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) 
        at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) 
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2345) 
        at android.os.Handler.dispatchMessage(Handler.java:106) 
        at android.os.Looper.loopOnce(Looper.java:233) 
        at android.os.Looper.loop(Looper.java:344) 
        at android.app.ActivityThread.main(ActivityThread.java:8210) 
        at java.lang.reflect.Method.invoke(Native Method) 
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584) 
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034) 
julianoes commented 1 year ago

Ok, I got around that by adding this line to app/build.gradle

implementation 'com.mapbox.mapboxsdk:mapbox-android-telemetry:6.1.0'

Now, as soon as I press the Run button I see this:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: io.mavsdk.androidclient, PID: 24596
    java.lang.NullPointerException: Attempt to invoke virtual method 'long com.mapbox.mapboxsdk.plugins.annotation.Annotation.getId()' on a null object reference
        at com.mapbox.mapboxsdk.plugins.annotation.AnnotationManager.delete(AnnotationManager.java:164)
        at io.mavsdk.androidclient.MapsActivity.onClickButtonRunStop(MapsActivity.java:268)
        at io.mavsdk.androidclient.MapsActivity.lambda$onCreate$1$MapsActivity(MapsActivity.java:85)
        at io.mavsdk.androidclient.-$$Lambda$MapsActivity$-XliznwkB4ydfom4cAvnKRDe22g.onClick(Unknown Source:2)
        at android.view.View.performClick(View.java:7488)
        at android.view.View.performClickInternal(View.java:7464)
        at android.view.View.access$3700(View.java:841)
        at android.view.View$PerformClick.run(View.java:28905)
        at android.os.Handler.handleCallback(Handler.java:938)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:233)
        at android.os.Looper.loop(Looper.java:344)
        at android.app.ActivityThread.main(ActivityThread.java:8210)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:584)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1034)
julianoes commented 1 year ago

Ok, I fixed that by changing:

diff --git a/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java b/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java
index 77bf594..75ff4cc 100644
--- a/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java
+++ b/examples/android-client/app/src/main/java/io/mavsdk/androidclient/MapsActivity.java
@@ -265,8 +265,10 @@ public class MapsActivity extends AppCompatActivity implements OnMapReadyCallbac
         }
       });

-      symbolManager.delete(currentPositionMarker);
-      currentPositionMarker = null;
+      if (currentPositionMarker != null) {
+        symbolManager.delete(currentPositionMarker);
+        currentPositionMarker = null;
+      }

       // change mIsMavsdkServerRunning value
       mIsMavsdkServerRunning = false;

Now I can reproduce it:

I/Quality: Skipped: false 2 cost 37.492622 refreshRate 16666666 processName io.mavsdk.androidclient
I/Mavsdk: MAVSDK version: v1.2.0
D/MAVSDK-Server: Running mavsdk_server with connection url: udp://:14540
I/Mavsdk: Waiting to discover system on udp://:14540...
E/Mavsdk: bind error: Address already in use
E/Mavsdk: Connection failed: Bind error
I/Quality: Skipped: false 1 cost 27.680754 refreshRate 16666666 processName io.mavsdk.androidclient
julianoes commented 1 year ago

It took me a while to be able to make manual changes to mavsdk_server and have that deployed to my phone without having to do maven releases (which I probably can't). Eventually I figured that out using the instructions here: https://stackoverflow.com/questions/9744721/relative-project-dependencies-in-gradle.

What I found is that when you do stop it might stop the gRPC server (although I'm not 100% sure there) but it certainly won't stop the MavsdkServer and won't destruct Mavsdk, so the connection is still there and will cause the bind error next time you try to start it.

I came up with this fix for it: https://github.com/mavlink/MAVSDK/pull/1877 I doubt it's the right way but I'll leave it to @JonasVautherin to comment on it.

julianoes commented 1 year ago

@jjcetraro this is how I tested it: https://github.com/mavlink/MAVSDK-Java/pull/104

jjcetraro commented 1 year ago

Incredible work what you did @julianoes ! Let's wait @JonasVautherin can authorize the merge 😄

jjcetraro commented 1 year ago

@JonasVautherin @divyanshu1234 any news? 😃

julianoes commented 1 year ago

Yes, @JonasVautherin is back and commented. Let's see.

JonasVautherin commented 1 year ago

@jjcetraro does this fix your issue? Just out of curiosity, doesn't it also work to call destroy() after calling stop()? My feeling is that it should have the same effect :thinking: (regarding the bind error: Address already in use).

Still, I agree that stop() should stop MAVSDK, but I'm not sure if I agree with https://github.com/mavlink/MAVSDK/pull/1877 :innocent:

jjcetraro commented 1 year ago

Hi @JonasVautherin! thanks for your support. I didn't test this new code, but I trust @julianoes that he test it and it works. Destroying the activity is not enough. I tested it many times, and the problem persists. The only thing that seems to work is to close the app, but that is unlikely.

One thing I saw is that when you execute the run method for the first time, a lot of threads are created:

The thing is that when you stop it, the threads are still there. I tried to destoy them manually, but with no success. I think that another way to unbind the port without closing the app, would be killing those threads, but I do not know how to do that. Thread.interrupt() doesn't work haha.

What are we waiting to release a new version of the library with the fix made by julianoes? 😃