dariol83 / ccsds

Open source Java implementation of publicly available CCSDS standards: SLE, TM/TC, AOS, Space Packets, COP-1, time formats, CFDP, Encapsulation Packets.
Apache License 2.0
96 stars 29 forks source link

[Question/Thoughts] Splitting TX and RX over different CFDP layers #22

Closed markjohndoyle closed 4 months ago

markjohndoyle commented 6 months ago

Hey Dario,

I was looking into splitting TX and RX over different CFDP layers. Looking through the code, nothing jumped out that would suggest this wouldn't work and the good news is that it does work fine! Hopefully, this explains it: image

However, I did have to perform what you might call a little hack, that is, setting the intial availability of the layers for rx and tx on both layers. So even though one layer was only used the tx it need to be flagged available for rx and vice versa for the receiving layer.

This raises the question, is this an abuse of the standard or is it just a little quirk of the lib when creating transactions? The CfdpTransaction will check it's own rxAllowed/txAllowed flags (isFrozen) so I think these can be set independently after the transaction is created. This means it might just be the fact the library constructs the outgoing (or incoming) transaction using the current availability of only the layer specified by the remote see here

In a split layer scenario with an outgoing transaction there isn't an obvious way to link the rx layer availability to the transaction because there is no way for the local entity to know what layer the remote entity will use to respond. Maybe it can just check if any "local" layer is available for rx on that target remote?

Hope that makse sense!

dariol83 commented 5 months ago

Hi Mark,

Thanks for the question, this is an interesting point, and I would need to read that part of the standard again to see if actually the two functions (TX/RX) should be decoupled and, if so, how I should change the internal design of the library.

Have you also thought of an approach of "composing" two UT layers into a single one, by some sort of composite + delegation pattern? The CfdpEntity will still see a single UT layer, which will use two different transmission technologies beneath. Of course, if your purpose is to independently set/react on TX/RX availability, this would not solve your issue.

Let me check the standard and the code, and come back to you.

Cheers, Dario

dariol83 commented 5 months ago

Hi again,

I read the standard again and I checked my code again. The standard indeed "imposes" a single UT Layer:

"The protocol assumes the availability of a single conceptual underlying communication system, referred to as the ‘Unitdata Transfer (UT) layer’, to which all CFDP entities in a given CFDP addressing domain have access. In order that the protocol may operate over a wide range of implementations, the services required of the UT layer have intentionally been kept as simple as possible; those services are assumed to be made available to any single CFDP entity at only a single conceptual service access point."

Taking this literally, the concept of TX/RX opportunity applies to the UT layer as a whole, but it is handled differently, depending whether a transaction is sending or receiving. In case of sending and receiving transactions in class 1, the sending transaction will care only about the TX and the receiving transaction will use only RX. But in class 2 the transaction (whatever type) must be able to handle (and it is interested in) both. In my code, the CfdpEntity is designed to be unaware of the specific transaction class: this is the reason why both calls to update...Opportunity are performed on the transaction in both cases (PutRequest or new incoming transaction created). In these two cases I might push the enquiry into the respective classes (i.e. in the transaction activation) and there set the availability depending on the class type, but I am afraid it won't change much: given a destination, the UT Layer that is returned is always the same one, according to the configuration in the MIB (RemoteEntityConfigurationInformation, i.e. one remote entity = 1 UT layer). I don't see how this can change.

There is also another aspect: the CfdpEntity also receives from the UtLayer the notification that a RX/TX opportunity window started or finished. The CfdpEntity is simply forwarding this to the transactions affected by the opportunity window.

To summarize: even if my lib might allow some sort of flexibility with UT Layers, the expectation of the standard and the related protocol is to have 1 UT Layer per CFDP entity addressing space. So the option to have 2 UT layers for RX and TX to handle the communication to two CFDP entities is not really valid. So to respond to your last observation:"In a split layer scenario with an outgoing transaction there isn't an obvious way to link the rx layer availability to the transaction because there is no way for the local entity to know what layer the remote entity will use to respond." You are right, there is no way to know. That's the reason why I would always assume that RX is always possible on any layer. Remember that the RX/TX observability is something that must be managed outside of the CFDP entity/transaction, i.e. by your application or by your UT layer implementation. CFDP Entity and transactions are only informed about that.

Said this, nobody prevents you to have a "combined" UT layer where the RX part is via TCP and the TX part is via Kafka: you could create a "composite" Ut Layer implementation for mixed Ut Layers, where you could theoretically use more possible channels (e.g. a TCP connection, Kafka queues for RX and TX) and hide this composition to the CFDP entity. In such case, as already said, the derivation of the RX and TX opportunities should be delegated completely to your application or to the composite UT layer.

Not sure if I helped, but that's what I think. It looks more a complication to me and, if you really have the use case, I would try to implement a UT Layer that combines the different communication types, but have a single CFDP UT Layer at CFDP transaction/entity level (as per standard).

Let me know what you think.

Cheers, Dario

markjohndoyle commented 5 months ago

Thanks for the response, Dario!

Everything makes sense. The standard language is a little tough to parse but I think you are probably right!

I did originally create a composite layer, that wrapped two other layers, but this has the same issues where it had to set rx and tx on both of the wrapped layers. This made me suspicious it wasn't quite right.

I still think there is a theoretical discussion, for example,

that's the reason why I would always assume that RX is always possible on any layer.

Assuming this you could say, is there one layer available for RX to the required remote. I have a feeling that's all that is required. Enabling/Disabling (may not be the correct term) availability to a remote for a layer works fine with split layers. The state is tracked in the CfdpTransaction itself like you say.

But that's a coffee discussion, I don't think you should consider changing your lib!

I'll can always just create a layer that just combines the two protocols 😁

dariol83 commented 5 months ago

Hi Mark,

I'll can always just create a layer than just combines the two protocols

I think this is exactly what the standard assumes you would need to do! :D

Cheers, Dario