-
Notifications
You must be signed in to change notification settings - Fork 10
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
Stateful connections #2
Comments
Hi there, thanks for your interest in this somewhat neglected project! :) While I'm not personally very excited by stateful AX.25 connections, it's definitely in scope for this crate and it would be nice to have a platform-agnostic implementation in the Rust ecosystem. If you want to have a go writing it I'll certainly review it for you and merge it in. If you go down that path I just want to confirm some basic architectural things. I always figured that a higher level protocol could be implemented by wrapping the existing frame-level Secondly, for simplicity (and low performance requirements) I used a very simple blocking interface. So no pressure. I'm unlikely to do this work. Let me know if you're tackling it and I'll do what I can to clear your path, but otherwise these notes can stay here for anybody who wants to pick it up. |
Here's roughly what I was thinking: The The By default, the
How does that sound to you? |
Cool, that sounds okay. Just two thoughts:
While the connection is operational it needs to do certain tasks spontaneously (more strictly, on a timer) like retransmissions and ACKs. Would you do this on a background thread, or would the user of the Connection be required to call a
I think both of these will need to be a In any case I'm pretty comfortable with what you're describing. If you want to run anything past me please do but otherwise I'm happy to wait and see what you come up with! |
I thought about it some more, and the Your logic makes sense and I agree a |
Ah you raise an interesting point. The simple Option 1: Totally distinct It would be possible to write an app using Each Overall this option is a bit clunky from the app developer's perspective, but modular and powerful. Option 2: Bring the thread into the Perhaps it would be nice for the crate to be more integrated. We could replace Our hypothetical app now becomes a bit simpler. We open the Option 3: In the options so far, How do we handle the monitoring tab in our example app? I guess we would need to change the external interface to More interestingly, how do we actually send and receive user messages on the Also I don't think the Conclusion Either option 1 or 2 makes the most sense to me. What you said about the
Yep, exactly. That would be most appropriate for a library like this one. I already have a couple of such enums, though looking at it now I should move to |
Personally, I still feel that option 3 is the most elegant. To me, it seems like option 2 and option 3 are similar - option 2 just holds a bunch of receivers, instead of a bunch of connections. With option 3, the |
Slight correction - if we want to allow the |
Fair enough. I guess I have a preference for actors/channels over shared ownership but if you're confident in it then let's go with it. If we're doing that, we should make sure that dropping the As an aside, it would be awesome if the inner connection state machine was unit testable, i.e. messages can be loaded in and out with explicit timestamps, rather than using |
I thought about it some more, and I actually think option 2 is better. I think my idea of having an array of mutexes could cause problems if the user also wanted to use mutex - I think possibly a deadlock condition could arise. I think that would also make it decently unit-testable OOTB; In unit tests, a custom sender/receiver pair could be created, and the receiver could be passed into the connection. |
Quick question about AX25 that I hope you could answer(running into this while implementing stateful connections) Are UI frames and I frames the same thing, but UI frames are used when the data can fit into a single frame? Otherwise, I assume, it's broken up into multiple I frames. |
I haven't studied the specs for a while but that doesn't sound right to me. The key feature of an Fragmentation of longer messages than fit in a frame is, I would argue, not our concern. The old AX.25 v2.0 spec I believe says nothing on the matter. The v2.2 one mentioned earlier defines an abstract interface for a segmenter/reassembler, but in practice you can do whatever fragmentation you want at the "application" (or sub-application) level. The only exception is that we should expose whether there is a limitation on the maximum length of an information frame defined in the TNC we are using. For example you can set such a limit in (Minor aside: the frame format as currently implemented is based on the v2.0 spec. In an ideal world it will be upgraded to support the full range of v2.2 frames but those stations are so rare that it would be far, far more useful to get v2.0 connections working first.) |
Ah, okay. That makes sense.
I think it would be nice if |
I agree, but I don't think I'm agreeing in quite the same way. :) I want to make three small background points first to show what I'm talking about. Frame sizes The spec allows an information field in a single frame to be up to 256 octets. However many operators choose to run at a smaller maximum of 80-120 octets. These shorter frames have less chance of being destroyed by noise or interference, so you get better throughput overall and longer ranges. The app developer should have the ability to control this. However sometimes the <256 limitation is external to the app (see #6). Lack of segmentation To my knowledge, AX.25 has no convention for splitting and reassembling a message that doesn't fit in a single This means that if you come up with a segmentation protocol, you can't use it to talk to anybody else except your own application, since no other stations will understand it. Since it is not part of AX.25, I don't think that functionality belongs in the library. (But we can make it easy to incorporate this behaviour! More on that in a moment.) Consistent frames, not streams TCP doesn't provide message boundaries. If you write an app that sends the following strings into a TCP connection:
...then it is most likely that the other side will receive AX.25 does not work like that. Frames are guaranteed to be passed from end to end, with information fields which will not be split into pieces or merged together. That means if you want to, you can use frames as implicit delimiters. You could send the two messages above, and the receiver would get What to do? With all of this in mind, I suggest a three-level API for
|
That makes perfect sense to me. Thanks for clarifying. |
Sorry for all the questions, but do you know how the timers t1, t2, and t3 are supposed to work? When they're stopped, should they reset? |
In the spec have a look at section 6.7.1. If you haven't done it before, I'd suggest you get a connection to your local BBS working using existing software and spend some time analysing the traffic with a tool like |
Okay, thanks. I'm out of town this week but I'll give that shot once I'm home. |
Are there any plans to add stateful connections to this library? I noticed it wasn't on the roadmap. Alternatively, if I implemented stateful connections, would a PR be accepted?
Awesome project, by the way!
The text was updated successfully, but these errors were encountered: