ORSSerialPort icon indicating copy to clipboard operation
ORSSerialPort copied to clipboard

Question: ability to work with Virtual serial ports

Open gerwindehaan opened this issue 10 years ago • 11 comments

I am rewriting an OSX control application using ORSSerialPort. In some occasions, I would like to control a serial device that is not directly connected to my machine, or mock the communication of such device locally for testing. Using socat one can create virtual serial ports, for example to channel communication from a real serial device locally or over a network.

For example, here I create a pair of virtual devices /dev/master and /dev/slave: sudo socat -d -d -d -d -lf /tmp/socat pty,link=/dev/master,ixoff=0,ixon=0,ispeed=9600,ospeed=9600,echo=0,crtscts=0,user=gerwin,group=staff pty,link=/dev/slave,rawer,echo=0,user=gerwin,group=staff

Using such setup, I am able to connect to virtual ports using pySerial. However, using ORSSerialPort did not work for me.

When stepping through the code this seems to originate from ORSSerialPort relying solely on IOKit, in which 'virtual' devices don't show up on its radar. Also when initialising an instance with a path, e.g. /dev/master, the corresponding io_object_t does not exist -- and initialisation returns nil.

I want to avoid going to deep into IOKit and kernel stuff (as suggested here).

Looking at the code I see that deep within, sendData writes to a filedescriptor. Is it in any way feasible that there could be a way to initialise an ORSSerialPort with a 'plain' file descriptor, skipping detailed ioctl settings, and treating this as a plain character stream (assuming this is how pySerial pulls it off). Any alternatives ?

gerwindehaan avatar Jan 28 '16 10:01 gerwindehaan

Hi @gerwindehaan. This is something I'd like to see available, too. In fact, I've thought it would be nice to be able to create virtual serial ports with ORSSerialPort. Not sure if that's feasible.

Anyway, to your actual question: This change to allow creating an ORSSerialPort with just a file descriptor and/or a path will be required as part of Issue #93 because Linux doesn't have IOKit. So, it's already on my radar. I'm not in a position to work on this myself at the moment as I'm busy with other projects, but would happily accept a pull request on the 3.0 branch where ORSSerialPort is being rewritten in Swift (see #92). Otherwise, it's something I will implement, but I'm not sure how long it will be before I can get to it.

armadsen avatar Jan 28 '16 14:01 armadsen

If you're interested in implementing this and submitting a pull request, feel free to ask questions. I think the basic approach is to "swap" the initializers in InternalSerialPort and SerialPort so that the path initializer is the designated/required one, and the IOKit initializer is the optional one. It's already the case (as you've noted) that the path (not the io_object_t) is used internally to get a file descriptor and read/write to/from the port. In other words, my hope is that this is not a terribly complicated change.

armadsen avatar Jan 28 '16 14:01 armadsen

Thanks for your reply! Here's an update: As an experiment I switched to using the 3.0 branch and had a go at swapping the initializers in InternalSerialPort. I can now basically connect to socat-generated virtual port like /dev/master and communicate with PySerial, nice!. Still quite some ioctl error messages I had to silence in conditionals in the opening of the port. Main problem now is getting the RequestResponse callbacks to work again - is that working through some special ioctl signals? tbc...

gerwindehaan avatar Feb 01 '16 15:02 gerwindehaan

Nice! The request/response API is entirely built on top of "high level" ORSSerialPort send/receive functionality. The implementation of the request response API shouldn't depend on the specifics of the low level send/receive implementation at all.

Any chance you could push your changes so far to your own branch so I can take a look?

armadsen avatar Feb 01 '16 20:02 armadsen

Ah, the request/reponse API is working allright; some debugging showed me that --somewhere in socat or pySerial-- my \r carriage returns (that I expect from my real device and as such put in response descriptor) were mangled into \n newlines and borked the matching. I want to make some tweaks/cleanups after which I can push it to my own branch

gerwindehaan avatar Feb 02 '16 21:02 gerwindehaan

just left it like it is to let you have a peek: https://github.com/gerwindehaan/ORSSerialPort/commits/3.0 ,need to still check if a file descriptor is actually present (or even nicer, have a watchdog to see a port appear/disappear)

gerwindehaan avatar Feb 03 '16 14:02 gerwindehaan

Just a note to say that I still haven't had a chance to look at this, but haven't forgotten, and will get to it when I can.

armadsen avatar Feb 14 '16 04:02 armadsen

Did anything ever become of this?

tomhoag avatar Apr 04 '20 04:04 tomhoag

Did anything ever become of this?

Wondering the same. I also have a use case for using socat to link a virtual serial port to a TCP port, and use that virtual serial port in a Mac app that is currently using ORSSerialPort to manage its serial connections (a ham radio logging app called SkookumLogger. Right now the app does not show my virtual serial port in its drop down I suspect because of the same limitation originally reported in this Issue.

macauley avatar Jan 20 '21 04:01 macauley

@macauley I have the exactly same needs - making SkookumLogger and RUMlogNG to talk to a virtual serial port.

spicahan avatar Jul 07 '22 18:07 spicahan

How to use the Objective-C version to solve the problem that the virtual serial port cannot be found?

sonwa avatar Jan 14 '23 01:01 sonwa