johnlauer / serial-port-json-server

A serial port JSON websocket server for Windows, Mac, Linux, Raspberry Pi, or BeagleBone Black that lets you communicate with your serial port from a web application. This enables web apps to be written that can communicate with your local serial device such as an Arduino, CNC controller, or any device that communicates over the serial port.
http://chilipeppr.com
GNU General Public License v2.0
355 stars 174 forks source link

close not calling unregister for port, resulting in close/reopen issues #32

Open treib opened 8 years ago

treib commented 8 years ago

As observed on raspberrypi with version 1.86:

The deferred close set up in spHandlerOpen() (line 494) appears to not be calling the unregister for a port when a close is issued. As a result, findPortByName() is returning true (isFound) for ports even after a close has been requested.

The problem this surfaces is a closed port will appear to be open in the list command ("IsOpen": true), and the checks in spWrite() and spWriteJson() to verify a port is open will falsely believe it is. When data is sent to these closed ports, this ultimately causes a state where only a restart of SPJS will restore communication to a port.

Steps to reproduce:

  1. Connect to a port in Chilipeppr and verify communication is working.
  2. Click the checkbox next to the port to disconnect (un-check the checkbox).
  3. Reload the Chilipeppr webpage.

At this point, the connection checkbox for the port will be checked (showing connected), but communication will be broken. The SPJS logs the following (as observed if connected to the SPJS webpage when this happens):

Error writing to /dev/ttyUSB0 write /dev/ttyUSB0: bad file descriptor Closing port.
Shutting down writer on /dev/ttyUSB0

From this point on, I am unable to communicate with the tinyg on /dev/ttyUSB0 until I issue a "restart" command to the SPJS.

johnlauer commented 8 years ago

This is a known issue and sadly there is no easy fix. It's not that unregister isn't getting called, it's actually that the close call never returns and the port never really actually gets closed. So unregister shouldn't get called until the port is actually closed. The workaround is to simply restart SPJS.

It would be great if you could help us debug it. The Arduino team solved this by wholesale moving SPJS to a new serial port library in Go. That did work for solving the close problem, however it created a way worse problem which was packet corruption. So, the serial port library got put back to the original one and now everything works perfectly except for closing the port.

Closing ports does seem to work fine on Windows and Mac, just not on Linux.

treib commented 8 years ago

Ahh, ok, sorry - I didn't realize this was a known issue. Thanks for the details John. I try to look into debugging it, although I likely won't be able to get to it right away.

Thanks!