Neos-Metaverse / NeosPublic

A public issue/wiki only repository for the NeosVR project
194 stars 9 forks source link

Serial Port Connection #2973

Open bentallea opened 3 years ago

bentallea commented 3 years ago

Is your feature request related to a problem? Please describe.

I would like to interface with a COM port from within NEOS with Components. This would enable much easier communication to external devices, as COM port serial communication is super easy to develop.

Relevant issues

None.

Describe the solution you'd like

I would like a component or logix to interface with serial ports directly.

Describe alternatives you've considered

websocket connections, but that is an extra layer of abstraction that I do not want.

Additional context

No response

kazu0617 commented 3 years ago

As an alternative, it is possible to write the corresponding process in neos.js, launch it in a separate account, and synchronize it with CloudVariable (WebSocket may be easier). For more direct access, a Plugin approach is also possible.

Aerizeon commented 3 years ago

@kazu0617 you don't even need to go that far - you can write a program that interfaces with neos via websockets, and reads/writes from the serial port.

ProbablePrime commented 3 years ago

Hey Everyone, Bentallea has already discounted web sockets in their initial post. They'd like a native solution.

Let's focus on that.

Earthmark commented 3 years ago

as COM port serial communication is super easy to develop. I don't believe you, but that's due to working with some very interesting devices using binary protocols, hopefully your relationship with those protocols is less pain-stricken than mine is.

To actual thoughts about this

COM in windows I believe gets interesting, I recall a lot of issues around buffering and such with the windows apis. I recall them being older and a bit more arcane in how they work (I recall a particular ability of them to raise an exception in C# that didn't inherit from Exception as a particularly nasty business). Better libraries may exist now though...

NOTE: I ended up looking up the serial port C# class, that looks much more modern and useable than what I was thinking of. This may be much safer and reliable than I recall, I was working in very old code that was... exotically written, my fears may not be present in the native C# class. It looks like this handles a lot of the under-the-hood processing for you, but I suppose that depends on what you want to do serial wise.

Do you have a use case of what kinds of devices you would be targeting? Talking text to a device is very different from writing a bootloader into silicon, I'm curious what formats and speeds your looking for, that may help the devs figure out support.

The neos concurrency model will make this interesting

Serial was very binary implementation specific, and with things like ymodem streaming data in a real-time or close to real time capacity may get funky, as logix can stall the update loop for up to a few seconds worst case and there's not much recourse for that if it happens, and it's very other-people-in-session dependent.

NOTE: It looks like the SerialPort class is message based, so you make your payload and wait for a response. That does resolve some of the real-time ness if that is acceptable for your use case.

This is almost certainly collections dependent

Perhaps requiring the creation of full binary messages, and those getting sent over at a specific baud would be valid. Either way I don't see a way this doesn't highly involve collections if it's binary message stuff.

Counter point: I guess I thought Websockets would be collections dependent though, but instead we got websockets that were string format only, like how COM has string and binary modes (kinda, all the asterisks here). It might be accepted to do string only mode until collections if websockets are precedent.

Ports may be security issues

Security wise the serial port list may be sensitive information as it's about the users local hardware setup, but a workaround for that could an access dialog prompts you for the serial port to connect to in user space, similar to how a websocket request is often made, but you need to pick a port on the prompt.

PS: There were similar requests for MIDI or some other audio protocol raw port thing. Decisions about the style of supporting this or something like midi would likely apply to each other. For instance a specific kind of access request for MIDI would likely apply to COM as well.

Frooxius commented 3 years ago

The main issue with this is security. I'm not sure if we'd add this directly for component access, since that would allow anything to make serial connections to anything potentially attached to anyone's PC.

We'd need to have some way to grant the permission to connect, but the usual way won't work too well, because there's only so many COM ports and it's hard for the end user to tell what they are. Presenting the user "Something in this world wants to connect to COM6" would probably just cause confusion and allow spoofing.

This might be more suitable for a device driver plugin system instead, where instead of the world handling the connection, you just write a device driver instead: https://github.com/Neos-Metaverse/NeosPublic/projects/12#card-61307662

Earthmark commented 3 years ago

It could be an abstract com port, so the in-world option doesn't know what com port it's connecting to, and the user is prompted in the connection dialog in userspace to pick from a list of ports. Never expose the name in world, only in userspace, and that should mitigate the scraping-com-port issue.

Frooxius commented 3 years ago

I'm not sure if that would be a good workflow though. The user won't likely know which port is which, so if a dialog like that pops up they'd still probably be confused. There also might be other things trying to access the same port once that's allowed.

I think this might be better done at lower level with the device drivers, instead of doing this directly through components.

Earthmark commented 3 years ago

Ahh, that makes sense to me, I take it drivers exist outside of the component space and provide an implementation for a specific set of component accessable features? If so I like this plan, and sounds like it would work well, a kinda safe-plugin system.

FlameSoulis commented 3 years ago

Not to mention, once we get into Linux territory... that gets even weirder. Sometimes devices will not show up as traditional ttySx or ttyUSBx, but ttyAMCx and ttyAMAx.

On top of that, if you have a GPS unit plugged in, they usually talk over com ports and I can smell some nightmare situations with that kind of information being available (IP data is one thing, but direct GPS coordinates...).

Not to mention, Windows loves to increment the COMM number into nearing triple digits on device reconnections. The moment you are working with COMM4, you may have something strange happen and suddenly it's COMM7. So locking down a specific port is... not always useful.