OSDLP design question

Hey Libre community,

Paul here… we are attempting to integrate the CCSDS Datalink/COP-1/SPP code @ this repo: librespacefoundation / Open Space Data Link Protocol · GitLab into our own code.

I’ve also found the qubik implementation that uses this code.

So, we want to be be able to support COP-1 expedited and sequence controlled telecommands. We also want to route these telecommands to 1 of 3 code services that handle either:

CFDP (file transfer - our own implementation)
Telecommand handler (our own implementation)
Telemetry request hander (our own implementation)

I can see that in the qubik implementation, there is a task (entry point start_osdlp_task). This task seems to decode the CCSDS synchronisation and channel coding bits and then presents the CCSDS TC Datalink frame to the OSDLP code… All fine so far.

Now I get a bit hazy… OSDLP takes this data, decodes the frame and does something with it. Esentially, I am trying to work out where I hook in the code that forwards this telecommand frame to either CFDP, telecommand handler or telemetry request handler?

I can see that the start_osdlp_task code gets the last tc and then enables a transmission task… I’m not sure exactly why but I am guessing that this has something to do with the qubik radio transceiver that is maybe either in transit or receive mode??

Any help in regards to the OSDLP/QUBIK comms code design would be handy… the doxygen pages seem empty?

Many thanks,

Paul.

1 Like

Hey Libre people,

I have been doing some digging through the code and have evaluated the following design regarding telecommands (uplink):

Essentially:

  • The “start_osdlp_task” gets the TC datalink frame and passes it to the OSDLP code.
  • The OSDLP code looks to see if this is a segmented frame etc and eventually adds the frame to another (non-FreeRTOS) queue.
  • The “start_mgmt_task” dequeues the message and deals with it… i.e. analyses the content to identify what the command is for e.g. deploy panels.

So here are a few questions:

  • The queue mechanism used between “start_osdlp_task” and “start_mgmt_task” does not use a FreeRTOS queue but a custom queue instead. What is the rationale for this?
  • I want to reduce the number of tasks down to a minimum and therefore, could I use 1 task that picks off the CCSDS datalink frame, calls the OSDLP code to pick out the data within the frame and then move that on to the necessary Telemetry/Telecommand/CFDP handlers? I guess I am asking what the rationale for the above 2 tasks is?

Many thanks,

Paul.

Hey all,

I love what you guys have done here with the OSDLP code, many thanks.

I’m really trying to understand how I might integrate this code into our stuff… Any advice on the above questions would be really appreciated.

Many thanks,

Paul.

1 Like

Let me try to tag @Sleepwalker - he might be the right person here.

2 Likes

Hello @paulmadle !

Sorry for the late response and thanks to @DL4PD for bringing this to my attention.

So as I see you already have a very good understanding of the code. Unfortunately this implementation was done a while ago in a very short time frame so it might not be ideally structured, and certainly it’s not well documented, but we plan to fix that soon. Now as for your questions:

The queue mechanism used between “start_osdlp_task” and “start_mgmt_task” does not use a FreeRTOS queue but a custom queue instead. What is the rationale for this?

If you take a look at the header files of the OSDLP library such as cop.h, you will se that all the functions related to the ques are __attribute__((weak)) at the start of their declaration. This is somehow equivalent to an abstract function in C++ and it means that the user must implement these functions in their own codebase. The rationale behind this is to make OSDLP as flexible as possible in order to be used in various systems with various performance limitations. This way the user can choose the queue implementation that best fits their design and their system. So you could as well use RTOS queues here.

I want to reduce the number of tasks down to a minimum and therefore, could I use 1 task that picks off the CCSDS datalink frame, calls the OSDLP code to pick out the data within the frame and then move that on to the necessary Telemetry/Telecommand/CFDP handlers? I guess I am asking what the rationale for the above 2 tasks is?

So basically as you also said, the very first entry point in the OSDL library from the side of TC receive is the osdlp_tc_receive function. What that will do is to queue the incoming TC at the appropriate queue based on the VCID. It made sense for us at that point to have a separate task for each VCID polling the corresponding queue for whenever a TC would arrive (using the receive_tc function). If you only want to have one task, you could, after the call to osdlp_tc_receive, check which queue was populated and handle over control of further processing of this frame to the appropriate higher level task depending on the received VCID. If you see in the start_osdlp_task after the call to osdlp_tc_receive there is also a tc = get_last_tc();. What this does, is it returns a tc_transfer_frame object corresponding to the last received TC with information about its VCID. We’re using that so as to send a corresponding acknowledgment after each reception.

If I haven’t completely answered your questions or if you have further ones I’d be happy to help!

Cheers!
George

2 Likes

Many thanks for the info @Sleepwalker, much appreciated.

We’ve now been integrating this OSDLP code into our code base… We have so far managed to send an expedited telecommand that switches on and off an LED, all good…

We are now moving on to telemetry data and here is a question:

In the qubik comms code, the function that deals with telemetry frame transmission is called “transmit_tm()”. This function calls “tm_get_tx_config()” passing in the VCID in order to prepare for the outgoing data. All fine so far…

Then this code calls “osdlp_tc_get_rx_config()” passing in the SAME VCID.

So now some questions:

  • I assume that the need to be reading the rx config at this stage is so that the code can prepare the CLCW field appropriately for COP-1 ARQ?
  • Our code supports 2 Virtual Channels on the uplink (telecommand) and 4 Virtual Channels on the downlink (telemetry). Whereas the qubik code must be in some way linking the uplink and downlink virtual channels together in order to support COP-1?
  • I’m not really sure why VCIDs are relevant to the production of the CLCW field in the telemetry frame? My understanding is that COP-1 sequence controlled telecommanding will work independent of the selected virtual channel… I think I must be missing something? Any help/pointers would be much appreciated.

So the way we went about this is that we had in total 4 different Virtual Channels. We did not differentiate between telemetry and telecommand VCIDs, as seen here at the end where they are defined. Also, it is mentioned in the standard in many places that the COP-1 runs per VC. So each VC should have their own FOP and FARM instance, and therefore their own CLCW (hence the vcid field in the CLCW). For example, Page 2-1 of COP-1 specification:

COP-1 consists of a pair of synchronized procedures for each Virtual Channel: a Frame
Operation Procedure-1 (FOP-1) that executes within the sending entity, and a Frame
Acceptance and Reporting Mechanism-1 (FARM-1) that executes within the receiving entity.
The FOP-1 transmits Transfer Frames of a particular Virtual Channel to the FARM-1 of the
same Virtual Channel. The FARM-1 returns reports of the status of Transfer Frame
acceptance to the FOP-1 using the Communications Link Control Words (CLCWs)

How you transmit this CLCW to the ground is not mentioned in the standard and it’s an architectural decision. This is useful when for example you need the COP-1 mechanism for a certain VC but you don’t need it for another.

If I haven’t covered you for some reason, please let me know.

Aha, excellent… That makes more sense now. So I guess for COP-1 sequence controlled telecommanding to work correctly, the VCID for uplink and downlink must match. i.e. the telemetry frame VCID must match that of the telecommand.
Sorry to be asking you CCSDS questions… It’s sometimes a little tricky to decypher it.

1 Like

Hey @Sleepwalker,

Thanks for your help on all of this… We now have OSDLP integrated into our flight software and talking both ways to YAMCS. Excellent work!

We are hoping to present a “CCSDS Space<>Ground comms for Dummies” webinar in November and wondered if you might be interested in presenting a few slides on OSDLP? It would be a session explaining TC/TM datalink and Space Packet protocols as well as presenting COP-1 sequence controlled protocol and how it works and why you might want to use it.

1 Like