Define Parameters for a TC to be read by the CommandPostProcessor

12 views
Skip to first unread message

Patrick Dohmen

unread,
Jan 11, 2026, 5:38:06 AMJan 11
to yamcs
Hello group,

Is there a way to define parameters inside a TC to be used by the CommandPostProcessor?

I am currently trying to configure a "flag" if a TC needs authorisation or not, as we have a few commands that should be used by the amateur radio community. Of course there needs to be some protection for sensitive commands.

What I am trying now is:

<MetaCommand name="generic_cmd_hmac"
shortDescription="Send a generic TC with HMAC">
<LongDescription>
Sends a generic command to the S/C using HMAC authentication and verification
</LongDescription>
<AncillaryDataSet>
<AncillaryData name="HMAC">true</AncillaryData>
</AncillaryDataSet>
<BaseMetaCommand metaCommandRef="base_packet">
</BaseMetaCommand>
<ArgumentList>
<Argument argumentTypeRef="custom_cmd_payload_type" name="custom_cmd_payload"
shortDescription="Sends an HMAC signed Telecommand" />
</ArgumentList>
<CommandContainer name="generic_cmd_hmac">
<EntryList>
<ArgumentRefEntry argumentRef="custom_cmd_payload" />
</EntryList>
<BaseContainer containerRef="base_packet" />
</CommandContainer>
</MetaCommand>


<MetaCommand name="deploy_antenna" shortDescription="TC to deploy antenna">
<LongDescription>
To be defined...
</LongDescription>
<AncillaryDataSet>
<AncillaryData name="Yamcs:CcsdsMapId">3</AncillaryData>
</AncillaryDataSet>
<BaseMetaCommand metaCommandRef="generic_cmd_hmac">
<ArgumentAssignmentList>
<ArgumentAssignment argumentName="ccsds_apid" argumentValue="100" />
</ArgumentAssignmentList>
</BaseMetaCommand>
<CommandContainer name="deploy_antenna">
<EntryList />
<BaseContainer containerRef="generic_cmd_hmac" />
</CommandContainer>
</MetaCommand>


Then read in the processor:

/**
* Checks if a command requires HMAC protection based on ancillary data in the MDB.
*
* @param pc The prepared command
* @return true if the command should be protected with HMAC
*/
private boolean commandRequiresHmac(PreparedCommand pc) {
// Check for ancillary data flag in the command definition
String ancillaryValue = pc.getMetaCommand().getAncillaryData("HMAC");
if (ancillaryValue != null) {
// If the flag exists, check if it's set to true
return "true".equalsIgnoreCase(ancillaryValue) ||
"yes".equalsIgnoreCase(ancillaryValue) ||
"1".equals(ancillaryValue);
}
// If no flag is specified, default behavior (can be configured)
// Return false to require explicit opt-in, or true for opt-out behavior
return false;
}


This doesn't seem to work, at least, the expected value (here: true) does never appear .

Any help would be gratefully appreciated!

Best regards,
Patrick, DL4PD

fabia...@spaceapplications.com

unread,
Jan 12, 2026, 5:23:50 AMJan 12
to yamcs
deploy_antenna is extending the (abstract) base command generic_cmd_hmac. So the following is likely what you need: pc.getMetaCommand().getBaseMetaCommand().getAncillaryData("HMAC")

Patrick Dohmen

unread,
Jan 12, 2026, 7:55:43 AMJan 12
to yamcs
Thanks for that hint!
It wasn't the full solution but it lead me to the following (maybe overcomplicated) implementation.
I am not a java expert - just for the records ;-)

/**
* Checks if a command requires HMAC protection based on ancillary data in the MDB.
*
* @param pc The prepared command
* @return true if the command should be protected with HMAC
*/
private boolean commandRequiresHmac(PreparedCommand pc) {
// Get the list of ancillary data from the command definition
List<org.yamcs.xtce.AncillaryData> ancillaryDataList = pc.getMetaCommand().getBaseMetaCommand().getAncillaryData();
if (ancillaryDataList != null) {
// Search for the "HMAC" ancillary data entry
for (org.yamcs.xtce.AncillaryData data : ancillaryDataList) {
if ("HMAC".equals(data.getName())) {
String value = data.getValue();
// Check if it's set to true
return "true".equalsIgnoreCase(value) ||
"yes".equalsIgnoreCase(value) ||
"1".equals(value);
Reply all
Reply to author
Forward
0 new messages