Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TCP mode 🚀 #42

Merged
merged 3 commits into from
Mar 24, 2023
Merged

Add TCP mode 🚀 #42

merged 3 commits into from
Mar 24, 2023

Conversation

mguentner
Copy link
Owner

Hello everybody,

I have finally found some time to work on adding TCP support for cannelloni (see also #20). This PR is a replacement of #38, and I would like to thank @simontegelid for their initial work!

With the extension of a decoder designed for streams, cannelloni can now support packet-oriented transports like TCP. Similar to the UDP protocol, the design is kept simple and straightforward. The protocol is binary and does not have any delimiters, and messages are sent one after the other. Since the CAN frame type provides enough information to know how many bytes need to be read, an additional data length code is not necessary.

The only addition to the protocol is a mandatory string that is sent upon connection establishment, which is currently set to CANNELLONIv1. This string allows instances to negotiate protocols, reject non-cannelloni peers (think nmap), and can be easily implemented on any hardware/software stack that is capable of communicating via TCP.

The key difference between the UDP/SCTP packet-based protocol and the TCP implementation is that frames are sent out immediately without buffering or sorting. Enabling these options will have no effect, and it might be good to throw an error if the user attempts to do so. The memory footprint can be improved in the future by reducing the FrameBuffer to just a few frames for passing between CANThread and TCPThread and vice versa.

In addition to adding TCP support, there has been some refactoring. For example, the main thread now has a pointer to ConnectionThread instead of an UDPThread since TCPThread does not inherit from UDPThread.

I will leave this PR open for 10 days (until March 23, 2023) so that people have time to comment.

pinging @jreppnow as you might be interested in participating in the discussion 👀

@jreppnow
Copy link

jreppnow commented Mar 14, 2023

Hi, thanks for the ping!

I was dead-certain I had already implemented TCP for the Rust version, but that apparently isn't the case.

Personally, I would have probably gone for a binary handshake instead of a character-based one that is integrated into the normal Cannelloni packets, but it's true that this is more likely to avoid accidental connections by other clients.

Regarding the string transmitted for the handshake, is it a C string (null-terminated) or fixed length?
If it is the former, one nice thing that you could do would be to allow "additional options" after the version string, for example comma-separated, for other implementions to use. An example would be a connecting client setting the maximum size of the out buffer to avoid relatively large numbers of frames arriving at the same time (edit: I see that you are doing immediate transmission for TCP and leave the buffering to the OS, so this example isn't really relevant for TCP).

@mguentner
Copy link
Owner Author

Currently the protocol information is transmitted without a delimiter, any node is expecting sizeof(CANNELLONI_CONNECT_V1_STRING)-1 bytes - so a constant length of 12 bytes.

That means it's quite trivial to increase the versions as long as they fit into 12 bytes. If another version (e.g. 2) should require options, these could be read after having negotiated the version, e.g.

[CANNELLONIv2][OPTIONBYTES][MESSAGE][MESSAGE]

At the moment I don't see a need for options. (Dynamically) reducing the frame / data rate is quite complex as within a CAN bus design you shouldn't drop frames randomly but prioritize some.
I would say that #32 might be a better approach to solve such issues.

My hope is that v1 will provide some learnings and also define such options.

@mguentner mguentner linked an issue Mar 15, 2023 that may be closed by this pull request
@mguentner mguentner merged commit 68ac396 into master Mar 24, 2023
@mguentner mguentner added cannelloni_v2 Feature for a new protocol version feature labels Apr 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cannelloni_v2 Feature for a new protocol version feature
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Implement TCP connection
2 participants