Skip to content
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

expose CFE_SB_IsValidMsgId() #263

Closed
skliper opened this issue Sep 30, 2019 · 19 comments · Fixed by #602
Closed

expose CFE_SB_IsValidMsgId() #263

skliper opened this issue Sep 30, 2019 · 19 comments · Fixed by #602
Assignees
Milestone

Comments

@skliper
Copy link
Contributor

skliper commented Sep 30, 2019

CFE apps would benefit from a publicly-available IsValidMsgId() function (or perhaps an expanded "is valid message" function, that would check all header fields?)

For example, SCH has a function to validate its message table entries and has its own logic for determining whether a message ID is valid or not.

This would particularly facilitate CCSDS_VER_2 transitions.

@skliper skliper added this to the 6.7.1 milestone Sep 30, 2019
@skliper skliper self-assigned this Sep 30, 2019
@skliper
Copy link
Contributor Author

skliper commented Sep 30, 2019

Imported from trac issue 232. Created by cdknight on 2018-01-16T18:26:34, last modified: 2019-07-03T12:48:08

@skliper
Copy link
Contributor Author

skliper commented Sep 30, 2019

Trac comment by jphickey on 2018-05-14 14:35:14:

Upvote this for next cFE release.

Particularly with the recent addition of extended CCSDS header, it is not necessarily a trivial check to determine if a MsgId value is valid or not. Apps should not be making assumptions about this value, and should only treat it as an opaque value.

Note that #245, if implemented, will turn any comparison test of MsgId values into a compiler error (a good thing). This would necessitate having a function to call in its place.

@skliper
Copy link
Contributor Author

skliper commented Sep 30, 2019

Trac comment by dcmccom3 on 2018-11-15 09:19:31:

In addition to the run-time functional change, we should create a compile-time solution. Multiple apps use an undefined MID macro for default table values. I looked at three apps(DS, HK, and SCH) and they each define a local undefined MID macro. They're also inconsistent in their definitions. DS & HK use 0 and SCH uses 0x1897.

Some preliminary thoughts:

  1. The EDS build tool chain may be the long term solution
  2. We need to check whether an app's code makes assumptions about the local definition. For example, simply checking whether a MID is great than the undefined value because the undefined value is assumed to be zero.

@skliper
Copy link
Contributor Author

skliper commented Sep 30, 2019

Trac comment by jphickey on 2018-11-15 09:38:37:

Can you elaborate on "compile-time solution"? There are two possibilities:

  • A value to use as a placeholder/initializer for msgids within data structures
  • A method to check if a given msgid is valid.

We also need to be sure apps differentiate between a "MsgId" and "TopicId". Many places that are checking MIDs would be better served by checking a topic ID instead and I think this will solve a lot of the issue.

Per our previous CCB nomenclature discussions (around the time of the CCSDS v2 header review), a topic ID is defined to be consistent across all CPUs in a mission (so i.e. CFE_ES is always assigned topic ID=1) whereas the MsgId is unique to a given instance of the app (so MsgId of CFE_ES on CPU1 is different than MsgId of CFE_ES on CPU2).

In other words, TopicId is a "normailzed MsgId".

The problem with MsgId is that there isn't one specific value we can isolate at compile time and say its always invalid, because it depends on framing type. TopicId is better here, as we //can// say that e.g. TopicId=0 is always reserved/invalid and this is independent of the framing type.

Historically we lacked this differentiation and apps were simply checking MsgId because its the value they got from the frame, when they probably should have been checking TopicId.

@skliper
Copy link
Contributor Author

skliper commented Sep 30, 2019

Trac comment by jhageman on 2019-07-03 12:48:08:

Moved unfinished 6.6.1 issues to next minor release

@skliper skliper removed their assignment Sep 30, 2019
@skliper skliper modified the milestones: 6.7.1, 6.7.0, 6.8.0 Sep 30, 2019
@skliper skliper removed this from the 6.8.0 milestone Nov 4, 2019
@skliper
Copy link
Contributor Author

skliper commented Nov 20, 2019

There is a related email chain requesting CFE_SB_GetPktType be exposed as an API, with responses of cmd, tlm, or invalid. This would support proposed SCH message table update to create the right type of packets using the MsgId.

@skliper
Copy link
Contributor Author

skliper commented Mar 6, 2020

Worth a note exposing as an API also needs a requirement and stub.

@skliper
Copy link
Contributor Author

skliper commented Mar 31, 2020

I'm concerned at this point MsgId to hdr and hdr to MsgId is more appropriately defined by the project, and you may need more information to go from MsgId to hdr. I think it will be challenging to generalize due to the extension and variety of use cases, other than saying there needs to be conversion APIs and it needs to produce a unique MsgId for each SB route., and fill in the rest of the header based on a MsgId? Or maybe these tables shouldn't use MsgId to try to fully define the header and we would benefit from separating the SB routing concept from generating headers?

@jphickey
Copy link
Contributor

Yes, I agree that the conversion from a packet content to CFE_SB_MsgId_t value and vice versa needs to be isolated into code which the user may modify if they so choose. This is precisely what the EDS modifications developed by the GHAPS project did. There is a separate library for that handles the "translation" jobs of getting/setting a CFE_SB_MsgId_t from a packet payload in memory, as well as translating a CFE_SB_MsgId_t to a TopicId value.

However, all that being good - it is still separate from this issue, where we still need to expose this API regardless. This is intended to just test if a given CFE_SB_MsgId_t value is OK and it needs to be based on how the type is defined - we need to get away from apps directly doing an integer comparison on this value, it violates the opaqueness/abstraction that it is supposed to have.

@skliper
Copy link
Contributor Author

skliper commented Mar 31, 2020

Agreed, separate issue.

@skliper
Copy link
Contributor Author

skliper commented Apr 10, 2020

@jphickey Do you have time to split the fix out from #592 and submit a pull request covering this issue this round? @ejtimmon is pending on this to resolve some final app tickets.

@skliper skliper added this to the 6.8.0 milestone Apr 10, 2020
@jphickey
Copy link
Contributor

Yes, I will submit something today

@jphickey
Copy link
Contributor

Clarification question -- what was the verdict on the application of API functions like:

if (CFE_SB_MsgId_Equal(MessageID, CFE_ES_SEND_HK_MID))

in place of the switch() statement?

Ideally I'd like to get that, plus the proper application of CFE_SB_MsgIdToValue/MsgIdFromValue macros into the build ASAP. (and of course exposing the IsValidMsgId routine too).

@skliper
Copy link
Contributor Author

skliper commented Apr 10, 2020

Yup, those changes are all good to go this round.

@CDKnightNASA
Copy link
Contributor

Quibble, given that this will have long-term ripple effects, could we call it "CFE_SB_MsgId_Is()" instead of "Equal"? Also removes the expectation that the MsgId is a scalar value.

jphickey added a commit to jphickey/cFE that referenced this issue Apr 10, 2020
Make CFE core apps consistent in their use of the CFE_SB_MsgId type
and with the CFE SB API.  This employs the CFE SB API whenever any
of the following needs to happen:

- Use of a CFE_SB_MsgId_t value within a printf (event, syslog, etc).
- Initialization of a CFE_SB_MsgId_t from an integer value
- Comparison of two CFE_SB_MsgId_t values
- Checking if a CFE_SB_MsgId_t value is within the valid set

Notably, this replaces the switch/case constructs used in message
dispatch with a nested if/else based on CFE_SB_MsgId_Equal(), as
the switch statement can only be used with an integer.

A few new macros are introduced, mainly because the inline functions
that already existed for this purpose cannot be used where evaluation
must be done at compile time (e.g. constants, struct initialization).
These are initially just typecasts, but could become more interesting
in future revisions.
@jphickey
Copy link
Contributor

I don't think the term Equal implies a scalar.... there is precedent for this too (e.g. see pthread_equal).

jphickey added a commit to jphickey/cFE that referenced this issue Apr 10, 2020
Make CFE core apps consistent in their use of the CFE_SB_MsgId type
and with the CFE SB API.  This employs the CFE SB API whenever any
of the following needs to happen:

- Use of a CFE_SB_MsgId_t value within a printf (event, syslog, etc).
- Initialization of a CFE_SB_MsgId_t from an integer value
- Comparison of two CFE_SB_MsgId_t values
- Checking if a CFE_SB_MsgId_t value is within the valid set

Notably, this replaces the switch/case constructs used in message
dispatch with a nested if/else based on CFE_SB_MsgId_Equal(), as
the switch statement can only be used with an integer.

A few new macros are introduced, mainly because the inline functions
that already existed for this purpose cannot be used where evaluation
must be done at compile time (e.g. constants, struct initialization).
These are initially just typecasts, but could become more interesting
in future revisions.
@skliper
Copy link
Contributor Author

skliper commented Apr 10, 2020

or could just if (CFE_SB_MsgIdToValue(MsgId)==value). IsEqual in my mind is for checking things of the same type, as in seeing if two MsgId's are equal. I don't have strong feelings with any of these suggestions, just adding another suggestion.

EDIT - typo

@skliper
Copy link
Contributor Author

skliper commented Apr 10, 2020

Or just relate the handler directly with the MsgId and skip the value all together. Somewhat related to suggestion to go to tables, and be able to register/unregister command handlers?

jphickey added a commit to jphickey/cFE that referenced this issue Apr 10, 2020
Make CFE core apps consistent in their use of the CFE_SB_MsgId type
and with the CFE SB API.  This employs the CFE SB API whenever any
of the following needs to happen:

- Use of a CFE_SB_MsgId_t value within a printf (event, syslog, etc).
- Initialization of a CFE_SB_MsgId_t from an integer value
- Comparison of two CFE_SB_MsgId_t values
- Checking if a CFE_SB_MsgId_t value is within the valid set

Notably, this replaces the switch/case constructs used in message
dispatch with a nested if/else based on CFE_SB_MsgId_Equal(), as
the switch statement can only be used with an integer.

A few new macros are introduced, mainly because the inline functions
that already existed for this purpose cannot be used where evaluation
must be done at compile time (e.g. constants, struct initialization).
These are initially just typecasts, but could become more interesting
in future revisions.
@jphickey
Copy link
Contributor

Or just relate the handler directly with the MsgId and skip the value all together. Somewhat related to suggestion to go to tables, and be able to register/unregister command handlers?

Yes - the intent should be to get away from application code assuming there is some single integer "value" behind the MsgId in the first place. In C++ we could override the == operator, but in C we cannot so hence why we need a named equality test function.

But as the value is included in a number of syslog and event messages as an integer, the integer representation will probably need to exist for some time.

Message Dispatching should be done using a dispatch table that is simply registered in SB, so code doesn't need to replicate this in every app. Right now there is a lot of code that is similar between apps but all a little different.

After start up, the run loop would just be something like:

    while (CFE_ES_RunLoop(&SAMPLE_AppData.RunStatus))
    {
        /* Pend on receipt of command packet */
        status = CFE_SB_RcvMsg(&SAMPLE_AppData.MsgPtr,
                               SAMPLE_AppData.CommandPipe,
                               SAMPLE_APP_POLL_TIMEOUT);

        if (status == CFE_SUCCESS)
        {
            CFE_SB_DispatchMessage(SAMPLE_AppData.MsgPtr, &SAMPLE_CMD_DISPATCH_TABLE);
        }
    }

The SAMPLE_CMD_DISPATCH_TABLE could be auto-populated by the build system based on the commands that are enabled/disabled in the user config. Once we have each command handler in a separate compilation unit, this is easy.

At any rate, once this is in possible, the entire duplication of effort in e.g. SAMPLE_ProcessCommandPacket, SAMPLE_ProcessGroundCommand that one sees in every app can go away, and the MsgId equality test would probably be very rarely used by the apps at that point.

jphickey added a commit to jphickey/cFE that referenced this issue Apr 13, 2020
Make CFE core apps consistent in their use of the CFE_SB_MsgId type
and with the CFE SB API.  This employs the CFE SB API whenever any
of the following needs to happen:

- Use of a CFE_SB_MsgId_t value within a printf (event, syslog, etc).
- Initialization of a CFE_SB_MsgId_t from an integer value
- Comparison of two CFE_SB_MsgId_t values
- Checking if a CFE_SB_MsgId_t value is within the valid set

A few new macros are introduced, mainly because the inline functions
that already existed for this purpose cannot be used where evaluation
must be done at compile time (e.g. constants, struct initialization).
These are initially just typecasts, but could become more interesting
in future revisions.
jphickey added a commit to jphickey/cFE that referenced this issue Apr 13, 2020
Make CFE core apps consistent in their use of the CFE_SB_MsgId type
and with the CFE SB API.  This employs the CFE SB API whenever any
of the following needs to happen:

- Use of a CFE_SB_MsgId_t value within a printf (event, syslog, etc).
- Initialization of a CFE_SB_MsgId_t from an integer value
- Comparison of two CFE_SB_MsgId_t values
- Checking if a CFE_SB_MsgId_t value is within the valid set

A few new macros are introduced, mainly because the inline functions
that already existed for this purpose cannot be used where evaluation
must be done at compile time (e.g. constants, struct initialization).
These are initially just typecasts, but could become more interesting
in future revisions.
jphickey added a commit that referenced this issue Apr 22, 2020
Manually merged to resolve conflicts.

From branch jphickey/fix-263-msgid-api:

Fix #245, Consistent use of MsgId type
Fix #263, Expose CFE_SB_IsValidMsgId() API

From branch dmknutsen/issue_240:

Fixes #240, removes MESSAGE_FORMAT_IS_CCSDS ifdefs from code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants