diff --git a/.travis.yml b/.travis.yml index 0616343b8..8b098f179 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,8 +17,8 @@ script: # Check versions - cppcheck --version - #cppcheck flight software cfe/fsw/cfe-core/src - - cppcheck --force --inline-suppr --std=c99 --language=c --error-exitcode=1 --enable=warning,performance,portability,style --suppress=variableScope --inconclusive fsw/cfe-core/src 2>cppcheck_flight_cfe.txt + #cppcheck flight software fsw/cfe-core/src and modules + - cppcheck --force --inline-suppr --std=c99 --language=c --error-exitcode=1 --enable=warning,performance,portability,style --suppress=variableScope --inconclusive fsw/cfe-core/src modules 2>cppcheck_flight_cfe.txt - | if [[ -s cppcheck_flight_cfe.txt ]]; then echo "You must fix cppcheck errors before submitting a pull request" diff --git a/cmake/mission_defaults.cmake b/cmake/mission_defaults.cmake index 8f49d54d5..79d1fb1bd 100644 --- a/cmake/mission_defaults.cmake +++ b/cmake/mission_defaults.cmake @@ -14,6 +14,7 @@ set(MISSION_CORE_MODULES "cfe-core" "osal" "psp" + "msg" ) # The "MISSION_GLOBAL_APPLIST" is a set of apps/libs that will be built diff --git a/fsw/cfe-core/src/inc/cfe_msg_api.h b/fsw/cfe-core/src/inc/cfe_msg_api.h new file mode 100644 index 000000000..7584b1f76 --- /dev/null +++ b/fsw/cfe-core/src/inc/cfe_msg_api.h @@ -0,0 +1,665 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message access APIs + */ + +#ifndef _cfe_msg_api_ +#define _cfe_msg_api_ + +/* + * Includes + */ +#include "common_types.h" +#include "cfe_msg_hdr.h" +#include "cfe_msg_typedefs.h" +#include "cfe_time.h" +#include "cfe_sb.h" + +/** \defgroup CFEAPIMSGHeader cFE Message header APIs + * \{ + */ + +/*****************************************************************************/ +/** + * \brief Initialize a message + * + * \par Description + * This routine initialize a message. If Clear is true the + * message is cleard and constant header defaults are set. + * The bits from MsgId and message size are always set. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] MsgId MsgId that corresponds to message + * \param[in] Size Total size of the mesage (used to set length field) + * \param[in] Clear Boolean to clear and set defaults + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_Init(CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t MsgId, CFE_MSG_Size_t Size, bool Clear); + +/*****************************************************************************/ +/** + * \brief Gets the total size of a message. + * + * \par Description + * This routine gets the total size of the message. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Size Total message size + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetSize(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Size_t *Size); + +/*****************************************************************************/ +/** + * \brief Sets the total size of a message. + * + * \par Description + * This routine sets the total size of the message. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] Size Total message size + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetSize(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Size_t Size); + +/*****************************************************************************/ +/** + * \brief Gets the message type. + * + * \par Description + * This routine gets the message type. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Type Message type + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetType(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Type_t *Type); + +/*****************************************************************************/ +/** + * \brief Sets the message type. + * + * \par Description + * This routine sets the message type. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] Type Message type + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetType(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Type_t Type); + +/*****************************************************************************/ +/** + * \brief Gets the message header version. + * + * \par Description + * This routine gets the message header version. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Version Header version + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetHeaderVersion(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_HeaderVersion_t *Version); + +/*****************************************************************************/ +/** + * \brief Sets the message header version. + * + * \par Description + * This routine sets the message header version. Typically only + * set within message initialization and not used by APPs. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] Version Header version + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetHeaderVersion(CFE_MSG_Message_t *MsgPtr, CFE_MSG_HeaderVersion_t Version); + +/*****************************************************************************/ +/** + * \brief Gets the message secondary header boolean + * + * \par Description + * This routine gets the message secondary header boolean. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] HasSecondary Has secondary header flag + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetHasSecondaryHeader(const CFE_MSG_Message_t *MsgPtr, bool *HasSecondary); + +/*****************************************************************************/ +/** + * \brief Sets the message secondary header boolean + * + * \par Description + * This routine sets the message has secondary header boolean. Typically only + * set within message initialization and not used by APPs. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] HasSecondary Has secondary header flag + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetHasSecondaryHeader(CFE_MSG_Message_t *MsgPtr, bool HasSecondary); + +/*****************************************************************************/ +/** + * \brief Gets the message application ID + * + * \par Description + * This routine gets the message application ID. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] ApId Application ID + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetApId(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_ApId_t *ApId); + +/*****************************************************************************/ +/** + * \brief Sets the message application ID + * + * \par Description + * This routine sets the message application ID. Typically set + * at initialization using the MsgId, but API available to set + * bits that may not be included in MsgId. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] ApId Application ID + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetApId(CFE_MSG_Message_t *MsgPtr, CFE_MSG_ApId_t ApId); + +/*****************************************************************************/ +/** + * \brief Gets the message segmentation flag + * + * \par Description + * This routine gets the message segmentation flag + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] SegFlag Segmentation flag + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetSegmentationFlag(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_SegmentationFlag_t *SegFlag); + +/*****************************************************************************/ +/** + * \brief Sets the message segmentation flag + * + * \par Description + * This routine sets the message segmentation flag. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] SegFlag Segmentation flag + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetSegmentationFlag(CFE_MSG_Message_t *MsgPtr, CFE_MSG_SegmentationFlag_t SegFlag); + +/*****************************************************************************/ +/** + * \brief Gets the message sequence count + * + * \par Description + * This routine gets the message sequence count. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] SeqCnt Sequence count + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetSequenceCount(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_SequenceCount_t *SeqCnt); + +/*****************************************************************************/ +/** + * \brief Sets the message sequence count + * + * \par Description + * This routine sets the message sequence count. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] SeqCnt Sequence count + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetSequenceCount(CFE_MSG_Message_t *MsgPtr, CFE_MSG_SequenceCount_t SeqCnt); + +/*****************************************************************************/ +/** + * \brief Gets the message EDS version + * + * \par Description + * This routine gets the message EDS version. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Version EDS Version + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetEDSVersion(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_EDSVersion_t *Version); + +/*****************************************************************************/ +/** + * \brief Sets the message EDS version + * + * \par Description + * This routine sets the message EDS version. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] Version EDS Version + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetEDSVersion(CFE_MSG_Message_t *MsgPtr, CFE_MSG_EDSVersion_t Version); + +/*****************************************************************************/ +/** + * \brief Gets the message endian + * + * \par Description + * This routine gets the message endian. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Endian Endian + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetEndian(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Endian_t *Endian); + +/*****************************************************************************/ +/** + * \brief Sets the message endian + * + * \par Description + * This routine sets the message endian. Invalid endian selection + * will set big endian. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] Endian Endian + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetEndian(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Endian_t Endian); + +/*****************************************************************************/ +/** + * \brief Gets the message playback flag + * + * \par Description + * This routine gets the message playback flag. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] PlayFlag Playback Flag + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetPlaybackFlag(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_PlaybackFlag_t *PlayFlag); + +/*****************************************************************************/ +/** + * \brief Sets the message playback flag + * + * \par Description + * This routine sets the message playback flag. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] PlayFlag Playback Flag + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetPlaybackFlag(CFE_MSG_Message_t *MsgPtr, CFE_MSG_PlaybackFlag_t PlayFlag); + +/*****************************************************************************/ +/** + * \brief Gets the message subsystem + * + * \par Description + * This routine gets the message subsystem + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Subsystem Subsystem + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetSubsystem(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Subsystem_t *Subsystem); + +/*****************************************************************************/ +/** + * \brief Sets the message subsystem + * + * \par Description + * This routine sets the message subsystem. Some bits may + * be set at initialization using the MsgId, but API available to set + * bits that may not be included in MsgId. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] Subsystem Subsystem + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetSubsystem(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Subsystem_t Subsystem); + +/*****************************************************************************/ +/** + * \brief Gets the message system + * + * \par Description + * This routine gets the message system id + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] System System + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetSystem(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_System_t *System); + +/*****************************************************************************/ +/** + * \brief Sets the message system + * + * \par Description + * This routine sets the message system id. Some bits may + * be set at initialization using the MsgId, but API available to set + * bits that may not be included in MsgId. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] System System + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetSystem(CFE_MSG_Message_t *MsgPtr, CFE_MSG_System_t System); + +/*****************************************************************************/ +/** + * \brief Calculates and sets the checksum of a message + * + * \par Description + * This routine calculates the checksum of a message according + * to an implementation-defined algorithm. Then, it sets the checksum field + * in the message with the calculated value. The contents and location of + * this field will depend on the underlying implementation of + * messages. It may be a checksum, a CRC, or some other algorithm. + * + * \par Assumptions, External Events, and Notes: + * - If the underlying implementation of messages does not + * include a checksum field, then this routine will return + * #CFE_MSG_WRONG_MSG_TYPE + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + * \retval #CFE_MSG_WRONG_MSG_TYPE \copybrief CFE_MSG_WRONG_MSG_TYPE + */ +int32 CFE_MSG_GenerateChecksum(CFE_MSG_Message_t *MsgPtr); + +/*****************************************************************************/ +/** + * \brief Validates the checksum of a message. + * + * \par Description + * This routine validates the checksum of a message + * according to an implementation-defined algorithm. + * + * \par Assumptions, External Events, and Notes: + * - If the underlying implementation of messages does not + * include a checksum field, then this routine will return + * #CFE_MSG_WRONG_MSG_TYPE and set the IsValid parameter false. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * This must point to the first byte of the message header. + * \param[out] IsValid Checksum validation result + * \arg true - valid + * \arg false - invalid or not supported/implemented + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + * \retval #CFE_MSG_WRONG_MSG_TYPE \copybrief CFE_MSG_WRONG_MSG_TYPE + */ +int32 CFE_MSG_ValidateChecksum(const CFE_MSG_Message_t *MsgPtr, bool *IsValid); + +/*****************************************************************************/ +/** + * \brief Sets the function code field in a message. + * + * \par Description + * This routine sets the function code of a message. + * + * \par Assumptions, External Events, and Notes: + * - If the underlying implementation of messages does not + * include a function code field, then this routine will do nothing to + * the message contents and will return #CFE_MSG_WRONG_MSG_TYPE. + * + * \param[in, out] MsgPtr A pointer to the buffer that contains the message. + * \param[in] FcnCode The function code to include in the message. + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + * \retval #CFE_MSG_WRONG_MSG_TYPE \copybrief CFE_MSG_WRONG_MSG_TYPE + * + */ +int32 CFE_MSG_SetFcnCode(CFE_MSG_Message_t *MsgPtr, CFE_MSG_FcnCode_t FcnCode); + +/*****************************************************************************/ +/** + * \brief Gets the function code field from a message. + * + * \par Description + * This routine gets the function code from a message. + * + * \par Assumptions, External Events, and Notes: + * - If the underlying implementation of messages does not + * include a function code field, then this routine will + * set FcnCode to zero and return #CFE_MSG_WRONG_MSG_TYPE + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] FcnCode The function code from the message + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + * \retval #CFE_MSG_WRONG_MSG_TYPE \copybrief CFE_MSG_WRONG_MSG_TYPE + */ +int32 CFE_MSG_GetFcnCode(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_FcnCode_t *FcnCode); + +/*****************************************************************************/ +/** + * \brief Gets the time field from a message. + * + * \par Description + * This routine gets the time from a message. + * + * \par Assumptions, External Events, and Notes: + * - If the underlying implementation of messages does not + * include a time field, then this routine will set Time + * to zero and return #CFE_MSG_WRONG_MSG_TYPE + * - Note default implementation of command messages do not have a time field. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] Time Time from the message + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + * \retval #CFE_MSG_WRONG_MSG_TYPE \copybrief CFE_MSG_WRONG_MSG_TYPE + */ +int32 CFE_MSG_GetMsgTime(const CFE_MSG_Message_t *MsgPtr, CFE_TIME_SysTime_t *Time); + +/*****************************************************************************/ +/** + * \brief Sets the time field in a message. + * + * \par Description + * This routine sets the time of a message. Most applications + * will want to use #CFE_SB_TimeStampMsg instead of this function. But, + * when needed, this API can be used to set multiple messages + * with identical time stamps. + * + * \par Assumptions, External Events, and Notes: + * - If the underlying implementation of messages does not include + * a time field, then this routine will do nothing to the message contents + * and will return #CFE_MSG_WRONG_MSG_TYPE. + * - Note default implementation of command messages do not have a time field. + * + * \param[in, out] MsgPtr A pointer to the message. + * \param[in] Time The time to include in the message. This will usually be a time + * from #CFE_TIME_GetTime. + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + * \retval #CFE_MSG_WRONG_MSG_TYPE \copybrief CFE_MSG_WRONG_MSG_TYPE + */ +int32 CFE_MSG_SetMsgTime(CFE_MSG_Message_t *MsgPtr, CFE_TIME_SysTime_t Time); + +/**\}*/ + +/** \defgroup CFEAPIMSGMsgId cFE Message Id APIs + * \{ + */ + +/*****************************************************************************/ +/** + * \brief Gets the message id from a message. + * + * \par Description + * This routine gets the message id from a message. The message id + * is a hash of bits in the message header, used by the software bus for + * routing. Message id needs to be unique for each endpoint + * in the system. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] MsgId Message id + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetMsgId(const CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t *MsgId); + +/*****************************************************************************/ +/** + * \brief Sets the message id bits in a message. + * + * \par Description + * This routine sets the message id bits in a message. The message id + * is a hash of bits in the message header, used by the software bus for + * routing. Message id needs to be unique for each endpoint + * in the system. + * \par Note + * This API only sets the bits in the header that make up the message ID. + * No other values in the header are modified. + * + * \param[in] MsgPtr A pointer to the buffer that contains the message. + * \param[out] MsgId Message id + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_SetMsgId(CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t MsgId); + +/*****************************************************************************/ +/** + * \brief Gets message type using message ID + * + * \par Description + * This routine gets the message type using the message ID + * + * \param[in] MsgId Message id + * \param[out] Type Message type + * + * \return Execution status, see \ref CFEReturnCodes + * \retval #CFE_SUCCESS \copybrief CFE_SUCCESS + * \retval #CFE_MSG_BAD_ARGUMENT \copybrief CFE_MSG_BAD_ARGUMENT + */ +int32 CFE_MSG_GetTypeFromMsgId(CFE_SB_MsgId_t MsgId, CFE_MSG_Type_t *Type); + +/**\}*/ + +#endif /* _cfe_msg_api_ */ diff --git a/fsw/cfe-core/src/inc/cfe_msg_typedefs.h b/fsw/cfe-core/src/inc/cfe_msg_typedefs.h new file mode 100644 index 000000000..0397d0fd7 --- /dev/null +++ b/fsw/cfe-core/src/inc/cfe_msg_typedefs.h @@ -0,0 +1,90 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message type defines + * - Separate from API so these can be adjusted for custom implementations + */ + +#ifndef _cfe_msg_typedefs_ +#define _cfe_msg_typedefs_ + +/* + * Includes + */ +#include "common_types.h" +#include "cfe_error.h" + +/* + * Defines + */ +/* Error bits won't fit a new module so reuse SB error codes */ +#define CFE_MSG_BAD_ARGUMENT CFE_SB_BAD_ARGUMENT /**< \brief Error - bad argument */ +#define CFE_MSG_NOT_IMPLEMENTED CFE_SB_NOT_IMPLEMENTED /**< \brief Error - not implemented */ +#define CFE_MSG_WRONG_MSG_TYPE CFE_SB_WRONG_MSG_TYPE /**< \brief Error - wrong type */ + +/* + * Types + */ +typedef uint32 CFE_MSG_Size_t; /**< \brief Message size (CCSDS needs uint32 for max size) */ +typedef uint32 CFE_MSG_Checksum_t; /**< \brief Message checksum (Oversized to avoid redefine) */ +typedef uint16 CFE_MSG_FcnCode_t; /**< \brief Message function code */ +typedef uint16 CFE_MSG_HeaderVersion_t; /**< \brief Message header version */ +typedef uint16 CFE_MSG_ApId_t; /**< \brief Message application ID */ +typedef uint16 CFE_MSG_SequenceCount_t; /**< \brief Message sequence count */ +typedef uint16 CFE_MSG_EDSVersion_t; /**< \brief Message EDS version */ +typedef uint16 CFE_MSG_Subsystem_t; /**< \brief Message subsystem */ +typedef uint16 CFE_MSG_System_t; /**< \brief Message system */ + +/** \brief Message type */ +typedef enum +{ + CFE_MSG_Type_Invalid, /**< \brief Message type invalid, undefined, not implemented */ + CFE_MSG_Type_Cmd, /**< \brief Command message type */ + CFE_MSG_Type_Tlm /**< \brief Telemetry message type */ +} CFE_MSG_Type_t; + +/** \brief Segmentation flags */ +typedef enum +{ + CFE_MSG_SegFlag_Invalid, /**< \brief Invalid segmentation flag */ + CFE_MSG_SegFlag_Continue, /**< \brief Continuation segment of User Data */ + CFE_MSG_SegFlag_First, /**< \brief First segment of User Data */ + CFE_MSG_SegFlag_Last, /**< \brief Last segment of User Data */ + CFE_MSG_SegFlag_Unsegmented /**< \brief Unsegemented data */ +} CFE_MSG_SegmentationFlag_t; + +/** \brief Endian flag */ +typedef enum +{ + CFE_MSG_Endian_Invalid, /**< \brief Invalid endian setting */ + CFE_MSG_Endian_Big, /**< \brief Big endian */ + CFE_MSG_Endian_Little /**< \brief Little endian */ +} CFE_MSG_Endian_t; + +/** \brief Playback flag */ +typedef enum +{ + CFE_MSG_PlayFlag_Invalid, /**< \brief Invalid playback setting */ + CFE_MSG_PlayFlag_Original, /**< \brief Original */ + CFE_MSG_PlayFlag_Playback /**< \brief Playback */ +} CFE_MSG_PlaybackFlag_t; + +#endif /* _cfe_msg_typedefs_ */ diff --git a/modules/msg/CMakeLists.txt b/modules/msg/CMakeLists.txt new file mode 100644 index 000000000..1d6f2e04c --- /dev/null +++ b/modules/msg/CMakeLists.txt @@ -0,0 +1,62 @@ +################################################################## +# +# cFE message module CMake build recipe +# +# This CMakeLists.txt adds source files for +# message module included in the cFE distribution. Selected +# files are built into a static library that in turn +# is linked into the final executable. +# +# Note this is different than applications which are dynamically +# linked to support runtime loading. The core applications all +# use static linkage. +# +################################################################## + +# Add the basic set of files which are always built +# Defined as absolute so this list can also be used to build unit tests +set(${DEP}_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_ccsdspri.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_init.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_msgid_shared.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_sechdr_checksum.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_sechdr_fc.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_sechdr_time_old.c +) + +# Source selection for if CCSDS extended header is included, and MsgId version use +if (MISSION_INCLUDE_CCSDSEXT_HEADER) + message(STATUS "CCSDS primary and extended header included in message header") + list(APPEND ${DEP}_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_ccsdsext.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_initdefaulthdr_priext.c) + if (MISSION_MSGID_V2) # MsgId v2 or v1 can be used with extended headers + message(STATUS "Message Id version 2 in use (MsgId V2)") + list(APPEND ${DEP}_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_msgid_v2.c) + else (MISSION_MSGID_V2) + message(STATUS "Message Id version 1 in use (MsgId V1)") + list(APPEND ${DEP}_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_msgid_v1.c) + endif (MISSION_MSGID_V2) +else (MISSION_INCLUDE_CCSDSEXT_HEADER) + message(STATUS "CCSDS primary header included in message header (not including CCSDS extended header)") + message(STATUS "Message Id version 1 in use (MsgId V1)") + list(APPEND ${DEP}_SRC + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_initdefaulthdr_pri.c + ${CMAKE_CURRENT_SOURCE_DIR}/src/cfe_msg_msgid_v1.c) + if (MISSION_MSGID_V2) + message(FATAL_ERROR "Message Id (MsgId) version 2 can only be used if MISSION_INCLUDE_CCSDSEXT_HEADER is set") + endif (MISSION_MSGID_V2) +endif (MISSION_INCLUDE_CCSDSEXT_HEADER) + +# Module library +add_library(${DEP} STATIC ${${DEP}_SRC}) + +# Add private include +target_include_directories(${DEP} PRIVATE private_inc) + +# Add unit test coverage subdirectory +if(ENABLE_UNIT_TESTS) + add_subdirectory(unit-test-coverage) +endif(ENABLE_UNIT_TESTS) diff --git a/modules/msg/mission_build.cmake b/modules/msg/mission_build.cmake new file mode 100644 index 000000000..b34a3f6e5 --- /dev/null +++ b/modules/msg/mission_build.cmake @@ -0,0 +1,27 @@ +########################################################### +# +# MSG mission build setup +# +# This file is evaluated as part of the "prepare" stage +# and can be used to set up prerequisites for the build, +# such as generating header files +# +########################################################### + +# Extended header inclusion selection +if (MISSION_INCLUDE_CCSDSEXT_HEADER) + set(MSG_HDR_FILE "default_cfe_msg_hdr_priext.h") +else (MISSION_INCLUDE_CCSDSEXT_HEADER) + set(MSG_HDR_FILE "default_cfe_msg_hdr_pri.h") +endif (MISSION_INCLUDE_CCSDSEXT_HEADER) + +# Generate the header definition files, use local default for this module) +generate_config_includefile( + FILE_NAME "cfe_msg_hdr.h" + FALLBACK_FILE "${CMAKE_CURRENT_LIST_DIR}/mission_inc/${MSG_HDR_FILE}" +) + +generate_config_includefile( + FILE_NAME "cfe_msg_sechdr.h" + FALLBACK_FILE "${CMAKE_CURRENT_LIST_DIR}/mission_inc/default_cfe_msg_sechdr.h" +) diff --git a/modules/msg/mission_inc/default_cfe_msg_hdr_pri.h b/modules/msg/mission_inc/default_cfe_msg_hdr_pri.h new file mode 100644 index 000000000..d422106db --- /dev/null +++ b/modules/msg/mission_inc/default_cfe_msg_hdr_pri.h @@ -0,0 +1,89 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Define cFS standard full header + * - Avoid direct access for portability, use APIs + * - Used to construct message structures + */ + +#ifndef _cfe_msg_hdr_ +#define _cfe_msg_hdr_ + +/* + * Include Files + */ + +#include "common_types.h" +#include "ccsds_hdr.h" +#include "cfe_msg_sechdr.h" + +/* + * Type Definitions + */ + +/********************************************************************** + * Structure definitions for full header + * + * These are based on historically supported definitions and not + * an open source standard. + */ + +/** + * \brief Full CCSDS header + */ +typedef struct +{ + CCSDS_PrimaryHeader_t Pri; /**< \brief CCSDS Primary Header */ +} CCSDS_SpacePacket_t; + +/** + * \brief cFS command header + */ +typedef struct +{ + + CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS header */ + CFE_MSG_CommandSecondaryHeader_t Sec; /**< \brief Secondary header */ + +} CFE_MSG_CommandHeader_t; + +/** + * \brief cFS telemetry header + */ +typedef struct +{ + + CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS header */ + CFE_MSG_TelemetrySecondaryHeader_t Sec; /**< \brief Secondary header */ + +} CFE_MSG_TelemetryHeader_t; + +/** + * \brief cFS Generic packet header + */ +typedef union +{ + CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS Header (Pri or Pri + Ext) */ + uint32 Align; /**< \brief Force 32-bit alignment */ + uint8 Byte[sizeof(CCSDS_SpacePacket_t)]; /**< \brief Byte level access */ +} CFE_MSG_Message_t; + +#endif /* _cfe_msg_hdr_ */ diff --git a/modules/msg/mission_inc/default_cfe_msg_hdr_priext.h b/modules/msg/mission_inc/default_cfe_msg_hdr_priext.h new file mode 100644 index 000000000..652925269 --- /dev/null +++ b/modules/msg/mission_inc/default_cfe_msg_hdr_priext.h @@ -0,0 +1,90 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Define cFS standard full header + * - Avoid direct access for portability, use APIs + * - Used to construct message structures + */ + +#ifndef _cfe_msg_hdr_ +#define _cfe_msg_hdr_ + +/* + * Include Files + */ + +#include "common_types.h" +#include "ccsds_hdr.h" +#include "cfe_msg_sechdr.h" + +/* + * Type Definitions + */ + +/********************************************************************** + * Structure definitions for full header + * + * These are based on historically supported definitions and not + * an open source standard. + */ + +/** + * \brief Full CCSDS header + */ +typedef struct +{ + CCSDS_PrimaryHeader_t Pri; /**< \brief CCSDS Primary Header */ + CCSDS_ExtendedHeader_t Ext; /**< \brief CCSDS Extended Header */ +} CCSDS_SpacePacket_t; + +/** + * \brief cFS command header + */ +typedef struct +{ + + CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS header */ + CFE_MSG_CommandSecondaryHeader_t Sec; /**< \brief Secondary header */ + +} CFE_MSG_CommandHeader_t; + +/** + * \brief cFS telemetry header + */ +typedef struct +{ + + CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS header */ + CFE_MSG_TelemetrySecondaryHeader_t Sec; /**< \brief Secondary header */ + +} CFE_MSG_TelemetryHeader_t; + +/** + * \brief cFS Generic packet header + */ +typedef union +{ + CCSDS_SpacePacket_t CCSDS; /**< \brief CCSDS Header (Pri or Pri + Ext) */ + uint32 Align; /**< \brief Force 32-bit alignment */ + uint8 Byte[sizeof(CCSDS_SpacePacket_t)]; /**< \brief Byte level access */ +} CFE_MSG_Message_t; + +#endif /* _cfe_msg_hdr_ */ diff --git a/modules/msg/mission_inc/default_cfe_msg_sechdr.h b/modules/msg/mission_inc/default_cfe_msg_sechdr.h new file mode 100644 index 000000000..d4d7a678a --- /dev/null +++ b/modules/msg/mission_inc/default_cfe_msg_sechdr.h @@ -0,0 +1,93 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Define cFS standard secondary header + * - Avoid direct access for portability, use APIs + * - Used to construct message structures + */ + +#ifndef _cfe_msg_sechdr_ +#define _cfe_msg_sechdr_ + +/* + * Include Files + */ + +#include "common_types.h" +#include "cfe_mission_cfg.h" + +/* + * Defines + */ + +/* These go away w/ single framework implementation */ +/* CCSDS_TIME_SIZE is specific to the selected CFE_SB time format */ +#if (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_16_SUBS) +/* 32 bits seconds + 16 bits subseconds */ +#define CCSDS_TIME_SIZE 6 +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_SUBS) +/* 32 bits seconds + 32 bits subseconds */ +#define CCSDS_TIME_SIZE 8 +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_M_20) +/* 32 bits seconds + 20 bits microsecs + 12 bits reserved */ +#define CCSDS_TIME_SIZE 8 +#else +/* unknown format */ +#error unable to define CCSDS_TIME_SIZE! +#endif + +/* + * Type Definitions + */ + +/********************************************************************** + * Structure definitions for secondary headers + * + * These are based on historically supported definitions and not + * an open source standard. + */ + +/** + * \brief cFS command secondary header + */ +typedef struct +{ + + uint8 FunctionCode; /**< \brief Command Function Code */ + /* bits shift ---------description-------- */ + /* 0x7F 0 Command function code */ + /* 0x80 7 Reserved */ + + uint8 Checksum; /**< \brief Command checksum (all bits, 0xFF) */ + +} CFE_MSG_CommandSecondaryHeader_t; + +/** + * \brief cFS telemetry secondary header + */ +typedef struct +{ + + uint8 Time[CCSDS_TIME_SIZE]; /**< \brief Time sized for selected format */ + +} CFE_MSG_TelemetrySecondaryHeader_t; + +#endif /* _cfe_msg_sechdr_ */ diff --git a/modules/msg/private_inc/cfe_msg_defaults.h b/modules/msg/private_inc/cfe_msg_defaults.h new file mode 100644 index 000000000..ab1541672 --- /dev/null +++ b/modules/msg/private_inc/cfe_msg_defaults.h @@ -0,0 +1,84 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message header defaults, used to initialize messages + * - Avoid including outside this module + */ + +#ifndef _cfe_msg_defaults_ +#define _cfe_msg_defaults_ + +/* + * Includes + */ +#include "cfe_platform_cfg.h" +#include "cfe_mission_cfg.h" + +/* + * Defines + */ + +/* Backwards compatibility */ +#ifndef CFE_PLATFORM_DEFAULT_APID +#define CFE_PLATFORM_DEFAULT_APID 0 /**< \brief Default APID, for bits not in MsgId */ +#endif + +#ifndef CFE_MISSION_CCSDSVER +#ifdef MESSAGE_FORMAT_IS_CCSDS_VER_2 +#define CFE_MISSION_CCSDSVER 1 /**< \brief Default CCSDS Version, cFS Ver 2 historically = 1 */ +#else +#define CFE_MISSION_CCSDSVER 0 /**< \brief Default CCSDS Version, cFS Ver 1 historically = 0 */ +#endif +#endif + +#ifndef CFE_PLATFORM_DEFAULT_SUBSYS +#define CFE_PLATFORM_DEFAULT_SUBSYS 0 /**< \brief Default SubSystem, for bits not in MsgId */ +#endif + +#ifndef CFE_PLATFORM_EDSVER +#define CFE_PLATFORM_EDSVER 1 /**< \brief Default EDS version, cFS historically = 1 */ +#endif + +/*****************************************************************************/ +/** + * \brief Set CCSDS Primary header defaults + * + * \par DESCRIPTION + * Only sets the constant defaults. Internal function assumes + * pointer is valid. + * + * \param[out] MsgPtr Message to set + */ +void CFE_MSG_SetDefaultCCSDSPri(CFE_MSG_Message_t *MsgPtr); + +/*****************************************************************************/ +/** + * \brief Set CCSDS Extended header defaults + * + * \par DESCRIPTION + * Only sets the constant defaults. Internal function assumes + * pointer is valid. + * + * \param[out] MsgPtr Message to set + */ +void CFE_MSG_SetDefaultCCSDSExt(CFE_MSG_Message_t *MsgPtr); + +#endif /* _cfe_msg_default_ */ diff --git a/modules/msg/private_inc/cfe_msg_priv.h b/modules/msg/private_inc/cfe_msg_priv.h new file mode 100644 index 000000000..32d785715 --- /dev/null +++ b/modules/msg/private_inc/cfe_msg_priv.h @@ -0,0 +1,81 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message private header + * - Avoid including outside this module + */ + +#ifndef _cfe_msg_priv_ +#define _cfe_msg_priv_ + +/* + * Includes + */ +#include "common_types.h" + +/*****************************************************************************/ +/** + * \brief get generic header field (uint8 array[2]) + * + * \par DESCRIPTION + * Big endian get of header field given mask. Only sets bits + * in value that are part of mask. + * + * \param[in] Word Header value to set + * \param[out] Val Value to set + * \param[in] Mask Mask used for set + */ +static inline void CFE_MSG_GetHeaderField(const uint8 *Word, uint16 *Val, uint16 Mask) +{ + *Val = (Word[0] << 8 | Word[1]) & Mask; +} + +/*****************************************************************************/ +/** + * \brief Set generic header field (uint8 array[2]) + * + * \par DESCRIPTION + * Big endian set of header field given value and mask. Only sets bits + * from value that are part of mask. + * + * \param[in, out] Word Header value to set + * \param[in] Val Value to set + * \param[in] Mask Mask used for set + */ +static inline void CFE_MSG_SetHeaderField(uint8 *Word, uint16 Val, uint16 Mask) +{ + Word[0] = (Word[0] & ~(Mask >> 8)) | ((Val & Mask) >> 8); + Word[1] = ((Word[1] & ~Mask) | (Val & Mask)) & 0xFF; +} + +/*****************************************************************************/ +/** + * \brief Initialize default header - implemented based on selected header format + * + * \par DESCRIPTION + * Sets the constant defaults for the entire header. Internal function + * assumes pointer is valid. + * + * \param[out] MsgPtr Message to set + */ +void CFE_MSG_InitDefaultHdr(CFE_MSG_Message_t *MsgPtr); + +#endif /* _cfe_msg_priv_ */ diff --git a/modules/msg/src/cfe_msg_ccsdsext.c b/modules/msg/src/cfe_msg_ccsdsext.c new file mode 100644 index 000000000..6c7587c3b --- /dev/null +++ b/modules/msg/src/cfe_msg_ccsdsext.c @@ -0,0 +1,250 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message CCSDS extended header implementations + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_msg_defaults.h" +#include "cfe_error.h" + +/* CCSDS Extended definitions */ +#define CFE_MSG_EDSVER_SHIFT 11 /**< \brief CCSDS EDS version shift */ +#define CFE_MSG_EDSVER_MASK 0xF800 /**< \brief CCSDS EDS version mask */ +#define CFE_MSG_ENDIAN_MASK 0x0400 /**< \brief CCSDS endiam mask, little endian when set */ +#define CFE_MSG_PLAYBACK_MASK 0x0200 /**< \brief CCSDS playback flag, playback when set */ +#define CFE_MSG_SUBSYS_MASK 0x01FF /**< \brief CCSDS Subsystem mask */ + +/****************************************************************************** + * CCSDS extended header initialization - See header file for details + */ +void CFE_MSG_SetDefaultCCSDSExt(CFE_MSG_Message_t *MsgPtr) +{ + + CFE_MSG_SetEDSVersion(MsgPtr, (CFE_MSG_EDSVersion_t)CFE_PLATFORM_EDSVER); + +#if (CFE_PLATFORM_ENDIAN == CCSDS_LITTLE_ENDIAN) + CFE_MSG_SetEndian(MsgPtr, CFE_MSG_Endian_Little); +#else + CFE_MSG_SetEndian(MsgPtr, CFE_MSG_Endian_Big); +#endif + + /* Default bits of the subsystem, for whatever isn't set by MsgId */ + CFE_MSG_SetSubsystem(MsgPtr, (CFE_MSG_Subsystem_t)CFE_PLATFORM_DEFAULT_SUBSYS); + CFE_MSG_SetSystem(MsgPtr, (CFE_MSG_System_t)CFE_MISSION_SPACECRAFT_ID); +} + +/****************************************************************************** + * Get message EDS version - See API and header file for details + */ +int32 CFE_MSG_GetEDSVersion(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_EDSVersion_t *Version) +{ + + if (MsgPtr == NULL || Version == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_GetHeaderField(MsgPtr->CCSDS.Ext.Subsystem, Version, CFE_MSG_EDSVER_MASK); + *Version >>= CFE_MSG_EDSVER_SHIFT; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message EDS version - See API and header file for details + */ +int32 CFE_MSG_SetEDSVersion(CFE_MSG_Message_t *MsgPtr, CFE_MSG_EDSVersion_t Version) +{ + if (MsgPtr == NULL || (Version > (CFE_MSG_EDSVER_MASK >> CFE_MSG_EDSVER_SHIFT))) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_SetHeaderField(MsgPtr->CCSDS.Ext.Subsystem, Version << CFE_MSG_EDSVER_SHIFT, CFE_MSG_EDSVER_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message endian - See API and header file for details + */ +int32 CFE_MSG_GetEndian(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Endian_t *Endian) +{ + + if (MsgPtr == NULL || Endian == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if ((MsgPtr->CCSDS.Ext.Subsystem[0] & (CFE_MSG_ENDIAN_MASK >> 8)) != 0) + { + *Endian = CFE_MSG_Endian_Little; + } + else + { + *Endian = CFE_MSG_Endian_Big; + } + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message endian - See API and header file for details + */ +int32 CFE_MSG_SetEndian(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Endian_t Endian) +{ + int32 status = CFE_SUCCESS; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if (Endian == CFE_MSG_Endian_Little) + { + MsgPtr->CCSDS.Ext.Subsystem[0] |= CFE_MSG_ENDIAN_MASK >> 8; + } + else if (Endian == CFE_MSG_Endian_Big) + { + MsgPtr->CCSDS.Ext.Subsystem[0] &= ~(CFE_MSG_ENDIAN_MASK >> 8); + } + else + { + status = CFE_MSG_BAD_ARGUMENT; + } + + return status; +} + +/****************************************************************************** + * Get message playback flag - See API and header file for details + */ +int32 CFE_MSG_GetPlaybackFlag(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_PlaybackFlag_t *PlayFlag) +{ + + if (MsgPtr == NULL || PlayFlag == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if ((MsgPtr->CCSDS.Ext.Subsystem[0] & (CFE_MSG_PLAYBACK_MASK >> 8)) != 0) + { + *PlayFlag = CFE_MSG_PlayFlag_Playback; + } + else + { + *PlayFlag = CFE_MSG_PlayFlag_Original; + } + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message playback flag - See API and header file for details + */ +int32 CFE_MSG_SetPlaybackFlag(CFE_MSG_Message_t *MsgPtr, CFE_MSG_PlaybackFlag_t PlayFlag) +{ + int32 status = CFE_SUCCESS; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if (PlayFlag == CFE_MSG_PlayFlag_Playback) + { + MsgPtr->CCSDS.Ext.Subsystem[0] |= CFE_MSG_PLAYBACK_MASK >> 8; + } + else if (PlayFlag == CFE_MSG_PlayFlag_Original) + { + MsgPtr->CCSDS.Ext.Subsystem[0] &= ~(CFE_MSG_PLAYBACK_MASK >> 8); + } + else + { + status = CFE_MSG_BAD_ARGUMENT; + } + + return status; +} + +/****************************************************************************** + * Get message subsystem - See API and header file for details + */ +int32 CFE_MSG_GetSubsystem(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Subsystem_t *Subsystem) +{ + + if (MsgPtr == NULL || Subsystem == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_GetHeaderField(MsgPtr->CCSDS.Ext.Subsystem, Subsystem, CFE_MSG_SUBSYS_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message subsystem - See API and header file for details + */ +int32 CFE_MSG_SetSubsystem(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Subsystem_t Subsystem) +{ + if (MsgPtr == NULL || ((Subsystem & ~CFE_MSG_SUBSYS_MASK) != 0)) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_SetHeaderField(MsgPtr->CCSDS.Ext.Subsystem, Subsystem, CFE_MSG_SUBSYS_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message system - See API and header file for details + */ +int32 CFE_MSG_GetSystem(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_System_t *System) +{ + + if (MsgPtr == NULL || System == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + *System = (MsgPtr->CCSDS.Ext.SystemId[0] << 8) + MsgPtr->CCSDS.Ext.SystemId[1]; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message system - See API and header file for details + */ +int32 CFE_MSG_SetSystem(CFE_MSG_Message_t *MsgPtr, CFE_MSG_System_t System) +{ + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + MsgPtr->CCSDS.Ext.SystemId[0] = (System >> 8) & 0xFF; + MsgPtr->CCSDS.Ext.SystemId[1] = System & 0xFF; + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_ccsdspri.c b/modules/msg/src/cfe_msg_ccsdspri.c new file mode 100644 index 000000000..b7d73679d --- /dev/null +++ b/modules/msg/src/cfe_msg_ccsdspri.c @@ -0,0 +1,352 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message CCSDS Primary header implementations + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_msg_defaults.h" +#include "cfe_error.h" + +/* CCSDS Primary Standard definitions */ +#define CFE_MSG_SIZE_OFFSET 7 /**< \brief CCSDS size offset */ +#define CFE_MSG_CCSDSVER_MASK 0xE000 /**< \brief CCSDS version mask */ +#define CFE_MSG_CCSDSVER_SHIFT 13 /**< \brief CCSDS version shift */ +#define CFE_MSG_TYPE_MASK 0x1000 /**< \brief CCSDS type mask, command when set */ +#define CFE_MSG_SHDR_MASK 0x0800 /**< \brief CCSDS secondary header mask, exists when set*/ +#define CFE_MSG_APID_MASK 0x07FF /**< \brief CCSDS ApID mask */ +#define CFE_MSG_SEGFLG_MASK 0xC000 /**< \brief CCSDS segmentation flag mask, all set = complete packet */ +#define CFE_MSG_SEGFLG_CNT 0x0000 /**< \brief CCSDS Segment continuation flag */ +#define CFE_MSG_SEGFLG_FIRST 0x4000 /**< \brief CCSDS Segment first flag */ +#define CFE_MSG_SEGFLG_LAST 0x8000 /**< \brief CCSDS Segment last flag */ +#define CFE_MSG_SEGFLG_UNSEG 0xC000 /**< \brief CCSDS Unsegmented flag */ +#define CFE_MSG_SEQCNT_MASK 0x3FFF /**< \brief CCSDS Sequence count mask */ + +/****************************************************************************** + * CCSDS Primary header initialization - See header file for details + */ +void CFE_MSG_SetDefaultCCSDSPri(CFE_MSG_Message_t *MsgPtr) +{ + + /* cFS standard is for secondary header to be present */ + CFE_MSG_SetHasSecondaryHeader(MsgPtr, true); + + /* cFS standard for CCSDS Version is Ver 1 = 0, Ver 2 = 1, but mission may redefine */ + CFE_MSG_SetHeaderVersion(MsgPtr, CFE_MISSION_CCSDSVER); + + /* Default bits of the APID, for whatever isn't set by MsgId */ + CFE_MSG_SetApId(MsgPtr, CFE_PLATFORM_DEFAULT_APID); + + /* Default to complete packets */ + CFE_MSG_SetSegmentationFlag(MsgPtr, CFE_MSG_SegFlag_Unsegmented); +} + +/****************************************************************************** + * Get message header version - See API and header file for details + */ +int32 CFE_MSG_GetHeaderVersion(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_HeaderVersion_t *Version) +{ + + if (MsgPtr == NULL || Version == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_GetHeaderField(MsgPtr->CCSDS.Pri.StreamId, Version, CFE_MSG_CCSDSVER_MASK); + *Version >>= CFE_MSG_CCSDSVER_SHIFT; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message header version - See API and header file for details + */ +int32 CFE_MSG_SetHeaderVersion(CFE_MSG_Message_t *MsgPtr, CFE_MSG_HeaderVersion_t Version) +{ + if (MsgPtr == NULL || (Version > (CFE_MSG_CCSDSVER_MASK >> CFE_MSG_CCSDSVER_SHIFT))) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_SetHeaderField(MsgPtr->CCSDS.Pri.StreamId, Version << CFE_MSG_CCSDSVER_SHIFT, CFE_MSG_CCSDSVER_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message type - See API and header file for details + */ +int32 CFE_MSG_GetType(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Type_t *Type) +{ + + if (MsgPtr == NULL || Type == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if ((MsgPtr->CCSDS.Pri.StreamId[0] & (CFE_MSG_TYPE_MASK >> 8)) != 0) + { + *Type = CFE_MSG_Type_Cmd; + } + else + { + *Type = CFE_MSG_Type_Tlm; + } + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message type - See API and header file for details + */ +int32 CFE_MSG_SetType(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Type_t Type) +{ + int32 status = CFE_SUCCESS; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if (Type == CFE_MSG_Type_Cmd) + { + MsgPtr->CCSDS.Pri.StreamId[0] |= CFE_MSG_TYPE_MASK >> 8; + } + else if (Type == CFE_MSG_Type_Tlm) + { + MsgPtr->CCSDS.Pri.StreamId[0] &= ~(CFE_MSG_TYPE_MASK >> 8); + } + else + { + status = CFE_MSG_BAD_ARGUMENT; + } + + return status; +} + +/****************************************************************************** + * Get message has secondary header flag - See API and header file for details + */ +int32 CFE_MSG_GetHasSecondaryHeader(const CFE_MSG_Message_t *MsgPtr, bool *HasSecondary) +{ + + if (MsgPtr == NULL || HasSecondary == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + *HasSecondary = (MsgPtr->CCSDS.Pri.StreamId[0] & (CFE_MSG_SHDR_MASK >> 8)) != 0; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message has secondary header flag - See API and header file for details + */ +int32 CFE_MSG_SetHasSecondaryHeader(CFE_MSG_Message_t *MsgPtr, bool HasSecondary) +{ + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + if (HasSecondary) + { + MsgPtr->CCSDS.Pri.StreamId[0] |= CFE_MSG_SHDR_MASK >> 8; + } + else + { + MsgPtr->CCSDS.Pri.StreamId[0] &= ~(CFE_MSG_SHDR_MASK >> 8); + } + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message application ID - See API and header file for details + */ +int32 CFE_MSG_GetApId(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_ApId_t *ApId) +{ + + if (MsgPtr == NULL || ApId == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_GetHeaderField(MsgPtr->CCSDS.Pri.StreamId, ApId, CFE_MSG_APID_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message application ID - See API and header file for details + */ +int32 CFE_MSG_SetApId(CFE_MSG_Message_t *MsgPtr, CFE_MSG_ApId_t ApId) +{ + if (MsgPtr == NULL || ((ApId & ~CFE_MSG_APID_MASK) != 0)) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_SetHeaderField(MsgPtr->CCSDS.Pri.StreamId, ApId, CFE_MSG_APID_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message segmentation flag - See API and header file for details + */ +int32 CFE_MSG_GetSegmentationFlag(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_SegmentationFlag_t *SegFlag) +{ + + uint16 rawval; + + if (MsgPtr == NULL || SegFlag == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_GetHeaderField(MsgPtr->CCSDS.Pri.Sequence, &rawval, CFE_MSG_SEGFLG_MASK); + + switch (rawval) + { + case CFE_MSG_SEGFLG_CNT: + *SegFlag = CFE_MSG_SegFlag_Continue; + break; + case CFE_MSG_SEGFLG_FIRST: + *SegFlag = CFE_MSG_SegFlag_First; + break; + case CFE_MSG_SEGFLG_LAST: + *SegFlag = CFE_MSG_SegFlag_Last; + break; + case CFE_MSG_SEGFLG_UNSEG: + default: + *SegFlag = CFE_MSG_SegFlag_Unsegmented; + } + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message segmentation flag - See API and header file for details + */ +int32 CFE_MSG_SetSegmentationFlag(CFE_MSG_Message_t *MsgPtr, CFE_MSG_SegmentationFlag_t SegFlag) +{ + uint16 rawval = 0; + int32 status = CFE_SUCCESS; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + switch (SegFlag) + { + case CFE_MSG_SegFlag_Continue: + rawval = CFE_MSG_SEGFLG_CNT; + break; + case CFE_MSG_SegFlag_First: + rawval = CFE_MSG_SEGFLG_FIRST; + break; + case CFE_MSG_SegFlag_Last: + rawval = CFE_MSG_SEGFLG_LAST; + break; + case CFE_MSG_SegFlag_Unsegmented: + rawval = CFE_MSG_SEGFLG_UNSEG; + break; + case CFE_MSG_SegFlag_Invalid: + default: + status = CFE_MSG_BAD_ARGUMENT; + } + + if (status == CFE_SUCCESS) + { + CFE_MSG_SetHeaderField(MsgPtr->CCSDS.Pri.Sequence, rawval, CFE_MSG_SEGFLG_MASK); + } + + return status; +} + +/****************************************************************************** + * Get message sequence count - See API and header file for details + */ +int32 CFE_MSG_GetSequenceCount(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_SequenceCount_t *SeqCnt) +{ + + if (MsgPtr == NULL || SeqCnt == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_GetHeaderField(MsgPtr->CCSDS.Pri.Sequence, SeqCnt, CFE_MSG_SEQCNT_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message sequence count - See API and header file for details + */ +int32 CFE_MSG_SetSequenceCount(CFE_MSG_Message_t *MsgPtr, CFE_MSG_SequenceCount_t SeqCnt) +{ + if (MsgPtr == NULL || ((SeqCnt & ~CFE_MSG_SEQCNT_MASK) != 0)) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_SetHeaderField(MsgPtr->CCSDS.Pri.Sequence, SeqCnt, CFE_MSG_SEQCNT_MASK); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message size - See API and header file for details + */ +int32 CFE_MSG_GetSize(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_Size_t *Size) +{ + + if (MsgPtr == NULL || Size == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + *Size = (MsgPtr->CCSDS.Pri.Length[0] << 8) + MsgPtr->CCSDS.Pri.Length[1] + CFE_MSG_SIZE_OFFSET; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message size - See API and header file for details + */ +int32 CFE_MSG_SetSize(CFE_MSG_Message_t *MsgPtr, CFE_MSG_Size_t Size) +{ + if (MsgPtr == NULL || Size < CFE_MSG_SIZE_OFFSET || Size > (0xFFFF + CFE_MSG_SIZE_OFFSET)) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Size is CCSDS header is total packet size - CFE_MSG_SIZE_OFFSET (7) */ + Size -= CFE_MSG_SIZE_OFFSET; + + MsgPtr->CCSDS.Pri.Length[0] = (Size >> 8) & 0xFF; + MsgPtr->CCSDS.Pri.Length[1] = Size & 0xFF; + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_init.c b/modules/msg/src/cfe_msg_init.c new file mode 100644 index 000000000..b64e2d0f6 --- /dev/null +++ b/modules/msg/src/cfe_msg_init.c @@ -0,0 +1,57 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message initialization + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_msg_defaults.h" +#include "string.h" + +/****************************************************************************** + * Top level message initialization - See API and header file for details + */ +int32 CFE_MSG_Init(CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t MsgId, CFE_MSG_Size_t Size, bool Clear) +{ + + int32 status; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Clear and set defaults if request */ + if (Clear) + { + memset(MsgPtr, 0, Size); + CFE_MSG_InitDefaultHdr(MsgPtr); + } + + /* Set values input */ + status = CFE_MSG_SetMsgId(MsgPtr, MsgId); + if (status == CFE_SUCCESS) + { + status = CFE_MSG_SetSize(MsgPtr, Size); + } + + return status; +} diff --git a/modules/msg/src/cfe_msg_initdefaulthdr_pri.c b/modules/msg/src/cfe_msg_initdefaulthdr_pri.c new file mode 100644 index 000000000..2904ab1ef --- /dev/null +++ b/modules/msg/src/cfe_msg_initdefaulthdr_pri.c @@ -0,0 +1,34 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message default header initialization - implementation without CCSDS + * extended header + */ +#include "cfe_msg_hdr.h" +#include "cfe_msg_defaults.h" + +/****************************************************************************** + * Top level message initialization - See header file for details + */ +void CFE_MSG_InitDefaultHdr(CFE_MSG_Message_t *MsgPtr) +{ + CFE_MSG_SetDefaultCCSDSPri(MsgPtr); +} diff --git a/modules/msg/src/cfe_msg_initdefaulthdr_priext.c b/modules/msg/src/cfe_msg_initdefaulthdr_priext.c new file mode 100644 index 000000000..c11f15347 --- /dev/null +++ b/modules/msg/src/cfe_msg_initdefaulthdr_priext.c @@ -0,0 +1,35 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message default header initialization - implementation without CCSDS + * extended header + */ +#include "cfe_msg_hdr.h" +#include "cfe_msg_defaults.h" + +/****************************************************************************** + * Top level message initialization - See header file for details + */ +void CFE_MSG_InitDefaultHdr(CFE_MSG_Message_t *MsgPtr) +{ + CFE_MSG_SetDefaultCCSDSPri(MsgPtr); + CFE_MSG_SetDefaultCCSDSExt(MsgPtr); +} diff --git a/modules/msg/src/cfe_msg_msgid_shared.c b/modules/msg/src/cfe_msg_msgid_shared.c new file mode 100644 index 000000000..79caaac7f --- /dev/null +++ b/modules/msg/src/cfe_msg_msgid_shared.c @@ -0,0 +1,46 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message id access functions, shared cFS implementation + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_error.h" + +/****************************************************************************** + * Get type from message id - See API and header file for details + * cFS default implementation + */ +int32 CFE_MSG_GetTypeFromMsgId(CFE_SB_MsgId_t MsgId, CFE_MSG_Type_t *Type) +{ + + CFE_MSG_Message_t msg; + + if (Type == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + CFE_MSG_SetMsgId(&msg, MsgId); + CFE_MSG_GetType(&msg, Type); + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_msgid_v1.c b/modules/msg/src/cfe_msg_msgid_v1.c new file mode 100644 index 000000000..8b79ec3d3 --- /dev/null +++ b/modules/msg/src/cfe_msg_msgid_v1.c @@ -0,0 +1,71 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message id access functions, cFS version 1 implementation + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_error.h" +#include "cfe_platform_cfg.h" + +/****************************************************************************** + * Get message id - See API and header file for details + * cFS default version 1 implementation using CCSDS headers + * + * Message Id = CCSDS Stream ID (in local endian) + */ +int32 CFE_MSG_GetMsgId(const CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t *MsgId) +{ + + CFE_SB_MsgId_Atom_t msgidval; + + if (MsgPtr == NULL || MsgId == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + msgidval = (MsgPtr->CCSDS.Pri.StreamId[0] << 8) + MsgPtr->CCSDS.Pri.StreamId[1]; + *MsgId = CFE_SB_ValueToMsgId(msgidval); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message id - See API and header file for details + * cFS default version 1 implementations using CCSDS headers + * + * CCSDS Stream ID = Message Id converted to big endian + */ +int32 CFE_MSG_SetMsgId(CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t MsgId) +{ + + CFE_SB_MsgId_Atom_t msgidval = CFE_SB_MsgIdToValue(MsgId); + + if (MsgPtr == NULL || msgidval > CFE_PLATFORM_SB_HIGHEST_VALID_MSGID) + { + return CFE_MSG_BAD_ARGUMENT; + } + + MsgPtr->CCSDS.Pri.StreamId[0] = (uint8)(msgidval >> 8); + MsgPtr->CCSDS.Pri.StreamId[1] = (uint8)(msgidval); + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_msgid_v2.c b/modules/msg/src/cfe_msg_msgid_v2.c new file mode 100644 index 000000000..6845f9755 --- /dev/null +++ b/modules/msg/src/cfe_msg_msgid_v2.c @@ -0,0 +1,111 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Message id access functions + * + * cFS default version 2 implementation using CCSDS headers + * + * Message Id: + * 7 bits from the primary header APID (0x7F of 0x7FF) + * 1 bit for the command/telemetry flag + * 0 bits from the Playback flag + * 8 bits from the secondary header APID qualifier (Subsystem) (0xFF of 0x01FF) + * 0 bits from the secondary header APID qualifier as the System + * = 16 bits total + * + * Byte 1 Byte 0 + * 7 6 5 4 3 2 1 0 7 6 5 4 3 2 1 0 + * +-+-+-+-+-+-+-+-+|--------|+-+-+-+-+-+-+-+ + * | APID Qualifier |C/T flg | Pri Hdr APID | + * +-+-+-+-+-+-+-+-+|--------|+-+-+-+-+-+-+-+ + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_error.h" +#include "cfe_platform_cfg.h" + +/* cFS MsgId definitions */ +#define CFE_MSG_MSGID_APID_MASK 0x007F /**< \brief CCSDS ApId mask for MsgId */ +#define CFE_MSG_MSGID_TYPE_MASK 0x0080 /**< \brief Message type mask for MsgId, set = cmd */ +#define CFE_MSG_MSGID_SUBSYS_MASK 0xFF00 /**< \brief Subsystem mask for MsgId */ + +/****************************************************************************** + * Get message id - See API and header file for details + */ +int32 CFE_MSG_GetMsgId(const CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t *MsgId) +{ + + CFE_SB_MsgId_Atom_t msgidval; + CFE_MSG_Type_t type; + + if (MsgPtr == NULL || MsgId == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, assumes tlm if invalid */ + CFE_MSG_GetType(MsgPtr, &type); + + /* Set message ID bits from CCSDS header fields */ + msgidval = MsgPtr->CCSDS.Pri.StreamId[1] & CFE_MSG_MSGID_APID_MASK; + if (type == CFE_MSG_Type_Cmd) + { + msgidval |= CFE_MSG_MSGID_TYPE_MASK; + } + msgidval |= (MsgPtr->CCSDS.Ext.Subsystem[1] << 8) & CFE_MSG_MSGID_SUBSYS_MASK; + + *MsgId = CFE_SB_ValueToMsgId(msgidval); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set message id - See API and header file for details + */ +int32 CFE_MSG_SetMsgId(CFE_MSG_Message_t *MsgPtr, CFE_SB_MsgId_t MsgId) +{ + + CFE_SB_MsgId_Atom_t msgidval = CFE_SB_MsgIdToValue(MsgId); + + if (MsgPtr == NULL || msgidval > CFE_PLATFORM_SB_HIGHEST_VALID_MSGID) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Clear and set PID_MSGID_MASK bits */ + MsgPtr->CCSDS.Pri.StreamId[1] = + (MsgPtr->CCSDS.Pri.StreamId[1] & ~CFE_MSG_MSGID_APID_MASK) | (msgidval & CFE_MSG_MSGID_APID_MASK); + + /* Set APIDQ Subsystem bits */ + MsgPtr->CCSDS.Ext.Subsystem[1] = ((msgidval & CFE_MSG_MSGID_SUBSYS_MASK) >> 8); + + /* Set type, ignores return since no failure action */ + if ((msgidval & CFE_MSG_MSGID_TYPE_MASK) != 0) + { + CFE_MSG_SetType(MsgPtr, CFE_MSG_Type_Cmd); + } + else + { + CFE_MSG_SetType(MsgPtr, CFE_MSG_Type_Tlm); + } + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_sechdr_checksum.c b/modules/msg/src/cfe_msg_sechdr_checksum.c new file mode 100644 index 000000000..aa645c864 --- /dev/null +++ b/modules/msg/src/cfe_msg_sechdr_checksum.c @@ -0,0 +1,116 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Checksum field access functions + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" + +/******************************************************************************/ +/** + * \brief Compute checksum - internal utility + * + * \param[in] MsgPtr Message pointer to checksum + * + * \return Calculated checksum + */ +CFE_MSG_Checksum_t CFE_MSG_ComputeCheckSum(const CFE_MSG_Message_t *MsgPtr) +{ + + uint32 PktLen = 0; + const uint8 * BytePtr = MsgPtr->Byte; + CFE_MSG_Checksum_t chksum = 0xFF; + + /* Message already checked, no error case reachable */ + CFE_MSG_GetSize(MsgPtr, &PktLen); + + while (PktLen--) + { + chksum ^= *(BytePtr++); + } + + return chksum; +} + +/****************************************************************************** + * Calculate and set checksum field - See API and header file for details + * Implementation supports cFS secondary definition or no secodary header + */ +int32 CFE_MSG_GenerateChecksum(CFE_MSG_Message_t *MsgPtr) +{ + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_CommandHeader_t *cmd = (CFE_MSG_CommandHeader_t *)MsgPtr; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Cmd || !hassechdr) + { + return CFE_MSG_WRONG_MSG_TYPE; + } + + /* Zero checksum so new checksum will be correct */ + cmd->Sec.Checksum = 0; + + /* Compute and set */ + cmd->Sec.Checksum = CFE_MSG_ComputeCheckSum((CFE_MSG_Message_t *)cmd); + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Validate checksum - See API and header file for details + * Implementation supports cFS secondary definition or no secondary header + */ +int32 CFE_MSG_ValidateChecksum(const CFE_MSG_Message_t *MsgPtr, bool *IsValid) +{ + + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + + if (MsgPtr == NULL || IsValid == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Cmd || !hassechdr) + { + return CFE_MSG_WRONG_MSG_TYPE; + } + + /* Compute, valid if == 0 */ + *IsValid = (CFE_MSG_ComputeCheckSum(MsgPtr) == 0); + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_sechdr_fc.c b/modules/msg/src/cfe_msg_sechdr_fc.c new file mode 100644 index 000000000..aa1c5abc9 --- /dev/null +++ b/modules/msg/src/cfe_msg_sechdr_fc.c @@ -0,0 +1,88 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Function code field access functions + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" + +#define CFE_MSG_FC_MASK 0x7F /**< \brief Function code mask */ + +/****************************************************************************** + * Get function code - See API and header file for details + * cFS default secondary header implementation + */ +int32 CFE_MSG_GetFcnCode(const CFE_MSG_Message_t *MsgPtr, CFE_MSG_FcnCode_t *FcnCode) +{ + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_CommandHeader_t *cmd = (CFE_MSG_CommandHeader_t *)MsgPtr; + + if (MsgPtr == NULL || FcnCode == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Cmd || !hassechdr) + { + *FcnCode = 0; + return CFE_MSG_WRONG_MSG_TYPE; + } + + *FcnCode = cmd->Sec.FunctionCode & CFE_MSG_FC_MASK; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Set function code - See API and header file for details + * cFS default secondary header implementation + */ +int32 CFE_MSG_SetFcnCode(CFE_MSG_Message_t *MsgPtr, CFE_MSG_FcnCode_t FcnCode) +{ + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_CommandHeader_t *cmd = (CFE_MSG_CommandHeader_t *)MsgPtr; + + if (MsgPtr == NULL || (FcnCode > CFE_MSG_FC_MASK)) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Cmd || !hassechdr) + { + return CFE_MSG_WRONG_MSG_TYPE; + } + + cmd->Sec.FunctionCode = FcnCode; + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_sechdr_time.c b/modules/msg/src/cfe_msg_sechdr_time.c new file mode 100644 index 000000000..71d8d7a84 --- /dev/null +++ b/modules/msg/src/cfe_msg_sechdr_time.c @@ -0,0 +1,97 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Time field access functions - cFS default 32 bit seconds, 16 bit subseconds + * in big endian format + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_error.h" +#include + +/****************************************************************************** + * Set message time - See API and header file for details + */ +int32 CFE_MSG_SetMsgTime(CFE_MSG_Message_t *MsgPtr, CFE_TIME_SysTime_t NewTime) +{ + + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_TelemetryHeader_t *tlm = (CFE_MSG_TelemetryHeader_t *)MsgPtr; + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Tlm || !hassechdr) + { + return CFE_MSG_WRONG_MSG_TYPE; + } + + /* Set big endian time field with default 32/16 layout */ + tlm->Sec.Time[0] = (NewTime.Seconds >> 24) & 0xFF; + tlm->Sec.Time[1] = (NewTime.Seconds >> 16) & 0xFF; + tlm->Sec.Time[2] = (NewTime.Seconds >> 8) & 0xFF; + tlm->Sec.Time[3] = NewTime.Seconds & 0xFF; + tlm->Sec.Time[4] = (NewTime.Subseconds >> 24) & 0xFF; + tlm->Sec.Time[5] = (NewTime.Subseconds >> 16) & 0xFF; + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message time - See API and header file for details + */ +int32 CFE_MSG_GetMsgTime(const CFE_MSG_Message_t *MsgPtr, CFE_TIME_SysTime_t *Time) +{ + + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_TelemetryHeader_t *tlm = (CFE_MSG_TelemetryHeader_t *)MsgPtr; + + if (MsgPtr == NULL || Time == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Tlm || !hassechdr) + { + memset(Time, 0, sizeof(*Time)); + return CFE_MSG_WRONG_MSG_TYPE; + } + + /* Get big endian time fields with default 32/16 layout */ + Time->Subseconds = (tlm->Sec.Time[4] << 24) + (tlm->Sec.Time[5] << 16); + Time->Seconds = (tlm->Sec.Time[0] << 24) + (tlm->Sec.Time[1] << 16) + (tlm->Sec.Time[2] << 8) + tlm->Sec.Time[3]; + + return CFE_SUCCESS; +} diff --git a/modules/msg/src/cfe_msg_sechdr_time_old.c b/modules/msg/src/cfe_msg_sechdr_time_old.c new file mode 100644 index 000000000..7b1a5b16b --- /dev/null +++ b/modules/msg/src/cfe_msg_sechdr_time_old.c @@ -0,0 +1,137 @@ +/* +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +*/ + +/****************************************************************************** + * Time field access functions + */ +#include "cfe_msg_api.h" +#include "cfe_msg_priv.h" +#include "cfe_error.h" +#include + +/****************************************************************************** + * Set message time - See API and header file for details + */ +int32 CFE_MSG_SetMsgTime(CFE_MSG_Message_t *MsgPtr, CFE_TIME_SysTime_t NewTime) +{ + + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_TelemetryHeader_t *tlm = (CFE_MSG_TelemetryHeader_t *)MsgPtr; + +/* declare format specific vars */ +#if (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_16_SUBS) + uint16 LocalSubs16; +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_M_20) + uint32 LocalSubs32; +#endif + + if (MsgPtr == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Tlm || !hassechdr) + { + return CFE_MSG_WRONG_MSG_TYPE; + } + + memcpy(&tlm->Sec.Time[0], &NewTime.Seconds, 4); + +#if (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_16_SUBS) + + /* convert time from CFE_TIME_SysTime_t format to packet format */ + LocalSubs16 = (uint16)(NewTime.Subseconds >> 16); + memcpy(&tlm->Sec.Time[4], &LocalSubs16, 2); + +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_SUBS) + + /* no conversion necessary -- packet format = CFE_TIME_SysTime_t format */ + memcpy(&tlm->Sec.Time[4], &NewTime.Subseconds, 4); + +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_M_20) + + /* convert time from CFE_TIME_SysTime_t format to packet format */ + LocalSubs32 = CFE_TIME_Sub2MicroSecs(NewTime.Subseconds) << 12; + memcpy(&tlm->Sec.Time[4], &LocalSubs32, 4); + +#endif + + return CFE_SUCCESS; +} + +/****************************************************************************** + * Get message time - See API and header file for details + */ +int32 CFE_MSG_GetMsgTime(const CFE_MSG_Message_t *MsgPtr, CFE_TIME_SysTime_t *Time) +{ + + uint32 status; + CFE_MSG_Type_t type; + bool hassechdr = false; + CFE_MSG_TelemetryHeader_t *tlm = (CFE_MSG_TelemetryHeader_t *)MsgPtr; + +#if (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_16_SUBS) + uint16 LocalSubs16; +#endif + + if (MsgPtr == NULL || Time == NULL) + { + return CFE_MSG_BAD_ARGUMENT; + } + + /* Ignore return, pointer already checked */ + CFE_MSG_GetHasSecondaryHeader(MsgPtr, &hassechdr); + + status = CFE_MSG_GetType(MsgPtr, &type); + if (status != CFE_SUCCESS || type != CFE_MSG_Type_Tlm || !hassechdr) + { + memset(Time, 0, sizeof(*Time)); + return CFE_MSG_WRONG_MSG_TYPE; + } + + memcpy(&Time->Seconds, &tlm->Sec.Time[0], 4); + +#if (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_16_SUBS) + + memcpy(&LocalSubs16, &tlm->Sec.Time[4], 2); + /* convert packet data into CFE_TIME_SysTime_t format */ + Time->Subseconds = ((uint32)LocalSubs16) << 16; + +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_SUBS) + + memcpy(&Time->Subseconds, &tlm->Sec.Time[4], 4); + /* no conversion necessary -- packet format = CFE_TIME_SysTime_t format */ + +#elif (CFE_MISSION_SB_PACKET_TIME_FORMAT == CFE_MISSION_SB_TIME_32_32_M_20) + + memcpy(&LocalSubs32, &tlm->Sec.Time[4], 4); + /* convert packet data into CFE_TIME_SysTime_t format */ + Time->Subseconds = CFE_TIME_Micro2SubSecs((LocalSubs32 >> 12)); + +#endif + + return CFE_SUCCESS; +}