nodejs / hardware

Hardware Working Group
42 stars 16 forks source link

DRAFT libuv uv_serial_t proposal #29

Closed reconbot closed 1 year ago

reconbot commented 5 years ago

Goal

A stream struct for reading and writing to serialportsuv_serial_t.

Future Goals

Rationale

A smaller, easier to reason, less likely to change addition to libuv allows the web serial spec and serialport to solidify their apis while leveraging the new features.

Prior art and references

Current state of serialports and libuv

It is possible to use uv_poll_t and Node.JS's fs.read and fs.write on posix systems to read and write data from a serialport. Windows requires custom c++ code to manage asynchronous reads and writes as the file based operations do not work for serialports. https://github.com/libuv/libuv/pull/484 abstracts the need for custom reading and writing code.

The way you configure a serialport differs between windows and posix systems. Some settings are possible when the file descriptor is opened (eg, locking and setting asynchronous I/O on windows). Most configuration is done on an open file descriptor. There is no current way to do this with libuv. https://github.com/libuv/libuv/pull/484 did not attempt to solve this.

Some state of a serialport is dependent on the remote connection. (CTS, DCD, DSR) and an evented way to receive state changes for these properties is desired. Polling may be the only option on some systems. (Needs research) The most common use case is to look for a change of DTR on the remote end of a connection reflected in the DSR flag locally.

Port discovery and port meta information are well defined in node-serialport. (with some upcoming changes eg. comName renamed to path) and rely on filesystem scanning (eg ls /dev), usb scanning (osx uses a combination of usb and ModemManager calls) and registry scanning (windows uses registry and com subsystem calls). The apparent mess of around port discovery and meta information is due to 40 years of legacy code in the various operating systems.

One commonly requested feature that is not part of the serialport ecosystem is evented device detection (eg, I plug in a device) this is better handled at device specific layer (eg usb) as no operating systems have serial specific support for this feature.

Proposal

A stream interface for reading and writing with no abstractions for opening, configuration or events. Additional functions for these concerns should be added later with a specific set of configuration options with cross platform support. This stream interface uv_serial_t would remove the majority c++ code from node serialport and allow nodejs to implement the discovery and meta information as it's not an IO concern.

If a small subset of opening and configuration options/functions is desired for this change (with room for expansion later) I think they should be limited to the following as they are easily supported cross platform.

Trott commented 5 years ago

/ping @nodejs/libuv for comments

saghul commented 5 years ago

A stream interface for reading and writing with no abstractions for opening, configuration or events. Additional functions for these concerns should be added later with a specific set of configuration options with cross platform support.

I'm not sure what this means. You mean something like uv_poll_t but with write and read functions similar to how uv_stream_t behaves?

reconbot commented 5 years ago

I think a uv_stream_t Is the goal I just don’t want half baked open and configuration options and it might make sense to not make them for the time being. I propose what a scaled down interface might look like later on, maybe it’s better to start with that.

saghul commented 5 years ago

Still not sure what you mean :-)

My understanding is that the uv_stream_t behavior is desired (IIRC there were some concerns in the past about libuv doing zero length reads in some cases on Windows), but without the full implementation of open / configuration, right?

I think at some point the idea of uv_fdstream_t appeared somewhere. The idea would be to have some uv_fdstream_open method taking an fd (or HANDLE on Windows) and give the users the stream API. How that fd is opened, and configured is outside of the scope of this handle.

Is this kind of what you had in mind?

reconbot commented 5 years ago

Not exactly. I want lib_uv to have a fully featured serialport api, I just don't think we have the bandwidth to build it cross platform. So I'd like to punt on features and allow adding to the open and configuration structs at a later date.

saghul commented 5 years ago

From libuv's perspective (not speaking on behalf of the project though), it would need to at least be functional. Having a partial but extensible implementation of open and configure may be acceptable, not having it at all wouldn't be acceptable IMHO.

reconbot commented 5 years ago

Perfect