Skip to content

Clarify position-zero fallback after EDSLIB_NO_MATCHING_VALUE in derived dispatch #120

Description

@FAROTECH

Summary

While exercising the generated EDS dispatch path in a native cFS/EdsLib runtime, I observed a case where the base argument type had registered derivatives, but the received buffer matched none of them.

On the current dispatcher path, the non-success result from derivative identification falls back to dispatch table position 0. In the exercised command family, that caused an otherwise undefined selector to invoke the first valid typed handler.

I am filing this as a semantics clarification rather than assigning a defect classification.

Current behavior

Current nasa/EdsLib dev baseline checked:

b7ea0c591ce19b70b063553a81cee9af831ce207

Relevant path:

CFE_EDSMSG_Dispatch()
  -> CFE_EDSMSG_Dispatch_FindArgType()
  -> CFE_EDSMSG_Dispatch_CheckActualBufferType()
  -> EdsLib_DataTypeDB_IdentifyBufferWithSize()

Current source:

https://github.com/nasa/EdsLib/blob/b7ea0c591ce19b70b063553a81cee9af831ce207/cfecfs/edsmsg/fsw/src/edsmsg_dispatcher.c

The relevant control flow is effectively:

Status = EdsLib_DataTypeDB_IdentifyBufferWithSize(...);

if (Status == EDSLIB_SUCCESS)
{
    /* use identified derivative */
}
else
{
    *DispatchTblPosition = 0;
}

The subsequent lookup and size check use the retained base type and can still return CFE_SUCCESS, after which dispatch position 0 is used.

At the EdsLib API layer, EdsLib_DataTypeDB_IdentifyBufferWithSize() propagates the result from EdsLib_DataTypeIdentifyBuffer_Impl():

https://github.com/nasa/EdsLib/blob/b7ea0c591ce19b70b063553a81cee9af831ce207/edslib/fsw/src/edslib_datatypedb_api.c

The underlying identification implementation initializes the result as EDSLIB_NO_MATCHING_VALUE and changes it to EDSLIB_SUCCESS only when a derivative result is identified:

https://github.com/nasa/EdsLib/blob/b7ea0c591ce19b70b063553a81cee9af831ce207/edslib/fsw/src/edslib_datatypedb_constraints.c

EDSLIB_NO_MATCHING_VALUE is a distinct EdsLib status (-8) for the no-match condition.

Runtime observation

The original runtime characterization used a frozen native cFS/EdsLib lane:

cFS
  088b2fa828db9ff7e00733f1908e0eeb59f66ce3

cFE
  c5fb2b4d540bd55eb6c3707da7dd13eee679d4dd

EdsLib
  2acc963b34f77692c6396555dcfb10ef43eb1046

The generated EDS command family had two valid command derivatives.

Selector Derivative status Observed result
Function Code 0 matching derivative first typed handler observed
Function Code 1 matching derivative second typed handler observed
Function Code 127 no generated derivative with that selector first typed handler observed

For the unmatched case, the structurally coherent packet was:

18 97 c0 00 00 01 7f ce

The observed typed handler was the same handler selected by Function Code 0.

Causal pressure test

To test whether the position-zero fallback was the relevant boundary, I performed an evidence-only intervention in a disposable build of the same pinned EdsLib baseline.

The intervention did not special-case Function Code 127 and did not modify the generated EDS command model.

It only distinguished:

base has zero derivatives
    -> preserve position-zero dispatch

base has derivatives + matching derivative
    -> preserve normal derivative dispatch

base has derivatives + no matching derivative
    -> return validation failure

The distinction used the existing EdsLib_DataTypeDB_GetDerivedInfo() metadata, including NumDerivatives.

Under that pressure test:

Case Result
matching derivative, FC 0 existing first typed handler still observed
matching derivative, FC 1 existing second typed handler still observed
base with derivatives, FC 127 matches none rejected at generated dispatch
genuinely non-derived NASA SAMPLE_APP/SEND_HK position-zero handler still observed

This supports the position-zero fallback as the causal boundary for the observed unmatched-derived behavior.

The evidence-only change is not being proposed here as a patch. It was used only to distinguish the runtime cases.

Historical context

There is one historical detail that may help determine intended semantics.

Before the 2026 cFS Draco batch update, the EdsLib dispatcher implementation explicitly entered derivative identification only when the interface metadata reported subcommands. If derivative identification then failed, it returned CFE_STATUS_UNKNOWN_MSG_ID rather than selecting the first dispatch entry.

Previous implementation:

https://github.com/nasa/EdsLib/blob/7eb94477c5aa32a2dba1f342df720a56722821a1/cfecfs/edsmsg/fsw/src/cfe_msg_dispatcher.c

The Draco batch update that introduced the current edsmsg_dispatcher.c form is:

0ce8acd

I am not assuming that this establishes a regression. I mention it because the previous and current dispatch paths appear to treat failed derivative identification differently, and that may be useful context for clarifying the intended contract.

Questions

For a base argument type that has one or more registered derivatives:

  1. Is falling back to dispatch position 0 intentional when EdsLib_DataTypeDB_IdentifyBufferWithSize() returns EDSLIB_NO_MATCHING_VALUE?
  2. Should a genuinely non-derived base type and a base with derivatives but no matching runtime derivative be semantically distinguished by the dispatcher?
  3. If position 0 is intentionally used in the unmatched-derived case, is it meant to represent a defined default handler, or only the sole entry used for genuinely non-derived types?
  4. If the unmatched-derived case is intended to fail, which cFE/EdsLib status is considered the appropriate public dispatch result?

Public evidence

The retained public runtime and causal characterization is available here:

https://github.com/FAROTECH/orbitfabric-eds-cfs-adapter/actions/runs/34048728392

The GitHub Actions run completed successfully because its acceptance criterion was characterization of the observed behavior, not automatic rejection of the undefined Function Code.

A small curated evidence bundle is attached with the issue. It contains the original observation summary, positive controls, the genuinely non-derived control, and the evidence-only causal-control patch. The patch is included as test evidence, not as a proposed implementation.

Provenance

This behavior surfaced while validating a public EDS/cFS interoperability integration. The question here is specifically about the intended EdsLib dispatch semantics and does not require any OrbitFabric-specific behavior.

nasa-edslib-derived-dispatch-evidence.zip

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions