1
votes

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 ?


Update Feb 10, 2016:

I discussed the situation with creator armadsen on the ORSSerialPort github issue list:

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.

I posted an answer to the final result below...

1
"For example, here I create a pair of virtual devices /dev/master and /dev/slave". Trying this on 10.13.1 (HighSierra) fails with: E symlink("/dev/ttys008", "/dev/master"): Operation not permittedTasos Zervos

1 Answers

0
votes

Update Feb 10, 2016:

I discussed the situation with creator armadsen on the ORSSerialPort github issue list:

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.

After this I made a proof-of-concept implementation that works for me with "just filedescriptors" and socat and can be found here:

https://github.com/gerwindehaan/ORSSerialPort/tree/3.0