diff --git a/README.md b/README.md index e7e5469..b9b8f9c 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ -Telemetry Output (TO) application for use with Core Flight Systems (CFS) missions. +Telemetry Output + +NASA core Flight System Scheduler Application + +Description + +Telemetry Output (TO) application is a core Flight System (cFS) application that is a plug in to the Core Flight Executive (cFE) component of the cFS. + +The cFS is a platform and project independent reusable software framework and set of reusable applications developed by NASA Goddard Space Flight Center. This framework is used as the basis for the flight software for satellite data systems and instruments, but can be used on other embedded systems. More information on the cFS can be found at http://cfs.gsfc.nasa.gov + +The Telemetry Output (TO) Application is responsible for transmitting telemetry to external destination(s) (such as a ground station) over transport devices(s). + + diff --git a/analysis/cppcheck_errors_to.txt b/analysis/cppcheck_errors_to.txt new file mode 100644 index 0000000..b112359 --- /dev/null +++ b/analysis/cppcheck_errors_to.txt @@ -0,0 +1 @@ +[../../io_lib/fsw/public_inc/tm_sync.h:33]: (error) Invalid number of character ({) when these macros are defined: '__cplusplus'. diff --git a/analysis/run_cppcheck_to.sh b/analysis/run_cppcheck_to.sh new file mode 100755 index 0000000..0b136b6 --- /dev/null +++ b/analysis/run_cppcheck_to.sh @@ -0,0 +1,18 @@ +#!/bin/bash +# Runs cppcheck on TO + +to_app="../fsw" +io_lib="../../io_lib/fsw" + +output_file="./cppcheck_to.txt" +error_file="./cppcheck_errors_to.txt" + +command -v cppcheck >/dev/null 2>&1 || { echo >&2 "Error: Requires cppcheck but it's not installed. Aborting."; exit 1; } + +paths_to_check="$to_app/src/ $to_app/examples/multi/ $to_app/examples/multi_tf/ $to_app/examples/rs422/ $to_app/examples/udp/" + +include_dirs="-I $to_app/platform_inc/ -I $to_app/mission_inc -I $io_lib/public_inc" + +flags="-v --report-progress --std=c89" + +cppcheck $flags $include_dirs $paths_to_check 2> $error_file > $output_file diff --git a/docs/SDD_Generic_CI-TO_V1_5.doc b/docs/SDD_Generic_CI-TO_V1_5.doc new file mode 100755 index 0000000..6bfcdd1 Binary files /dev/null and b/docs/SDD_Generic_CI-TO_V1_5.doc differ diff --git a/docs/SDD_Generic_CI-TO_V1_5.pdf b/docs/SDD_Generic_CI-TO_V1_5.pdf new file mode 100755 index 0000000..6683d5d Binary files /dev/null and b/docs/SDD_Generic_CI-TO_V1_5.pdf differ diff --git a/fsw/examples/README b/fsw/examples/README new file mode 100644 index 0000000..29aa3ed --- /dev/null +++ b/fsw/examples/README @@ -0,0 +1,43 @@ +# Author: Guy de Carufel (Odyssey Space Research) +# Date: Jan 26, 2016 + +This directory holds example implementations of the custom layer for this application. + +To make use of an example, use the setup.sh +> ./setup.sh -h + +The normal setup is to copy the files in the appropriate locations and then modify then +according to your mission needs. +For the "ci/to_lab" application equivalent, use the udp example. +>./setup.sh udp + +You can link to files in the examples in this directory rather than making copies +by using the -l option +>./setup.sh -l multi + + +DEVELOPERS NOTE: +1. Always revert back to the udp example as a copy (not a link) before comitting to +the repo if you made changes to example files. +We want to keep the udp to_custom.c as the default example. +>./setup.sh udp + +2. If you add examples, make sure to name the directory the same in both CI & TO. + + +USEFUL TIP: +Add the following to your .bashrc to update both CI/TO at the same time: + +setCustomLink() { + cd ${MISSION_HOME}/apps/ci/fsw/examples/ + ./setup.sh -l $1 + cd ${MISSION_HOME}/apps/to/fsw/examples/ + ./setup.sh -l $1 +} + +setCustomCopy() { + cd ${MISSION_HOME}/apps/ci/fsw/examples/ + ./setup.sh $1 + cd ${MISSION_HOME}/apps/to/fsw/examples/ + ./setup.sh $1 +} diff --git a/fsw/examples/multi/MISSION_to_types.h b/fsw/examples/multi/MISSION_to_types.h new file mode 100644 index 0000000..762c2a5 --- /dev/null +++ b/fsw/examples/multi/MISSION_to_types.h @@ -0,0 +1,77 @@ +/******************************************************************************/ +/** \file MISSION_to_types.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Command and telemetry data strucutres for TO application (Multi) +* +* \par +* This header file contains definitions of command and telemetry data +* structures for TO applications for the Multi transport protocol example. +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/inc/ folder. +* - Standard command messages are defined in to_cmds.h +* - Default HK Telemetry structure is defined in to_hktlm.h +* +* \par Modification History: +* - 2015-06-02 | Guy de Carufel | Code Started +* - 2015-09-22 | Guy de Carufel | Moved hktlm to to_hktlm.h +*******************************************************************************/ +#ifndef _MISSION_TO_TYPES_H_ +#define _MISSION_TO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Include Files +*/ +#include "cfe.h" +#include "../to/fsw/src/to_hktlm.h" + +/* +** Defines +*/ +#define TO_MAX_IP_STRING_SIZE 16 + +/* Define enable / disable commands */ +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + char cDestIp[TO_MAX_IP_STRING_SIZE]; /**< Destination IP */ + uint16 usDestPort; /**< Destination PORT */ + int32 iFileDesc; /**< File Descriptor of Port to use. */ +} TO_EnableOutputCmd_t; + + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; +} TO_DisableOutputCmd_t; + + +/*************** Telemetry **************/ +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; +} TO_InData_t; + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint32 uiCounter; +} TO_OutData_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* _MISSION_TO_TYPES_H_ */ + +/*============================================================================== +** End of file MISSION_to_types.h +**============================================================================*/ diff --git a/fsw/examples/multi/to_custom.c b/fsw/examples/multi/to_custom.c new file mode 100644 index 0000000..4b445c2 --- /dev/null +++ b/fsw/examples/multi/to_custom.c @@ -0,0 +1,285 @@ +/******************************************************************************/ +/** \file to_custom.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions for Custom Layer of TO Multi Devices +* +* \par +* This file defines the functions for a custom implementation of the custom +* layer of the TO application with temeletry output to multiple devices +* (RS422 and UDP) +* +* \par API Functions Defined: +* - TO_CustomInit() - Initialize the transport protocol +* - TO_CustomAppCmds() - Process custom App Commands +* - TO_CustomEnableOutputCmd() - Enable telemetry output +* - TO_CustomDisableOutputCmd() - Disable telemetry output +* - TO_CustomCleanup() - Cleanup callback to close transport channel. +* - TO_CustomProcessData() - Send output data over transport protocol. +* +* \par Private Functions Defined: +* - TO_SendDataTypePktCmd() - Send Test packet (Reference to_lab app) +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All input messages are CCSDS messages +* - Both CI and TO makes use of the same RS422 device +* - All config macros defined in to_platform_cfg.h +* +* \par Modification History: +* - 2015-06-03 | Guy de Carufel | Code Started +*******************************************************************************/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "network_includes.h" +#include "trans_udp.h" +#include "trans_rs422.h" + +#include "to_app.h" +#include "ci_msgids.h" + +/* +** Local Defines +*/ + +/* +** Local Structure Declarations +*/ +typedef struct +{ + int32 iFileDesc; /**< File Descriptor of serial port */ + IO_TransUdp_t udp; /**< UDP working */ + uint8 buffer[2000]; +} TO_CustomData_t; + +/* +** External Global Variables +*/ +extern TO_AppData_t g_TO_AppData; + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ +static TO_CustomData_t g_TO_CustomData; + +/* +** Local Function Definitions +*/ +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); +static int32 TO_CustomProcessSizeSent(int32, int32, int32,uint16); + +/******************************************************************************* +** Custom Application Functions +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Custom Initialization +*******************************************************************************/ +int32 TO_CustomInit(void) +{ + int32 iStatus = TO_SUCCESS; + + /* Set Critical Message Ids which must always be + * in config table. */ + g_TO_AppData.criticalMid[0] = TO_HK_TLM_MID; + g_TO_AppData.criticalMid[1] = CI_HK_TLM_MID; + + /* Create socket for outgoing */ + if (IO_TransUdpCreateSocket(&g_TO_CustomData.udp) < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Route 0: Udp */ + g_TO_AppData.routes[0].usExists = 1; + /* Route 1: Serial */ + g_TO_AppData.routes[1].usExists = 1; + + /* Tie route 0 to CF channel 0 */ + g_TO_AppData.routes[0].sCfChnlIdx = 0; + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of custom app commands +*******************************************************************************/ +int32 TO_CustomAppCmds(CFE_SB_Msg_t* pMsg) +{ + int32 iStatus = TO_SUCCESS; + uint32 uiCmdCode = CFE_SB_GetCmdCode(pMsg); + switch (uiCmdCode) + { + case TO_SEND_DATA_TYPE_CC: + TO_SendDataTypePktCmd(pMsg); + break; + + default: + iStatus = TO_ERROR; + break; + } + + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of output telemetry +*******************************************************************************/ +int32 TO_CustomProcessData(CFE_SB_Msg_t * pMsg, int32 size, int32 iTblIdx, + uint16 usRouteId) +{ + int32 iSentSize = 0; + int32 iStatus = TO_SUCCESS; + int32 iReturn = TO_SUCCESS; + + CFE_PSP_MemCpy((void *) &g_TO_CustomData.buffer[0], (void *) pMsg, size); + + /* For route 0, use socket */ + if (usRouteId == 0) + { + iSentSize = IO_TransUdpSnd(&g_TO_CustomData.udp, + &g_TO_CustomData.buffer[0], size); + iStatus = TO_CustomProcessSizeSent(size, iSentSize, iTblIdx, 0); + if (iStatus != TO_SUCCESS) + { + iReturn = TO_ERROR; + } + } + /* For route 1, use serial port */ + if (usRouteId == 1) + { + iSentSize = IO_TransRS422Write(g_TO_CustomData.iFileDesc, + &g_TO_CustomData.buffer[0], size); + iStatus = TO_CustomProcessSizeSent(size, iSentSize, iTblIdx, 1); + if (iStatus != TO_SUCCESS) + { + iReturn = TO_ERROR; + } + } + + return iReturn; +} + + +/******************************************************************************/ +/** \brief Check Data Sent Size (Local) +*******************************************************************************/ +int32 TO_CustomProcessSizeSent(int32 size, int32 iSentSize, int32 iTblIdx, + uint16 routeId) +{ + int32 iStatus = TO_SUCCESS; + + if (iSentSize < 0) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO Output errno %d. Route ID:%u disabled ", + errno, routeId); + TO_DisableRoute(routeId); + iStatus = TO_ERROR; + } + else if (iSentSize != size) + { + CFE_SB_MsgId_t usMsgId = TO_GetMessageID(iTblIdx); + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO sent incomplete message (Insuficient bandwidth likely). " + "MID:%d, ROUTE ID:%u, MsgSize:%d, SentSize:%d. Route disabled.", + usMsgId, routeId, size, iSentSize); + TO_DisableRoute(routeId); + iStatus = TO_ERROR; + } + + return iStatus; +} + + +/******************************************************************************/ +/** \brief Custom Cleanup +*******************************************************************************/ +void TO_CustomCleanup(void) +{ + if (g_TO_AppData.usOutputEnabled) + { + CFE_EVS_SendEvent(TO_CUSTOM_INF_EID, CFE_EVS_INFORMATION, + "TO - Closing Socket."); + IO_TransUdpCloseSocket(&g_TO_CustomData.udp); + } + + return; +} + +/******************************************************************************/ +/** \brief Enable Output Command Response +*******************************************************************************/ +int32 TO_CustomEnableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + int32 iStatus = IO_TRANS_UDP_NO_ERROR; + int32 routeMask = TO_ERROR; + char cDestIp[TO_MAX_IP_STRING_SIZE]; + uint16 usDestPort = 0; + + TO_EnableOutputCmd_t * pCustomCmd = (TO_EnableOutputCmd_t *) pCmdMsg; + strncpy(cDestIp, pCustomCmd->cDestIp, sizeof(cDestIp)); + + if (pCustomCmd->usDestPort > 0) + { + usDestPort = pCustomCmd->usDestPort; + } + else + { + usDestPort = TO_DEFAULT_DEST_PORT; + } + + iStatus = IO_TransUdpSetDestAddr(&g_TO_CustomData.udp, pCustomCmd->cDestIp, + usDestPort); + if (iStatus < 0) + { + goto end_of_function; + } + + g_TO_CustomData.iFileDesc = pCustomCmd->iFileDesc; + + CFE_EVS_SendEvent(TO_CUSTOM_INF_EID, CFE_EVS_INFORMATION, + "Serial Output Device File Descriptor Set."); + + /* Both routes are now configured */ + TO_SetRouteAsConfigured(0); + TO_SetRouteAsConfigured(1); + + /* Enable both routes 0 and 1. */ + routeMask = 0x0003; + +end_of_function: + return routeMask; +} + +/******************************************************************************/ +/** \brief Disable Output Command Response +*******************************************************************************/ +int32 TO_CustomDisableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + /* Disable */ + g_TO_AppData.usOutputEnabled = 0; + return TO_SUCCESS; +} + + +/******************************************************************************* +** Non standard custom Commands +*******************************************************************************/ + +/*============================================================================== +** End of file to_custom.c +**============================================================================*/ diff --git a/fsw/examples/multi/to_platform_cfg.h b/fsw/examples/multi/to_platform_cfg.h new file mode 100644 index 0000000..c6dc4e3 --- /dev/null +++ b/fsw/examples/multi/to_platform_cfg.h @@ -0,0 +1,82 @@ +/******************************************************************************/ +/** \file to_platform_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Sample config file for TO Application with Multi device +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/to/fsw/platform_inc folder. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +#ifndef _TO_PLATFORM_CFG_H_ +#define _TO_PLATFORM_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ +#define TO_SCH_PIPE_DEPTH 10 +#define TO_CMD_PIPE_DEPTH 10 +#define TO_TLM_PIPE_DEPTH 10 + +#define TO_NUM_CRITICAL_MIDS 3 + +#define TO_MAX_TBL_ENTRIES 100 +#define TO_WAKEUP_TIMEOUT 500 + +#define TO_CONFIG_TABLENAME "to_config" +#define TO_CONFIG_FILENAME "/cf/apps/to_config.tbl" + +#define TO_GROUP_NUMBER_MASK 0xFF000000 +#define TO_MULTI_GROUP_MASK 0x00FFFFFF + +#define TO_DEFAULT_DEST_PORT 5011 + +#define TO_CF_THROTTLE_SEM_NAME "CFTOSemId" + +/* +** Include Files +*/ + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_PLATFORM_CFG_H_ */ + +/*============================================================================== +** End of file to_platform_cfg.h +**============================================================================*/ + diff --git a/fsw/examples/multi_tf/MISSION_to_types.h b/fsw/examples/multi_tf/MISSION_to_types.h new file mode 100644 index 0000000..9e71ac5 --- /dev/null +++ b/fsw/examples/multi_tf/MISSION_to_types.h @@ -0,0 +1,86 @@ +/******************************************************************************/ +/** \file MISSION_to_types.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Command and telemetry data strucutres for TO application (Multi) +* +* \par +* This header file contains definitions of command and telemetry data +* structures for TO applications for the Multi transport protocol example. +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/inc/ folder. +* - Standard command messages are defined in to_cmds.h +* - Default HK Telemetry structure is defined in to_hktlm.h +* +* \par Modification History: +* - 2015-06-02 | Guy de Carufel | Code Started +* - 2015-09-22 | Guy de Carufel | Moved hktlm to to_hktlm.h +*******************************************************************************/ +#ifndef _MISSION_TO_TYPES_H_ +#define _MISSION_TO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Include Files +*/ +#include "cfe.h" +#include "../to/fsw/src/to_hktlm.h" + +#include "cop1.h" + +/* +** Defines +*/ +#define TO_MAX_IP_STRING_SIZE 16 + +/* Define enable / disable commands */ +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + char cDestIp[TO_MAX_IP_STRING_SIZE]; /**< Destination IP */ + uint16 usDestPort; /**< Destination PORT */ + int32 iFileDesc; /**< File Descriptor of Port to use. */ +} TO_EnableOutputCmd_t; + + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; +} TO_DisableOutputCmd_t; + + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + COP1_Clcw_t clcw; /**< COP-1 CLCW Data */ +} TO_CustomSetOcfCmd_t; + + +/*************** Telemetry **************/ +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; +} TO_InData_t; + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint32 uiCounter; +} TO_OutData_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* _MISSION_TO_TYPES_H_ */ + +/*============================================================================== +** End of file MISSION_to_types.h +**============================================================================*/ diff --git a/fsw/examples/multi_tf/to_custom.c b/fsw/examples/multi_tf/to_custom.c new file mode 100644 index 0000000..ef7739f --- /dev/null +++ b/fsw/examples/multi_tf/to_custom.c @@ -0,0 +1,572 @@ +/******************************************************************************/ +/** \file to_custom.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions for Custom Layer of TO Multi Devices with TFs. +* +* \par +* This file defines the functions for a custom implementation of the custom +* layer of the TO application with transfer frames sent over multiple +* devices (RS422 and UDP) with the Space Data link protocol Transfer frames. +* +* \par API Functions Defined: +* - TO_CustomInit() - Initialize the transport protocol +* - TO_CustomAppCmds() - Process custom App Commands +* - TO_CustomEnableOutputCmd() - Enable telemetry output +* - TO_CustomDisableOutputCmd() - Disable telemetry output +* - TO_CustomCleanup() - Cleanup callback to close transport channel. +* - TO_CustomProcessData() - Send output data over transport protocol. +* +* \par Private Functions Defined: +* - TO_SendDataTypePktCmd() - Send Test packet (Reference to_lab app) +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All output messages are Transfer Frames +* - All config macros defined in to_platform_cfg.h +* +* \par Modification History: +* - 2015-12-23 | Guy de Carufel | Code Started +*******************************************************************************/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "network_includes.h" +#include "io_lib_utils.h" +#include "trans_udp.h" +#include "trans_rs422.h" +#include "tm_sdlp.h" +#include "tm_sync.h" +#include "cop1.h" + +#include "to_app.h" +#include "ci_msgids.h" + +/* +** Local Defines +*/ + +/* +** Local Structure Declarations +*/ +typedef struct +{ + TM_SDLP_FrameInfo_t frameInfo; + TM_SDLP_ChannelConfig_t vcConfig; + uint8 ocfBuff[4]; + uint8 ofBuff[TO_CUSTOM_TF_OVERFLOW_SIZE]; +} TO_CustomVChnl_t; + +typedef struct +{ + TM_SDLP_GlobalConfig_t mcConfig; + uint8 mcFrameCnt; + TO_CustomVChnl_t vc; +} TO_CustomMChnl_t; + +typedef struct +{ + TO_CustomMChnl_t mc; + uint8 buffer[TO_CUSTOM_TF_SIZE + TM_SYNC_ASM_SIZE]; +} TO_CustomPChnl_t; + +typedef struct +{ + IO_TransUdp_t udp; + TO_CustomPChnl_t pc; +} TO_CustomSocketPChnl_t; + +typedef struct +{ + int32 portFd; + TO_CustomPChnl_t pc; +} TO_CustomSerialPChnl_t; + +typedef struct +{ + TO_CustomSocketPChnl_t socket; + TO_CustomSerialPChnl_t serial; + uint8 idleBuff[TO_CUSTOM_TF_IDLE_SIZE]; +} TO_CustomData_t; + +/* +** External Global Variables +*/ +extern TO_AppData_t g_TO_AppData; + +/* +** Global Variables +*/ +static TO_CustomData_t g_TO_CustomData; + +/* +** Local Variables +*/ +static uint8 idlePattern[32]; +static CFE_SB_Msg_t *pIdlePacket = (CFE_SB_Msg_t *) &g_TO_CustomData.idleBuff; +static const uint16 iCaduSize = TO_CUSTOM_TF_SIZE + TM_SYNC_ASM_SIZE; + +/* +** Local Function Definitions +*/ +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); +static void TO_CustomSetOcfCmd(CFE_SB_Msg_t *pCmdMsg); +static int32 TO_CustomProcessPacket(CFE_SB_Msg_t *pMsg, uint16 usRouteId); +static TO_CustomPChnl_t * TO_CustomGetChnl(uint16 usRouteId); +static int32 TO_CustomProcessSizeSent(int32, int32, uint16); + +/******************************************************************************* +** Custom Application Functions +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Custom Initialization +*******************************************************************************/ +int32 TO_CustomInit(void) +{ + int32 iStatus = TO_SUCCESS; + TO_CustomPChnl_t *pChnl; + + /* Create socket for outgoing */ + if (IO_TransUdpCreateSocket(&g_TO_CustomData.socket.udp) < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Set Critical Message Ids which must always be + * in config table. */ + g_TO_AppData.criticalMid[0] = TO_HK_TLM_MID; + g_TO_AppData.criticalMid[1] = CI_HK_TLM_MID; + + /* Initialize Idle pattern as pseudo-random sequence. */ + IO_LIB_UTIL_GenPseudoRandomSeq(&idlePattern[0], 0xa9, 0xff); + + /* Initialize Idle packet with repeating idle pattern */ + TM_SDLP_InitIdlePacket(pIdlePacket, &idlePattern[0], + TO_CUSTOM_TF_IDLE_SIZE, 255); + + /* Initialize Master channels */ + g_TO_CustomData.serial.pc.mc.mcConfig.scId = CFE_SPACECRAFT_ID; + g_TO_CustomData.serial.pc.mc.mcConfig.frameLength = TO_CUSTOM_TF_SIZE; + g_TO_CustomData.serial.pc.mc.mcConfig.hasErrCtrl = TO_CUSTOM_TF_ERR_CTRL; + g_TO_CustomData.serial.pc.mc.mcFrameCnt = 0; + + g_TO_CustomData.socket.pc.mc.mcConfig.scId = CFE_SPACECRAFT_ID; + g_TO_CustomData.socket.pc.mc.mcConfig.frameLength = TO_CUSTOM_TF_SIZE; + g_TO_CustomData.socket.pc.mc.mcConfig.hasErrCtrl = TO_CUSTOM_TF_ERR_CTRL; + g_TO_CustomData.socket.pc.mc.mcFrameCnt = 0; + + /* NOTE: We are setting VC ID to: Socket: 0, Serial: 1 */ + + /* Set channel config table */ + TM_SDLP_ChannelConfig_t chnlConfig[TO_CUSTOM_NUM_CHNL] = + { + {0, 0, 0, 1, 0, 0, TO_CUSTOM_TF_OVERFLOW_SIZE}, + {1, 0, 0, 1, 0, 0, TO_CUSTOM_TF_OVERFLOW_SIZE} + }; + + pChnl = &g_TO_CustomData.socket.pc; + CFE_PSP_MemCpy((void *) &pChnl->mc.vc.vcConfig, (void *) &chnlConfig[0], + sizeof(TM_SDLP_ChannelConfig_t)); + + if (TM_SDLP_InitChannel(&pChnl->mc.vc.frameInfo, + &pChnl->buffer[TM_SYNC_ASM_SIZE], + &pChnl->mc.vc.ofBuff[0], + &pChnl->mc.mcConfig, + &pChnl->mc.vc.vcConfig) < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + pChnl = &g_TO_CustomData.serial.pc; + CFE_PSP_MemCpy((void *) &pChnl->mc.vc.vcConfig, (void *) &chnlConfig[0], + sizeof(TM_SDLP_ChannelConfig_t)); + + if (TM_SDLP_InitChannel(&pChnl->mc.vc.frameInfo, + &pChnl->buffer[TM_SYNC_ASM_SIZE], + &pChnl->mc.vc.ofBuff[0], + &pChnl->mc.mcConfig, + &pChnl->mc.vc.vcConfig) < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Route 0: Udp */ + g_TO_AppData.routes[0].usExists = 1; + /* Route 1: Serial */ + g_TO_AppData.routes[1].usExists = 1; + + /* Tie route 0 to CF channel 0 */ + g_TO_AppData.routes[0].sCfChnlIdx = 0; + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of custom app commands +*******************************************************************************/ +int32 TO_CustomAppCmds(CFE_SB_Msg_t* pMsg) +{ + int32 iStatus = TO_SUCCESS; + uint32 uiCmdCode = CFE_SB_GetCmdCode(pMsg); + switch (uiCmdCode) + { + case TO_SEND_DATA_TYPE_CC: + TO_SendDataTypePktCmd(pMsg); + break; + + case TO_SET_OCF_DATA_CC: + TO_CustomSetOcfCmd(pMsg); + break; + + default: + iStatus = TO_ERROR; + break; + } + + return iStatus; +} + +/******************************************************************************/ +/** \brief Process data packet +*******************************************************************************/ +int32 TO_CustomProcessData(CFE_SB_Msg_t * pMsg, int32 size, int32 iTblIdx, + uint16 usRouteId) +{ + return TO_CustomProcessPacket(pMsg, usRouteId); +} + + +/******************************************************************************/ +/** \brief Start a new frame, copying overflow data if present. +*******************************************************************************/ +int32 TO_CustomFrameStart(uint16 usRouteId) +{ + int32 iStatus = TO_SUCCESS; + TO_CustomPChnl_t *pChnl = NULL; + TM_SDLP_FrameInfo_t *pFrameInfo = NULL; + + pChnl = TO_CustomGetChnl(usRouteId); + if (!pChnl) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO_CustomFrameStart Error: Invalid Route ID:%u", + usRouteId); + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Start Frame */ + pFrameInfo = &pChnl->mc.vc.frameInfo; + iStatus = TM_SDLP_StartFrame(pFrameInfo); + +end_of_function: + return iStatus; +} + + +/******************************************************************************/ +/** \brief Complete frame and send +*******************************************************************************/ +int32 TO_CustomFrameSend(uint16 usRouteId, int32 iInStatus) +{ + int32 iCaduSize = 0; + int32 iSentSize = 0; + int32 iStatus = TO_SUCCESS; + + TO_CustomPChnl_t *pChnl = NULL; + TM_SDLP_FrameInfo_t *pFrameInfo = NULL; + uint8 *pMcFrameCnt = NULL; + uint8 *pOcf = NULL; + + pChnl = TO_CustomGetChnl(usRouteId); + if (!pChnl) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO_CustomFrameSend Error: Invalid Route ID:%u", + usRouteId); + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Set Pointers */ + pFrameInfo = &pChnl->mc.vc.frameInfo; + pMcFrameCnt = &pChnl->mc.mcFrameCnt; + pOcf = &pChnl->mc.vc.ocfBuff[0]; + + /* Check if there is packets, otherwise, fill with OID. */ + iStatus = TM_SDLP_FrameHasData(pFrameInfo); + if (iStatus == 1) + { + /* Add an idle packet to fill remaining free space */ + iStatus = TM_SDLP_AddIdlePacket(pFrameInfo, pIdlePacket); + } + else if (iStatus == 0) + { + /* Set frame as Only Idle Data (OID) */ + iStatus = TM_SDLP_SetOidFrame(pFrameInfo, pIdlePacket); + } + + if (iStatus != TO_SUCCESS) + { + goto end_of_function; + } + + /* Complete Frame */ + iStatus = TM_SDLP_CompleteFrame(pFrameInfo, pMcFrameCnt, pOcf); + if (iStatus != TO_SUCCESS) + { + goto end_of_function; + } + + /* Synchronize frame into CADU */ + iCaduSize = TM_SYNC_Synchronize(pChnl->buffer, TM_SYNC_ASM_STR, + TM_SYNC_ASM_SIZE, + TO_CUSTOM_TF_SIZE, + TO_CUSTOM_TF_RANDOMIZE); + if (iCaduSize < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Send Frame */ + if (usRouteId == 0) + { + iSentSize = IO_TransUdpSnd(&g_TO_CustomData.socket.udp, + &g_TO_CustomData.socket.pc.buffer[0], + iCaduSize); + } + else if (usRouteId == 1) + { + iSentSize = IO_TransRS422Write(g_TO_CustomData.serial.portFd, + &g_TO_CustomData.serial.pc.buffer[0], + iCaduSize); + } + + iStatus = TO_CustomProcessSizeSent(iCaduSize, iSentSize, 0); + + /* If Process Data Failed, disable route. */ + if (iInStatus != TM_SDLP_SUCCESS) + { + TO_DisableRoute(usRouteId); + + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO_CustomFrameSend Error: Failed input status. " + "Disabling route:%u.", + usRouteId); + } + +end_of_function: + return iStatus; +} + + +/******************************************************************************/ +/** \brief Process a Packet and add to frame +*******************************************************************************/ +int32 TO_CustomProcessPacket(CFE_SB_Msg_t *pMsg, uint16 usRouteId) +{ + int32 iStatus = TO_SUCCESS; + TO_CustomPChnl_t *pChnl = NULL; + TM_SDLP_FrameInfo_t *pFrameInfo = NULL; + + pChnl = TO_CustomGetChnl(usRouteId); + if (!pChnl) + { + /* This should never happen since route ID is checked several times + before */ + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO_CustomProcessPacket Error: Invalid Route ID:%u", + usRouteId); + iStatus = TO_ERROR; + goto end_of_function; + } + + pFrameInfo = &pChnl->mc.vc.frameInfo; + + /* Add Packet */ + iStatus = TM_SDLP_AddPacket(pFrameInfo, pMsg); + if (iStatus >= 0) + { + iStatus = TO_SUCCESS; + } + +end_of_function: + return iStatus; +} + + +/******************************************************************************/ +/** \brief Get the physical channel based on route id +*******************************************************************************/ +TO_CustomPChnl_t * TO_CustomGetChnl(uint16 usRouteId) +{ + TO_CustomPChnl_t *pChnl = NULL; + + if (usRouteId == 0) + { + pChnl = &g_TO_CustomData.socket.pc; + } + else if(usRouteId == 1) + { + pChnl = &g_TO_CustomData.serial.pc; + } + + return pChnl; +} + + +/******************************************************************************/ +/** \brief Check Data Sent Size (Local) +*******************************************************************************/ +int32 TO_CustomProcessSizeSent(int32 size, int32 iSentSize, uint16 routeId) +{ + int32 iStatus = TO_SUCCESS; + + if (iSentSize < 0) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO Output errno %d. Route ID:%u disabled ", + errno, routeId); + TO_DisableRoute(routeId); + iStatus = TO_ERROR; + } + else if (iSentSize != size) + { + /* NOTE: If this happens, that means a partial frame was sent. Your + Ground support equipment must be able to handle partial frames. + For example, ITOS does not handle this case well and goes into + a weird state, where every following TF is corrupted. + This condition indicates that throttling is necessary. */ + + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO sent incomplete message (Insuficient bandwidth likely). " + "ROUTE ID:%u, MsgSize:%d, SentSize:%d. Route disabled.", + routeId, size, iSentSize); + TO_DisableRoute(routeId); + iStatus = TO_ERROR; + } + + return iStatus; +} + + +/******************************************************************************/ +/** \brief Custom Cleanup +*******************************************************************************/ +void TO_CustomCleanup(void) +{ + if (g_TO_AppData.usOutputEnabled) + { + CFE_EVS_SendEvent(TO_CUSTOM_INF_EID, CFE_EVS_INFORMATION, + "TO - Closing Socket."); + IO_TransUdpCloseSocket(&g_TO_CustomData.socket.udp); + } + + return; +} + + +/******************************************************************************/ +/** \brief Set the OCF trailer with the CLCW - Internal Cmd. +*******************************************************************************/ +void TO_CustomSetOcfCmd(CFE_SB_Msg_t *pCmdMsg) +{ + TO_CustomSetOcfCmd_t *cmd = (TO_CustomSetOcfCmd_t *) pCmdMsg; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_CustomSetOcfCmd_t))) + { + switch (COP1_GetClcwVcId(&cmd->clcw)) + { + case 0: + CFE_PSP_MemCpy(&g_TO_CustomData.socket.pc.mc.vc.ocfBuff[0], + &cmd->clcw, 4); + break; + + case 1: + CFE_PSP_MemCpy(&g_TO_CustomData.serial.pc.mc.vc.ocfBuff[0], + &cmd->clcw, 4); + break; + + default: + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "Received invalid Channel ID in TO_SET_OCF_DATA_CC"); + } + } +} + +/******************************************************************************/ +/** \brief Enable Output Command Response +*******************************************************************************/ +int32 TO_CustomEnableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + int32 iStatus = IO_TRANS_UDP_NO_ERROR; + int32 routeMask = TO_ERROR; + char cDestIp[TO_MAX_IP_STRING_SIZE]; + uint16 usDestPort = 0; + + TO_EnableOutputCmd_t * pCustomCmd = (TO_EnableOutputCmd_t *) pCmdMsg; + strncpy(cDestIp, pCustomCmd->cDestIp, sizeof(cDestIp)); + + if (pCustomCmd->usDestPort > 0) + { + usDestPort = pCustomCmd->usDestPort; + } + else + { + usDestPort = TO_DEFAULT_DEST_PORT; + } + + iStatus = IO_TransUdpSetDestAddr(&g_TO_CustomData.socket.udp, + pCustomCmd->cDestIp, + usDestPort); + if (iStatus < 0) + { + goto end_of_function; + } + + g_TO_CustomData.serial.portFd = pCustomCmd->iFileDesc; + + CFE_EVS_SendEvent(TO_CUSTOM_INF_EID, CFE_EVS_INFORMATION, + "Serial Output Device File Descriptor Set."); + + /* Both routes are now configured */ + TO_SetRouteAsConfigured(0); + TO_SetRouteAsConfigured(1); + + /* Enable both routes 0 and 1. */ + routeMask = 0x0003; + +end_of_function: + return routeMask; +} + +/******************************************************************************/ +/** \brief Disable Output Command Response +*******************************************************************************/ +int32 TO_CustomDisableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + /* Disable */ + g_TO_AppData.usOutputEnabled = 0; + return TO_SUCCESS; +} + + +/******************************************************************************* +** Non standard custom Commands +*******************************************************************************/ + +/*============================================================================== +** End of file to_custom.c +**============================================================================*/ diff --git a/fsw/examples/multi_tf/to_platform_cfg.h b/fsw/examples/multi_tf/to_platform_cfg.h new file mode 100644 index 0000000..ed52fa2 --- /dev/null +++ b/fsw/examples/multi_tf/to_platform_cfg.h @@ -0,0 +1,94 @@ +/******************************************************************************/ +/** \file to_platform_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Sample config file for TO Application with Multi device +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/to/fsw/platform_inc folder. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +#ifndef _TO_PLATFORM_CFG_H_ +#define _TO_PLATFORM_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ +#define TO_FRAMING_ENABLED 1 + +#define TO_SCH_PIPE_DEPTH 10 +#define TO_CMD_PIPE_DEPTH 10 +#define TO_TLM_PIPE_DEPTH 10 + +#define TO_NUM_CRITICAL_MIDS 3 + +#define TO_MAX_TBL_ENTRIES 100 +#define TO_WAKEUP_TIMEOUT 500 + +#define TO_CONFIG_TABLENAME "to_config" +#define TO_CONFIG_FILENAME "/cf/apps/to_config.tbl" + +#define TO_GROUP_NUMBER_MASK 0xFF000000 +#define TO_MULTI_GROUP_MASK 0x00FFFFFF + +#define TO_DEFAULT_DEST_PORT 5011 + +#define TO_CF_THROTTLE_SEM_NAME "CFTOSemId" + +#define TO_CUSTOM_TF_SIZE 1000 +#define TO_CUSTOM_TF_OVERFLOW_SIZE TO_CUSTOM_TF_SIZE +#define TO_CUSTOM_TF_IDLE_SIZE TO_CUSTOM_TF_SIZE + +#define TO_CUSTOM_NUM_CHNL 2 +#define TO_CUSTOM_TF_SCID 0 +#define TO_CUSTOM_TF_ERR_CTRL 0 +#define TO_CUSTOM_TF_RANDOMIZE 0 + + +/* +** Include Files +*/ + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_PLATFORM_CFG_H_ */ + +/*============================================================================== +** End of file to_platform_cfg.h +**============================================================================*/ + diff --git a/fsw/examples/rs422/MISSION_to_types.h b/fsw/examples/rs422/MISSION_to_types.h new file mode 100644 index 0000000..85e6fc2 --- /dev/null +++ b/fsw/examples/rs422/MISSION_to_types.h @@ -0,0 +1,75 @@ +/******************************************************************************/ +/** \file MISSION_to_types.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Command and telemetry data strucutres for TO application (RS422) +* +* \par +* This header file contains definitions of command and telemetry data +* structures for TO applications for the UDP transport protocol example. +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/inc/ folder. +* - Standard command messages are defined in to_cmds.h +* - Default HK Telemetry structure is defined in to_hktlm.h +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2015-09-22 | Guy de Carufel | Moved hktlm to to_hktlm.h +*******************************************************************************/ +#ifndef _MISSION_TO_TYPES_H_ +#define _MISSION_TO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Include Files +*/ +#include "cfe.h" +#include "../to/fsw/src/to_hktlm.h" + +/* +** Defines +*/ + +/* Define enable / disable commands */ +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + int32 iFileDesc; /**< File Descriptor of Port to use. */ +} TO_EnableOutputCmd_t; + + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; +} TO_DisableOutputCmd_t; + + + +/*************** Telemetry **************/ +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; +} TO_InData_t; + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint32 uiCounter; +} TO_OutData_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* _MISSION_TO_TYPES_H_ */ + +/*============================================================================== +** End of file MISSION_to_types.h +**============================================================================*/ diff --git a/fsw/examples/rs422/to_custom.c b/fsw/examples/rs422/to_custom.c new file mode 100644 index 0000000..14e5dba --- /dev/null +++ b/fsw/examples/rs422/to_custom.c @@ -0,0 +1,198 @@ +/******************************************************************************/ +/** \file to_custom.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions for Custom Layer of TO Application for RS422 +* +* \par +* This file defines the functions for a custom implementation of the custom +* layer of the TO application over an RS422 serial port. +* +* \par API Functions Defined: +* - TO_CustomInit() - Initialize the transport protocol +* - TO_CustomAppCmds() - Process custom App Commands +* - TO_CustomEnableOutputCmd() - Enable telemetry output +* - TO_CustomDisableOutputCmd() - Disable telemetry output +* - TO_CustomCleanup() - Cleanup callback to close transport channel. +* - TO_CustomProcessData() - Send output data over transport protocol. +* +* \par Private Functions Defined: +* - TO_SendDataTypePktCmd() - Send Test packet (Reference to_lab app) +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All input messages are CCSDS messages +* - Both CI and TO makes use of the same RS422 device +* - All config macros defined in to_platform_cfg.h +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "network_includes.h" +#include "trans_rs422.h" + +#include "to_app.h" + +/* +** Local Defines +*/ + +/* +** Local Structure Declarations +*/ +typedef struct +{ + int32 iFileDesc; /**< File Descriptor of serial port */ +} TO_CustomData_t; + +/* +** External Global Variables +*/ +extern TO_AppData_t g_TO_AppData; + +/* +** Global Variables +*/ +TO_CustomData_t g_TO_CustomData; + +/* +** Local Variables +*/ + +/* +** Local Function Definitions +*/ +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); + +/******************************************************************************* +** Custom Application Functions +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Custom Initialization +*******************************************************************************/ +int32 TO_CustomInit(void) +{ + int32 iStatus = TO_SUCCESS; + + /* Set Critical Message Ids which must always be + * in config table. */ + g_TO_AppData.criticalMid[0] = CFE_ES_SHELL_TLM_MID; + g_TO_AppData.criticalMid[1] = CFE_EVS_EVENT_MSG_MID; + g_TO_AppData.criticalMid[2] = CFE_SB_ALLSUBS_TLM_MID; + + /* Route 0: Serial */ + g_TO_AppData.routes[0].usExists = 1; + + /* Tie route 0 to CF channel 0 */ + g_TO_AppData.routes[0].sCfChnlIdx = 0; + + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of custom app commands +*******************************************************************************/ +int32 TO_CustomAppCmds(CFE_SB_Msg_t* pMsg) +{ + int32 iStatus = TO_SUCCESS; + uint32 uiCmdCode = CFE_SB_GetCmdCode(pMsg); + switch (uiCmdCode) + { + case TO_SEND_DATA_TYPE_CC: + TO_SendDataTypePktCmd(pMsg); + break; + + default: + iStatus = TO_ERROR; + break; + } + + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of output telemetry +*******************************************************************************/ +int32 TO_CustomProcessData(CFE_SB_Msg_t * pMsg, int32 size, int32 iTblIdx, + uint16 usRouteId) +{ + int32 iSentSize = 0; + int32 iStatus = TO_SUCCESS; + + if (usRouteId == 0) + { + iSentSize = IO_TransRS422Write(g_TO_CustomData.iFileDesc, + (uint8 *) pMsg, + size); + if (iSentSize < 0) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO RS422 sendto errno %d. " + "Telemetry output disabled.", errno); + g_TO_AppData.usOutputEnabled = 0; + iStatus = TO_ERROR; + } + else if (iSentSize != size) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO RS422 sent incomplete message."); + iStatus = TO_ERROR; + } + } + + return iSentSize; +} + + +/******************************************************************************/ +/** \brief Custom Cleanup +*******************************************************************************/ +void TO_CustomCleanup(void) +{ + /* Nothing to do here. The fileDescriptor is closed in CI. */ + return; +} + +/******************************************************************************/ +/** \brief Enable Output Command Response +*******************************************************************************/ +int32 TO_CustomEnableOutputCmd(CFE_SB_Msg_t *cmdpMsg) +{ + int32 routeMask = 0x0001; + + TO_EnableOutputCmd_t * pCustomCmd = (TO_EnableOutputCmd_t *) cmdpMsg; + g_TO_CustomData.iFileDesc = pCustomCmd->iFileDesc; + TO_SetRouteAsConfigured(0); + + return routeMask; +} + +/******************************************************************************/ +/** \brief Disable Output Command Response +*******************************************************************************/ +int32 TO_CustomDisableOutputCmd(CFE_SB_Msg_t *cmdpMsg) +{ + /* Disable */ + g_TO_AppData.usOutputEnabled = 0; + return TO_SUCCESS; +} + + +/******************************************************************************* +** Non standard custom Commands +*******************************************************************************/ + + +/*============================================================================== +** End of file to_custom.c +**============================================================================*/ diff --git a/fsw/examples/rs422/to_platform_cfg.h b/fsw/examples/rs422/to_platform_cfg.h new file mode 100644 index 0000000..1af0b63 --- /dev/null +++ b/fsw/examples/rs422/to_platform_cfg.h @@ -0,0 +1,80 @@ +/******************************************************************************/ +/** \file to_platform_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Sample config file for TO Application with RS422 device +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/to/fsw/platform_inc folder. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +#ifndef _TO_PLATFORM_CFG_H_ +#define _TO_PLATFORM_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ +#define TO_SCH_PIPE_DEPTH 10 +#define TO_CMD_PIPE_DEPTH 10 +#define TO_TLM_PIPE_DEPTH 10 + +#define TO_NUM_CRITICAL_MIDS 3 + +#define TO_MAX_TBL_ENTRIES 100 +#define TO_WAKEUP_TIMEOUT 500 + +#define TO_CONFIG_TABLENAME "to_config" +#define TO_CONFIG_FILENAME "/cf/apps/to_config.tbl" + +#define TO_GROUP_NUMBER_MASK 0xFF000000 +#define TO_MULTI_GROUP_MASK 0x00FFFFFF + +#define TO_CF_THROTTLE_SEM_NAME "CFTOSemId" + +/* +** Include Files +*/ + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_PLATFORM_CFG_H_ */ + +/*============================================================================== +** End of file to_platform_cfg.h +**============================================================================*/ + diff --git a/fsw/examples/setup.sh b/fsw/examples/setup.sh new file mode 100755 index 0000000..0bfd255 --- /dev/null +++ b/fsw/examples/setup.sh @@ -0,0 +1,123 @@ +#!/bin/bash +# Desc: This Script will copy or link example files to appropriate locations. +# Author: Guy de Carufel, Allen Brown (Odyssey Space Research) +# Date: May 11, 2016 + +usage () +{ + echo -e "\nHELP TEXT\n" + echo -e "\tScript to cp (or link) example files to appropriate locations." + echo -e "\tNOTE: Target will be overwritten if it already exists.\n" + echo -e "\tOption: -h This help text." + echo -e "\tOption: -l Create symbolic link instead of a copy." + echo -e "\tOption: -m {NAME} Mission name. (default: MISSION_NAME env var)" + echo -e "\t (This controls the *_to_types.h name.)" + echo -e "\tArg: example (dir) name." + echo -e "\n\tNote: Expects either a MISSION_HOME or APP_DIR env variable " + echo -e "\t to locate apps/inc (which must exist)." + echo -e "\tNote: Either the MISSION_NAME env var or the -m option must be used." + + echo -e "\n\tExample: ./setup.sh -l -m MY_MISSION udp" + echo -e "\n\tWill create following symbolic links:" + echo -e "\tln -s udp/to_custom.c ../src/" + echo -e "\tln -s udp/to_platform_cfg.h ../platform_inc/" + echo -e "\tln -s udp/MISSION_to_types.h MISSION_HOME/apps/inc/MY_MISION_to_types.h" + echo -e "\t(cp called instead of ln -s if -l option not used.)\n" +} + +link=0 + +while [ "$1" != "" ]; do + + echo "===DEBUG In while loop, args: $@ ===" + + case $1 in + -h | --help ) usage + exit + ;; + -l | --link ) link=1 + ;; + -m | --mission ) mission=$2 + shift + ;; + * ) break + + esac + shift +done + +if [ $# -ne 1 ]; then + echo -e "\tA single argument required. eg. setup.sh udp" + usage + exit +fi + +# Check the CFS_TST way +if [ -z "$MISSION_HOME" ]; then + # Check the gsfc_build/"classic build" way (setvars.sh) + if [ -z "$APP_DIR" ]; then + echo -e "Either the env var MISSION_HOME (CFS_TST build)" + echo -e " or APP_DIR (gsfc ""classic"" build) must be set." + exit 1 + fi +else + APP_DIR="${MISSION_HOME}/apps" +fi + +if [ ! -d "$APP_DIR" ]; then + echo -e "\t$APP_DIR does not point to an existing directory." + exit +fi + +if [ ! -d "$APP_DIR/inc" ]; then + echo -e "\t$APP_DIR/inc does not exist. Create directory first." + exit +fi + +if [ -z "$mission" ]; then + if [ -z "$MISSION_NAME" ]; then + echo -e "Need a mission name from the -m option via the MISSION_NAME env var." + exit 1 + else + mission=$MISSION_NAME + fi +fi + +mission="${mission^^}" + +if [ ! -d "$PWD/$1" ]; then + echo -e "\tBad example name. ARG should be the name of the example directory." + exit +fi + +echo -e "\tArguments supplied:" + +if [ "$link" -eq 1 ]; then + echo -e "\tOption: -l (create symbolic links)" +fi +echo -e "\tMission name: $mission" +echo -e "\tExample name: $1\n" + +rm -f $PWD/../src/to_custom.c +rm -f $PWD/../platform_inc/to_platform_cfg.h +rm -f ${APP_DIR}/inc/${mission}_to_types.h +echo -e "\tRemoved files:" +echo -e "\t$PWD/../src/to_custom.c" +echo -e "\t$PWD/../platform_inc/to_platform_cfg.h" +echo -e "\t${APP_DIR}/inc/${mission}_to_types.h\n" + +if [ "$link" -eq 1 ]; then + ln -sf $PWD/$1/to_custom.c $PWD/../src/to_custom.c + ln -sf $PWD/$1/to_platform_cfg.h $PWD/../platform_inc/to_platform_cfg.h + ln -sf $PWD/$1/MISSION_to_types.h ${APP_DIR}/inc/${mission}_to_types.h + echo -e "\tCreating Symbolic links:" +else + cp -f $PWD/$1/to_custom.c $PWD/../src/to_custom.c + cp -f $PWD/$1/to_platform_cfg.h $PWD/../platform_inc/to_platform_cfg.h + cp -f $PWD/$1/MISSION_to_types.h ${APP_DIR}/inc/${mission}_to_types.h + echo -e "\tFiles copied:" +fi + +echo -e "\t$PWD/$1/to_custom.c -> $PWD/../src/to_custom.c" +echo -e "\t$PWD/$1/to_platform_cfg.h -> $PWD/../platform_inc/to_platform_cfg.h" +echo -e "\t$PWD/$1/MISSION_to_types.h -> ${APP_DIR}/inc/${mission}_to_types.h\n" diff --git a/fsw/examples/udp/MISSION_to_types.h b/fsw/examples/udp/MISSION_to_types.h new file mode 100644 index 0000000..6f139c0 --- /dev/null +++ b/fsw/examples/udp/MISSION_to_types.h @@ -0,0 +1,78 @@ +/******************************************************************************/ +/** \file MISSION_to_types.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Command and telemetry data strucutres for TO application (UDP) +* +* \par +* This header file contains definitions of command and telemetry data +* structures for TO applications for the UDP transport protocol example. +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/inc/ folder. +* - Standard command messages are defined in to_cmds.h +* - Default HK Telemetry structure is defined in to_hktlm.h +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2015-09-22 | Guy de Carufel | Moved hktlm to to_hktlm.h +*******************************************************************************/ +#ifndef _MISSION_TO_TYPES_H_ +#define _MISSION_TO_TYPES_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Include Files +*/ +#include "cfe.h" +#include "../to/fsw/src/to_hktlm.h" + +/* +** Defines +*/ +#define TO_MAX_IP_STRING_SIZE 16 + + +/* Define enable / disable commands */ +typedef struct +{ + uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + char cDestIp[TO_MAX_IP_STRING_SIZE]; /* Destination IP */ + uint16 usDestPort; /* Destination PORT */ +} TO_EnableOutputCmd_t; + + +typedef struct +{ + uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; +} TO_DisableOutputCmd_t; + + + +/*************** Telemetry **************/ +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; +} TO_InData_t; + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint32 uiCounter; +} TO_OutData_t; + + +#ifdef __cplusplus +} +#endif + +#endif /* _MISSION_TO_TYPES_H_ */ + +/*============================================================================== +** End of file MISSION_to_types.h +**============================================================================*/ diff --git a/fsw/examples/udp/to_custom.c b/fsw/examples/udp/to_custom.c new file mode 100644 index 0000000..971f327 --- /dev/null +++ b/fsw/examples/udp/to_custom.c @@ -0,0 +1,230 @@ +/******************************************************************************/ +/** \file to_custom.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions for Custom Layer of TO Application for UDP +* +* \par +* This file defines the functions for a custom implementation of the custom +* layer of the TO application over UDP Socket. +* +* \par API Functions Defined: +* - TO_CustomInit() - Initialize the transport protocol +* - TO_CustomAppCmds() - Process custom App Commands +* - TO_CustomEnableOutputCmd() - Enable telemetry output +* - TO_CustomDisableOutputCmd() - Disable telemetry output +* - TO_CustomCleanup() - Cleanup callback to close transport channel. +* - TO_CustomProcessData() - Send output data over transport protocol. +* +* \par Private Functions Defined: +* - TO_SendDataTypePktCmd() - Send Test packet (Reference to_lab app) +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All input messages are CCSDS messages +* - All config macros defined in to_platform_cfg.h +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2015-06-02 | Guy de Carufel | Revised for new UDP API +*******************************************************************************/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "network_includes.h" +#include "trans_udp.h" + +#include "to_app.h" +#include "ci_msgids.h" + +/* +** Local Defines +*/ + +/* +** Local Structure Declarations +*/ +typedef struct +{ + IO_TransUdp_t udp; /**< UDP working */ +} TO_CustomData_t; + +/* +** External Global Variables +*/ +extern TO_AppData_t g_TO_AppData; + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ +static TO_CustomData_t g_TO_CustomData; + +/* +** Local Function Definitions +*/ +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); + +/******************************************************************************* +** Custom Application Functions +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Custom Initialization +*******************************************************************************/ +int32 TO_CustomInit(void) +{ + int32 iStatus = TO_SUCCESS; + + /* Create socket for outgoing */ + if (IO_TransUdpCreateSocket(&g_TO_CustomData.udp) < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + /* NOTE: For this simple UDP example, we are only requiring The following + 3 messages. If more message IDs should be included by default, add them + here and update the TO_NUM_CRITICAL_MIDS value. */ + + /* Set Critical Message Ids which must always be in config table. */ + g_TO_AppData.criticalMid[0] = TO_HK_TLM_MID; + g_TO_AppData.criticalMid[1] = CI_HK_TLM_MID; + g_TO_AppData.criticalMid[2] = CFE_EVS_EVENT_MSG_MID; + + /* Route 0: Udp. Linked to CF Channel Index 0. */ + g_TO_AppData.routes[0].usExists = 1; + g_TO_AppData.routes[0].sCfChnlIdx = 0; + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of custom app commands +*******************************************************************************/ +int32 TO_CustomAppCmds(CFE_SB_Msg_t* pMsg) +{ + int32 iStatus = TO_SUCCESS; + uint32 uiCmdCode = CFE_SB_GetCmdCode(pMsg); + switch (uiCmdCode) + { + case TO_SEND_DATA_TYPE_CC: + TO_SendDataTypePktCmd(pMsg); + break; + + default: + iStatus = -1; + break; + } + + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of output telemetry +*******************************************************************************/ +int32 TO_CustomProcessData(CFE_SB_Msg_t * pMsg, int32 size, int32 iTblIdx, + uint16 usRouteId) +{ + int32 iStatus = 0; + + if (g_TO_AppData.routes[0].usIsEnabled == 0 || usRouteId != 0) + { + goto end_of_function; + } + + iStatus = IO_TransUdpSnd(&g_TO_CustomData.udp, (uint8 *) pMsg, size); + + if (iStatus < 0) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO UDP sendto errno %d. Telemetry output disabled.", + errno); + g_TO_AppData.usOutputEnabled = 0; + } + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Custom Cleanup +*******************************************************************************/ +void TO_CustomCleanup(void) +{ + if (g_TO_AppData.usOutputEnabled) + { + CFE_EVS_SendEvent(TO_CUSTOM_INF_EID, CFE_EVS_INFORMATION, + "TO - Closing Socket."); + IO_TransUdpCloseSocket(&g_TO_CustomData.udp); + } + + return; +} + +/******************************************************************************/ +/** \brief Enable Output Command Response +*******************************************************************************/ +int32 TO_CustomEnableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + int32 iStatus = IO_TRANS_UDP_NO_ERROR; + int32 routeMask = TO_ERROR; + char cDestIp[TO_MAX_IP_STRING_SIZE]; + uint16 usDestPort = 0; + + TO_EnableOutputCmd_t * pCustomCmd = (TO_EnableOutputCmd_t *) pCmdMsg; + strncpy(cDestIp, pCustomCmd->cDestIp, sizeof(cDestIp)); + + if (pCustomCmd->usDestPort > 0) + { + usDestPort = pCustomCmd->usDestPort; + } + else + { + usDestPort = TO_DEFAULT_DEST_PORT; + } + + iStatus = IO_TransUdpSetDestAddr(&g_TO_CustomData.udp, pCustomCmd->cDestIp, + usDestPort); + + if (iStatus < 0) + { + goto end_of_function; + } + + /* We are done configuring route 0 */ + TO_SetRouteAsConfigured(0); + routeMask = 0x0001; + +end_of_function: + return routeMask; +} + +/******************************************************************************/ +/** \brief Disable Output Command Response +*******************************************************************************/ +int32 TO_CustomDisableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + /* Disable */ + g_TO_AppData.usOutputEnabled = 0; + return TO_SUCCESS; +} + + +/******************************************************************************* +** Non standard custom Commands +*******************************************************************************/ + +/*============================================================================== +** End of file to_custom.c +**============================================================================*/ diff --git a/fsw/examples/udp/to_platform_cfg.h b/fsw/examples/udp/to_platform_cfg.h new file mode 100644 index 0000000..92fe9ef --- /dev/null +++ b/fsw/examples/udp/to_platform_cfg.h @@ -0,0 +1,69 @@ +/******************************************************************************/ +/** \file to_platform_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Sample config file for TO Application with UDP device +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/to/fsw/platform_inc folder. +* - Overwrite any default settings by defining them here. +* - Define any implementation specific settings. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +#ifndef _TO_PLATFORM_CFG_H_ +#define _TO_PLATFORM_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ +#define TO_NUM_CRITICAL_MIDS 3 +#define TO_DEFAULT_DEST_PORT 5011 + + +/* +** Include Files +*/ + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_PLATFORM_CFG_H_ */ + +/*============================================================================== +** End of file to_platform_cfg.h +**============================================================================*/ + diff --git a/fsw/for_build/Makefile b/fsw/for_build/Makefile new file mode 100644 index 0000000..3ae1d95 --- /dev/null +++ b/fsw/for_build/Makefile @@ -0,0 +1,109 @@ +####################################################################################### +# +# File: CFS Application Makefile +# Author: GSFC/Flight Software Branch/Code 582 +# Date: 2008-2010 +# +####################################################################################### + +# +# Subsystem produced by this makefile +# +export APPTARGET = to + +# +# Entry Point for task +# +ENTRY_PT = TO_AppMain + +# +# Object files required to build subsystem. +# +OBJS = to_app.o to_cmds.o to_utils.o to_custom.o + +# +# Source files required to build subsystem; used to generate dependencies. +# As long as there are no assembly files this can be automated. +# +SOURCES = $(OBJS:.o=.c) + +# +# Specify extra C Flags needed to build this subsystem +# +LOCAL_COPTS = + +# +# EXEDIR is defined here, just in case it needs to be different for a custom build +# +EXEDIR=../exe + +# +# Certain OSs and Application Loaders require the following option for shared libraries. +# Currently only needed for vxWorks 5.5 and RTEMS. +# For each shared library that this app depends on, you need to have an entry like the +# following: +# -R../tst_lib/tst_lib.elf +# +SHARED_LIB_LINK = + +#====================================================================================== +# Should not have to change below this line, except for customized mission and cFE +# directory structures +#====================================================================================== +# +# Set build type to CFE_APP. This allows us to +# define different compiler flags for the cFE Core and Apps. +# +BUILD_TYPE = CFE_APP + +# +# Include all necessary cFE make rules +# Any of these can be copied to a local file and changed if needed. +# +# cfe-config.mak contains PSP and OS selection +# +include ../cfe/cfe-config.mak +# +# debug-opts.mak contains debug switches +# +include ../cfe/debug-opts.mak +# +# compiler-opts.mak contains compiler definitions and switches/defines +# +include $(CFE_PSP_SRC)/$(PSP)/make/compiler-opts.mak + +# +# Setup the include path for this subsystem +# The OS specific includes are in the build-rules.make file +# +# If this subsystem needs include files from another app, add the path here. +# +INCLUDE_PATH = -I$(OSAL_SRC)/inc \ + -I$(CFE_CORE_SRC)/inc \ + -I$(CFE_PSP_SRC)/inc \ + -I$(CFE_PSP_SRC)/$(PSP)/inc \ + -I$(CFS_APP_SRC)/inc \ + -I$(CFS_APP_SRC)/io_lib/fsw/public_inc \ + -I$(CFS_APP_SRC)/$(APPTARGET)/fsw/src \ + -I$(CFS_APP_SRC)/$(APPTARGET)/fsw/tables \ + -I$(CFS_MISSION_INC) \ + -I../cfe/inc \ + -I../inc + +# +# Define the VPATH make variable. +# This can be modified to include source from another directory. +# If there is no corresponding app in the cfs-apps directory, then this can be discarded, +# or if the mission chooses to put the src in another directory such as "src", then that +# can be added here as well. +# +VPATH = $(CFS_APP_SRC)/$(APPTARGET)/fsw/src \ + $(CFS_APP_SRC)/$(APPTARGET)/fsw/tables + +# +# Include the common make rules for building a cFE Application +# +include $(CFE_CORE_SRC)/make/app-rules.mak + +####################################################################################### + diff --git a/fsw/for_build/totables.mak b/fsw/for_build/totables.mak new file mode 100644 index 0000000..28fea29 --- /dev/null +++ b/fsw/for_build/totables.mak @@ -0,0 +1,112 @@ +############################################################################### +# File: CFS Application Table Makefile +# +# +# History: +# +############################################################################### +# +# The Application needs to be specified here +# +APPTARGET = to + +# +# List the tables that are generated here. +# Restrictions: +# 1. The table file name must be the same as the C source file name +# 2. There must be a single C source file for each table +# +TABLES = to_config.tbl to_config_2.tbl + +################################################################################## +# Normally, nothing has to be changed below this line +# The following are changes that may have to be made for a custom app environment: +# 1. INCLUDE_PATH - This may be customized to tailor the include path for an app +# 2. VPATH - This may be customized to tailor the location of the table sources. +# For example: if the tables were stored in a "tables" subdirectory +# ( build/cpu1/sch/tables ) +################################################################################# + +# +# Object files required for tables +# +OBJS = $(TABLES:.tbl=.o) + +# +# Source files required to build tables. +# +SOURCES = $(OBJS:.o=.c) + +## +## Specify extra C Flags needed to build this subsystem +## +LOCAL_COPTS = + +## +## EXEDIR is defined here, just in case it needs to be different for a custom +## build +## +EXEDIR=../exe + +######################################################################## +# Should not have to change below this line, except for customized +# Mission and cFE directory structures +######################################################################## + +# +# Set build type to CFE_APP. This allows us to +# define different compiler flags for the cFE Core and Apps. +# +BUILD_TYPE = CFE_TABLE + +## +## Include all necessary cFE make rules +## Any of these can be copied to a local file and +## changed if needed. +## +## +## cfe-config.mak contians arch, BSP, and OS selection +## +include ../cfe/cfe-config.mak + +## +## debug-opts.mak contains debug switches -- Note that the table must be +## built with -g for the elf2tbl utility to work. +## +include ../cfe/debug-opts.mak + +## +## compiler-opts.mak contains compiler definitions and switches/defines +## +include $(CFE_PSP_SRC)/$(PSP)/make/compiler-opts.mak + +## +## Setup the include path for this subsystem +## The OS specific includes are in the build-rules.make file +## +## If this subsystem needs include files from another app, add the path here. +## +INCLUDE_PATH = \ +-I$(OSAL_SRC)/inc \ +-I$(CFE_CORE_SRC)/inc \ +-I$(CFE_PSP_SRC)/$(PSP)/inc \ +-I$(CFE_PSP_SRC)/inc \ +-I$(CFS_APP_SRC)/inc \ +-I$(CFS_APP_SRC)/$(APPTARGET)/fsw/src \ +-I$(CFS_MISSION_INC) \ +-I../cfe/inc \ +-I../inc + +## +## Define the VPATH make variable. +## This can be modified to include source from another directory. +## If there is no corresponding app in the cfe-apps directory, then this can be discarded, or +## if the mission chooses to put the src in another directory such as "src", then that can be +## added here as well. +## +VPATH = $(CFS_APP_SRC)/$(APPTARGET)/fsw/tables + +## +## Include the common make rules for building a cFE Application +## +include $(CFE_CORE_SRC)/make/table-rules.mak diff --git a/fsw/mission_inc/to_mission_cfg.h b/fsw/mission_inc/to_mission_cfg.h new file mode 100644 index 0000000..f2966f0 --- /dev/null +++ b/fsw/mission_inc/to_mission_cfg.h @@ -0,0 +1,72 @@ +/******************************************************************************/ +/** \file to_mission_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Mission Configuration Header File for TO Application +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All Mission configuration files should be defined in apps/inc folder. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2016-05-11 | Allen Brown | Updated headers +*******************************************************************************/ +#ifndef _TO_MISSION_CFG_H_ +#define _TO_MISSION_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ + +/* +** Include Files +*/ +#include "cfe.h" + +#include "to_perf_ids.h" +#include "to_msgids.h" +#include "to_msgdefs.h" + +/* Note, this header uses a mission name prefix convention. + This include may need to be altered. */ +#include "CFS_TST_to_types.h" + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_MISSION_CFG_H_ */ + +/*============================================================================== +** End of file to_mission_cfg.h +**============================================================================*/ + diff --git a/fsw/mission_inc/to_perf_ids.h b/fsw/mission_inc/to_perf_ids.h new file mode 100644 index 0000000..6ed184b --- /dev/null +++ b/fsw/mission_inc/to_perf_ids.h @@ -0,0 +1,38 @@ + /************************************************************************* + ** File: + ** to_perfids.h + ** + ** Copyright © 2016 United States Government as represented by the + ** Administrator of the National Aeronautics and Space Administration. + ** All Other Rights Reserved. + ** + ** This software was created at NASA's Johnson Space Center. + ** This software is governed by the NASA Open Source Agreement and may be + ** used, distributed and modified only pursuant to the terms of that + ** agreement. + ** + ** Purpose: + ** This file contains the cFE performance ID's used by Telemetry Output + ** + ** References: + ** Flight Software Branch C Coding Standard Version 1.2 + ** CFS Development Standards Document + ** + ** Notes: + ** 1) XXX_PERF_ID is used to measure an application's performance on + ** various functions. + ** + ** \par Modification History: + ** - 2016-05-11 | Allen Brown | Initial Version + *************************************************************************/ +#ifndef _TO_PERF_IDS_H_ +#define _TO_PERF_IDS_H_ + +#define TO_MAIN_TASK_PERF_ID 0x0072 + +#endif /* _TO_PERF_IDS_H_ */ + +/*======================================================================================= +** End of file ci_perf_ids.h +**=====================================================================================*/ + diff --git a/fsw/platform_inc/to_msgids.h b/fsw/platform_inc/to_msgids.h new file mode 100644 index 0000000..775e572 --- /dev/null +++ b/fsw/platform_inc/to_msgids.h @@ -0,0 +1,54 @@ + /************************************************************************* + ** File: + ** to_msgids.h + ** + ** Copyright © 2016 United States Government as represented by the + ** Administrator of the National Aeronautics and Space Administration. + ** All Other Rights Reserved. + ** + ** This software was created at NASA's Johnson Space Center. + ** This software is governed by the NASA Open Source Agreement and may be + ** used, distributed and modified only pursuant to the terms of that + ** agreement. + ** + ** Purpose: + ** This file contains the message ID's used by Telemetry Output + ** + ** References: + ** Flight Software Branch C Coding Standard Version 1.2 + ** CFS Development Standards Document + ** + ** Notes: + ** + ** \par Modification History: + ** - 2016-05-11 | Allen Brown | Initial Version + ** + *************************************************************************/ +#ifndef _to_msgids_ +#define _to_msgids_ + +/************************************************************************* + ** Macro Definitions + *************************************************************************/ + +/** + ** \name TO Command Message Numbers */ +/** \{ */ +#define TO_APP_CMD_MID (0x1880) +#define TO_SEND_HK_MID (0x1881) +#define TO_WAKEUP_MID (0x1882) +/** \} */ + +/** + ** \name TO Telemetery Message Number */ +/** \{ */ +#define TO_HK_TLM_MID (0x0880) +#define TO_OUT_DATA_MID (0x0881) +#define TO_DATA_TYPE_MID (0x0882) +/** \} */ + +#endif /*_to_msgids_*/ + +/************************/ +/* End of File Comment */ +/************************/ diff --git a/fsw/platform_inc/to_platform_cfg.h b/fsw/platform_inc/to_platform_cfg.h new file mode 100644 index 0000000..92fe9ef --- /dev/null +++ b/fsw/platform_inc/to_platform_cfg.h @@ -0,0 +1,69 @@ +/******************************************************************************/ +/** \file to_platform_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Sample config file for TO Application with UDP device +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Make use of the setup.sh script to move / link this file to the +* {MISSION_HOME}/apps/to/fsw/platform_inc folder. +* - Overwrite any default settings by defining them here. +* - Define any implementation specific settings. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +#ifndef _TO_PLATFORM_CFG_H_ +#define _TO_PLATFORM_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ +#define TO_NUM_CRITICAL_MIDS 3 +#define TO_DEFAULT_DEST_PORT 5011 + + +/* +** Include Files +*/ + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_PLATFORM_CFG_H_ */ + +/*============================================================================== +** End of file to_platform_cfg.h +**============================================================================*/ + diff --git a/fsw/src/to_app.c b/fsw/src/to_app.c new file mode 100644 index 0000000..b8d86e6 --- /dev/null +++ b/fsw/src/to_app.c @@ -0,0 +1,965 @@ +/******************************************************************************/ +/** \file to_app.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions for TO Application +* +* \par +* This source code file contains the application layer functions for TO. +* +* \par +* This file defines the application functions for the Telemetry Output (TO) +* application. The application layer is responsible to interact with the cFE +* Software bus, send the HK packet and the OutData packet. It is also +* responsible for the management of the configuration table, and respond to +* the TO commands. +* +* \par Functions Defined: +* - TO_AppMain() - Main entry point. Initializes, then calls TO_RcvMsg. +* - TO_AppInit() - Initializes the TO Application +* - TO_InitEvent() - Initializes the events +* - TO_InitData() - Initializes HK and OutData packets. +* - TO_InitTable() - Initializes the configuration table +* - TO_InitPipe() - Initializes the pipes (Scheduler, telemetry, command) +* - TO_ValidateTable() - Validate the message configuration table +* - TO_RcvMsg() - Pends on SB to perform main funtions. +* - TO_ProcessTlmPipes() - Process all active telemetry pipes +* - TO_ProcessNewData() - Process data on specific pipe +* - TO_ProcessNewCmds() - Call appropriate fnct based on CMD MID. +* - TO_ProcessNewAppCmds() - Call appropriate fnct based on CMD Code. +* - TO_ReportHousekeeping() - Send to SB the HK packet. +* - TO_SendOutData() - Send the OutData packet to the SB. +* - TO_CleanupCallback() - Call custom cleanup. +* +* \par Custom Functions Required: +* - TO_CustomInit() - Initialize the routes and output devices +* - TO_CustomAppCmds() - Response to custom commands +* - TO_CustomProcessData() - Process data over specific route +* - TO_CustomCleanup() - Cleanup of route devices +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All Custom functions are to be defined in to_custom.c +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include +#include "cfe.h" +#include "to_app.h" + +/* +** Local Defines +*/ + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ +TO_AppData_t g_TO_AppData; + +/* +** Local Variables +*/ + +/******************************************************************************/ +/** \brief Main Entry Point for TO Application +*******************************************************************************/ +void TO_AppMain(void) +{ + int32 iStatus=CFE_SUCCESS; + + /* Register the Application with Executive Services */ + iStatus = CFE_ES_RegisterApp(); + if (iStatus != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("TO - Failed to register the app (0x%08X)\n", + iStatus); + goto TO_AppMain_Exit_Tag; + } + + /* Performance Log Entry stamp - #1 */ + CFE_ES_PerfLogEntry(TO_MAIN_TASK_PERF_ID); + + /* Perform Application initializations */ + if (TO_AppInit() != CFE_SUCCESS) + { + g_TO_AppData.uiRunStatus = CFE_ES_APP_ERROR; + } + + /* Application Main Loop. Call CFE_ES_RunLoop() to check for changes in the + ** Application's status. If there is a request to kill this Application, + ** it will be passed in through the RunLoop call. */ + while (CFE_ES_RunLoop(&g_TO_AppData.uiRunStatus) == TRUE) + { + /* Performance Log Exit stamp */ + CFE_ES_PerfLogExit(TO_MAIN_TASK_PERF_ID); + + iStatus = TO_RcvMsg(g_TO_AppData.uiWakeupTimeout); + } + + /* Performance Log Exit stamp - #2 */ + CFE_ES_PerfLogExit(TO_MAIN_TASK_PERF_ID); + +TO_AppMain_Exit_Tag: + /* Exit the application */ + CFE_ES_ExitApp(g_TO_AppData.uiRunStatus); +} + +/******************************************************************************/ +/** \brief Initialize the Event Filter Table. +*******************************************************************************/ +int32 TO_AppInit(void) +{ + int32 iStatus=CFE_SUCCESS; + + /* Start as disabled. */ + g_TO_AppData.usOutputEnabled = 0; + g_TO_AppData.usOutputActive = 0; + g_TO_AppData.uiRunStatus = CFE_ES_APP_RUN; + + /* Init Events */ + if (TO_InitEvent() != CFE_SUCCESS) + { + iStatus = TO_ERROR; + CFE_ES_WriteToSysLog("TO - Event Init failed. \n"); + goto TO_AppInit_Exit_Tag; + } + + /* Init Data (Always succesful) */ + TO_InitData(); + + /* Init Custom (Route configuration, etc.) */ + if (TO_CustomInit() != CFE_SUCCESS) + { + iStatus = TO_ERROR; + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "TO - Custom Init failed."); + goto TO_AppInit_Exit_Tag; + } + + /* Init Config Table */ + if (TO_InitTable() != CFE_SUCCESS) + { + iStatus = TO_ERROR; + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "TO - Table Init failed."); + goto TO_AppInit_Exit_Tag; + } + + /* Init Pipes */ + if (TO_InitPipe() != CFE_SUCCESS) + { + iStatus = TO_ERROR; + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "TO - Pipe Init failed."); + goto TO_AppInit_Exit_Tag; + } + + /* Install the cleanup callback */ + OS_TaskInstallDeleteHandler((void*)&TO_CleanupCallback); + +TO_AppInit_Exit_Tag: + if (iStatus == CFE_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_INF_EID, CFE_EVS_INFORMATION, + "Application initialized"); + } + else + { + CFE_ES_WriteToSysLog("TO - Application failed to initialize\n"); + } + + return (iStatus); +} + +/******************************************************************************/ +/** \brief Initialize the Event Filter Table. +*******************************************************************************/ +int32 TO_InitEvent(void) +{ + int32 iStatus=CFE_SUCCESS; + int32 ii = 0; + + /* Create the event table */ + CFE_PSP_MemSet((void*)g_TO_AppData.EventTbl, 0x00, + sizeof(g_TO_AppData.EventTbl)); + + for (ii = 0; ii < TO_EVT_CNT; ++ii) + { + g_TO_AppData.EventTbl[ii].EventID = ii; + } + + /* Register the table with CFE */ + iStatus = CFE_EVS_Register(g_TO_AppData.EventTbl, + TO_EVT_CNT, CFE_EVS_BINARY_FILTER); + if (iStatus != CFE_SUCCESS) + { + CFE_ES_WriteToSysLog("TO - Failed to register with EVS (0x%08X)\n", + iStatus); + } + + return (iStatus); +} + + +/******************************************************************************/ +/** \brief Initialize Data +*******************************************************************************/ +int32 TO_InitData(void) +{ + uint8 ii = 0; + int32 iStatus=CFE_SUCCESS; + char name[OS_MAX_API_NAME]; + char id[3]; + TO_TlmPipe_t *pTlmPipe; + TO_CfChannel_t *pCfChnl; + + /* Init output data */ + CFE_PSP_MemSet((void*)&g_TO_AppData.OutData, 0x00, + sizeof(g_TO_AppData.OutData)); + CFE_SB_InitMsg(&g_TO_AppData.OutData, + TO_OUT_DATA_MID, sizeof(g_TO_AppData.OutData), TRUE); + + /* Init housekeeping packet */ + CFE_PSP_MemSet((void*)&g_TO_AppData.HkTlm, 0x00, sizeof(g_TO_AppData.HkTlm)); + CFE_SB_InitMsg(&g_TO_AppData.HkTlm, + TO_HK_TLM_MID, sizeof(g_TO_AppData.HkTlm), TRUE); + + /* Init wakeup count */ + g_TO_AppData.uiWakeupTimeout = TO_WAKEUP_TIMEOUT; + g_TO_AppData.usWakeupCount = 0; + + /* Init critical MIDs */ + for (ii = 0; ii < TO_NUM_CRITICAL_MIDS; ++ii) + { + g_TO_AppData.criticalMid[ii] = 0; + } + + /* Go Over every route */ + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + /* Initialize all pipes. May be overwritten in TO_CustomInit() */ + pTlmPipe = &g_TO_AppData.tlmPipes[ii]; + pTlmPipe->usTlmPipeDepth = TO_TLM_PIPE_DEPTH; + CFE_PSP_MemSet((void*)pTlmPipe->cTlmPipeName, '\0', + sizeof(pTlmPipe->cTlmPipeName)); + + strncpy(name, "TO_TLM_PIPE_", OS_MAX_API_NAME-3); + sprintf(id, "%u", ii); + strcat(name, id); + strncpy(pTlmPipe->cTlmPipeName, name, OS_MAX_API_NAME-1); + + /* Initialize the Route info. Config Routes in TO_CustomInit() */ + /* Must set usExist = 1 for routes to be used to_custom.c */ + g_TO_AppData.routes[ii].usWakePeriod = 1; + g_TO_AppData.routes[ii].sCfChnlIdx = -1; + g_TO_AppData.routes[ii].usExists = 0; + g_TO_AppData.routes[ii].usIsConfig = 0; + g_TO_AppData.routes[ii].usIsEnabled = 0; + + } + + /* Go over every CF Channel and initialize. + * + * NOTE: + * - Every CF channel included is enabled by default. + * - Set cCfCntSemName in TO_CustomInit if used. + * - Two CF Channels must not share the same throttling semaphore name. + * - CF Channels are associated to a route through route->sCfChnlIdx */ + for (ii = 0; ii < TO_NUM_CF_CHANNELS; ++ii) + { + pCfChnl = &g_TO_AppData.cfChnls[ii]; + pCfChnl->usIsEnabled = 1; + pCfChnl->uiCfCntSemId = 0; + strncpy(pCfChnl->cCfCntSemName, TO_CF_THROTTLE_SEM_NAME, + OS_MAX_API_NAME); + } + + return iStatus; +} + + +/******************************************************************************/ +/** \brief Initialize Table +*******************************************************************************/ +int32 TO_InitTable(void) +{ + int32 iStatus = CFE_SUCCESS; + void * pTable; + + /* Register the table with cFE Table services. */ + iStatus = CFE_TBL_Register(&g_TO_AppData.tableHandle, TO_CONFIG_TABLENAME, + sizeof(TO_ConfigTable_t), + CFE_TBL_OPT_DEFAULT, + (CFE_TBL_CallbackFuncPtr_t) TO_ValidateTable); + + if (iStatus != CFE_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_Register() returned error 0x%08x. Aborting table init.", + iStatus); + + goto end_of_function; + } + + /* Load the TO configuration table file */ + iStatus = CFE_TBL_Load(g_TO_AppData.tableHandle, CFE_TBL_SRC_FILE, + TO_CONFIG_FILENAME); + + if (iStatus != CFE_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_Load() returned error 0x%08x. Aborting table init.", + iStatus); + + goto end_of_function; + } + + /* Manage the TO config table */ + iStatus = CFE_TBL_Manage(g_TO_AppData.tableHandle); + if (iStatus != CFE_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_Manage() returned error 0x%08x. Aborting table init.", + iStatus); + + goto end_of_function; + } + + /* Make sure the TO_Load Table is accessible */ + iStatus = CFE_TBL_GetAddress (&pTable, g_TO_AppData.tableHandle); + + /* Status should be CFE_TBL_INFO_UPDATED because we loaded it above */ + if (iStatus != CFE_TBL_INFO_UPDATED) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_GetAddress() returned error 0x%08x. " + "Aborting table init.", + iStatus); + + goto end_of_function; + } + + /* Store the pointer */ + g_TO_AppData.pConfigTable = (TO_ConfigTable_t *) pTable; + + /* Register to receive TBL manage request commands for table updates. */ + iStatus = CFE_TBL_NotifyByMessage(g_TO_AppData.tableHandle, + TO_APP_CMD_MID, + TO_MANAGE_TABLE_CC, 0); + if (iStatus != CFE_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_NotifyByMessage() returned error 0x%08x. " + "Aborting table init.", iStatus); + } + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Initialize the Pipes +*******************************************************************************/ +int32 TO_InitPipe(void) +{ + int32 iStatus=CFE_SUCCESS; + int32 jj; + TO_TlmPipe_t *pTlmPipe = NULL; + TO_Route_t *pRoute = NULL; + TO_CfChannel_t *pCfChnl = NULL; + + /* Init schedule pipe */ + g_TO_AppData.usSchPipeDepth = TO_SCH_PIPE_DEPTH; + CFE_PSP_MemSet((void*)g_TO_AppData.cSchPipeName, '\0', + sizeof(g_TO_AppData.cSchPipeName)); + strncpy(g_TO_AppData.cSchPipeName, "TO_SCH_PIPE", OS_MAX_API_NAME-1); + + /* Subscribe to Wakeup messages */ + iStatus = CFE_SB_CreatePipe(&g_TO_AppData.SchPipeId, + g_TO_AppData.usSchPipeDepth, + g_TO_AppData.cSchPipeName); + if (iStatus == CFE_SUCCESS) + { + CFE_SB_Subscribe(TO_WAKEUP_MID, g_TO_AppData.SchPipeId); + } + else + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "Failed to create SCH pipe (Error:0x%08x)", iStatus); + goto TO_InitPipe_Exit_Tag; + } + + /* Init command pipe */ + g_TO_AppData.usCmdPipeDepth = TO_CMD_PIPE_DEPTH ; + CFE_PSP_MemSet((void*)g_TO_AppData.cCmdPipeName, '\0', + sizeof(g_TO_AppData.cCmdPipeName)); + strncpy(g_TO_AppData.cCmdPipeName, "TO_CMD_PIPE", OS_MAX_API_NAME-1); + + /* Subscribe to command messages */ + iStatus = CFE_SB_CreatePipe(&g_TO_AppData.CmdPipeId, + g_TO_AppData.usCmdPipeDepth, + g_TO_AppData.cCmdPipeName); + if (iStatus == CFE_SUCCESS) + { + CFE_SB_Subscribe(TO_APP_CMD_MID, g_TO_AppData.CmdPipeId); + CFE_SB_Subscribe(TO_SEND_HK_MID, g_TO_AppData.CmdPipeId); + } + else + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "Failed to create CMD pipe (Error:0x%08x)", iStatus); + goto TO_InitPipe_Exit_Tag; + } + + /* Create route Pipes and CF Channels */ + for (jj = 0; jj < TO_MAX_NUM_ROUTES; ++jj) + { + pRoute = &g_TO_AppData.routes[jj]; + + /* Route must exist in order to create a pipe link to CF channel */ + if (pRoute->usExists) + { + /* Create a route specific telemetry pipe */ + pTlmPipe = &g_TO_AppData.tlmPipes[jj]; + iStatus = CFE_SB_CreatePipe(&pTlmPipe->cfePipeId, + pTlmPipe->usTlmPipeDepth, + pTlmPipe->cTlmPipeName); + + if (iStatus != CFE_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "Failed to create TLM pipe:%s, " + "(CFE Error:0x%08x)", + pTlmPipe->cTlmPipeName, iStatus); + goto TO_InitPipe_Exit_Tag; + } + + /* Setup CF channel Semaphore for routes with channel */ + if (pRoute->sCfChnlIdx >= 0) + { + if (pRoute->sCfChnlIdx >= TO_NUM_CF_CHANNELS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "Route:%u, has invalid sCfChnlIdx of %d." + " Only %u CF channels available. ", + jj, pRoute->sCfChnlIdx, TO_NUM_CF_CHANNELS); + iStatus = TO_ERROR; + goto TO_InitPipe_Exit_Tag; + } + + pCfChnl = &g_TO_AppData.cfChnls[pRoute->sCfChnlIdx]; + + /* Initialize CF Counting Sem to Pipe Depth */ + /* NOTE: This will fail if two routes attempt to use the same + * CF channel. */ + iStatus = OS_CountSemCreate(&pCfChnl->uiCfCntSemId, + pCfChnl->cCfCntSemName, + pTlmPipe->usTlmPipeDepth, 0); + if (iStatus != OS_SUCCESS) + { + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "Failed to create counting semaphore " + "for CF channel:%s for route ID:%u. " + "(OSAL Error:%d)", + pCfChnl->cCfCntSemName, jj, iStatus); + goto TO_InitPipe_Exit_Tag; + } + } + } + } + + /* Subscribe to messages on the telemetry pipe for all existing routes */ + iStatus = TO_SubscribeAllMsgs(); + if (iStatus != TO_SUCCESS) + { + goto TO_InitPipe_Exit_Tag; + } + +TO_InitPipe_Exit_Tag: + return (iStatus); +} + +/******************************************************************************/ +/** \brief Validate Table Load +*******************************************************************************/ +int32 TO_ValidateTable(void* table) +{ + int32 iStatus = CFE_SUCCESS; + int32 reachedUnused = 0; + int32 ii, jj; + + TO_ConfigTable_t * pTable = (TO_ConfigTable_t *) table; + + /* Loop over all entries, looking for gaps and duplicate MID */ + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ii++) + { + TO_TableEntry_t *entry = &pTable->entries[ii]; + + /* If the entry is in use */ + if (entry->usMsgId != TO_UNUSED_ENTRY && + entry->usMsgId != TO_REMOVED_ENTRY) + { + /* After an Unused entry found, there should be no more entries. */ + if (reachedUnused) + { + CFE_EVS_SendEvent(TO_TBL_ERR_EID, CFE_EVS_ERROR, + "Table Validation failed. " + "Unused Entry before entry index:%d", ii); + iStatus = TO_ERROR; + goto end_of_function; + } + + /* Look for duplicates */ + for (jj = ii + 1; jj < TO_MAX_TBL_ENTRIES; jj++) + { + TO_TableEntry_t *entryCmp = &pTable->entries[jj]; + + if (entryCmp->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + else if (entryCmp->usMsgId != TO_REMOVED_ENTRY && + entry->usMsgId == entryCmp->usMsgId) + { + CFE_EVS_SendEvent(TO_TBL_ERR_EID, CFE_EVS_ERROR, + "Table Validation failed. " + "Duplicate MID:0x%04x", entry->usMsgId); + + iStatus = TO_ERROR; + goto end_of_function; + } + } + } + else if (entry->usMsgId == TO_UNUSED_ENTRY) + { + reachedUnused = 1; + } + } + + /* Check that all critical messages are present. */ + for (ii = 0; ii < TO_NUM_CRITICAL_MIDS; ii++) + { + iStatus = TO_FindTableIndex(pTable, g_TO_AppData.criticalMid[ii]); + + if (g_TO_AppData.criticalMid[ii] != 0 && iStatus == TO_NO_MATCH) + { + CFE_EVS_SendEvent(TO_TBL_ERR_EID, CFE_EVS_ERROR, + "Table Validation failed. " + "Missing Critical MID:0x%04x", + g_TO_AppData.criticalMid[ii]); + + iStatus = TO_ERROR; + goto end_of_function; + } + } + + iStatus = CFE_SUCCESS; + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Receive Messages from Software Bus +*******************************************************************************/ +int32 TO_RcvMsg(int32 iBlocking) +{ + int32 iStatus=CFE_SUCCESS; + CFE_SB_MsgPtr_t pMsg=NULL; + CFE_SB_MsgId_t MsgId; + + /* Wait for WakeUp messages from scheduler */ + iStatus = CFE_SB_RcvMsg(&pMsg, g_TO_AppData.SchPipeId, iBlocking); + + /* Performance Log Entry stamp - #2 */ + CFE_ES_PerfLogEntry(TO_MAIN_TASK_PERF_ID); + + if (iStatus == CFE_SUCCESS) + { + MsgId = CFE_SB_GetMsgId(pMsg); + switch (MsgId) + { + case TO_WAKEUP_MID: + TO_ProcessNewCmds(); + TO_ProcessTlmPipes(); + TO_SendOutData(); + break; + + default: + CFE_EVS_SendEvent(TO_MSGID_ERR_EID, CFE_EVS_ERROR, + "Recvd invalid SCH usMsgId (0x%04X)", MsgId); + } + } + /* Implementation may set usWakeupTimeout instead of relying on + * Scheduler for wakeup message. */ + else if (iStatus == CFE_SB_TIME_OUT) + { + TO_ProcessNewCmds(); + TO_ProcessTlmPipes(); + TO_SendOutData(); + } + else + { + CFE_EVS_SendEvent(TO_PIPE_ERR_EID, CFE_EVS_ERROR, + "TO: SB pipe read error (0x%08x), app will exit", + iStatus); + g_TO_AppData.uiRunStatus= CFE_ES_APP_ERROR; + } + + return (iStatus); +} + + +/******************************************************************************/ +/** \brief Process Telemetry Pipes +*******************************************************************************/ +void TO_ProcessTlmPipes(void) +{ + uint8 ii = 0; + uint16 wakeCnt = g_TO_AppData.usWakeupCount; + + /* Loop over every pipe and process data. */ + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + /* Only existing routes will have a pipe to process */ + if (g_TO_AppData.routes[ii].usExists) + { + /* Process the pipe if the period corresponds. */ + if (wakeCnt % g_TO_AppData.routes[ii].usWakePeriod == 0) + { + TO_ProcessNewData(&g_TO_AppData.tlmPipes[ii], ii); + } + } + else + { + break; + } + } + + /* Increment the wakeup count */ + g_TO_AppData.usWakeupCount++; + /* If we hit the max wakeup count, rollover to 0 */ + if (g_TO_AppData.usWakeupCount == TO_MAX_WAKEUP_COUNT) + { + g_TO_AppData.usWakeupCount = 0; + } + + return; +} + + + +/******************************************************************************/ +/** \brief Process New Data +*******************************************************************************/ +void TO_ProcessNewData(TO_TlmPipe_t *pTlmPipe, uint16 usRouteId) +{ + CFE_SB_MsgPtr_t pTlmMsg=NULL; + CFE_SB_MsgId_t usMsgId = 0; + boolean bGotNewMsg=TRUE; + int32 size = 0; + int32 iStatus = 0; + int32 iTblIdx = 0; + TO_TableEntry_t *pEntry=NULL; + boolean bHasCfChnl=FALSE; + int16 sCfChnlIdx; + uint16 uiCntSemId; + OS_count_sem_prop_t cntSemProp; + +#ifdef TO_FRAMING_ENABLED + /* Prepare framing mechanism, if applicable. */ + if (g_TO_AppData.usOutputEnabled && g_TO_AppData.usOutputActive && + g_TO_AppData.routes[usRouteId].usIsEnabled) + { + iStatus = TO_CustomFrameStart(usRouteId); + if (iStatus != TO_SUCCESS) + { + /* Error event should be issued in TO_CustomFrameStart */ + goto end_of_function; + } + } +#endif + + /* Get the Counting Sem Id if applicable */ + sCfChnlIdx = g_TO_AppData.routes[usRouteId].sCfChnlIdx; + if (sCfChnlIdx >= 0 && g_TO_AppData.cfChnls[sCfChnlIdx].usIsEnabled) + { + bHasCfChnl = TRUE; + uiCntSemId = g_TO_AppData.cfChnls[sCfChnlIdx].uiCfCntSemId; + } + + while (bGotNewMsg) + { + if (CFE_SB_RcvMsg(&pTlmMsg, pTlmPipe->cfePipeId, CFE_SB_POLL) == + CFE_SUCCESS) + { + /* Process if output is enabled and active. Otherwise, drop. */ + if (g_TO_AppData.usOutputEnabled && g_TO_AppData.usOutputActive) + { + usMsgId = CFE_SB_GetMsgId(pTlmMsg); + iTblIdx = TO_FindTableIndex(g_TO_AppData.pConfigTable, usMsgId); + + if (iTblIdx == TO_NO_MATCH) + { + CFE_EVS_SendEvent(TO_PIPE_ERR_EID, CFE_EVS_ERROR, + "Received invalid MID on TlmPipe. " + "MID:0x%04x", usMsgId); + } + /* Process message if the table entry is enabled for + * this route. */ + else + { + pEntry = &g_TO_AppData.pConfigTable->entries[iTblIdx]; + + /* Process data over enabled routes for enabled messages */ + if (pEntry->usState && + (pEntry->usRouteMask & (1<usTlmPipeDepth) + { + /* If the current count is less than pipe depth, + * give one count */ + OS_CountSemGive(uiCntSemId); + } + } + } + else + { + bGotNewMsg = FALSE; + } + } + +#ifdef TO_FRAMING_ENABLED +end_of_function: + + /* Complete and send a frame, if applicable. */ + /* NOTE: The CustomProcessData may have failed. Custom function responsible + for dealing with status as provided. */ + if (g_TO_AppData.usOutputEnabled && g_TO_AppData.usOutputActive && + g_TO_AppData.routes[usRouteId].usIsEnabled) + { + TO_CustomFrameSend(usRouteId, iStatus); + } + + return; +#endif +} + + +/******************************************************************************/ +/** \brief Process New Commands +*******************************************************************************/ +void TO_ProcessNewCmds(void) +{ + CFE_SB_MsgPtr_t pCmdMsg=NULL; + CFE_SB_MsgId_t usMsgId; + boolean bGotNewMsg=TRUE; + + while (bGotNewMsg) + { + if (CFE_SB_RcvMsg(&pCmdMsg, g_TO_AppData.CmdPipeId, CFE_SB_POLL) == + CFE_SUCCESS) + { + usMsgId = CFE_SB_GetMsgId(pCmdMsg); + switch (usMsgId) + { + case TO_APP_CMD_MID: + TO_ProcessNewAppCmds(pCmdMsg); + break; + + case TO_SEND_HK_MID: + TO_ReportHousekeeping(); + break; + + default: + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_MSGID_ERR_EID, CFE_EVS_ERROR, + "Recvd invalid CMD usMsgId (0x%04X)", + usMsgId); + break; + } + } + else + { + bGotNewMsg = FALSE; + } + } +} + +/******************************************************************************/ +/** \brief Process New App Commands +*******************************************************************************/ +void TO_ProcessNewAppCmds(CFE_SB_MsgPtr_t pMsg) +{ + int32 iStatus = TO_SUCCESS; + uint32 uiCmdCode = 0; + + if (pMsg != NULL) + { + uiCmdCode = CFE_SB_GetCmdCode(pMsg); + switch (uiCmdCode) + { + case TO_NOOP_CC: + TO_NoopCmd(pMsg); + break; + + case TO_RESET_CC: + TO_ResetCmd(pMsg); + break; + + case TO_ENABLE_OUTPUT_CC: + TO_EnableOutputCmd(pMsg); + break; + + case TO_DISABLE_OUTPUT_CC: + TO_DisableOutputCmd(pMsg); + break; + + case TO_PAUSE_OUTPUT_CC: + TO_PauseOutputCmd(pMsg); + break; + + case TO_RESUME_OUTPUT_CC: + TO_ResumeOutputCmd(pMsg); + break; + + case TO_ADD_TBL_ENTRY_CC: + TO_AddTblEntryCmd(pMsg); + break; + + case TO_REMOVE_TBL_ENTRY_CC: + TO_RemoveTblEntryCmd(pMsg); + break; + + case TO_ENABLE_TBL_ENTRY_CC: + TO_EnableTblEntryCmd(pMsg); + break; + + case TO_DISABLE_TBL_ENTRY_CC: + TO_DisableTblEntryCmd(pMsg); + break; + + case TO_ENABLE_GROUP_CC: + TO_EnableGroupCmd(pMsg); + break; + + case TO_DISABLE_GROUP_CC: + TO_DisableGroupCmd(pMsg); + break; + + case TO_ENABLE_ALL_CC: + TO_EnableAllCmd(pMsg); + break; + + case TO_DISABLE_ALL_CC: + TO_DisableAllCmd(pMsg); + break; + + case TO_SET_ROUTE_BY_MID_CC: + TO_SetRouteByMidCmd(pMsg); + break; + + case TO_SET_ROUTE_BY_GROUP_CC: + TO_SetRouteByGroupCmd(pMsg); + break; + + case TO_MANAGE_TABLE_CC: + TO_ManageTableCmd(pMsg); + break; + + case TO_ACTIVATE_ROUTES_CC: + TO_ActivateRoutesCmd(pMsg); + break; + + case TO_DEACTIVATE_ROUTES_CC: + TO_DeactivateRoutesCmd(pMsg); + break; + + case TO_SET_ROUTE_PERIOD_CC: + TO_SetRoutePeriodCmd(pMsg); + break; + + case TO_SET_WAKEUP_TIMEOUT_CC: + TO_SetWakeupTimeoutCmd(pMsg); + break; + + + /* Any other commands are assumed to be custom commands. */ + default: + iStatus = TO_CustomAppCmds(pMsg); + + if (iStatus != TO_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Recvd invalid cmd code (%d)", uiCmdCode); + } + break; + } + } +} + +/******************************************************************************/ +/** \brief Report Housekeeping Packet +*******************************************************************************/ +void TO_ReportHousekeeping(void) +{ + CFE_SB_TimeStampMsg((CFE_SB_MsgPtr_t)&g_TO_AppData.HkTlm); + CFE_SB_SendMsg((CFE_SB_MsgPtr_t)&g_TO_AppData.HkTlm); +} + +/******************************************************************************/ +/** \brief Send the OutData Packet +*******************************************************************************/ +void TO_SendOutData(void) +{ + CFE_SB_TimeStampMsg((CFE_SB_MsgPtr_t)&g_TO_AppData.OutData); + CFE_SB_SendMsg((CFE_SB_MsgPtr_t)&g_TO_AppData.OutData); +} + +/******************************************************************************/ +/** \brief Perform cleanup on shutdown +*******************************************************************************/ +void TO_CleanupCallback(void) +{ + /* Call Custom Cleanup to close transport protocol, etc. */ + TO_CustomCleanup(); +} + +/*============================================================================== +** End of file to_app.c +**============================================================================*/ diff --git a/fsw/src/to_app.h b/fsw/src/to_app.h new file mode 100644 index 0000000..b99639f --- /dev/null +++ b/fsw/src/to_app.h @@ -0,0 +1,1197 @@ +/******************************************************************************/ +/** \file to_app.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Header file for the TO application +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Application functions are defined in to_app.c +* - Command functions are declared in to_cmds.h and defined in to_cmds.c +* - Utilities are defined in to_utils.c +* - Custom functions are defined in to_custom.c +* - A route is configured through to_custom.c +* - SEND_HK is subscribed to the command pipe. The wakeup rate should +* generally be set faster than the SEND_HK rate, otherwise HK packets +* will be dropped. SEND_HK is required to get housekeeping data. +* - The TO_WAKEUP_TIMEOUT value may be used instead of Scheduler +* table for app processing rate. Timeout rate can be changed by cmd. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2016-05-11 | Allen Brown | Updated comments +*******************************************************************************/ + +#ifndef _TO_APP_H_ +#define _TO_APP_H_ + +#ifdef __cplusplus +extern "C" { +#endif + + +/******************************************************************************* +** Includes +*******************************************************************************/ +#include +#include +#include + +#include "osconfig.h" + +#include "to_platform_cfg.h" +#include "to_mission_cfg.h" +#include "to_events.h" +#include "to_tbldefs.h" +#include "to_cmds.h" + +/******************************************************************************* +** Macro Definitions +*******************************************************************************/ +/** \name Version numbers */ +/** \{ */ +#define TO_MAJOR_VERSION 1 +#define TO_MINOR_VERSION 0 +#define TO_REVISION 0 +#define TO_MISSION_REV 0 +/** \} */ + +/** \name Return codes */ +/** \{ */ +#define TO_SUCCESS 0 +#define TO_ERROR (-1) +#define TO_TBL_FULL_ERR (-2) +#define TO_BAD_ARG_ERR (-3) +#define TO_NO_MATCH (-4) +#define TO_NO_EFFECT (-5) +/** \} */ + +#define TO_MAX_NUM_ROUTES 16 +#define TO_MAX_ROUTE_MASK 0xffffL + + +/** Default values of macros if not defined in to_platform_cfg.h */ +/** \name Default Settings */ +/** \{ */ +#ifndef TO_WAKEUP_TIMEOUT +#define TO_WAKEUP_TIMEOUT 500 +#endif +#ifndef TO_MIN_WAKEUP_TIMEOUT +#define TO_MIN_WAKEUP_TIMEOUT 500 +#endif + +/* NOTE: Changing this value will impact what are valid uiWakePeriod + * values for a route. Valid values are any factors of this max count. */ +#ifndef TO_MAX_WAKEUP_COUNT +#define TO_MAX_WAKEUP_COUNT 20000 +#endif + +#ifndef TO_SCH_PIPE_DEPTH +#define TO_SCH_PIPE_DEPTH 10 +#endif + +#ifndef TO_CMD_PIPE_DEPTH +#define TO_CMD_PIPE_DEPTH 10 +#endif +#ifndef TO_TLM_PIPE_DEPTH +#define TO_TLM_PIPE_DEPTH 10 +#endif + +#ifndef TO_NUM_CRITICAL_MIDS +#define TO_NUM_CRITICAL_MIDS 0 +#endif + +#ifndef TO_GROUP_NUMBER_MASK +#define TO_GROUP_NUMBER_MASK 0xFF000000 +#endif +#ifndef TO_MULTI_GROUP_MASK +#define TO_MULTI_GROUP_MASK 0x00FFFFFF +#endif + +#ifndef TO_CONFIG_TABLENAME +#define TO_CONFIG_TABLENAME "to_config" +#endif +#ifndef TO_CONFIG_FILENAME +#define TO_CONFIG_FILENAME "/cf/apps/to_config.tbl" +#endif + +#ifndef TO_NUM_CF_CHANNELS +#define TO_NUM_CF_CHANNELS 1 +#endif + +#ifndef TO_CF_THROTTLE_SEM_NAME +#define TO_CF_THROTTLE_SEM_NAME "CFTOSemId" +#endif +/** \} */ + + +/******************************************************************************* +** Structure definitions +*******************************************************************************/ +/** /brief TO Telemetry Pipes */ +typedef struct +{ + CFE_SB_PipeId_t cfePipeId; /**< Telemetry Pipe ID */ + uint16 usTlmPipeDepth; /**< Telemetry Pipe depth */ + char cTlmPipeName[OS_MAX_API_NAME]; /**< Telemetry Pipe name */ +} TO_TlmPipe_t; + +typedef struct +{ + uint16 usWakePeriod; /**< Multiple of TO rate when route should + be processed (and associated pipe. */ + int16 sCfChnlIdx; /**< Index of CF channel (-1 if none) */ + uint16 usExists; /**< A Route exists (Pipe to be created) */ + uint16 usIsConfig; /**< Route is configured (through to_custom.c) */ + uint16 usIsEnabled; /**< Route is enabled (Telemetry processed) */ +} TO_Route_t; + +typedef struct +{ + uint16 usIsEnabled; /**< Channel is Enabled (default:true) */ + uint32 uiCfCntSemId; /**< The CF Throttling Counting Semaphore ID. + Set by TO_InitPipe. */ + char cCfCntSemName[OS_MAX_API_NAME]; + /**< Name of CF throttling semaphore */ +} TO_CfChannel_t; + + +/** /brief AppData Structure Defenition */ +typedef struct +{ + /* CFE Event table */ + CFE_EVS_BinFilter_t EventTbl[TO_EVT_CNT]; /**< Event Filter Table. */ + + /* CFE scheduling pipe */ + CFE_SB_PipeId_t SchPipeId; /**< Schedule Pipe ID */ + uint16 usSchPipeDepth; /**< Schedule Pipe depth */ + char cSchPipeName[OS_MAX_API_NAME]; /**< Schedule Pipe name */ + + /* CFE command pipe */ + CFE_SB_PipeId_t CmdPipeId; /**< Command Pipe ID */ + uint16 usCmdPipeDepth; /**< Command Pipe depth */ + char cCmdPipeName[OS_MAX_API_NAME]; /**< Command Pipe name */ + + /* Routing structures */ + TO_Route_t routes[TO_MAX_NUM_ROUTES]; /**< Output Routes */ + TO_TlmPipe_t tlmPipes[TO_MAX_NUM_ROUTES]; /**< Telemetry Pipes */ + TO_CfChannel_t cfChnls[TO_NUM_CF_CHANNELS]; /**< CF Channels */ + + /* Task-related */ + uint32 uiRunStatus; /**< Application Run Status */ + + /* Wakeup schedule */ + uint32 uiWakeupTimeout; /**< Wakeup timeout in ms */ + uint16 usWakeupCount; /**< Wakeup cnts, for route wake period check. */ + + /* Output data (Data destined for other applications over SB) + Data structure defined in $MISSION/apps/inc/{MISSION}_to_types.h */ + TO_OutData_t OutData; /**< Output SB Data Packet */ + + /* Housekeeping telemetry + Data structure defined in $MISSION/apps/inc/{MISSION}_to_types.h */ + TO_HkTlm_t HkTlm; /**< Housekeeping Packet */ + + /* MIDs which must be present in the config tbl Set in TO_CustomInit. */ + CFE_SB_MsgId_t criticalMid[TO_NUM_CRITICAL_MIDS]; /**< Critical msg Ids */ + + /* Configuration tables */ + TO_ConfigTable_t *pConfigTable; /**< Pointer to the config table */ + CFE_TBL_Handle_t tableHandle; /**< Table handle */ + + /* Output flags. + TO_CustomProcessData called when output is enabled and active. */ + uint16 usOutputEnabled; /**< Output enabled(by enable/disable) */ + uint16 usOutputActive; /**< Output active (by pause/resume) */ + +} TO_AppData_t; + + +/******************************************************************************* +** Application Function Declarations (defined in to_app.c) +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Main Entry Point for TO Application +* +* \par Description/Algorithm +* This function is the main entry point of the TO Application. It +* performs the following: +* 1. Registers the Application with cFE +* 2. Initializes the application through TO_AppInit +* 3. Loops over the TO_RcvMsg function to perform main function. +* 4. Exit application on kill signal or error +* +* \par Assumptions, External Events, and Notes: +* - The TO_MAIN_TASK_PERF_ID Entered in TO_RcvMsg +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns None +* +* \see +* #TO_AppInit +* #TO_RcvMsg +* #TO_CleanupCallback +*******************************************************************************/ +void TO_AppMain(void); + +/******************************************************************************/ +/** \brief Initialize The Application +* +* \par Description/Algorithm +* High level initialization function. Calls in order: +* 1. TO_InitEvent +* 2. TO_InitData +* 3. TO_CustomInit +* 4. TO_InitTable +* 5. TO_InitPipe +* 6. Installs the Cleanup Callback function. +* +* \par Assumptions, External Events, and Notes: +* - Output is initially disabled +* - The TO_CustomInit is defined in to_custom.c +* - TO_CustomInit is called before table and pipe init so that +* criticalMID array can be set, as well as route, pipe and CF Channel +* config. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* \retcode #TO_ERROR \retdesc Initialization Error \endcode +* +* \see +* #TO_InitEvent +* #TO_InitData +* #TO_InitTable +* #TO_InitPipe +* #TO_CustomInit +*******************************************************************************/ +int32 TO_AppInit(void); + +/******************************************************************************/ +/** \brief Initialize the Event Filter Table. +* +* \par Description/Algorithm +* 1. Set the EventTbl EventIds based on ids defined in to_events.h +* 2. Register the events with cFE Table services. +* +* \par Assumptions, External Events, and Notes: +* - All Events are intialized as unfiltered. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* \retstmt Any of the error codes from #CFE_EVS_Register \endstmt +* \endreturns +* +* \see +* #TO_AppInit +*******************************************************************************/ +int32 TO_InitEvent(void); + +/******************************************************************************/ +/** \brief Initialize Data +* +* \par Description/Algorithm +* Initialize the Housekeeping Packet, the OutData Packet, pipes and +* route parameters. +* +* \par Assumptions, External Events, and Notes: +* - All Routes are initialized as non-existing and non-configured. +* - All route telemetry pipes given TO_TLM_PIPE_DEPTH depth. +* - Routes configuration can be overwritten in TO_CustomInit. +* - The default CF Channel is not associated with any route by default. +* - If more than 1 CF Channel are used, their CfCntSemName must be set in +* TO_CustomInit. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* +* \see +* #TO_AppInit +*******************************************************************************/ +int32 TO_InitData(void); + +/******************************************************************************/ +/** \brief Initialize Table +* +* \par Description/Algorithm +* Initialize the configuration through the following steps: +* 1. Registers table with CFE TBL services +* 2. Loads the table to CFE TBL services +* 3. Manages the table with CFE TBL services +* 4. Verifies Table load +* 5. Stores the table pointer +* 6. Registers with CFE TBL manager for notify message. +* +* \par Assumptions, External Events, and Notes: +* - The table is validated on Load through TO_ValidateTable +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* \retstmt Any of the error codes from #CFE_TBL_Register \endstmt +* \retstmt Any of the error codes from #CFE_TBL_Load \endstmt +* \retstmt Any of the error codes from #CFE_TBL_Manage \endstmt +* \retstmt Any of the error codes from #CFE_TBL_GetAddress \endstmt +* \retstmt Any of the error codes from #CFE_TBL_NotifyByMessage \endstmt +* +* \see +* #TO_AppInit +*******************************************************************************/ +int32 TO_InitTable(void); + +/******************************************************************************/ +/** \brief Initialize the Pipes +* +* \par Description/Algorithm +* Initialize the Scheduler, Tlm and Cmd Pipes. +* - The Scheduler pipe is subscribed to the WAKEUP message. +* - The Command pipe is subscribed to TO_APP_CMD_MID and TO_SEND_HK. +* - Each enabled route will create a corresponding telemetry pipe. +* - A counting semaphore for CF app throttling is created for each +* CF channel referenced by a route. Each counting semaphore +* created is initialized to the pipe depth of the corresponding +* route telemetry pipe. +* - Each telemetry pipe is subscribed to all message IDs included in the +* configuration table for the corresponding route. +* +* \par Assumptions, External Events, and Notes: +* - The CfCntSemName of each CF Channel used must be distinct. Set in +* TO_CustomInit. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* \retstmt Any of the error codes from #CFE_SB_Pipe \endstmt +* \endreturns +* +* \see +* #TO_AppInit +*******************************************************************************/ +int32 TO_InitPipe(void); + +/******************************************************************************/ +/** \brief Validate Table Load +* +* \par Description/Algorithm +* Validate the table load by verifying the following: +* - All Message IDs should be unique (no repeating MIDs) +* - All used table entries are sequential (no gaps) +* - All criticalMID message IDs are present in table. +* +* \par Assumptions, External Events, and Notes: +* - An Event is issued on any validation error. +* - This function is called by cFE TBL services on a new table load. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* \retcode #TO_ERROR \retdesc Validation Failed \endcode +* \endreturns +* +* \see +* #TO_InitTable +*******************************************************************************/ +int32 TO_ValidateTable(void *); + +/******************************************************************************/ +/** \brief Receive Messages from Software Bus +* +* \par Description/Algorithm +* - Pend on the SchPipe for TO_WAKEUP_MID. +* - On wakeup, call TO_ProcessNewCmds, TO_ProcessNewData and +* TO_SendOutData. +* - On timed-out, perform all three functions as on wakeup. +* +* \par Assumptions, External Events, and Notes: +* - Timeout based on uiWakeupTimeout, with default of TO_WAKEUP_TIMEOUT +* - Quit app on error status. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] iBlocking blocking timeout (set to CFE_SB_PEND_FOREVER) +* +* \returns +* \retcode #CFE_SUCCESS \retdesc \copydoc CFE_SUCCESS \endcode +* \retstmt Any of the error codes from #CFE_SB_RcvMsg \endstmt +* +* \see +* #TO_AppMain +*******************************************************************************/ +int32 TO_RcvMsg(int32 iBlocking); + +/******************************************************************************/ +/** \brief ProcessTlmPipes +* +* \par Description/Algorithm +* - Loop over every created tlm pipe (one per existing TO Route) +* and call ProccessNewData on that pipe based on route's wake period. +* - Increment wakeup count and force rollover if TO_MAX_WAKEUP_COUNT is +* reached. +* +* \par Assumptions, External Events, and Notes: +* - This function is called in response to the TO_WAKEUP_MID or timeout +* of SchPipe. +* - Messages will be processed based on the routePeriod parameter of +* each route. Process if wakeupCnt % route->wakePeriod == 0. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns None +* +* \see +* #TO_RcvMsg +* #TO_ProcessNewData +*******************************************************************************/ +void TO_ProcessTlmPipes(void); + +/******************************************************************************/ +/** \brief Process New Data over route telemetry pipe +* +* \par Description/Algorithm +* - Retrieve all new messages over telemetry pipe for specific route. +* - If the message received is enabled according to the config table, Call +* TO_CustomProcessData for message. +* - If the route is associated with a CF Channel, manage the counting +* semaphore count for CF App throttling. +* - Optionally, call TO_CustomFrameStart and TO_CustomFrameSend before +* and after processing all pipe messages if TO_FRAMING_ENABLED is +* defined. +* +* \par Assumptions, External Events, and Notes: +* - Messages are dropped from pipe if either usOutputEnabled or +* usOutputActive is false. +* - If framing is enabled, messages should be sent over route device +* (eg. UDP) in TO_CustomFrameSend. TO_CustomProcessData should be used +* to add messages to frame. TO_CustomFrameStart should prepare +* new frame. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pTlmPipe Pointer to current telemetry pipe structure. +* \param[in] routeId Index of current route. +* +* \returns None +* +* \see +* #TO_ProcessTlmPipes +* #TO_CustomProcessData +*******************************************************************************/ +void TO_ProcessNewData(TO_TlmPipe_t *pTlmPipe, uint16 usRouteId); + +/******************************************************************************/ +/** \brief Process New Commands +* +* \par Description/Algorithm +* - Loop over Cmd Pipe for any new messages. +* - Call TO_ProcessNewAppCmds on the receipt of the TO_APP_CMD_MID. +* - Call TO_ReportHousekeeping on receipt of TO_SEND_HK_MID. +* - Error otherwise. +* +* \par Assumptions, External Events, and Notes: +* - This function is called in response to the TO_WAKEUP_MID or timeout on +* SchPipe. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns None +* +* \see +* #TO_RcvMsg +* #TO_ProcessNewAppCmds +* #TO_ReportHousekeeping +*******************************************************************************/ +void TO_ProcessNewCmds(void); + +/******************************************************************************/ +/** \brief Process New Application Commands +* +* \par Description/Algorithm +* Perform appropriate response based on the received command code. +* +* \par Assumptions, External Events, and Notes: +* - This function is called by TO_ProcessNewCmds on receipt of new cmd. +* - The command length of each command is verified +* - Any other command codes is considered custom, and processed by +* TO_CustomAppCmds. +* - Command message structures and function declaration are defined in +* to_cmds.h +* - Command response functions are defined in to_cmds.c +* - Command Codes are defined in to_msgdefs.h +* - Custom command messages are defined in {MISSION}_to_types.h +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns None +* +* \see +* #TO_ProcessNewCmds +* #TO_CustomAppCmds +* #ALL_TO_CMDS +*******************************************************************************/ +void TO_ProcessNewAppCmds(CFE_SB_MsgPtr_t); + +/******************************************************************************/ +/** \brief Report Housekeeping Packet +* +* \par Description/Algorithm +* Send the housekeeping packet to the software bus. +* +* \par Assumptions, External Events, and Notes: +* - This function is called in response to the TO_SEND_HK_MID on +* CmdPipe by TO_ProcessNewCmds. +* - The default HK packet is defined in to_hktlm.h. +* - Default HK packet may be included in {MISSION}_to_types.h or +* redefined therein. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns None +* +* \see +* #TO_ProcessNewCmds +*******************************************************************************/ +void TO_ReportHousekeeping(void); + +/******************************************************************************/ +/** \brief Send the OutData Packet +* +* \par Description/Algorithm +* Send the OutData packet to the software bus. +* +* \par Assumptions, External Events, and Notes: +* - This function is called in response to the TO_WAKEUP_MID or timeout of +* schPipe. +* - The OutData packet is defined in {MISSION}_to_types.h. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns None +* +* \see +* #TO_RcvMsg +*******************************************************************************/ +void TO_SendOutData(void); + +/******************************************************************************/ +/** \brief Perform cleanup on shutdown +* +* \par Call the custom cleanup function to close I/O channels, etc. +* +* \par Assumptions, External Events, and Notes: +* - TO_CustomCleanup is defined in to_custom.c +* - This function gets called on CFE_ES_ExitApp from TO_AppMain. +* +* \param None +* +* \returns None +* +* \see +* #TO_AppMain +* #TO_AppInit +* #TO_CustomCleanup +*******************************************************************************/ +void TO_CleanupCallback(void); + + +/******************************************************************************* +** Utility Function Declarations (defined in to_utils.c) +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Find Empty Table Index. +* +* \par Description/Algorithm +* Return the table index of the first entry that is unused. +* +* \par Assumptions, External Events, and Notes: +* - An entry that was removed by TO_REMOVE_TBL_ENTRY is considired empty. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns tableIdx index number of empty entry +* \retcode #TO_TBL_FULL_ERR \retdesc No empty entries - tbl full. \endcode +* \endreturns +* +* \see +* #TO_AddTblEntryCmd +*******************************************************************************/ +int32 TO_FindEmptyTableIndex(void); + +/******************************************************************************/ +/** \brief Find Table Index by MID. +* +* \par Description/Algorithm +* Return the table entry corresponding to the MID. +* +* \par Assumptions, External Events, and Notes: +* - Will return TO_NO_MATCH if no table entry found. +* +* \param[in] pTable Pointer to the table to search. +* \param[in] usMsgId Message Id to find. +* +* \returns tableIdx Table index number of MID +* \retcode #TO_NO_MATCH \retdesc No matching entry w/ usMsgId \endcode +* \endreturns +* +* \see +* #TO_AddTblEntryCmd +* #TO_RemoveTblEntryCmd +* #TO_EnableTblEntryCmd +* #TO_DisableTblEntryCmd +* #TO_SetRouteByMidCmd +* #TO_ManageTableCmd +*******************************************************************************/ +int32 TO_FindTableIndex(TO_ConfigTable_t* pTable, CFE_SB_MsgId_t usMsgId); + +/******************************************************************************/ +/** \brief Set state (Enable/Disable) based on Group. +* +* \par Description/Algorithm +* Set the state of the table entries to disable / enable based on the +* supplied groupData. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] groupData GroupData paramater to evaluate. +* \param[in] enableFlag enable = 1, disable = 0 +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful change \endcode +* \retcode #TO_BAD_ARG_ERR \retdesc Bad input argument \endcode +* \retcode #TO_NO_MATCH \retdesc No matching entry w/ groupData \endcode +* \retcode #TO_NO_EFFECT \retdesc function had no effect \endcode +* \endreturns +* +* \see +* #TO_EnableGroupCmd +* #TO_DisableGroupCmd +*******************************************************************************/ +int32 TO_SetStateByGroup(uint32 groupData, uint16 enableFlag); + +/******************************************************************************/ +/** \brief Set routeMask based on Group. +* +* \par Description/Algorithm +* Set the routeMask of the table entries based on the supplied groupData. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] groupData GroupData paramater to evaluate. +* \param[in] routeMask Route Mask to set entry with +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful change \endcode +* \retcode #TO_BAD_ARG_ERR \retdesc Bad input argument \endcode +* \retcode #TO_NO_MATCH \retdesc No matching entry w/ groupData \endcode +* \retcode #TO_NO_EFFECT \retdesc function had no effect \endcode +* \endreturns +* +* \see +* #TO_EnableGroupCmd +* #TO_DisableGroupCmd +*******************************************************************************/ +int32 TO_SetRouteByGroup(uint32 uiGroupData, uint16 usRouteMask); + +/******************************************************************************/ +/** \brief Set State for all used table entries +* +* \par Description/Algorithm +* Set the state for all table entries (enable /disable) +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] usEnableFlag Enable = 1, Disable = 0 +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful change \endcode +* \retcode #TO_NO_EFFECT \retdesc function had no effect \endcode +* \endreturns +* +* \see +* #TO_EnableAllTblEntriesCmd +* #TO_DisableAllTblEntriesCmd +*******************************************************************************/ +int32 TO_SetAllEntryState(uint16 usEnableFlag); + +/******************************************************************************/ +/** \brief Set Route as configured +* +* \par Description/Algorithm +* Set route as configured and updates HK->usConfigRoutes. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] uRouteId RouteId that was configured +* +* \returns None +*******************************************************************************/ +void TO_SetRouteAsConfigured(uint16 usRouteId); + +/******************************************************************************/ +/** \brief Set Route as unconfigured +* +* \par Description/Algorithm +* Set route as unconfigured and updates HK->usConfigRoutes. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] uRouteId RouteId That was unconfigured +* +* \returns None +*******************************************************************************/ +void TO_SetRouteAsUnconfigured(uint16 usRouteId); + +/******************************************************************************/ +/** \brief Disable specific route +* +* \par Description/Algorithm +* Disables and update housekeeping usEnabledRoutes parameter. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] uRouteId RouteId To disable +* +* \returns None +*******************************************************************************/ +void TO_DisableRoute(uint16 usRouteId); + +/******************************************************************************/ +/** \brief Validate RouteMask against existing routes +* +* \par Description/Algorithm +* Verify that all routes within the route mask is an existing route. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] uRouteMask RouteMask to validate +* +* \returns +* \retcode #TO_SUCCESS \retdesc RouteMask is valid \endcode +* \retcode #TO_ERROR \retdesc RouteMask is invalid \endcode +* \endreturns +* +* \see +* #TO_SetRoutePeriodCmd +* #TO_CustomEnableOutputCmd +*******************************************************************************/ +int32 TO_ValidateRouteMask(uint16 usRouteMask); + +/******************************************************************************/ +/** \brief Get route mask by table index +* +* \par Description/Algorithm +* Return the RouteMask based on the supplied table index +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] iTblIndex Table Index +* +* \returns Route Mask or 0x0000 if bad input table index. +*******************************************************************************/ +uint16 TO_GetRouteMask(int32 tblIdx); + +/******************************************************************************/ +/** \brief Get message ID by table index +* +* \par Description/Algorithm +* Return the Message ID based on the supplied table index +* +* \par Assumptions, External Events, and Notes: +* +* \param[in] iTblIndex Table Index +* +* \returns MID or 0 if bad input table index. +*******************************************************************************/ +CFE_SB_MsgId_t TO_GetMessageID(int32 tblIdx); + +/******************************************************************************/ +/** \brief Verify the command length against expected length +* +* \par Description/Algorithm +* Get the message length through the SB API and compare it with the passed +* in expected length. If not equal, issue an error event, increment the +* uiCmdErrCnt and return false. +* +* \par Assumptions, External Events, and Notes: +* - Call this function for all received commands to verify the length. +* - Also to be used in the custom layer. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pMsg Pointer to the CCSDS message. +* \param[in] expectedLen Expected Command message length. +* +* \returns True or False +* +* \see +* #ALL_TO_CMDS +* #TO_CustomAppCmds +*******************************************************************************/ +boolean TO_VerifyCmdLength(CFE_SB_MsgPtr_t, uint16); + +/******************************************************************************/ +/** \brief Subscribe route pipes to all config table messages +* +* \par Description/Algorithm +* All pipes of existing routes will subscribe to all messages +* According to configuration table. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful \endcode +* \retcode #TO_ERRROR \retdesc Error occurred in CFE_SB_SubscribeEx \endcode +* \endreturns +* +* \see +* #TO_InitPipe +* #TO_SubscribeMsg +*******************************************************************************/ +int32 TO_SubscribeAllMsgs(void); + +/******************************************************************************/ +/** \brief Subscribe route pipes to specified message +* +* \par Description/Algorithm +* All pipes corresponding to enabled routes will subscribe to message +* according to configuration table. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pEntry The Table entry of the message ID to subscribe +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful \endcode +* \retcode #TO_BAD_ARG_ERR \retdesc Bad input argument \endcode +* \retcode #TO_ERRROR \retdesc Error occurred in CFE_SB_SubscribeEx \endcode +* \endreturns +* +* \see +* #TO_AddTblEntryCmd +* #TO_ManageTableCmd +* #TO_SubscribeAllMsgs +*******************************************************************************/ +int32 TO_SubscribeMsg(TO_TableEntry_t *pEntry); + +/******************************************************************************/ +/** \brief Unsubscribe route pipes to all config table messages +* +* \par Description/Algorithm +* All pipes corresponding to existing routes will unsubscribe to all +* messages according to configuration table. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pConfigTable The Config Table to use +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful \endcode +* \retcode #TO_BAD_ARG_ERR \retdesc Bad input argument \endcode +* \retcode #TO_ERRROR \retdesc Error occurred in CFE_SB_Unsubscribe \endcode +* \endreturns +* +* \see +* #TO_UnsubscribeMsg +*******************************************************************************/ +int32 TO_UnsubscribeAllMsgs(TO_ConfigTable_t *pConfigTable); + +/******************************************************************************/ +/** \brief Unsubscribe route pipes to specified message +* +* \par Description/Algorithm +* All pipes corresponding to enabled routes will unsubscribe to message +* according to configuration table. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pEntry The Table entry of the message ID to unsubscribe +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful \endcode +* \retcode #TO_BAD_ARG_ERR \retdesc Bad input argument \endcode +* \retcode #TO_ERRROR \retdesc Error occurred in CFE_SB_Unsubscribe \endcode +* \endreturns +* +* \see +* #TO_RemoveTblEntryCmd +* #TO_ManageTableCmd +* #TO_UnsubscribeAllMsgs +*******************************************************************************/ +int32 TO_UnsubscribeMsg(TO_TableEntry_t *pEntry); + + +/******************************************************************************* +** Required Custom Functions (defined in to_custom.c) +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Custom Initialization +* +* \par Description/Algorithm +* This function is mainly responsible to initialize the transport +* protocol(s). It also configures the criticalMid array, routes, pipe +* names and CF channel semaphore names. +* +* \par Assumptions, External Events, and Notes: +* - Configuration macros defined in to_platform_cfg.h should be used when +* configuring the transport protocol(s). +* - The criticalMid array is used to ensure that these MID are always +* present in the table. +* - Any existing route in implementation must has isExist set to 1. +* - Any CF channels used should have it's cfCntSemName set, and have +* the corresponding route sCfChnlIdx set. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* +* \returns +* \retcode #TO_SUCCESS \retdesc Succesful \endcode +* \retcode #TO_BAD_ARG_ERR \retdesc Bad input argument \endcode +* \retcode #TO_ERROR \retdesc Initialization Error \endcode +* +* \see +* #TO_AppInit +* #TO_ValidateTable +*******************************************************************************/ +int32 TO_CustomInit(void); + +/******************************************************************************/ +/** \brief Process of custom app commands +* +* \par Description/Algorithm +* This function is responsible to process any custom app commands. Make +* use of same pattern as in TO_ProcessNewAppCmds, with a switch case on +* the received command code of the message. This function is called on +* any user defined non-generic commands from TO_ProcessNewAppCmds. Return +* TO_ERROR if the command code is not recognized. +* +* \par Assumptions, External Events, and Notes: +* - This function is called in response to the TO_APP_CMD_MID, called +* from the TO_ProcessNewAppCmds function, on a custom command code. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* \param[in] pCmdMsg The pointer to the (CCSDS) app command message. +* +* \returns +* \retcode #TO_SUCCESS \retdesc Success \endcode +* \retcode #TO_ERROR \retdesc Bad Command code \endcode +* +* \see +* #TO_ProcessNewAppCmds +* #TO_VerifyCmdLength +* #CFE_SB_GetCmdCode +*******************************************************************************/ +int32 TO_CustomAppCmds(CFE_SB_MsgPtr_t pCmdMsg); + + +/******************************************************************************/ +/** \brief Start a new frame +* +* \par Description/Algorithm +* This function may be used to prepare / start a new frame before +* adding individual packets. +* +* \par Assumptions, External Events, and Notes: +* - This function is only useful if multi-packet framing is performed +* - If an error occurs, function is responsible for issuing event. +* - Refer to the multi_tf example for an example using TM_SDLP library. +* - Method only required if TO_FRAMING_ENABLED macro is defined +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* \param[in] usRouteId The current Route ID to use +* +* \returns +* \retcode #TO_SUCCESS \retdesc Success \endcode +* \retcode #TO_ERROR \retdesc Error occured \endcode +* +* \see +* #TO_ProcessNewData +*******************************************************************************/ +int32 TO_CustomFrameStart(uint16 usRouteId); + + +/******************************************************************************/ +/** \brief Complete and send frame +* +* \par Description/Algorithm +* This function may be used to complete a frame and send over I/O device. +* Specific implementation is user specific, but may include operations +* such as filling frame with empty data, setting frame headers before +* sending, and sending over appropriate transport device. +* +* \par Assumptions, External Events, and Notes: +* - This function is only useful if multi-packet framing is performed +* - If an error occurs, function is responsible for issuing event. +* - Refer to the multi_tf example for an example using TM_SDLP library. +* - Method only required if TO_FRAMING_ENABLED macro is defined. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* \param[in] usRouteId The current Route ID to use +* \param[in] iInStatus Status from previous call +* +* \returns +* \retcode #TO_SUCCESS \retdesc Success \endcode +* \retcode #TO_ERROR \retdesc Error occured \endcode +* +* \see +* #TO_ProcessNewData +*******************************************************************************/ +int32 TO_CustomFrameSend(uint16 usRouteId, int32 iInStatus); + + +/******************************************************************************/ +/** \brief Custom Process Data +* +* \par Description/Algorithm +* This function is responsible to process all outgoing telemetry +* receveived over the telemetry pipe. The custom implementation should +* follow this general pattern: +* 1. Look at the table entry routeMask and perform what follows according +* to the route. +* 2. Perform any format change for outgoing telemetry. Use local buffer if +* required. +* 3. Call any I/O data link protocol services for packet framing +* 4. Send message over appropriate transport protocol (if applicable) +* +* \par Assumptions, External Events, and Notes: +* - This function is called by TO_ProcessNewData. +* - The state (enabled/disable) of the table entry is verified as enabled +* in TO_ProcessNewData. +* - Make use of the routeMask as a bit Mask (eg. routeMask & 0x01) +* - Refer to IO_LIB for available protocols. +* - If Framing is enabled, this function is responsible for adding +* individual CFS packets to the frame, before the full frame is sent +* over TO_CustomFrameSend. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* \param[in] pCmdMsg The pointer to the (CCSDS) app command message. +* \param[in] size The size of the message +* \param[in] tblIdx The table index associated with this message +* \param[in] usRouteId The current Route ID to use +* +* \returns +* \retcode #TO_SUCCESS \retdesc Success \endcode +* \retcode #TO_ERROR \retdesc Error on send \endcode +* +* \see +* #TO_ProcessNewData +* #TO_CustomFrameSend +*******************************************************************************/ +int32 TO_CustomProcessData(CFE_SB_MsgPtr_t pTlmMsg, int32 size, int32 tblIdx, + uint16 usRouteId); + +/******************************************************************************/ +/** \brief Custom Cleanup +* +* \par Description/Algorithm +* This function will close any transport protocols (if required) +* in response to exiting the application. +* +* \par Assumptions, External Events, and Notes: +* - This function is called from TO_CleanupCallback. +* +* \param[in,out] g_TO_CustomData TO Global Custom Data +* +* \returns None +* +* \see +* #TO_AppMain +* #TO_CleanupCallback +*******************************************************************************/ +void TO_CustomCleanup(void); + +/******************************************************************************/ +/** \brief Enable Output Command Response +* +* \par Description/Algorithm +* This function extends the TO_EnableOutputCmd function in order to +* perform any necessary transport protocol configurations to enable +* specific routes based on input command. +* - The function should configure transport protocols based on +* routes to enable. +* - Call TO_SetRouteAsConfigured for each route ID configured. +* - Return the routeMask of newly configured routes. +* +* \par Assumptions, External Events, and Notes: +* - This function is called from TO_EnableOutputCmd +* - TO_ValidateRouteMask may be called on input routeMask. +* - TO_SetRouteAsConfigured must be called on newly configured routes. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* \param[in] pCmdMsg The pointer to the (CCSDS) command message. +* +* \returns +* A positive value is interpreted as route mask to enable +* \retcode #TO_SUCCESS \retdesc Success \endcode +* \retcode #TO_ERROR \retdesc Error Occured \endcode +* +* \see +* #TO_EnableOutputCmd +* #TO_CustomDisableOutputCmd +* #TO_ValidateRouteMask +* #TO_SetRouteAsConfigured +*******************************************************************************/ +int32 TO_CustomEnableOutputCmd(CFE_SB_MsgPtr_t pCmdMsg); + +/******************************************************************************/ +/** \brief Disable Output Command Response +* +* \par Description/Algorithm +* This function extends the TO_DisableOutputCmd function in order to +* perform any necessary desired actions to disable output. +* The function should set usOutputEnabled to 0 if all output is to be +* disabled. +* - If command is used to disable specific routes, function may close +* transport protocols and set routes as unconfigured with +* TO_SetRouteAsUnconfigured. The route would then need to be +* reconfigured through EnableOutputCmd. Otherwise it could +* leave them as configured and return a routeMask to only disable them. +* - Return a routeMask for routes that must be disabled. +* +* \par Assumptions, External Events, and Notes: +* - This function is called from TO_DisableOutputCmd +* - Implementation may choose to ignore command, by returning TO_ERROR. +* Issue appropriate event. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in,out] g_TO_CustomData TO Global Custom Data +* \param[in] pCmdMsg The pointer to the (CCSDS) command message. +* +* \returns +* A positive value is interpreted as route mask to disable +* \retcode #TO_SUCCESS \retdesc Success \endcode +* \retcode #TO_ERROR \retdesc Error Occured \endcode +* +* \see +* #TO_DisableOutputCmd +* #TO_CustomEnabledOutputCmd +* #TO_SetRouteAsUnconfigured +*******************************************************************************/ +int32 TO_CustomDisableOutputCmd(CFE_SB_MsgPtr_t); + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_APP_H_ */ + +/*============================================================================== +** End of file to_app.h +**============================================================================*/ diff --git a/fsw/src/to_cmds.c b/fsw/src/to_cmds.c new file mode 100644 index 0000000..0bf2a6e --- /dev/null +++ b/fsw/src/to_cmds.c @@ -0,0 +1,1252 @@ +/******************************************************************************/ +/** \file to_cmds.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions of command responses +* +* \par +* This file defines command responses for TO functions. +* +* \par Cmd Functions Defined: +* - TO_NoopCmd - No-operation command. Returns version number. +* - TO_ResetCmd - Reset Housekeeping counters. +* - TO_EnableOutputCmd - Enable output with call to custom fnct. +* - TO_DisableOutputCmd - Disable output with call to custom fnct. +* - TO_PauseOutputCmd - Pause output (set outputActive = 0) +* - TO_ActivateRoutesCmd - Activate routes (set usIsEnabled = 1) +* - TO_DeactivateRoutesCmd - Deactivate routes (set usIsEnabled = 0) +* - TO_ResumeOutputCmd - Resume output (set outputActive = 1) +* - TO_AddTblEntryCmd - Add a new entry to config table. +* - TO_RemoveTblEntryCmd - Remove a table entry by MID. +* - TO_EnableTblEntryCmd - Enable a table entry by MID. +* - TO_DisableTblEntryCmd - Disable a table entry by MID. +* - TO_EnableGroupCmd - Enable table entries by Group. +* - TO_DisableGroupCmd - Disable table entries by Group. +* - TO_EnableAllCmd - Enable all table entries. +* - TO_DisableAllCmd - Disable all table entries. +* - TO_SetRouteByMidCmd - Set table entry RouteMask by MID. +* - TO_SetRouteByGroupCmd - Set table entries RouteMask by Group. +* - TO_ManageTableCmd - Manage Table cmd (sent by CFE_TBL) +* - TO_SetRoutePeriodCmd - Set routes' wakeup period. +* - TO_SetWakeupTimeoutcmd - Set the TO Wakeup Timeout. +* +* \par Custom Functions Required: +* - TO_CustomEnableOutputCmd - Custom response to enable output cmd. +* - TO_CustomDisableOutputCmd - Custom response to disable output cmd. +* +* \par Limitations, Assumptions, External Events, and Notes: +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ +#include "to_app.h" +#include "to_cmds.h" +#include "cfe_tbl_msg.h" + +extern TO_AppData_t g_TO_AppData; + +/* Optional Custom Commands. + * Call these through the TO_CustomAppCmds function in to_custom.c if desired. + * Add an extern prototype definition in the to_custom.c file. */ +void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Noop Command (TO_NOOP_CC) +*******************************************************************************/ +void TO_NoopCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_NoArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, + CFE_EVS_INFORMATION, + "No-op command. Version %d.%d.%d.%d", + TO_MAJOR_VERSION, + TO_MINOR_VERSION, + TO_REVISION, + TO_MISSION_REV); + } +} + + +/******************************************************************************/ +/** \brief Reset Command (TO_RESET_CC) +*******************************************************************************/ +void TO_ResetCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_NoArgCmd_t))) + { + /* Note: the subCnt is not reset. */ + + g_TO_AppData.HkTlm.usCmdCnt = 0; + g_TO_AppData.HkTlm.usCmdErrCnt = 0; + g_TO_AppData.HkTlm.usMsgSubErrCnt = 0; + g_TO_AppData.HkTlm.usTblUpdateCnt = 0; + g_TO_AppData.HkTlm.usTblErrCnt = 0; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd RESET cmd (%d)", TO_RESET_CC); + } +} + + +/******************************************************************************/ +/** \brief Enable Output Command (TO_ENABLE_OUTPUT_CC) +*******************************************************************************/ +void TO_EnableOutputCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + int32 ii = 0; + int32 routeMask = 0; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_EnableOutputCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd ENABLE_OUTPUT cmd (%d)", + TO_ENABLE_OUTPUT_CC); + + /* NOTES: + - The CustomEnableOutputCmd is responsible for doing any + necessary device configuration based on the routeMask. + - The custom layer is also responsible for validating the + routeMask command parameter, if present. + May use TO_ValidateRouteMask utility function. + */ + + /* The custom function respond with the routeMask that it enabled. */ + routeMask = TO_CustomEnableOutputCmd(pCmdMsg); + + if (routeMask > TO_MAX_ROUTE_MASK) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + " Route mask exceeds max route mask." + " ENABLE_OUTPUT Cmd failed."); + } + else if (routeMask >= 0) + { + /* Set all routes by mask as enabled */ + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + if (routeMask & (1 << ii)) + { + if (!g_TO_AppData.routes[ii].usExists || + !g_TO_AppData.routes[ii].usIsConfig) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Attempting to enable route:%u which " + "does not exist or is not configured.", ii); + goto end_of_command; + } + + g_TO_AppData.routes[ii].usIsEnabled = 1; + } + } + + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 1; + + /* Update housekeeping usEnabledRoutes */ + g_TO_AppData.HkTlm.usEnabledRoutes |= routeMask; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "ENABLE OUTPUT CMD Succesful for Routes:0x%04x", + routeMask); + } + else + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + " ENABLE OUTPUT CMD failed."); + } + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Disable Output Command (TO_DISABLE_OUTPUT_CC) +*******************************************************************************/ +void TO_DisableOutputCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + int32 iStatus = TO_SUCCESS; + int32 routeMask = TO_SUCCESS; + int32 ii; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_DisableOutputCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd DISABLE_OUTPUT cmd (%d)", + TO_DISABLE_OUTPUT_CC); + + if (g_TO_AppData.usOutputEnabled == 0) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Output already disabled. " + "DISABLE_OUTPUT CMD ignored."); + goto end_of_command; + } + + /* NOTE: Examples of Custom implementation actions: + - Ignore command + - Disable all output (usOutputEnabled = 0 + - Disable specific routes by returning routeMask */ + iStatus = TO_CustomDisableOutputCmd(pCmdMsg); + + if (iStatus == TO_SUCCESS) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "DISABLE_OUTPUT CMD Succesful."); + } + /* If a positive value is returned, disable specified route mask */ + else if (iStatus > 0) + { + routeMask = iStatus; + + if (routeMask > TO_MAX_ROUTE_MASK) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + " Route mask exceeds max route mask." + " DISABLE_OUTPUT CMD failed."); + goto end_of_command; + } + + /* Set all routes by mask as disabled */ + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + if (routeMask & (1 << ii)) + { + g_TO_AppData.routes[ii].usIsEnabled = 0; + } + } + + g_TO_AppData.HkTlm.usEnabledRoutes &= ~routeMask; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "DISABLE_OUTPUT CMD Successful for Routes:0x%04x", + routeMask); + } + else + { + /* Error message issued by TO_CustomDisableOutputCmd() */ + /* Increment error counter if appropriate within Custom function. */ + } + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Activate Routes Command (TO_ACTIVATE_ROUTES_CC) +*******************************************************************************/ +void TO_ActivateRoutesCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + uint16 ii; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_RouteMaskArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd ACTIVATE_ROUTES cmd (%d)", + TO_ACTIVATE_ROUTES_CC); + + TO_RouteMaskArgCmd_t *cmd = (TO_RouteMaskArgCmd_t *) pCmdMsg; + + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + if (cmd->usRouteMask & (1 << ii)) + { + if (g_TO_AppData.routes[ii].usIsConfig == 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Route ID:%u is not configured and so can't be enabled. " + "ACTIVATE ROUTES with route mask:0x%04x failed.", + ii, cmd->usRouteMask); + goto end_of_command; + } + + if (g_TO_AppData.routes[ii].usIsEnabled == 1) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Route ID:%u is already enabled.", ii); + } + + g_TO_AppData.routes[ii].usIsEnabled = 1; + } + } + + g_TO_AppData.HkTlm.usEnabledRoutes |= cmd->usRouteMask; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Routes 0x%04x succesfully enabled.", cmd->usRouteMask); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Deactivate Routes Command (TO_DEACTIVATE_ROUTES_CC) +*******************************************************************************/ +void TO_DeactivateRoutesCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + uint16 ii; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_RouteMaskArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd DEACTIVATE_ROUTES cmd (%d)", + TO_DEACTIVATE_ROUTES_CC); + + TO_RouteMaskArgCmd_t *cmd = (TO_RouteMaskArgCmd_t *) pCmdMsg; + + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + if (cmd->usRouteMask & (1 << ii)) + { + g_TO_AppData.routes[ii].usIsEnabled = 0; + } + } + + g_TO_AppData.HkTlm.usEnabledRoutes &= ~cmd->usRouteMask; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Routes 0x%04x succesfully disabled.", cmd->usRouteMask); + } + + return; +} + + +/******************************************************************************/ +/** \brief Pause Output Command (TO_PAUSE_OUTPUT_CC) +*******************************************************************************/ +void TO_PauseOutputCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_NoArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd PAUSE_OUTPUT cmd (%d)", + TO_PAUSE_OUTPUT_CC); + + if (g_TO_AppData.usOutputEnabled == 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Output is disabled - can't pause. " + "PAUSE_OUTPUT CMD failed."); + goto end_of_command; + } + + g_TO_AppData.usOutputActive = 0; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "PAUSE_OUTPUT CMD Succesful."); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Resume Output Command (TO_RESUME_OUTPUT_CC) +*******************************************************************************/ +void TO_ResumeOutputCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_NoArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd RESUME_OUTPUT cmd (%d)", + TO_RESUME_OUTPUT_CC); + + if (g_TO_AppData.usOutputEnabled == 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Output is disabled - " + "send enable instead of resume. " + "RESUME_OUTPUT CMD failed."); + goto end_of_command; + } + + g_TO_AppData.usOutputActive = 1; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "RESUME_OUTPUT CMD Succesful."); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Add a Table Entry (TO_ADD_TBL_ENTRY_CC) +*******************************************************************************/ +void TO_AddTblEntryCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_AddTblEntryCmd_t * pCmd = (TO_AddTblEntryCmd_t *) pCmdMsg; + TO_TableEntry_t *pEntry = NULL; + int32 index = 0; + int32 exists = 0; + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_AddTblEntryCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd ADD_TBL_ENTRY cmd (%d)", + TO_ADD_TBL_ENTRY_CC); + + /* Note that the RouteMask is not validated here as table entries + are permitted to have routeMasks which include non-existing routes. + Those routes will simply be ignored. */ + + /* Validate MID */ + if (pCmd->usMsgId == TO_REMOVED_ENTRY || + pCmd->usMsgId == TO_UNUSED_ENTRY) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid MSG ID: 0x%04x." + " TO_ADD_TBL_ENTRY CMD failed.", + pCmd->usMsgId); + goto end_of_command; + } + + index = TO_FindEmptyTableIndex(); + + if (index == TO_TBL_FULL_ERR) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "No empty table entries." + " TO_ADD_TBL_ENTRY CMD failed."); + } + else + { + /* Verify table for duplicate usMsgIds */ + exists = TO_FindTableIndex(g_TO_AppData.pConfigTable, pCmd->usMsgId); + + if (exists != TO_NO_MATCH) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Pre-existing table entry with MID:0x%04x" + " TO_ADD_TBL_ENTRY CMD failed.", pCmd->usMsgId); + goto end_of_command; + } + + pEntry = &g_TO_AppData.pConfigTable->entries[index]; + pEntry->usMsgId = pCmd->usMsgId; + pEntry->qos = pCmd->qos; + pEntry->usMsgLimit = pCmd->usMsgLimit; + pEntry->usRouteMask = pCmd->usRouteMask; + + /* Subscribe tlm pipes to new msgid according to routeMask */ + iStatus = TO_SubscribeMsg(pEntry); + if (iStatus != CFE_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "TO_ADD_TBL_ENTRY CMD failed.", pCmd->usMsgId); + /* Reset entry */ + pEntry->usMsgId = 0; + pEntry->qos.Priority = 0; + pEntry->qos.Reliability = 0; + pEntry->usMsgLimit = 0; + pEntry->usRouteMask = 0; + + goto end_of_command; + } + + /* Set table entry. */ + pEntry->uiGroupData = pCmd->uiGroupData; + pEntry->usFlag = pCmd->usFlag; + pEntry->usState = pCmd->usState; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Succesfully added TBL entry. " + "Index:%d, MsgID:0x%04x, RouteMask:0x%04x, " + "usMsgLimit:%d, uiGroupData:0x%08x, initState:%u", + index, pEntry->usMsgId, pEntry->usRouteMask, + pEntry->usMsgLimit, pEntry->uiGroupData, + pEntry->usState); + } + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Remove a Table Entry by MID (TO_REMOVE_TBL_ENTRY_CC) +*******************************************************************************/ +void TO_RemoveTblEntryCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_MidArgCmd_t * pCmd = (TO_MidArgCmd_t *) pCmdMsg; + TO_TableEntry_t *pEntry = NULL; + int32 index = 0; + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_MidArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd REMOVE_TBL_ENTRY cmd (%d)", + TO_REMOVE_TBL_ENTRY_CC); + + /* Validate MID */ + if (pCmd->usMsgId == TO_REMOVED_ENTRY || + pCmd->usMsgId == TO_UNUSED_ENTRY) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid MSG ID: 0x%04x." + " TO_REMOVE_TBL_ENTRY CMD failed.", + pCmd->usMsgId); + goto end_of_command; + } + + /* Find the Table entry corresponding to MID */ + index = TO_FindTableIndex(g_TO_AppData.pConfigTable, pCmd->usMsgId); + + if (index < 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "MSG ID not found." + " TO_REMOVE_TBL_ENTRY CMD failed."); + goto end_of_command; + } + + pEntry = &g_TO_AppData.pConfigTable->entries[index]; + + /* Unsubscribe the MID from the Tlm Pipes */ + iStatus = TO_UnsubscribeMsg(pEntry); + if (iStatus != TO_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "TO_REMOVE_TBL_ENTRY CMD failed."); + goto end_of_command; + } + + /* Set the table entry as removed. */ + pEntry->usMsgId = TO_REMOVED_ENTRY; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Succesfully Removed TBL entry. " + "Index:%d, MsgId:0x%04x", + index, pCmd->usMsgId); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Enable a Table Entry by MID (TO_ENABLE_TBL_ENTRY_CC) +*******************************************************************************/ +void TO_EnableTblEntryCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_MidArgCmd_t * pCmd = (TO_MidArgCmd_t *) pCmdMsg; + TO_TableEntry_t *pEntry = NULL; + int32 index = 0; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_MidArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd ENABLE_TBL_ENTRY cmd (%d)", + TO_ENABLE_TBL_ENTRY_CC); + + /* Validate MID */ + if (pCmd->usMsgId == TO_REMOVED_ENTRY || + pCmd->usMsgId == TO_UNUSED_ENTRY) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid MSG ID: 0x%04x." + " TO_ENABLE_TBL_ENTRY CMD failed.", + pCmd->usMsgId); + goto end_of_command; + } + + index = TO_FindTableIndex(g_TO_AppData.pConfigTable, pCmd->usMsgId); + + if (index < 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "MSG ID not found." + " TO_ENABLE_TBL_ENTRY CMD failed."); + goto end_of_command; + } + + /* Set the table entry as enabled. */ + pEntry = &g_TO_AppData.pConfigTable->entries[index]; + + if (pEntry->usState == 1) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Table Entry idx:%u for MID:0x%04x already " + "enabled. TO_ENABLE_TBL_ENTRY CMD ignored.", + index, pCmd->usMsgId); + goto end_of_command; + } + + pEntry->usState = 1; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Succesfully Enabled TBL entry:%u, MID:0x%04x", + index, pCmd->usMsgId); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Disable a Table Entry by MID (TO_DISABLE_TBL_ENTRY_CC) +*******************************************************************************/ +void TO_DisableTblEntryCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_MidArgCmd_t * pCmd = (TO_MidArgCmd_t *) pCmdMsg; + TO_TableEntry_t * pEntry = NULL; + int32 index = 0; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_MidArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd DISABLE_TBL_ENTRY cmd (%d)", + TO_DISABLE_TBL_ENTRY_CC); + + /* Validate MID */ + if (pCmd->usMsgId == TO_REMOVED_ENTRY || + pCmd->usMsgId == TO_UNUSED_ENTRY) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid MSG ID: 0x%04x." + " TO_DISABLE_TBL_ENTRY CMD failed.", + pCmd->usMsgId); + goto end_of_command; + } + + index = TO_FindTableIndex(g_TO_AppData.pConfigTable, pCmd->usMsgId); + + if (index < 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "MSG ID not found." + " TO_DISABLE_TBL_ENTRY CMD failed."); + goto end_of_command; + } + + /* Set the table entry as enabled. */ + pEntry = &g_TO_AppData.pConfigTable->entries[index]; + + if (pEntry->usState == 0) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Table Entry idx:%u for MID:0x%04x already " + "disabled. TO_DISABLE_TBL_ENTRY CMD ignored.", + index, pCmd->usMsgId); + goto end_of_command; + } + pEntry->usState = 0; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Succesfully Disabled TBL entry:%u, MID:0x%04x", + index, pCmd->usMsgId); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Enable Table Entries by Group (TO_ENABLE_GROUP_CC) +*******************************************************************************/ +void TO_EnableGroupCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_GroupArgCmd_t * pCmd = (TO_GroupArgCmd_t *) pCmdMsg; + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_GroupArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd ENABLE_GROUP cmd (%d)", + TO_ENABLE_GROUP_CC); + + iStatus = TO_SetStateByGroup(pCmd->uiGroupData, 1); + + if (iStatus == TO_BAD_ARG_ERR) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Bad uiGroupData argument." + "ENABLE_GROUP CMD failed."); + } + else if (iStatus == TO_NO_MATCH) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "No group match found. " + "ENABLE_GROUP CMD failed."); + } + else if (iStatus == TO_NO_EFFECT) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Group already enabled. " + "ENABLE_GROUP CMD ignored."); + } + else if (iStatus == TO_SUCCESS) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "ENABLE GROUP CMD Successful. GroupData:0x%08x", + pCmd->uiGroupData); + } + } +} + + +/******************************************************************************/ +/** \brief Disable Table Entries by Group (TO_DISABLE_GROUP_CC) +*******************************************************************************/ +void TO_DisableGroupCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_GroupArgCmd_t * pCmd = (TO_GroupArgCmd_t *) pCmdMsg; + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_GroupArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd DISABLE_GROUP cmd (%d)", + TO_DISABLE_GROUP_CC); + + iStatus = TO_SetStateByGroup(pCmd->uiGroupData, 0); + + if (iStatus == TO_BAD_ARG_ERR) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Bad uiGroupData argument." + "DISABLE_GROUP CMD Ignored."); + } + else if (iStatus == TO_NO_MATCH) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "No group match found." + "DISABLE_GROUP CMD Ignored."); + } + else if (iStatus == TO_NO_EFFECT) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Group already disabled." + "DISABLE_GROUP CMD Ignored."); + } + else if (iStatus == TO_SUCCESS) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "DISABLE GROUP CMD Successful. GroupData:0x%08x", + pCmd->uiGroupData); + } + } +} + + +/******************************************************************************/ +/** \brief Enable All Used Table Entries (TO_ENABLE_ALL_CC) +*******************************************************************************/ +void TO_EnableAllCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_NoArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd ENABLE ALL cmd (%d)", + TO_ENABLE_ALL_CC); + + iStatus = TO_SetAllEntryState(1); + + if (iStatus == TO_NO_EFFECT) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "All table entries already enabled. " + "ENABLE_ALL CMD Ignored."); + } + else + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "All Entries enabled."); + } + } +} + + +/******************************************************************************/ +/** \brief Disable All Used Table Entries (TO_DISABLE_ALL_CC) +*******************************************************************************/ +void TO_DisableAllCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_NoArgCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd DISABLE ALL cmd (%d)", + TO_DISABLE_ALL_CC); + + iStatus = TO_SetAllEntryState(0); + + if (iStatus == TO_NO_EFFECT) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "All table entries already disabled. " + "DISABLE_ALL CMD Ignored."); + } + else + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "All Entries disabled."); + } + } +} + + +/******************************************************************************/ +/** \brief Set table entry routeMask by MID (TO_SET_ROUTE_BY_MID_CC) +*******************************************************************************/ +void TO_SetRouteByMidCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_SetRouteByMidCmd_t * pCmd = (TO_SetRouteByMidCmd_t *) pCmdMsg; + TO_TableEntry_t * pEntry = NULL; + int32 index = 0; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_SetRouteByMidCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd SET_ROUTE_BY_MID cmd (%d)", + TO_SET_ROUTE_BY_MID_CC); + + /* Note that the RouteMask is not validated here as table entries + are permitted to have routeMasks which include non-existing routes. + Those routes will simply be ignored. */ + + /* Validate MID */ + if (pCmd->usMsgId == TO_REMOVED_ENTRY || + pCmd->usMsgId == TO_UNUSED_ENTRY) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid MSG ID: 0x%04x." + " TO_SET_ROUTE_BY_MID CMD failed.", + pCmd->usMsgId); + goto end_of_command; + } + + index = TO_FindTableIndex(g_TO_AppData.pConfigTable, pCmd->usMsgId); + + if (index < 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "MSG ID not found." + " TO_SET_ROUTE_BY_MID CMD failed."); + goto end_of_command; + } + + /* Set the table entry route */ + pEntry = &g_TO_AppData.pConfigTable->entries[index]; + pEntry->usRouteMask = pCmd->usRouteMask; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Succesfully set usRouteMask=0x%04x for entry:%u, " + "MID:0x%04x", + pCmd->usRouteMask, index, pCmd->usMsgId); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Set table entry routeMask by Group (TO_SET_ROUTE_BY_GROUP_CC) +*******************************************************************************/ +void TO_SetRouteByGroupCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_SetRouteByGroupCmd_t * pCmd = (TO_SetRouteByGroupCmd_t *) pCmdMsg; + int32 iStatus = TO_SUCCESS; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_SetRouteByGroupCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd SET_ROUTE_BY_GROUP cmd (%d)", + TO_SET_ROUTE_BY_GROUP_CC); + + /* Note that the RouteMask is not validated here as table entries + are permitted to have routeMasks which include non-existing routes. + Those routes will simply be ignored. */ + + iStatus = TO_SetRouteByGroup(pCmd->uiGroupData, pCmd->usRouteMask); + + if (iStatus == TO_BAD_ARG_ERR) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "SET_ROUTE_BY_GROUP CMD - Bad uiGroupData arg." + " CMD Ignored."); + } + else if (iStatus == TO_NO_MATCH) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "SET_ROUTE_BY_GROUP CMD - No group match found." + " CMD Ignored."); + } + else if (iStatus == TO_NO_EFFECT) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Route already set for group. " + "SET_ROUTE_BY_GROUP CMD ignored."); + } + else if (iStatus == TO_SUCCESS) + { + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "SET_ROUTE_BY_GROUP CMD Successful. " + "usRouteMask=0x%04x, uGroupData=0x%08x", + pCmd->usRouteMask, pCmd->uiGroupData); + } + } + + return; +} + + +/******************************************************************************/ +/** \brief Manage the Table - Hook for TBL Services (TO_MANAGE_TABLE_CC) +*******************************************************************************/ +void TO_ManageTableCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + int32 iStatus = CFE_SUCCESS; + TO_ConfigTable_t *pTable = NULL; + TO_ConfigTable_t oldTable; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(CFE_TBL_NotifyCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd MANAGE TABLE CMD (%d)", + TO_MANAGE_TABLE_CC); + + /* Temporarily save the previous table */ + memcpy((void *) &oldTable, (void *) g_TO_AppData.pConfigTable, + sizeof(TO_ConfigTable_t)); + + /* Release the table pointer so that CFE can update it. */ + iStatus = CFE_TBL_ReleaseAddress(g_TO_AppData.tableHandle); + if (iStatus != CFE_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + g_TO_AppData.HkTlm.usTblErrCnt++; + CFE_EVS_SendEvent(TO_TBL_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_ReleaseAddress() returned error 0x%08x. " + "TO_ManageTable failed.", + iStatus); + goto end_of_command; + } + + /* This is where the table gets updated. */ + iStatus = CFE_TBL_Manage(g_TO_AppData.tableHandle); + if (iStatus != CFE_SUCCESS && iStatus != CFE_TBL_INFO_UPDATED) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + g_TO_AppData.HkTlm.usTblErrCnt++; + CFE_EVS_SendEvent(TO_TBL_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_Manage() returned error 0x%08x. TO_ManageTable failed.", + iStatus); + + /* Re-acquire table address. */ + CFE_TBL_GetAddress ((void **) &pTable, g_TO_AppData.tableHandle); + g_TO_AppData.pConfigTable = pTable; + + goto end_of_command; + } + + iStatus = CFE_TBL_GetAddress ((void **) &pTable, + g_TO_AppData.tableHandle); + /* Status should be CFE_TBL_INFO_UPDATED because we loaded it above */ + if (iStatus == CFE_TBL_INFO_UPDATED) + { + /* Store the new table pointer */ + g_TO_AppData.pConfigTable = pTable; + + /* Unsubscribe all messages from old table */ + iStatus = TO_UnsubscribeAllMsgs(&oldTable); + if (iStatus != CFE_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + g_TO_AppData.HkTlm.usTblErrCnt++; + CFE_EVS_SendEvent(TO_PIPE_ERR_EID, CFE_EVS_ERROR, + "Unsubscription of messages failed. " + "Reverting back table. TO_ManageTable failed."); + memcpy((void *) pTable, (void *) &oldTable, + sizeof(TO_ConfigTable_t)); + iStatus = TO_SubscribeAllMsgs(); + goto end_of_command; + } + + /* Subscribe to all messages in new table */ + iStatus = TO_SubscribeAllMsgs(); + if (iStatus != CFE_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + g_TO_AppData.HkTlm.usTblErrCnt++; + CFE_EVS_SendEvent(TO_PIPE_ERR_EID, CFE_EVS_ERROR, + "Subscription of messages failed. " + "Reverting back table. TO_ManageTable failed."); + memcpy((void *) pTable, (void *) &oldTable, + sizeof(TO_ConfigTable_t)); + iStatus = TO_SubscribeAllMsgs(); + goto end_of_command; + } + + g_TO_AppData.HkTlm.usTblUpdateCnt++; + CFE_EVS_SendEvent(TO_TBL_INF_EID, CFE_EVS_INFORMATION, + "ConfigTable updated succesfully. "); + } + else if (iStatus == CFE_SUCCESS) + { + /* Store the pointer */ + g_TO_AppData.pConfigTable = pTable; + + CFE_EVS_SendEvent(TO_TBL_INF_EID, CFE_EVS_INFORMATION, + "ConfigTable did not change."); + } + else + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + g_TO_AppData.HkTlm.usTblErrCnt++; + CFE_EVS_SendEvent(TO_TBL_ERR_EID, CFE_EVS_ERROR, + "CFE_TBL_GetAddress() returned error 0x%08x. " + "TO_ManageTable failed.", + iStatus); + } + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Set the route period by RouteMask (TO_SET_ROUTE_PERIOD_CC) +*******************************************************************************/ +void TO_SetRoutePeriodCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_SetRoutePeriodCmd_t * pCmd = (TO_SetRoutePeriodCmd_t *) pCmdMsg; + uint16 ii; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_SetRoutePeriodCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd SET_ROUTE_PERIOD cmd (%d)", + TO_SET_ROUTE_PERIOD_CC); + + /* Validate RouteMask */ + if (TO_ValidateRouteMask(pCmd->usRouteMask) != TO_SUCCESS) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid RouteMask: 0x%04x. " + "RouteMask includes non-existing routes. " + "TO_SET_ROUTE_PERIOD CMD failed.", + pCmd->usRouteMask); + goto end_of_command; + } + + /* Validate Wake Period value */ + if (pCmd->usWakePeriod > TO_MAX_WAKEUP_COUNT) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid WakePeriod:%d. " + "Period must be <= TO_MAX_WAKEUP_COUNT:%u. " + "TO_SET_ROUTE_PERIOD CMD failed.", + pCmd->usWakePeriod, TO_MAX_WAKEUP_COUNT); + goto end_of_command; + } + + if (TO_MAX_WAKEUP_COUNT % pCmd->usWakePeriod != 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Received invalid WakePeriod:%d. " + "Wake Period must be a factor of %u. " + "TO_SET_ROUTE_PERIOD CMD failed.", + pCmd->usWakePeriod, TO_MAX_WAKEUP_COUNT); + goto end_of_command; + } + + /* Go over every route and set route period. */ + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + if (pCmd->usRouteMask & (1<usWakePeriod; + } + } + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "SET_ROUTE_PERIOD CMD Successful. " + "usRouteMask=0x%04x, usWakePeriod=%d", + pCmd->usRouteMask, pCmd->usWakePeriod); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/** \brief Set Wakeup Timeout (TO_SET_WAKEUP_TIMEOUT_CC) +*******************************************************************************/ +void TO_SetWakeupTimeoutCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_SetWakeupTimeoutCmd_t * pCmd = (TO_SetWakeupTimeoutCmd_t *) pCmdMsg; + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(TO_SetWakeupTimeoutCmd_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Recvd SET_WAKEUP_TIMEOUT cmd (%d)", + TO_SET_ROUTE_PERIOD_CC); + + /* Validate input timeout value */ + if (pCmd->uiWakeupTimeout != CFE_SB_PEND_FOREVER && + pCmd->uiWakeupTimeout < TO_MIN_WAKEUP_TIMEOUT) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + CFE_EVS_SendEvent(TO_CMD_ERR_EID, CFE_EVS_ERROR, + "Cmd Timeout value %d must be >= to " + "TO_MIN_WAKEUP_TIMEOUT: %d. " + "TO_SET_WAKEUP_TIMEOUT CMD failed.", + pCmd->uiWakeupTimeout, TO_MIN_WAKEUP_TIMEOUT); + goto end_of_command; + } + + g_TO_AppData.uiWakeupTimeout = pCmd->uiWakeupTimeout; + + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "SET_WAKEUP_TIMEOUT CMD Successful. " + "wakeup Timeout:%d (ms).", pCmd->uiWakeupTimeout); + } + +end_of_command: + return; +} + + +/******************************************************************************/ +/* Optional Commands. Include these commands in TO_CustomAppCmds() */ +/******************************************************************************/ + +/******************************************************************************/ +/** \brief Convenience Command: Send Test Data Packet + * + * \par + * This is a legacy command that was present in to_lab application, + * useful for determining byte packing / order on platform with respect + * to ground displays. Should only be used during development. +*******************************************************************************/ +void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_TypeDefPacket_t testPacket; + int16 i; + char string_variable[10] = "ABCDEFGHIJ"; + + + if (TO_VerifyCmdLength(pCmdMsg, sizeof(CFE_SB_CmdHdr_t))) + { + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "TO - Recvd SEND_DATA_TYPE cmd (%d)", + TO_SEND_DATA_TYPE_CC); + + /* initialize data types packet */ + CFE_SB_InitMsg(&testPacket, + TO_DATA_TYPE_MID, + sizeof(testPacket), TRUE); + + CFE_SB_TimeStampMsg((CFE_SB_MsgPtr_t) &testPacket); + + /* initialize the packet data */ + testPacket.synch = 0x6969; + + testPacket.bit1 = 1; + testPacket.bit2 = 0; + testPacket.bit34 = 2; + testPacket.bit56 = 3; + testPacket.bit78 = 1; + testPacket.nibble1 = 0xA; + testPacket.nibble2 = 0x4; + + testPacket.bl1 = FALSE; + testPacket.bl2 = TRUE; + testPacket.b1 = 16; + testPacket.b2 = 127; + testPacket.b3 = 0x7F; + testPacket.b4 = 0x45; + testPacket.w1 = 0x2468; + testPacket.w2 = 0x7FFF; + testPacket.dw1 = 0x12345678; + testPacket.dw2 = 0x87654321; + testPacket.f1 = 90.01; + testPacket.f2 = .0000045; + testPacket.df1 = 99.9; + testPacket.df2 = .4444; + + for (i=0; i < 10; i++) + { + testPacket.str[i] = string_variable[i]; + } + + CFE_SB_SendMsg((CFE_SB_Msg_t *)&testPacket); + } +} + + +/*============================================================================== +** End of file to_cmds.c +**============================================================================*/ diff --git a/fsw/src/to_cmds.h b/fsw/src/to_cmds.h new file mode 100644 index 0000000..d42f62a --- /dev/null +++ b/fsw/src/to_cmds.h @@ -0,0 +1,484 @@ +/******************************************************************************/ +/** \file to_cmds.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Header file for command responses for TO +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Functions are called from TO_ProcessNewAppCmds in to_app.c +* - Command functions are defined in to_cmds.c +* - Custom functions are defined in to_custom.c +* - Command codes defined in to_msgdefs.h +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2016-05-11 | Allen Brown | Updated comments +*******************************************************************************/ + +#ifndef _TO_CMDS_H_ +#define _TO_CMDS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +** Includes +*******************************************************************************/ +#include "cfe.h" + +/******************************************************************************* +** Command Structure definitions +*******************************************************************************/ +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; +} TO_NoArgCmd_t; + + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_MsgId_t usMsgId; /**< Msg Id parameter */ +} TO_MidArgCmd_t; + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint16 usRouteMask; /**< Route Mask */ +} TO_RouteMaskArgCmd_t; + + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint32 uiGroupData; /**< GroupData for entry selection */ +} TO_GroupArgCmd_t; + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_MsgId_t usMsgId; /**< Message ID (must be unique) */ + CFE_SB_Qos_t qos; /**< Quality of Service flag */ + uint16 usMsgLimit; /**< Max Num. of this Msgs in pipe */ + uint16 usRouteMask; /**< Bitwize Route Mask */ + uint32 uiGroupData; /**< Group data Mask */ + uint16 usFlag; /**< Custom defined flag */ + uint16 usState; /**< Message ID is enabled = 1 */ +} TO_AddTblEntryCmd_t; + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + CFE_SB_MsgId_t usMsgId; /**< MsgId parameter */ + uint16 usRouteMask; /**< RouteMask to set table entry */ +} TO_SetRouteByMidCmd_t; + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint32 uiGroupData; /**< GroupData for entry selection */ + uint16 usRouteMask; /**< RouteMask to set table entries */ + uint16 spare; /**< Padding */ +} TO_SetRouteByGroupCmd_t; + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint16 usRouteMask; /**< RouteMask to set table entries */ + uint16 usWakePeriod; /**< Modulus of TO Wakeup rate */ +} TO_SetRoutePeriodCmd_t; + +typedef struct +{ + uint8 ucCmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint32 uiWakeupTimeout; /**< New wakeup timeout in ms */ +} TO_SetWakeupTimeoutCmd_t; + + +typedef struct +{ + uint8 TlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint16 synch; + + uint16 bit1:1; + uint16 bit2:1; + uint16 bit34:2; + uint16 bit56:2; + uint16 bit78:2; + + uint16 nibble1:4; + uint16 nibble2:4; + + uint8 bl1, bl2; /* boolean */ + + int8 b1, b2, b3, b4; + int16 w1,w2; + + int32 dw1, dw2; + float f1, f2; + double df1, df2; + char str[10]; +} TO_TypeDefPacket_t; + + +/******************************************************************************* +** Application Command Function Declarations (defined in to_cmds.c) +*******************************************************************************/ + +/******************************************************************************/ +/** \brief No-Operations command (TO_NOOP_CC) +* +* \par Description/Algorithm +* Increment command counter and issue event with TO version number. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_NoArgCmd_t +*******************************************************************************/ +void TO_NoopCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Reset Counter command (TO_RESET_CC) +* +* \par Description/Algorithm +* Reset Housekeeping counters, with the exception of usMsgSubCnt. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_NoArgCmd_t +*******************************************************************************/ +void TO_ResetCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Enable Output Command (TO_ENABLE_OUTPUT_CC) +* +* \par Description/Algorithm +* - Call TO_CustomEnableOutputCmd. +* - Set usOutputEnable and usOutputActive to 1. +* - Enable all routes (usIsEnabled = 1) based on returned routeMask. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_EnableOutputCmd_t +* +* \see +* #TO_CustomEnableOutputCmd +*******************************************************************************/ +void TO_EnableOutputCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Disable Output Command (TO_DISABLE_OUTPUT_CC) +* +* \par Description/Algorithm +* - Call TO_CustomDisableOutputCmd. +* - Set usOutputEnable and usOutputActive to 1. +* - Enable all routes (usIsEnabled = 1) based on returned routeMask. +* +* \par Assumptions, External Events, and Notes: +* - Command ignored if usOutputEnabled = 0 +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_DisableOutputCmd_t +*******************************************************************************/ +void TO_DisableOutputCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Activate Routes Command (TO_ACTIVATE_ROUTES_CC) +* +* \par Description/Algorithm +* - Enable routes based on route mask. +* +* \par Assumptions, External Events, and Notes: +* - All routes in routeMask must be configured in order to be enabled +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_RouteMaskArgCmd_t +*******************************************************************************/ +void TO_ActivateRoutesCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Deactivate Routes Command (TO_DEACTIVATE_ROUTES_CC) +* +* \par Description/Algorithm +* - Disable routes based on route mask. +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_RouteMaskArgCmd_t +*******************************************************************************/ +void TO_DeactivateRoutesCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Pause Output Command (TO_PAUSE_OUTPUT_CC) +* +* \par Description/Algorithm +* - Set usOutputActive to 0 +* +* \par Assumptions, External Events, and Notes: +* - Output must be enabled (usOutputEnabled) to be able to Pause. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_NoArgCmd_t +*******************************************************************************/ +void TO_PauseOutputCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Resume Output Command (TO_RESUME_OUTPUT_CC) +* +* \par Description/Algorithm +* - Set usOutputActive to 1 +* +* \par Assumptions, External Events, and Notes: +* - Output must be enabled (usOutputEnabled) to be able to Resume. +* - Cmd ignored if output is active. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_NoArgCmd_t +*******************************************************************************/ +void TO_ResumeOutputCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Add a Table Entry (TO_ADD_TBL_ENTRY_CC) +* +* \par Description/Algorithm +* - Validate MID in command +* - Verify table is not full +* - Verify that MID is not already in table +* - Add new table entry to available table index +* - Subscribe route pipes to new entry's MID based on entry's routeMask +* +* \par Assumptions, External Events, and Notes: +* - New table entry must have unique MID (not present in table) +* - Route mask in table entry may include non-existing routes +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_AddTblEntryCmd_t +*******************************************************************************/ +void TO_AddTblEntryCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Remove a Table Entry by MID (TO_REMOVE_TBL_ENTRY_CC) +* +* \par Description/Algorithm +* - Validate MID in command +* - Find table entry of MID +* - Unsubscribe route pipes for MID based on entry's routeMask +* - Set table entry as TO_REMOVED_ENTRY +* +* \par Assumptions, External Events, and Notes: +* - An entry with MID must be present +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_MidArgCmd_t +*******************************************************************************/ +void TO_RemoveTblEntryCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Enable a Table Entry by MID (TO_ENABLE_TBL_ENTRY_CC) +* +* \par Description/Algorithm +* - Validate MID in command +* - Find table entry of MID +* - Enable table entry (usState = 1) +* +* \par Assumptions, External Events, and Notes: +* - Command is ignored if entry is already enabled +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_MidArgCmd_t +*******************************************************************************/ +void TO_EnableTblEntryCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Disable a Table Entry by MID (TO_DISABLE_TBL_ENTRY_CC) +* +* \par Description/Algorithm +* - Validate MID in command +* - Find table entry of MID +* - Disable table entry (usState = 0) +* +* \par Assumptions, External Events, and Notes: +* - Command is ignored if entry is already disabled +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_MidArgCmd_t +*******************************************************************************/ +void TO_DisableTblEntryCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Enable Table Entries by Group (TO_ENABLE_GROUP_CC) +* +* \par Description/Algorithm +* - Find all entries with matching GroupData +* - Set matching entrie's state to 1 (enabled) +* +* \par Assumptions, External Events, and Notes: +* - Command has no effect if no entry has matching GroupData +* - Command is ignored if entries with GroupData is already enabled +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_GroupArgCmd_t +*******************************************************************************/ +void TO_EnableGroupCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Disable Table Entries by Group (TO_DISABLE_GROUP_CC) +* +* \par Description/Algorithm +* - Find all entries with matching GroupData +* - Set matching entrie's state to 0 (disabled) +* +* \par Assumptions, External Events, and Notes: +* - Command has no effect if no entry has matching GroupData +* - Command is ignored if entries with GroupData is already disabled +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_GroupArgCmd_t +*******************************************************************************/ +void TO_DisableGroupCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Enable All Used Table Entries (TO_ENABLE_ALL_CC) +* +* \par Description/Algorithm +* - Set all non-empty entry state to 1 (enabled) +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_NoArgCmd_t +*******************************************************************************/ +void TO_EnableAllCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Disable All Used Table Entries (TO_DISABLE_ALL_CC) +* +* \par Description/Algorithm +* - Set all non-empty entry state to 1 (disabled) +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_NoArgCmd_t +*******************************************************************************/ +void TO_DisableAllCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Set table entry routeMask by MID (TO_SET_ROUTE_BY_MID_CC) +* +* \par Description/Algorithm +* - Validate MID +* - Find table entry +* - Set table entry RouteMask +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_SetRouteByMidCmd_t +*******************************************************************************/ +void TO_SetRouteByMidCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Set table entry routeMask by Group (TO_SET_ROUTE_BY_GROUP_CC) +* +* \par Description/Algorithm +* - Find table entries matching input group +* - Set found table entries' RouteMask +* +* \par Assumptions, External Events, and Notes: +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_SetRouteByGroupCmd_t +*******************************************************************************/ +void TO_SetRouteByGroupCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Manage the Table - Hook for TBL Services (TO_ManageTable_CC) +* +* \par Description/Algorithm +* - Call CFE_TBL_ReleaseAddress +* - Call CFE_TBL_Manage +* - Call CFE_TBL_GetAddress +* - Save new table address +* - Unsubscribe all tlm pipes from messages in previous table, according +* to routeMask +* - Subscribe all tlm pipes from messages in new table according to +* routeMask +* +* \par Assumptions, External Events, and Notes: +* - This command should only be called by CFE_TBL services in response +* to a table activate command (CFE_TBL_ACTIVATE_CC). +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type CFE_TBL_NotifyCmd_t +*******************************************************************************/ +void TO_ManageTableCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Set the route period by RouteMask (TO_SET_ROUTE_PERIOD_CC) +* +* \par Description/Algorithm +* - Validate input routeMask +* - Set the route wakeup period of all routes in routeMask +* +* \par Assumptions, External Events, and Notes: +* - To be valid, all routes within routeMask must exist +* - The input wakePeriod must be a factor of TO_MAX_WAKEUP_COUNT +* (TO_MAX_WAKEUP_COUNT % wakePeriod == 0) +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_SetRoutePeriodCmd_t +*******************************************************************************/ +void TO_SetRoutePeriodCmd(CFE_SB_MsgPtr_t); + + +/******************************************************************************/ +/** \brief Set Wakeup Timeout (TO_SET_WAKEUP_TIMEOUT_CC) +* +* \par Description/Algorithm +* - Set a new value for the Wakeup Timeout in ms +* +* \par Assumptions, External Events, and Notes: +* - The input value must be greater or equal to TO_MIN_WAKEUP_TIMEOUT +* - May be used to set the rate of execution of the TO application +* if no TO_WAKEUP_MID is issued by the SCH application. +* +* \param[in,out] g_TO_AppData TO Global Application Data +* \param[in] pCmdMsg Cmd of type TO_SetWakeupTimeoutCmd_t +*******************************************************************************/ +void TO_SetWakeupTimeoutCmd(CFE_SB_MsgPtr_t); + +#ifdef __cplusplus +} +#endif + +#endif + +/*============================================================================== +** End of file to_cmds.h +**============================================================================*/ diff --git a/fsw/src/to_custom.c b/fsw/src/to_custom.c new file mode 100644 index 0000000..971f327 --- /dev/null +++ b/fsw/src/to_custom.c @@ -0,0 +1,230 @@ +/******************************************************************************/ +/** \file to_custom.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions for Custom Layer of TO Application for UDP +* +* \par +* This file defines the functions for a custom implementation of the custom +* layer of the TO application over UDP Socket. +* +* \par API Functions Defined: +* - TO_CustomInit() - Initialize the transport protocol +* - TO_CustomAppCmds() - Process custom App Commands +* - TO_CustomEnableOutputCmd() - Enable telemetry output +* - TO_CustomDisableOutputCmd() - Disable telemetry output +* - TO_CustomCleanup() - Cleanup callback to close transport channel. +* - TO_CustomProcessData() - Send output data over transport protocol. +* +* \par Private Functions Defined: +* - TO_SendDataTypePktCmd() - Send Test packet (Reference to_lab app) +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All input messages are CCSDS messages +* - All config macros defined in to_platform_cfg.h +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2015-06-02 | Guy de Carufel | Revised for new UDP API +*******************************************************************************/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "network_includes.h" +#include "trans_udp.h" + +#include "to_app.h" +#include "ci_msgids.h" + +/* +** Local Defines +*/ + +/* +** Local Structure Declarations +*/ +typedef struct +{ + IO_TransUdp_t udp; /**< UDP working */ +} TO_CustomData_t; + +/* +** External Global Variables +*/ +extern TO_AppData_t g_TO_AppData; + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ +static TO_CustomData_t g_TO_CustomData; + +/* +** Local Function Definitions +*/ +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); + +/******************************************************************************* +** Custom Application Functions +*******************************************************************************/ + +/******************************************************************************/ +/** \brief Custom Initialization +*******************************************************************************/ +int32 TO_CustomInit(void) +{ + int32 iStatus = TO_SUCCESS; + + /* Create socket for outgoing */ + if (IO_TransUdpCreateSocket(&g_TO_CustomData.udp) < 0) + { + iStatus = TO_ERROR; + goto end_of_function; + } + + /* NOTE: For this simple UDP example, we are only requiring The following + 3 messages. If more message IDs should be included by default, add them + here and update the TO_NUM_CRITICAL_MIDS value. */ + + /* Set Critical Message Ids which must always be in config table. */ + g_TO_AppData.criticalMid[0] = TO_HK_TLM_MID; + g_TO_AppData.criticalMid[1] = CI_HK_TLM_MID; + g_TO_AppData.criticalMid[2] = CFE_EVS_EVENT_MSG_MID; + + /* Route 0: Udp. Linked to CF Channel Index 0. */ + g_TO_AppData.routes[0].usExists = 1; + g_TO_AppData.routes[0].sCfChnlIdx = 0; + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of custom app commands +*******************************************************************************/ +int32 TO_CustomAppCmds(CFE_SB_Msg_t* pMsg) +{ + int32 iStatus = TO_SUCCESS; + uint32 uiCmdCode = CFE_SB_GetCmdCode(pMsg); + switch (uiCmdCode) + { + case TO_SEND_DATA_TYPE_CC: + TO_SendDataTypePktCmd(pMsg); + break; + + default: + iStatus = -1; + break; + } + + return iStatus; +} + +/******************************************************************************/ +/** \brief Process of output telemetry +*******************************************************************************/ +int32 TO_CustomProcessData(CFE_SB_Msg_t * pMsg, int32 size, int32 iTblIdx, + uint16 usRouteId) +{ + int32 iStatus = 0; + + if (g_TO_AppData.routes[0].usIsEnabled == 0 || usRouteId != 0) + { + goto end_of_function; + } + + iStatus = IO_TransUdpSnd(&g_TO_CustomData.udp, (uint8 *) pMsg, size); + + if (iStatus < 0) + { + CFE_EVS_SendEvent(TO_CUSTOM_ERR_EID, CFE_EVS_ERROR, + "TO UDP sendto errno %d. Telemetry output disabled.", + errno); + g_TO_AppData.usOutputEnabled = 0; + } + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Custom Cleanup +*******************************************************************************/ +void TO_CustomCleanup(void) +{ + if (g_TO_AppData.usOutputEnabled) + { + CFE_EVS_SendEvent(TO_CUSTOM_INF_EID, CFE_EVS_INFORMATION, + "TO - Closing Socket."); + IO_TransUdpCloseSocket(&g_TO_CustomData.udp); + } + + return; +} + +/******************************************************************************/ +/** \brief Enable Output Command Response +*******************************************************************************/ +int32 TO_CustomEnableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + int32 iStatus = IO_TRANS_UDP_NO_ERROR; + int32 routeMask = TO_ERROR; + char cDestIp[TO_MAX_IP_STRING_SIZE]; + uint16 usDestPort = 0; + + TO_EnableOutputCmd_t * pCustomCmd = (TO_EnableOutputCmd_t *) pCmdMsg; + strncpy(cDestIp, pCustomCmd->cDestIp, sizeof(cDestIp)); + + if (pCustomCmd->usDestPort > 0) + { + usDestPort = pCustomCmd->usDestPort; + } + else + { + usDestPort = TO_DEFAULT_DEST_PORT; + } + + iStatus = IO_TransUdpSetDestAddr(&g_TO_CustomData.udp, pCustomCmd->cDestIp, + usDestPort); + + if (iStatus < 0) + { + goto end_of_function; + } + + /* We are done configuring route 0 */ + TO_SetRouteAsConfigured(0); + routeMask = 0x0001; + +end_of_function: + return routeMask; +} + +/******************************************************************************/ +/** \brief Disable Output Command Response +*******************************************************************************/ +int32 TO_CustomDisableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + /* Disable */ + g_TO_AppData.usOutputEnabled = 0; + return TO_SUCCESS; +} + + +/******************************************************************************* +** Non standard custom Commands +*******************************************************************************/ + +/*============================================================================== +** End of file to_custom.c +**============================================================================*/ diff --git a/fsw/src/to_events.h b/fsw/src/to_events.h new file mode 100644 index 0000000..ef850c3 --- /dev/null +++ b/fsw/src/to_events.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/** \file to_events.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief ID Header File for TO Application +* +* \par +* This header file contains definitions of the TO Event IDs +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +#ifndef _TO_EVENTS_H_ +#define _TO_EVENTS_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* Event IDs */ +typedef enum +{ + TO_RESERVED_EID = 0, + TO_INF_EID = 1, + TO_INIT_INF_EID = 2, + TO_CMD_INF_EID = 3, + TO_TBL_INF_EID = 4, + TO_CUSTOM_INF_EID = 5, + TO_ERR_EID = 6, + TO_INIT_ERR_EID = 7, + TO_CMD_ERR_EID = 8, + TO_TBL_ERR_EID = 9, + TO_PIPE_ERR_EID = 10, + TO_MSGID_ERR_EID = 11, + TO_MSGLEN_ERR_EID = 12, + TO_CUSTOM_ERR_EID = 13, + TO_EVT_CNT +} TO_Events_t; + +#ifdef __cplusplus +} +#endif + +#endif + +/*============================================================================== +** End of file to_events.h +**============================================================================*/ + diff --git a/fsw/src/to_hktlm.h b/fsw/src/to_hktlm.h new file mode 100644 index 0000000..520b801 --- /dev/null +++ b/fsw/src/to_hktlm.h @@ -0,0 +1,51 @@ +/******************************************************************************/ +/** \file to_hktlm.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Default HK Telemetry +* +* \par +* This header contains the definition of the default HK Telemetry. +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Include this file in your MISSION_to_types.hh or define your own. +* - If a custom HK tlm is required, make sure to include all parameters +* in this default HK packet in your custom implementation. +* - The usMsgSubCnt is not reset on a TO_RESET_CC command. +* +* \par Modification History: +* - 2015-09-22 | Guy de Carufel | Code Started +*******************************************************************************/ +#ifndef _TO_HKTLM_H_ +#define _TO_HKTLM_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "cfe.h" + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint16 usCmdCnt; /**< Count of all commands received */ + uint16 usCmdErrCnt; /**< Count of command errors */ + uint16 usMsgSubCnt; /**< Count of subscribed messages by all + telemetry pipe. */ + uint16 usMsgSubErrCnt; /**< Count of subscription errors */ + uint16 usTblUpdateCnt; /**< Count of table updates through CFE_TBL */ + uint16 usTblErrCnt; /**< Count of table update errors */ + uint16 usConfigRoutes; /**< Current mask of configured routes */ + uint16 usEnabledRoutes; /**< Current mask of enabled routes */ +} TO_HkTlm_t; + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_HKTLM_H_ */ + +/*============================================================================== +** End of file to_hktlm.h +**============================================================================*/ diff --git a/fsw/src/to_msgdefs.h b/fsw/src/to_msgdefs.h new file mode 100644 index 0000000..3ff9786 --- /dev/null +++ b/fsw/src/to_msgdefs.h @@ -0,0 +1,105 @@ +/************************************************************************ +** File: +** to_msgdefs.h +** +** Copyright © 2016 United States Government as represented by the +** Administrator of the National Aeronautics and Space Administration. +** All Other Rights Reserved. +** +** This software was created at NASA's Johnson Space Center. +** This software is governed by the NASA Open Source Agreement and may be +** used, distributed and modified only pursuant to the terms of that +** agreement. +** +** Purpose: +** Specification for the CFS Telemetry Output (TO) command and telemetry +** message constant definitions. +** +** Notes: +** These Macro definitions have been put in this file so this file can +** be included directly into ASIST build test scripts. ASIST RDL files +** can accept C language #defines but can't handle type definitions. +** As a result: DO NOT PUT ANY TYPEDEFS OR STRUCTURE DEFINITIONS IN +** THIS FILE! +** ADD THEM TO ANOTHER HEADER IF NEEDED! +** +** ASIST documentation has yet to be provided for all the items in this file. +** +** \par Modification History: +** - 2016-05-11 | Allen Brown | Initial Version +** +*************************************************************************/ + +#ifndef _to_msgdefs_ +#define _to_msgdefs_ + +/************************************************************************ +** Macro Definitions +*************************************************************************/ + + +/************************************************************************ +** Command Code Definitions +*************************************************************************/ + +/** \tocmd Noop +** +** \par Description +** Implements the Noop command that insures the TO app is alive +** +** \tocmdmnemonic \TO_NOOP +** +** \par Command Structure +** To be documented. +** +** \par Command Verification +** Successful execution of this command may be verified with +** the following telemetry: To be documented. +** +** \par Error Conditions +** This command may fail for the following reason(s): +** - Command packet length not as expected +** +** \par Evidence of failure may be found in the following telemetry: +** To be documented. +** +** \par Criticality +** To be documented. +** +** \sa #TO_RESET_CC +*/ +#define TO_NOOP_CC 0 + +/* Note, the rest of these require ASIST documentation. */ +#define TO_RESET_CC 1 +#define TO_ENABLE_OUTPUT_CC 2 +#define TO_DISABLE_OUTPUT_CC 3 +#define TO_PAUSE_OUTPUT_CC 4 +#define TO_RESUME_OUTPUT_CC 5 +#define TO_ADD_TBL_ENTRY_CC 6 +#define TO_REMOVE_TBL_ENTRY_CC 7 +#define TO_ENABLE_TBL_ENTRY_CC 8 +#define TO_DISABLE_TBL_ENTRY_CC 9 +#define TO_ENABLE_GROUP_CC 10 +#define TO_DISABLE_GROUP_CC 11 +#define TO_ENABLE_ALL_CC 12 +#define TO_DISABLE_ALL_CC 13 +#define TO_SET_ROUTE_BY_MID_CC 14 +#define TO_SET_ROUTE_BY_GROUP_CC 15 +#define TO_MANAGE_TABLE_CC 16 +#define TO_ACTIVATE_ROUTES_CC 17 +#define TO_DEACTIVATE_ROUTES_CC 18 +#define TO_SET_ROUTE_PERIOD_CC 19 +#define TO_SET_WAKEUP_TIMEOUT_CC 20 + +/* Public Custom Commands */ +#define TO_SEND_DATA_TYPE_CC 30 + +/* Internal Custom Commands */ +#define TO_SET_OCF_DATA_CC 40 + +#endif /* _to_msgdefs_ */ + +/************************/ +/* End of File Comment */ +/************************/ diff --git a/fsw/src/to_tbldefs.h b/fsw/src/to_tbldefs.h new file mode 100644 index 0000000..172746b --- /dev/null +++ b/fsw/src/to_tbldefs.h @@ -0,0 +1,82 @@ +/******************************************************************************/ +/** \file to_tbldefs.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Define the configuration table for Telemetry Outputs +* +* \par Limitations, Assumptions, External Events, and Notes: +* Each table entry defines: +* 1. The message id +* 2. The qos and msgLength - Used for message subscription +* 3. The routeMask - For output message routing +* 4. The groupData - To modify multiple entries with single command +* 5. The state - The state of the entry (enabled = 1 /disabled = 0) +* A Valid Table: +* 1. No two entries with same MID +* 2. No gaps (all used entries are consecutive) +* 3. All g_TO_AppData.criticalMid are included in the table +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ +#ifndef _TO_TBLDEFS_ +#define _TO_TBLDEFS_ + +#ifdef __cplusplus +extern "C" { +#endif + +/******************************************************************************* +** Includes +*******************************************************************************/ +#include "cfe.h" +#include "to_platform_cfg.h" + +/******************************************************************************* +** Macro Definitions +*******************************************************************************/ +#define TO_UNUSED_ENTRY 0 +#define TO_REMOVED_ENTRY 1 + +/** \name Default Table Size */ +/** \{ */ +#ifndef TO_MAX_TBL_ENTRIES +#define TO_MAX_TBL_ENTRIES 100 +#endif +/** \} */ + +/******************************************************************************* +** Type Definitions +*******************************************************************************/ +/** +** \brief TO Table Entry for message subscription and routing. +*/ +typedef struct +{ + CFE_SB_MsgId_t usMsgId; /**< Message ID (must be unique) */ + CFE_SB_Qos_t qos; /**< Quality of Service flag */ + uint16 usMsgLimit; /**< Max Num. of this Msgs in pipe */ + uint16 usRouteMask; /**< Bitwize Route Mask */ + uint32 uiGroupData; /**< Group data Mask */ + uint16 usFlag; /**< Custom defined flag */ + uint16 usState; /**< Message ID is enabled = 1 */ +} TO_TableEntry_t; + +/** +** \brief TO Table definition +*/ +typedef struct +{ + TO_TableEntry_t entries[TO_MAX_TBL_ENTRIES]; +} TO_ConfigTable_t; + +#ifdef __cplusplus +} +#endif + +#endif + +/*============================================================================== +** End of file to_tbldefs.h +**============================================================================*/ diff --git a/fsw/src/to_utils.c b/fsw/src/to_utils.c new file mode 100644 index 0000000..ceddcd2 --- /dev/null +++ b/fsw/src/to_utils.c @@ -0,0 +1,534 @@ +/******************************************************************************/ +/** \file to_utils.c +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Function Definitions of utility functions +* +* \par +* This file defines utility functions used by other TO functions. +* +* \par API Functions Defined: +* - TO_FindEmptyTableIndex - Find an empty table index +* - TO_FindTableIndex - Find a table index based on MID +* - TO_SetStateByGroup - Set the state (enable/disable) by groupData +* - TO_SetRouteByGroup - Set the routeMask by groupData +* - TO_SetAllEntryState - Set the state (enable/disable) for all entries +* - TO_DisableRoute - Disable a route ID and revised hk->usEnabledRoutes +* - TO_ValidateRouteMask - Check that all routes in routeMask exist +* - TO_GetRouteMask - Get the route mask at table index +* - TO_GetMessageId - Get message ID at table index +* - TO_VerifyCmdLength - Verify length of command message +* - TO_SubscribeAllMsgs - Subscribe all messages to route pipes by routeMask +* - TO_SubscribeMsg - Subscribe message to route pipes by routeMask +* - TO_UnsubscribeAllMsgs - Unsub. all messages for route pipes by routeMask +* - TO_UnsSubscribeMsg - Unsub. message for route pipes by routeMask +* +* \par Private Functions Defined: +* +* \par Limitations, Assumptions, External Events, and Notes: +* - Utilities used by to_cmds.c and to_custom.c +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +*******************************************************************************/ + +/* +** Include Files +*/ +#include "to_app.h" + +/* +** External Global Variables +*/ +extern TO_AppData_t g_TO_AppData; + + +/******************************************************************************/ +/** \brief Find Empty Table Index. +*******************************************************************************/ +int32 TO_FindEmptyTableIndex(void) +{ + uint32 ii = 0; + uint32 tableIdx = TO_TBL_FULL_ERR; + TO_TableEntry_t *pEntry = NULL; + + /* Find either an unused entry or an entry that has been + * deleted. */ + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ii++) + { + pEntry = &g_TO_AppData.pConfigTable->entries[ii]; + if (pEntry->usMsgId == TO_UNUSED_ENTRY || + pEntry->usMsgId == TO_REMOVED_ENTRY) + { + tableIdx = ii; + break; + } + } + + return tableIdx; +} + +/******************************************************************************/ +/** \brief Find Table Index by MID. +*******************************************************************************/ +int32 TO_FindTableIndex(TO_ConfigTable_t *pTable, + CFE_SB_MsgId_t usMsgId) +{ + uint32 ii = 0; + uint32 tableIdx = TO_NO_MATCH; + TO_TableEntry_t *pEntry = NULL; + + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ii++) + { + pEntry = &pTable->entries[ii]; + /* If we've reached an unused entry, it doesn't exist. */ + if (pEntry->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + else if (pEntry->usMsgId == usMsgId) + { + tableIdx = ii; + break; + } + } + + return tableIdx; +} + +/******************************************************************************/ +/** \brief Set state (Enable/Disable) based on Group. +*******************************************************************************/ +int32 TO_SetStateByGroup(uint32 uiGroupData, uint16 usEnableFlag) +{ + int32 iStatus = TO_NO_MATCH; + uint32 ii = 0; + TO_TableEntry_t *pEntry = NULL; + uint32 uiCmdGroup = uiGroupData & TO_GROUP_NUMBER_MASK; + uint32 uiCmdMulti = uiGroupData & TO_MULTI_GROUP_MASK; + uint32 uiEntryGroup = 0; + uint32 uiEntryMulti = 0; + int16 newState = 0; + + if (uiCmdGroup == 0 && uiCmdMulti == 0) + { + iStatus = TO_BAD_ARG_ERR; + goto end_of_function; + } + + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ii++) + { + pEntry = &g_TO_AppData.pConfigTable->entries[ii]; + + if (pEntry->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + + uiEntryGroup = pEntry->uiGroupData & TO_GROUP_NUMBER_MASK; + uiEntryMulti = pEntry->uiGroupData & TO_MULTI_GROUP_MASK; + + if ((uiEntryGroup == uiCmdGroup) || (uiEntryMulti & uiCmdMulti)) + { + if (pEntry->usState != usEnableFlag) + { + newState = 1; + } + + pEntry->usState = usEnableFlag; + iStatus = TO_SUCCESS; + } + } + + if (iStatus == TO_SUCCESS && newState == 0) + { + iStatus = TO_NO_EFFECT; + } + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Set usRouteMask based on Group. +*******************************************************************************/ +int32 TO_SetRouteByGroup(uint32 uiGroupData, uint16 usRouteMask) +{ + int32 iStatus = TO_NO_MATCH; + uint32 ii = 0; + TO_TableEntry_t *pEntry = NULL; + uint32 uiCmdGroup = uiGroupData & TO_GROUP_NUMBER_MASK; + uint32 uiCmdMulti = uiGroupData & TO_MULTI_GROUP_MASK; + uint32 uiEntryGroup = 0; + uint32 uiEntryMulti = 0; + int16 newState = 0; + + if (uiCmdGroup == 0 && uiCmdMulti == 0) + { + iStatus = TO_BAD_ARG_ERR; + goto end_of_function; + } + + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ii++) + { + pEntry = &g_TO_AppData.pConfigTable->entries[ii]; + + /* No more entries. We're done. */ + if (pEntry->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + + uiEntryGroup = pEntry->uiGroupData & TO_GROUP_NUMBER_MASK; + uiEntryMulti = pEntry->uiGroupData & TO_MULTI_GROUP_MASK; + + if ((uiEntryGroup == uiCmdGroup) || (uiEntryMulti & uiCmdMulti)) + { + if (pEntry->usRouteMask != usRouteMask) + { + newState = 1; + } + + pEntry->usRouteMask = usRouteMask; + iStatus = TO_SUCCESS; + } + } + + if (iStatus == TO_SUCCESS && newState == 0) + { + iStatus = TO_NO_EFFECT; + } + +end_of_function: + return iStatus; +} + +/******************************************************************************/ +/** \brief Set State for all used table entries +*******************************************************************************/ +int32 TO_SetAllEntryState(uint16 usEnableFlag) +{ + int32 iStatus = TO_SUCCESS; + TO_TableEntry_t *pEntry = NULL; + uint32 ii = 0; + int32 newState = 0; + + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ii++) + { + pEntry = &g_TO_AppData.pConfigTable->entries[ii]; + + /* If we hit TO_UNUSED, we are done. */ + if (pEntry->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + + if (pEntry->usState != usEnableFlag) + { + newState = 1; + } + + pEntry->usState = usEnableFlag; + } + + if (newState == 0) + { + iStatus = TO_NO_EFFECT; + } + + return iStatus; +} + + +/******************************************************************************/ +/** \brief Set Route as configured +*******************************************************************************/ +void TO_SetRouteAsConfigured(uint16 routeId) +{ + /* Set the route as configured */ + g_TO_AppData.routes[routeId].usIsConfig = 1; + g_TO_AppData.HkTlm.usConfigRoutes |= (1 << routeId); +} + +/******************************************************************************/ +/** \brief Set Route as unconfigured +*******************************************************************************/ +void TO_SetRouteAsUnconfigured(uint16 routeId) +{ + /* Set the route as configured */ + g_TO_AppData.routes[routeId].usIsConfig = 0; + g_TO_AppData.HkTlm.usConfigRoutes &= ~(1 << routeId); +} + + +/******************************************************************************/ +/** \brief Disable Route ID +*******************************************************************************/ +void TO_DisableRoute(uint16 routeId) +{ + g_TO_AppData.routes[routeId].usIsEnabled = 0; + g_TO_AppData.HkTlm.usEnabledRoutes &= ~(1 << routeId); +} + + +/******************************************************************************/ +/** \brief Verify RouteMask compared to configured routes. +*******************************************************************************/ +int32 TO_ValidateRouteMask(uint16 usRouteMask) +{ + int32 iStatus = TO_SUCCESS; + uint16 ii; + + /* Validate Route. The route must exist to be valid. */ + for (ii = 0; ii < TO_MAX_NUM_ROUTES; ++ii) + { + if ((!g_TO_AppData.routes[ii].usExists << ii) & usRouteMask) + { + iStatus = TO_ERROR; + break; + } + } + + return iStatus; +} + +/******************************************************************************/ +/** \brief Get the route mask based at table index +*******************************************************************************/ +uint16 TO_GetRouteMask(int32 tblIdx) +{ + if (tblIdx >= TO_MAX_TBL_ENTRIES) + { + return 0x0000; + } + + return g_TO_AppData.pConfigTable->entries[tblIdx].usRouteMask; +} + +/******************************************************************************/ +/** \brief Get the Message ID based at table index +*******************************************************************************/ +CFE_SB_MsgId_t TO_GetMessageID(int32 tblIdx) +{ + if (tblIdx >= TO_MAX_TBL_ENTRIES) + { + return 0; + } + + return g_TO_AppData.pConfigTable->entries[tblIdx].usMsgId; +} + + +/******************************************************************************/ +/** \brief Verify the command length against expected length +*******************************************************************************/ +boolean TO_VerifyCmdLength(CFE_SB_MsgPtr_t pMsg, + uint16 usExpectedLen) +{ + boolean bResult=FALSE; + uint16 usMsgLen=0; + + if (pMsg != NULL) + { + usMsgLen = CFE_SB_GetTotalMsgLength(pMsg); + + if (usExpectedLen == usMsgLen) + { + bResult = TRUE; + } + else + { + CFE_SB_MsgId_t MsgId = CFE_SB_GetMsgId(pMsg); + uint16 usCmdCode = CFE_SB_GetCmdCode(pMsg); + + CFE_EVS_SendEvent(TO_MSGLEN_ERR_EID, CFE_EVS_ERROR, + "Rcvd invalid msgLen: usMsgId=0x%04X, " + "cmdCode=%d, msgLen=%d, expectedLen=%d", + MsgId, usCmdCode, usMsgLen, usExpectedLen); + + g_TO_AppData.HkTlm.usCmdErrCnt++; + } + } + + return (bResult); +} + + + +/******************************************************************************/ +/** \brief Subscribe all Messages to appropriate pipes +*******************************************************************************/ +int32 TO_SubscribeAllMsgs(void) +{ + uint16 ii; + int32 iStatus = TO_SUCCESS; + TO_TableEntry_t *pEntry = NULL; + + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ++ii) + { + pEntry = &g_TO_AppData.pConfigTable->entries[ii]; + if (pEntry == NULL) + { + iStatus = TO_ERROR; + break; + } + + if (pEntry->usMsgId != TO_UNUSED_ENTRY && + pEntry->usMsgId != TO_REMOVED_ENTRY) + { + iStatus = TO_SubscribeMsg(pEntry); + + if (iStatus != TO_SUCCESS) + { + break; + } + } + /* We've reached the end of used entries. */ + else if (pEntry->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + } + + return iStatus; +} + + +/******************************************************************************/ +/** \brief Subscribe Message to appropriate pipes +*******************************************************************************/ +int32 TO_SubscribeMsg(TO_TableEntry_t *pEntry) +{ + uint16 jj; + TO_TlmPipe_t *pTlmPipe = NULL; + int32 iStatus = TO_SUCCESS; + + if (pEntry == NULL) + { + iStatus = TO_BAD_ARG_ERR; + goto end_of_function; + } + + for (jj = 0; jj < TO_MAX_NUM_ROUTES; ++jj) + { + pTlmPipe = &g_TO_AppData.tlmPipes[jj]; + + /* Subscribe the message to the current route pipe if it exists. */ + if (pEntry->usRouteMask & (1 << jj) && g_TO_AppData.routes[jj].usExists) + { + iStatus = CFE_SB_SubscribeEx(pEntry->usMsgId, + pTlmPipe->cfePipeId, + pEntry->qos, + pEntry->usMsgLimit); + + if (iStatus != CFE_SUCCESS) + { + g_TO_AppData.HkTlm.usMsgSubErrCnt++; + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "TO Pipe:%s failed to subscribe to MID 0x%04x", + pTlmPipe->cTlmPipeName, pEntry->usMsgId); + break; + } + else + { + g_TO_AppData.HkTlm.usMsgSubCnt++; + } + } + } + +end_of_function: + return iStatus; +} + + +/******************************************************************************/ +/** \brief Unsubscribe all Messages to appropriate pipes +*******************************************************************************/ +int32 TO_UnsubscribeAllMsgs(TO_ConfigTable_t *pConfigTable) +{ + uint16 ii; + int32 iStatus = TO_SUCCESS; + TO_TableEntry_t *pEntry = NULL; + + if (pConfigTable == NULL) + { + iStatus = TO_BAD_ARG_ERR; + goto end_of_function; + } + + for (ii = 0; ii < TO_MAX_TBL_ENTRIES; ++ii) + { + pEntry = &pConfigTable->entries[ii]; + + if (pEntry->usMsgId != TO_UNUSED_ENTRY && + pEntry->usMsgId != TO_REMOVED_ENTRY) + { + iStatus = TO_UnsubscribeMsg(pEntry); + + if (iStatus != TO_SUCCESS) + { + break; + } + } + /* We've reached the end of used entries. */ + else if (pEntry->usMsgId == TO_UNUSED_ENTRY) + { + break; + } + } + +end_of_function: + return iStatus; +} + + +/******************************************************************************/ +/** \brief Unsubscribe Message to appropriate pipes +*******************************************************************************/ +int32 TO_UnsubscribeMsg(TO_TableEntry_t *pEntry) +{ + uint16 jj; + TO_TlmPipe_t *pTlmPipe = NULL; + int32 iStatus = TO_SUCCESS; + + if (pEntry == NULL) + { + iStatus = TO_BAD_ARG_ERR; + goto end_of_function; + } + + for (jj = 0; jj < TO_MAX_NUM_ROUTES; ++jj) + { + pTlmPipe = &g_TO_AppData.tlmPipes[jj]; + + /* Unsubscribe the message to the current route pipe. */ + if (pEntry->usRouteMask & (1 << jj) && g_TO_AppData.routes[jj].usExists) + { + iStatus = CFE_SB_Unsubscribe(pEntry->usMsgId, + pTlmPipe->cfePipeId); + + if (iStatus != CFE_SUCCESS) + { + g_TO_AppData.HkTlm.usMsgSubErrCnt++; + CFE_EVS_SendEvent(TO_INIT_ERR_EID, CFE_EVS_ERROR, + "TO Pipe:%s failed to unsubscribe to MID 0x%04x", + pTlmPipe->cTlmPipeName, pEntry->usMsgId); + break; + } + else + { + g_TO_AppData.HkTlm.usMsgSubCnt--; + } + } + } + +end_of_function: + return iStatus; +} + + + +/*============================================================================== +** End of file to_utils.c +**============================================================================*/ diff --git a/fsw/tables/table_change.sh b/fsw/tables/table_change.sh new file mode 100644 index 0000000..267d41f --- /dev/null +++ b/fsw/tables/table_change.sh @@ -0,0 +1,21 @@ +## This is a test script to load and activate to_config_2.tbl to verify table changes. +## Notes +## 1: ValidateChecksum checks in ci_custom.c must not be performed as in UDP example. +## Since cmdUtil does not compute a checksum for commands sent. +## 2: Ensure that your criticalMsgIds array does not include message ID that +## Are not included in the to_config_2.tbl, otherwise table validation will +## fail. + + +# Load to_config_2.tbl +echo "Step 1: Load the to_config_2.tbl through CFE TBL." +cmdUtil --port=5010 --endian=LE --pktid=0x1804 --cmdcode=2 --string="64:/cf/apps/to_config_2.tbl" +sleep 1 +# Verify the new inactive table +echo "Step 2: Verify the new table through CFE_TBL." +cmdUtil --port=5010 --endian=LE --pktid=0x1804 --cmdcode=4 --half=0 --string="40:TO.to_config" +sleep 1 +# Activate the new table (CFE TBL will call TO_ManageTable +echo "Step 3: Activate the new table through CFE_TBL." +cmdUtil --port=5010 --endian=LE --pktid=0x1804 --cmdcode=5 --string="40:TO.to_config" +sleep 1 diff --git a/fsw/tables/to_config.c b/fsw/tables/to_config.c new file mode 100644 index 0000000..3c20e87 --- /dev/null +++ b/fsw/tables/to_config.c @@ -0,0 +1,228 @@ +/*============================================================================== +** File Name: to_config.c +** +** Title: TO table definition +** +** $Author: $ +** $Revision: $ +** $Date: $ +** +** Purpose: To provide the table for default data config. +** +** Functions Contained: +** None +** +** +** Limitations, Assumptions, External Events, and Notes: +** 1. None +** +** +**============================================================================== +*/ + +/* +#ifndef _TO_CONFIG_ +#define _TO_CONFIG_ + + +#ifdef __cplusplus +extern "C" { +#endif +*/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "cfe_tbl_filedef.h" +#include "to_platform_cfg.h" +#include "to_mission_cfg.h" +#include "to_app.h" +#include "to_tbldefs.h" +#include "to_grpids.h" + +#include "cfe_msgids.h" + +#include "to_msgids.h" +#include "ci_msgids.h" +#include "cf_msgids.h" +#include "sch_msgids.h" +#include "hs_msgids.h" +#include "hk_msgids.h" +#include "sch_msgids.h" + + +/* +** Local Defines +*/ + + +/* +** Local Structure Declarations +*/ + +static CFE_TBL_FileDef_t CFE_TBL_FileDef = +{ + "to_ConfigTable", "TO.to_config", "TO config table", + "to_config.tbl", sizeof(TO_ConfigTable_t) +}; + +/* +** Default TO iLoad table data +*/ + +TO_ConfigTable_t to_ConfigTable = +{ + { + /* 0 - 9 */ + {CF_CONFIG_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CF_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CF_SPACE_TO_GND_PDU_MID, {0,0}, 32, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CF_TRANS_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_ES_APP_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_ES_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_ES_MEMSTATS_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_ES_SHELL_TLM_MID, {0,0}, 32, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_EVS_EVENT_MSG_MID, {0,0}, 32, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_EVS_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + + /* 10 - 19 */ + {CFE_SB_ALLSUBS_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_SB_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_SB_ONESUB_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_SB_STATS_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_TBL_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_TBL_REG_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_TIME_DIAG_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_TIME_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {TO_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {HS_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + + /* 20 - 29 */ + {SCH_DIAG_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {SCH_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {HK_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {CI_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {TO_DATA_TYPE_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + + /* 30 - 39 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 40 - 49 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 50 - 59 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 60 - 69 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 70 - 79 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 80 - 89 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 90 - 99 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0} + } +}; + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +/* +#ifdef __cplusplus +} +#endif + +#endif +*/ + +/* _TO_CONFIG_ */ diff --git a/fsw/tables/to_config_2.c b/fsw/tables/to_config_2.c new file mode 100644 index 0000000..a3f2a79 --- /dev/null +++ b/fsw/tables/to_config_2.c @@ -0,0 +1,221 @@ +/*============================================================================== +** File Name: to_config.c +** +** Title: TO table definition +** +** $Author: $ +** $Revision: $ +** $Date: $ +** +** Purpose: To provide the table for default data config. +** +** Functions Contained: +** None +** +** +** Limitations, Assumptions, External Events, and Notes: +** 1. None +** +** +**============================================================================== +*/ + +/* +#ifndef _TO_CONFIG_ +#define _TO_CONFIG_ + + +#ifdef __cplusplus +extern "C" { +#endif +*/ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include "cfe_tbl_filedef.h" +#include "to_platform_cfg.h" +#include "to_mission_cfg.h" +#include "to_app.h" +#include "to_tbldefs.h" +#include "to_grpids.h" + +#include "cfe_msgids.h" + +#include "ci_msgids.h" + + +/* +** Local Defines +*/ + + +/* +** Local Structure Declarations +*/ + +static CFE_TBL_FileDef_t CFE_TBL_FileDef = +{ + "to_ConfigTable", "TO.to_config", "TO config table", + "to_config_2.tbl", sizeof(TO_ConfigTable_t) +}; + +/* +** Default TO iLoad table data +*/ + +TO_ConfigTable_t to_ConfigTable = +{ + { + /* 0 - 9 */ + {TO_HK_TLM_MID, {0,0}, 1, 0x0003, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {CI_HK_TLM_MID, {0,0}, 1, 0x0003, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {CFE_TBL_HK_TLM_MID, {0,0}, 1, 0x0003, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {CFE_EVS_EVENT_MSG_MID, {0,0}, 32, 0x0003, TO_GROUP_CFE | TO_MGROUP_ONE, 0,1}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 40 - 49 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 50 - 59 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 30 - 39 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 40 - 49 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 50 - 59 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 60 - 69 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 70 - 79 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 80 - 89 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + + /* 90 - 99 */ + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0} + } +}; + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +/* +#ifdef __cplusplus +} +#endif + +#endif +*/ + +/* _TO_CONFIG_ */ diff --git a/fsw/tables/to_grpids.h b/fsw/tables/to_grpids.h new file mode 100644 index 0000000..76c31fc --- /dev/null +++ b/fsw/tables/to_grpids.h @@ -0,0 +1,45 @@ +/*======================================================================================= +** File Name: to_grpids.h +** +** Title: Group IDs used by the default TO table +**=====================================================================================*/ + +#ifndef _TO_GRP_IDS_H_ +#define _TO_GRP_IDS_H_ + +/* +** Pragmas +*/ + +/* +** Include Files +*/ + +/* +** Local Defines +*/ +/* Define multigroups as bit. Max is TO_MULTI_GROUP_MASK (default: 24-bits) */ +#define TO_MGROUP_NONE 0 +#define TO_MGROUP_ONE 1 +#define TO_MGROUP_TWO 1 << 1 +#define TO_MGROUP_THREE 1 << 2 +#define TO_MGROUP_FOUR 1 << 3 +#define TO_MGROUP_FIVE 1 << 4 +#define TO_MGROUP_SIX 1 << 5 +#define TO_MGROUP_SEVEN 1 << 6 +#define TO_MGROUP_EIGHT 1 << 7 +#define TO_MGROUP_NINE 1 << 8 +#define TO_MGROUP_TEN 1 << 9 + +/* Define group as Hex based on TO_GROUP_NUMBER_MASK (default: 0x00 << 24 to 0xff << 24) */ +#define TO_GROUP_NONE 0x00000000 +#define TO_GROUP_CFE 0x01000000 +#define TO_GROUP_APP 0x02000000 +#define TO_GROUP_THREE 0x03000000 + +#endif /* _TO_GRP_IDS_H_ */ + +/*======================================================================================= +** End of file sch_grpids.h +**=====================================================================================*/ + diff --git a/fsw/unit_test/.gitignore b/fsw/unit_test/.gitignore new file mode 100644 index 0000000..1111189 --- /dev/null +++ b/fsw/unit_test/.gitignore @@ -0,0 +1,5 @@ +*.o +*.exe +*.gcov +*.out +*.gcno diff --git a/fsw/unit_test/Readme.txt b/fsw/unit_test/Readme.txt new file mode 100644 index 0000000..fbedbeb --- /dev/null +++ b/fsw/unit_test/Readme.txt @@ -0,0 +1,21 @@ +This directory holds the unit tests for the TO application. + +To build and run the unit tests: +1. Be sure an appropriate *_to_types.h is in the apps/inc directory by: + a. cd ../examples + b. ./setup.sh -m CFS_TST udp (see below) + c. cd ../unit_test +2. make clean +3. make +4. make run +5. make gcov + +Background: +The unit tests also expect (like the apps) to find the + apps/inc/CFS_TST_ci_types.h + apps/inc/CFS_TST_to_types.h +where the mission name, CFS_TST, is assumed by default. + +These are put into place by the [ci/to]/fsw/examples/setup.py scripts. +Choose the appropriate name for your code to compile if you aren't +using "CFS_TST". diff --git a/fsw/unit_test/makefile b/fsw/unit_test/makefile new file mode 100644 index 0000000..41fb41a --- /dev/null +++ b/fsw/unit_test/makefile @@ -0,0 +1,150 @@ +############################################################################## +## GNU Makefile for building UT unit tests + +# +# Supported MAKEFILE targets: +# clean - deletes object files, executables, output files, and gcov files +# all - makes utf_test_runner.exe +# run - runs utf_test_runner.exe +# gcov - prints a GCOV coverage report (make all, make run, make gcov) +# +# GCOV is disabled by default. If you are using the source level debugger you will want to +# disable GCOV. To enable GCOV you can override the ENABLE_GCOV variable on the command line +# by setting it to TRUE. For example "make ENABLE_GCOV=TRUE". +# + +APP=to + +CFE_PATH = $(CFE_FSW)/cfe-core +OSAL_PATH = $(OSAL_DIR) +PSP_PATH = $(PSP_DIR) + +# +# VPATH specifies the search paths for source files outside of the current directory. Note that +# all object files will be created in the current directory even if the source file is not in the +# current directory. +# +VPATH := ../src +VPATH += ./ut-assert/src + +# +# INCLUDES specifies the search paths for include files outside of the current directory. +# Note that the -I is required. +# +INCLUDES := -I. +INCLUDES += -I.. +INCLUDES += -I../src +INCLUDES += -I../tables +INCLUDES += -I../mission_inc +INCLUDES += -I../platform_inc +INCLUDES += -I../../../inc +#INCLUDES += -I../../../io_lib/fsw/public_inc +INCLUDES += -I./ut-assert/inc +INCLUDES += -I$(CFE_PATH)/os/inc +INCLUDES += -I$(CFE_PATH)/src/inc +INCLUDES += -I$(CFE_PATH)/src/time +INCLUDES += -I$(CFE_PATH)/src/sb +INCLUDES += -I$(CFE_PATH)/src/es +INCLUDES += -I$(CFE_PATH)/src/evs +INCLUDES += -I$(CFE_PATH)/src/fs +INCLUDES += -I$(CFE_PATH)/src/tbl +INCLUDES += -I$(CFE_PATH)/../mission_inc +INCLUDES += -I$(CFE_PATH)/../platform_inc/cpu1 +INCLUDES += -I$(OSAL_PATH)/src/os/inc +INCLUDES += -I$(OSAL_PATH)/build/inc +INCLUDES += -I$(PSP_PATH)/fsw/inc +INCLUDES += -I$(PSP_PATH)/fsw/pc-linux/inc + +# +# UT_OBJS specifies unit test object files. +# +UT_OBJS := ut_osapi_stubs.o +UT_OBJS += ut_osfileapi_stubs.o +UT_OBJS += ut_cfe_psp_memutils_stubs.o +UT_OBJS += ut_cfe_sb_stubs.o +UT_OBJS += ut_cfe_sb_hooks.o +UT_OBJS += ut_cfe_es_stubs.o +UT_OBJS += ut_cfe_es_hooks.o +UT_OBJS += ut_cfe_evs_stubs.o +UT_OBJS += ut_cfe_evs_hooks.o +UT_OBJS += ut_cfe_tbl_stubs.o +UT_OBJS += ut_cfe_tbl_hooks.o +UT_OBJS += ut_cfe_fs_stubs.o +UT_OBJS += utassert.o +UT_OBJS += utlist.o +UT_OBJS += uttest.o +UT_OBJS += uttools.o +UT_OBJS += $(APP)_testcase.o +UT_OBJS += $(APP)_stubs.o + +# +# APP_OBJS specifies flight software object files. +# +APP_OBJS := $(APP)_app.o $(APP)_utils.o $(APP)_cmds.o + + +############################################################################### + +COMPILER=gcc +LINKER=gcc + +# +# Compiler and Linker Options +# +ENABLE_GCOV = TRUE +ifeq ($(ENABLE_GCOV), TRUE) +GCOV_COPT = -fprofile-arcs -ftest-coverage -pg -p +GCOV_LOPT = -pg -p -fprofile-arcs -ftest-coverage -lgcov +endif + +#WARNINGS = -Wall -W -ansi -Werror -Wstrict-prototypes -Wundef +WARNINGS = -Wall -Wstrict-prototypes +DEBUGGER = -g + +COPT = $(WARNINGS) $(DEBUGGER) $(GCOV_COPT) -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ +#COPT = $(WARNINGS) $(DEBUGGER) $(GCOV_COPT) -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D_ix86_ + +LOPT = $(GCOV_LOPT) + +############################################################################### +## Rule to make the specified TARGET +## +%.exe: %.o + $(LINKER) $(LOPT) $^ -o $*.exe + +############################################################################### +## "C" COMPILER RULE +## +%.o: %.c + $(COMPILER) -c $(COPT) $(INCLUDES) $< + +############################################################################## +## + +all:$(APP)_testrunner.exe + +$(APP)_testrunner.exe: $(APP)_testrunner.o $(UT_OBJS) $(APP_OBJS) + +clean :: + rm -f *.o *.exe *.gcda *.gcno *.gcov gmon.out + +run :: + ./$(APP)_testrunner.exe + +#gcov :: +# @echo +# @gcov $(APP_OBJS:.o=.gcda) | sed 'N;s/\n/ /' | \ +# sed -n '/File/p' | sed '/ads/d' | \ +# sed 's/ Lines executed:/ /; s/File/gcov:/; s/of//' +# @rm -f *.gcda *.gcno +# @echo + +gcov :: + @echo + @gcov $(APP_OBJS:.o=.gcda) | sed 'N;s/\n/ /' | \ + sed -n '/File/p' | sed '/ads/d' | sed -e '/\.h/d' | \ + sed 's/ Lines executed:/ /; s/File/gcov:/; s/of// ' + @rm -f *.gcda *.gcno + @echo + +# end of file diff --git a/fsw/unit_test/out b/fsw/unit_test/out new file mode 100644 index 0000000..3382665 --- /dev/null +++ b/fsw/unit_test/out @@ -0,0 +1,23 @@ +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc to_testrunner.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_osapi_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_osfileapi_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_psp_memutils_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_sb_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_sb_hooks.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_es_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_es_hooks.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_evs_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_evs_hooks.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_tbl_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_tbl_hooks.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/ut_cfe_fs_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/utassert.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/utlist.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/uttest.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ./ut-assert/src/uttools.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc to_testcase.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc to_stubs.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ../src/to_app.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ../src/to_utils.c +gcc -c -Wall -Wstrict-prototypes -g -fprofile-arcs -ftest-coverage -pg -p -DSOFTWARE_LITTLE_BIT_ORDER -D_EL -D__x86_64__ -DUT_VERBOSE -D_LINUX_OS_ -I. -I.. -I../src -I../tables -I../platform_inc -I../mission_inc -I../../../inc -I../../../io_lib/fsw/public_inc -I./ut-assert/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/os/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/time -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/sb -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/es -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/evs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/fs -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/src/tbl -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../mission_inc -I/home/gdecaruf/cfs/COP_CFS/cfe/fsw/cfe-core/../platform_inc/cpu1 -I/home/gdecaruf/cfs/COP_CFS/osal/src/os/inc -I/home/gdecaruf/cfs/COP_CFS/osal/build/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/inc -I/home/gdecaruf/cfs/COP_CFS/psp/fsw/pc-linux/inc ../src/to_cmds.c +gcc -pg -p -fprofile-arcs -ftest-coverage -lgcov to_testrunner.o ut_osapi_stubs.o ut_osfileapi_stubs.o ut_cfe_psp_memutils_stubs.o ut_cfe_sb_stubs.o ut_cfe_sb_hooks.o ut_cfe_es_stubs.o ut_cfe_es_hooks.o ut_cfe_evs_stubs.o ut_cfe_evs_hooks.o ut_cfe_tbl_stubs.o ut_cfe_tbl_hooks.o ut_cfe_fs_stubs.o utassert.o utlist.o uttest.o uttools.o to_testcase.o to_stubs.o to_app.o to_utils.o to_cmds.o -o to_testrunner.exe diff --git a/fsw/unit_test/to_mission_cfg.h b/fsw/unit_test/to_mission_cfg.h new file mode 100644 index 0000000..33e9f82 --- /dev/null +++ b/fsw/unit_test/to_mission_cfg.h @@ -0,0 +1,110 @@ +/******************************************************************************/ +/** \file to_mission_cfg.h +* +* \author Guy de Carufel (Odyssey Space Research), NASA, JSC, ER6 +* +* \brief Mission Configuration Header File for TO Application +* +* \par Limitations, Assumptions, External Events, and Notes: +* - All Mission configuration files should be defined in apps/inc folder. +* +* \par Modification History: +* - 2015-01-09 | Guy de Carufel | Code Started +* - 2016-05-11 | Allen Brown | Updated headers +*******************************************************************************/ +#ifndef _TO_MISSION_CFG_H_ +#define _TO_MISSION_CFG_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +/* +** Pragmas +*/ + +/* +** Local Defines +*/ + +/* +** Include Files +*/ +#include "cfe.h" + +#include "to_perf_ids.h" +#include "to_msgids.h" +#include "to_msgdefs.h" + + +/* Define enable / disable commands. */ +typedef struct +{ + uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint16 usRouteMask; /**< Route Mask to enable */ +} TO_EnableOutputCmd_t; + + +typedef struct +{ + uint8 CmdHeader[CFE_SB_CMD_HDR_SIZE]; + uint16 usRouteMask; /**< Route Mask to enable */ +} TO_DisableOutputCmd_t; + + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint32 uiCounter; +} TO_OutData_t; + + +typedef struct +{ + uint8 ucTlmHeader[CFE_SB_TLM_HDR_SIZE]; + uint16 usCmdCnt; /**< Count of all commands received */ + uint16 usCmdErrCnt; /**< Count of command errors */ + uint16 usMsgSubCnt; /**< Count of subscribed messages by all + telemetry pipe. */ + uint16 usMsgSubErrCnt; /**< Count of subscription errors */ + uint16 usTblUpdateCnt; /**< Count of table updates through CFE_TBL */ + uint16 usTblErrCnt; /**< Count of table update errors */ + uint16 usConfigRoutes; /**< Current mask of configured routes */ + uint16 usEnabledRoutes; /**< Current mask of enabled routes */ + uint16 usPktCnt; /**< Count of packet sent */ + uint16 usPktErrCnt; /**< Count of packet processing errors */ + uint16 usFrameErrCnt; /**< Count of frame errors */ +} TO_HkTlm_t; + + + +/* +** Local Structure Declarations +*/ + +/* +** External Global Variables +*/ + +/* +** Global Variables +*/ + +/* +** Local Variables +*/ + +/* +** Local Function Prototypes +*/ + +#ifdef __cplusplus +} +#endif + +#endif /* _TO_MISSION_CFG_H_ */ + +/*============================================================================== +** End of file to_mission_cfg.h +**============================================================================*/ + diff --git a/fsw/unit_test/to_platform_cfg.h b/fsw/unit_test/to_platform_cfg.h new file mode 100644 index 0000000..e604e6c --- /dev/null +++ b/fsw/unit_test/to_platform_cfg.h @@ -0,0 +1,22 @@ +/* + * File: to_platform_config.h + * + * Purpose: + * Platform config for unit test. + * + * History: + * Feb 2, 2016 G. de Carufel + * * + */ + +#ifndef _Ut_TO_PLATFORM_CONFIG_H_ +#define _Ut_TO_PLATFORM_CONFIG_H_ + +/* Overwrite settings */ +#define TO_MAX_TBL_ENTRIES 5 +#define TO_NUM_CRITICAL_MIDS 3 +#define TO_MAX_WAKEUP_COUNT 3 +#define TO_FRAMING_ENABLED + + +#endif diff --git a/fsw/unit_test/to_stubs.c b/fsw/unit_test/to_stubs.c new file mode 100644 index 0000000..f0c605b --- /dev/null +++ b/fsw/unit_test/to_stubs.c @@ -0,0 +1,190 @@ +/* + * File: to_stubs.c + * + * Purpose: + * Stub out various functions not stubbed out by the UT-Assert code + */ + +#include +#include +#include + +#include "cfe.h" + +#include "to_stubs.h" +#include "to_app.h" +#include "to_cmds.h" + +extern TO_AppData_t g_TO_AppData; +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t); +int32 Ut_OS_CountSemGetInfoHook(uint32 sem_id, OS_count_sem_prop_t *count_prop); + +Ut_TO_ReturnCodeTable_t Ut_TO_ReturnCodeTable[UT_TO_MAX_INDEX]; + +void Ut_TO_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_TO_MAX_INDEX) { + Ut_TO_ReturnCodeTable[Index].Value = RtnVal; + Ut_TO_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported Index In SetReturnCode Call %u\n", Index); + } +} + + +boolean Ut_TO_UseReturnCode(uint32 Index) +{ + if (Ut_TO_ReturnCodeTable[Index].Count > 0) { + Ut_TO_ReturnCodeTable[Index].Count--; + if (Ut_TO_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + + + +/* Functions normally declared in Custom File (to_custom.c) */ +int32 TO_CustomInit(void) +{ + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMINIT_INDEX)) + return Ut_TO_ReturnCodeTable[UT_TO_CUSTOMINIT_INDEX].Value; + + /* Set Critical Message Ids which must always be in config table. */ + g_TO_AppData.criticalMid[0] = TO_HK_TLM_MID; + + /* Route 0: Udp. Linked to CF Channel Index 0. */ + g_TO_AppData.routes[0].usExists = 1; + g_TO_AppData.routes[0].sCfChnlIdx = 0; + + return TO_SUCCESS; +} + + +int32 TO_CustomAppCmds(CFE_SB_MsgPtr_t pCmdMsg) +{ + uint32 uiCmdCode = CFE_SB_GetCmdCode(pCmdMsg); + + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMAPPCMDS_INDEX)) + return Ut_TO_ReturnCodeTable[UT_TO_CUSTOMAPPCMDS_INDEX].Value; + + switch (uiCmdCode) + { + case TO_SEND_DATA_TYPE_CC: + TO_SendDataTypePktCmd(pCmdMsg); + break; + + default: + g_TO_AppData.HkTlm.usCmdCnt++; + CFE_EVS_SendEvent(TO_CMD_INF_EID, CFE_EVS_INFORMATION, + "Received Custom Cmd (%d)", + uiCmdCode); + break; + } + + return TO_SUCCESS; +} + + +/* This implementation simply outputs packet to console by default. */ +int32 TO_CustomProcessData(CFE_SB_MsgPtr_t pTlmMsg, int32 size, int32 tblIdx, + uint16 usRouteId) +{ + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMPROCESSDATA_INDEX)) + { + g_TO_AppData.HkTlm.usPktErrCnt++; + return Ut_TO_ReturnCodeTable[UT_TO_CUSTOMPROCESSDATA_INDEX].Value; + } + + g_TO_AppData.HkTlm.usPktCnt++; + UtPrintf("Packet added to frame %u: ", usRouteId); + UtPrintx(pTlmMsg, size); + + return TO_SUCCESS; +} + +int32 TO_CustomFrameStart(uint16 usRouteId) +{ + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMFRAMESTART_INDEX)) + return Ut_TO_ReturnCodeTable[UT_TO_CUSTOMFRAMESTART_INDEX].Value; + + return TO_SUCCESS; +} + + +int32 TO_CustomFrameSend(uint16 usRouteId, int32 iStatus) +{ + if (iStatus == TO_ERROR) + { + g_TO_AppData.HkTlm.usFrameErrCnt++; + return iStatus; + } + + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMFRAMESEND_INDEX)) + return Ut_TO_ReturnCodeTable[UT_TO_CUSTOMFRAMESEND_INDEX].Value; + + printf("Frame Sent on route %u.\n", usRouteId); + + return TO_SUCCESS; +} + + + +void TO_CustomCleanup(void) +{ + return; +} + +/* Simple set whichever route is received as configured */ +int32 TO_CustomEnableOutputCmd(CFE_SB_MsgPtr_t pCmdMsg) +{ + TO_EnableOutputCmd_t * pCustomCmd = (TO_EnableOutputCmd_t *) pCmdMsg; + int32 routeMask = TO_ERROR; + + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX)) + return Ut_TO_ReturnCodeTable[UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX].Value; + + if (pCustomCmd->usRouteMask & (1<<0)) + { + routeMask |= (1<<0); + TO_SetRouteAsConfigured(0); + } + if (pCustomCmd->usRouteMask & (1<<1)) + { + routeMask |= (1<<1); + TO_SetRouteAsConfigured(1); + } + + return routeMask; +} + +int32 TO_CustomDisableOutputCmd(CFE_SB_Msg_t *pCmdMsg) +{ + TO_DisableOutputCmd_t *pCmd = (TO_DisableOutputCmd_t *) pCmdMsg; + + int32 value; + if (Ut_TO_UseReturnCode(UT_TO_CUSTOMDISABLEOUTPUTCMD_INDEX)) + { + value = Ut_TO_ReturnCodeTable[UT_TO_CUSTOMDISABLEOUTPUTCMD_INDEX].Value; + if (value < 0) + { + g_TO_AppData.HkTlm.usCmdErrCnt++; + } + return value; + } + + g_TO_AppData.usOutputEnabled = 0; + + return pCmd->usRouteMask; +} + +int32 Ut_OS_CountSemGetInfoHook(uint32 sem_id, OS_count_sem_prop_t *count_prop) +{ + (void) sem_id; + + count_prop->value = 0; + return OS_SUCCESS; +} + diff --git a/fsw/unit_test/to_stubs.h b/fsw/unit_test/to_stubs.h new file mode 100644 index 0000000..0971dd5 --- /dev/null +++ b/fsw/unit_test/to_stubs.h @@ -0,0 +1,40 @@ +/* + * File: to_stubs.h + * + * Purpose: + * Provide stubs for unit testing TO + * + * History: + * Feb 2, 2016 G. de Carufel + * * + */ + +#ifndef _Ut_TO_STUBS_H_ +#define _Ut_TO_STUBS_H_ + +#include "uttools.h" + +typedef enum +{ + UT_TO_CUSTOMINIT_INDEX, + UT_TO_CUSTOMAPPCMDS_INDEX, + UT_TO_CUSTOMPROCESSDATA_INDEX, + UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX, + UT_TO_CUSTOMDISABLEOUTPUTCMD_INDEX, + UT_TO_CUSTOMFRAMESTART_INDEX, + UT_TO_CUSTOMFRAMESEND_INDEX, + UT_TO_MAX_INDEX +} Ut_TO_INDEX_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_TO_ReturnCodeTable_t; + + +void Ut_TO_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); +boolean Ut_TO_UseReturnCode(uint32 Index); + + +#endif diff --git a/fsw/unit_test/to_testcase.c b/fsw/unit_test/to_testcase.c new file mode 100644 index 0000000..f3e77ba --- /dev/null +++ b/fsw/unit_test/to_testcase.c @@ -0,0 +1,2493 @@ +/* + * Filename: to_testcase.c + * + * Purpose: This file contains unit test cases for the ci application + * + */ + +/* + * Includes + */ +#include "cfe.h" +#include "cfe_tbl_msg.h" + +#include "to_stubs.h" +#include "to_app.h" +#include "to_grpids.h" + +#include "utassert.h" +#include "uttest.h" +#include "utlist.h" +#include "ut_cfe_tbl_stubs.h" +#include "ut_cfe_tbl_hooks.h" +#include "ut_cfe_evs_stubs.h" +#include "ut_cfe_evs_hooks.h" +#include "ut_cfe_sb_stubs.h" +#include "ut_cfe_sb_hooks.h" +#include "ut_cfe_es_stubs.h" +#include "ut_osapi_stubs.h" +#include "ut_osfileapi_stubs.h" +#include "ut_cfe_fs_stubs.h" +#include + +extern TO_AppData_t g_TO_AppData; + + +TO_ConfigTable_t to_ConfigTable = +{ + { + {TO_HK_TLM_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {TO_OUT_DATA_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {TO_DATA_TYPE_MID, {0,0}, 1, 0xffff, TO_GROUP_APP | TO_MGROUP_ONE, 0,1}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0}, + {TO_UNUSED_ENTRY, {0,0}, 0, 0x0000, TO_GROUP_NONE, 0,0} + } +}; + + +extern void TO_SendDataTypePktCmd(CFE_SB_MsgPtr_t pMsg); +extern int32 Ut_OS_CountSemGetInfoHook(uint32 sem_id, OS_count_sem_prop_t *count_prop); + +/* --------------------- Begin test cases --------------------------------- */ + +/******************************************************************************* +** +** TO_InitEvent Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_InitEvent_RegisterFail(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + Ut_CFE_EVS_SetReturnCode(UT_CFE_EVS_REGISTER_INDEX, + CFE_EVS_UNKNOWN_FILTER, 1); + + /* Execute Test */ + actual = TO_AppInit(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitEvent - Event Register Fail"); +} + +void Test_TO_InitEvent(void) +{ + /* Setup Inputs */ + int32 expected = CFE_SUCCESS; + int32 actual = 0; + + /* Execute Test */ + actual = TO_InitEvent(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitEvent - Nominal"); +} + + +/******************************************************************************* +** +** TO_InitData Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_InitData(void) +{ + /* Setup Inputs */ + int32 expected = TO_SUCCESS; + int32 actual = 0; + + /* Execute Test */ + actual = TO_InitData(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitData - Nominal"); + UtAssert_True(g_TO_AppData.uiWakeupTimeout == TO_WAKEUP_TIMEOUT, + "Side effect test."); +} + + + +/******************************************************************************* +** +** TO_InitCustom Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_CustomInit_Fail(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + + Ut_TO_SetReturnCode(UT_TO_CUSTOMINIT_INDEX, + TO_ERROR, 1); + + /* Execute Test */ + actual = TO_CustomInit(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "CustomInit - Fail"); +} + + +/******************************************************************************* +** +** TO_InitTable Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_InitTable_RegisterFail(void) +{ + /* Setup Inputs */ + int32 expected = -1; + int32 actual = 0; + + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_REGISTER_INDEX, + -1, 1); + + /* Execute Test */ + actual = TO_AppInit(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitTable - RegisterFail"); +} + + +void Test_TO_InitTable_LoadFail(void) +{ + /* Setup Inputs */ + int32 expected = -1; + int32 actual = 0; + + g_TO_AppData.tableHandle = -1; + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_LOAD_INDEX, + -1, 1); + + /* Execute Test */ + actual = TO_InitTable(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitTable - LoadFail"); + UtAssert_True(g_TO_AppData.tableHandle == 0, "Side effect test."); +} + + +void Test_TO_InitTable_ManageFail(void) +{ + /* Setup Inputs */ + int32 expected = -2; + int32 actual = 0; + + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_MANAGE_INDEX, + expected, 1); + + /* Execute Test */ + actual = TO_InitTable(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitTable - ManageFail"); +} + + +void Test_TO_InitTable_GetAddressFail(void) +{ + /* Setup Inputs */ + int32 expected = -3; + int32 actual = 0; + + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_GETADDRESS_INDEX, + expected, 1); + + /* Execute Test */ + actual = TO_InitTable(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitTable - GetAddressFail"); +} + + +void Test_TO_InitTable_NotifyByMessageFail(void) +{ + /* Setup Inputs */ + int32 expected = -4; + int32 actual = 0; + + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_NOTIFYBYMESSAGE_INDEX, + expected, 1); + + /* Execute Test */ + actual = TO_InitTable(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitTable - NotifyByMessageFail"); +} + + +void Test_TO_InitTable(void) +{ + /* Setup Inputs */ + int32 expected = TO_SUCCESS; + int32 actual = 0; + + + /* Execute Test */ + actual = TO_InitTable(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitTable - Nominal"); +} + +/******************************************************************************* +** +** TO_InitPipe Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_InitPipe_CreatePipeFail(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_CREATEPIPE_INDEX, + CFE_SB_BAD_ARGUMENT, 1); + + /* Execute Test */ + actual = TO_AppInit(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitPipe - SCH CreatePipe Fail"); + + expected = CFE_SB_BAD_ARGUMENT; + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_CREATEPIPE_INDEX, + CFE_SB_BAD_ARGUMENT, 2); + + /* Execute Test */ + actual = TO_InitPipe(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitPipe - CMD CreatePipe Fail"); + UtAssert_True(g_TO_AppData.usCmdPipeDepth == TO_CMD_PIPE_DEPTH, + "Side effect test."); + + expected = CFE_SB_BAD_ARGUMENT; + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_CREATEPIPE_INDEX, + CFE_SB_BAD_ARGUMENT, 3); + + /* Execute Test */ + actual = TO_InitPipe(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitPipe - Route 0 TlmPipe CreatePipe Fail"); +} + +void Test_TO_InitPipe_CfChnlIdxFail(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + + g_TO_AppData.routes[0].sCfChnlIdx = TO_NUM_CF_CHANNELS; + + /* Execute Test */ + actual = TO_InitPipe(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitPipe - sCFChnlIdx Invalid"); +} + + +void Test_TO_InitPipe_CfCountSemCreateFail(void) +{ + /* Setup Inputs */ + int32 expected = OS_ERROR; + int32 actual = 0; + + g_TO_AppData.routes[0].sCfChnlIdx = 0; + Ut_OSAPI_SetReturnCode(UT_OSAPI_COUNTSEMCREATE_INDEX, + OS_ERROR, 1); + + /* Execute Test */ + actual = TO_InitPipe(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitPipe - CF CountSemCreate Fail"); +} + + +void Test_TO_InitPipe_SubscribeMsgFail(void) +{ + /* Setup Inputs */ + int32 expected = -1; + int32 actual = 0; + + g_TO_AppData.pConfigTable = NULL; + + /* Execute Test */ + actual = TO_InitPipe(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "InitPipe - Tlm message Subscribe Fail"); +} + + +void Test_TO_InitPipe(void) +{ + /* Setup Inputs */ + int32 expected = CFE_SUCCESS; + int32 actual = 0; + + /* Prepare table first */ + TO_InitTable(); + + /* Execute Test */ + actual = TO_InitPipe(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "Init Pipe - Nominal"); +} + +/******************************************************************************* +** +** TO_AppInit Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_AppInit(void) +{ + /* Setup Inputs */ + int32 expected = TO_SUCCESS; + int32 actual = 0; + + /* Execute Test */ + actual = TO_AppInit(); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "AppInit - Nominal"); +} + + +/******************************************************************************* +** +** TO_ValidateTable Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_ValidateTable_Gap(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + + to_ConfigTable.entries[0].usMsgId = TO_UNUSED_ENTRY; + + /* Execute Test */ + actual = TO_ValidateTable(&to_ConfigTable); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "ValidateTable - Gap Error"); +} + + +void Test_TO_ValidateTable_Duplicate(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + + to_ConfigTable.entries[0].usMsgId = TO_DATA_TYPE_MID; + + /* Execute Test */ + actual = TO_ValidateTable(&to_ConfigTable); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "ValidateTable - Duplicate Error"); +} + + +void Test_TO_ValidateTable_CriticalMid(void) +{ + /* Setup Inputs */ + int32 expected = TO_ERROR; + int32 actual = 0; + + to_ConfigTable.entries[0].usMsgId = TO_HK_TLM_MID; + g_TO_AppData.criticalMid[1] = CFE_EVS_EVENT_MSG_MID; + + /* Execute Test */ + actual = TO_ValidateTable(&to_ConfigTable); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "ValidateTable - CriticalMid Error"); +} + +void Test_TO_ValidateTable(void) +{ + /* Setup Inputs */ + int32 expected = TO_SUCCESS; + int32 actual = 0; + + g_TO_AppData.criticalMid[1] = 0; + + /* Execute Test */ + actual = TO_ValidateTable(&to_ConfigTable); + + /* Verify Outputs */ + UtAssert_True(actual == expected, "ValidateTable - Nominal"); +} + +/******************************************************************************* +** +** TO_AppMain Tests +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_AppMain_RegisterFail(void) +{ + g_TO_AppData.uiWakeupTimeout = 0; + Ut_CFE_ES_SetReturnCode(UT_CFE_ES_REGISTERAPP_INDEX, + -1, 1); + + /* Execute Test */ + TO_AppMain(); + + UtAssert_True(g_TO_AppData.uiWakeupTimeout == 0, + "AppMain - RegisterApp Fail"); +} + + +void Test_TO_AppMain_InitFail(void) +{ + Ut_TO_SetReturnCode(UT_TO_CUSTOMINIT_INDEX, + TO_ERROR, 1); + + TO_AppMain(); + + UtAssert_True(g_TO_AppData.uiWakeupTimeout == TO_WAKEUP_TIMEOUT, + "AppMain - AppInit Fail"); + +} + +void Test_TO_AppMain_RcvMsgFail(void) +{ + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_RCVMSG_INDEX, + CFE_SB_BAD_ARGUMENT, 1); + + TO_AppMain(); + + UtAssert_True(g_TO_AppData.uiRunStatus == CFE_ES_APP_ERROR, + "AppMain - RcvMsg Fail"); + + /* For code coverage */ + TO_CleanupCallback(); +} + + +/******************************************************************************* +** +** TO_RcvMsg Test +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_RcvMsg_NoMsgError(void) +{ + int32 actual; + int32 expected = CFE_SB_NO_MESSAGE; + + /* Initialize the Command pipe and subscribe to messages */ + TO_InitPipe(); + + actual = TO_RcvMsg(CFE_SB_POLL); + UtAssert_True(actual == expected, "RcvMsg - NoMsgError"); +} + +void Test_TO_RcvMsg_BadMsg(void) +{ + int32 actual; + int32 expected = CFE_SUCCESS; + CFE_SB_Msg_t msg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &msg; + + /* Initialize the Command pipe and subscribe to messages */ + TO_InitPipe(); + + CFE_SB_SetMsgId(pMsg, 0); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(msg)); + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.SchPipeId); + + actual = TO_RcvMsg(CFE_SB_PEND_FOREVER); + UtAssert_True(actual == expected, "RcvMsg - Bad MID"); +} + +void Test_TO_RcvMsg_Wakeup(void) +{ + int32 actual; + int32 expected = CFE_SUCCESS; + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + /* Initialize the Command pipe and subscribe to messages */ + TO_InitPipe(); + + CFE_SB_SetMsgId(pMsg, TO_WAKEUP_MID); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(cmdMsg)); + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.SchPipeId); + + actual = TO_RcvMsg(CFE_SB_PEND_FOREVER); + UtAssert_True(actual == expected, "RcvMsg - Wakeup MID"); +} + +void Test_TO_RcvMsg_Timeout(void) +{ + int32 actual; + int32 expected = CFE_SB_TIME_OUT; + + /* Initialize the Command pipe and subscribe to messages */ + TO_InitPipe(); + + actual = TO_RcvMsg(10); + UtAssert_True(actual == expected, "RcvMsg - timeout"); +} + + +/******************************************************************************* +** +** TO_ProcessTlmPipes Test +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_ProcessTlmPipes(void) +{ + TO_AppInit(); + + g_TO_AppData.routes[0].usWakePeriod = 3; + + TO_ProcessTlmPipes(); + UtAssert_True(g_TO_AppData.usWakeupCount == 1, "ProcessTlmPipes - Nominal"); + + TO_ProcessTlmPipes(); + TO_ProcessTlmPipes(); + UtAssert_True(g_TO_AppData.usWakeupCount == 0, "ProcessTlmPipes - Rollover"); +} + + +/******************************************************************************* +** +** TO_ProcessNewData Test +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_ProcessNewData_FrameError(void) +{ + TO_AppInit(); + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 1; + g_TO_AppData.routes[0].usIsEnabled = 1; + + Ut_TO_SetReturnCode(UT_TO_CUSTOMFRAMESTART_INDEX, + TO_ERROR, 1); + + TO_ProcessNewData(&g_TO_AppData.tlmPipes[0], 0); + + UtAssert_True(g_TO_AppData.HkTlm.usFrameErrCnt == 1, + "ProcessNewData - Framing Fail"); +} + + +void Test_TO_ProcessNewData_BadMsg(void) +{ + TO_OutData_t msg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &msg; + + TO_AppInit(); + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 1; + g_TO_AppData.routes[0].usIsEnabled = 1; + + /* Send a Bad Message */ + CFE_SB_SetMsgId(pMsg, 0); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(msg)); + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.tlmPipes[0].cfePipeId); + + TO_ProcessNewData(&g_TO_AppData.tlmPipes[0], 0); + + UtAssert_True(g_TO_AppData.HkTlm.usPktCnt == 0, "ProcessNewData - Bad Msg"); +} + + +void Test_TO_ProcessNewData_CustomProcessError(void) +{ + TO_OutData_t msg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &msg; + + TO_AppInit(); + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 1; + g_TO_AppData.routes[0].usIsEnabled = 1; + + /* Send a Bad Message */ + CFE_SB_SetMsgId(pMsg, TO_OUT_DATA_MID); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(msg)); + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.tlmPipes[0].cfePipeId); + + Ut_TO_SetReturnCode(UT_TO_CUSTOMPROCESSDATA_INDEX, + TO_ERROR, 1); + + TO_ProcessNewData(&g_TO_AppData.tlmPipes[0], 0); + + UtAssert_True(g_TO_AppData.HkTlm.usPktErrCnt == 1, + "ProcessNewData - CustomProcessData Fail"); +} + + +void Test_TO_ProcessNewData(void) +{ + TO_OutData_t msg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &msg; + + TO_AppInit(); + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 1; + g_TO_AppData.routes[0].usIsEnabled = 1; + + /* Send a good Message */ + CFE_SB_SetMsgId(pMsg, TO_OUT_DATA_MID); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(msg)); + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.tlmPipes[0].cfePipeId); + + Ut_OSAPI_SetFunctionHook(UT_OSAPI_COUNTSEMGETINFO_INDEX, + Ut_OS_CountSemGetInfoHook); + + TO_ProcessNewData(&g_TO_AppData.tlmPipes[0], 0); + + UtAssert_True(g_TO_AppData.HkTlm.usPktCnt == 1, + "ProcessNewData - Nominal"); +} + +/******************************************************************************* +** +** TO_ProcessNewCmds Test +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_ProcessNewCmds_BadMsg(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + /* Initialize the Command pipe and subscribe to messages */ + TO_InitPipe(); + + /* Send a Bad Command */ + CFE_SB_SetMsgId(pMsg, 0); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.CmdPipeId); + + TO_ProcessNewCmds(); + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ProcessNewCmds - Bad Msg"); +} + + +void Test_TO_ProcessNewCmds_AppCmd(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + /* Initialize the Command pipe and subscribe to messages */ + TO_InitPipe(); + + /* Send Noop Cmd Command */ + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_NOOP_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.CmdPipeId); + + TO_ProcessNewCmds(); + UtAssert_True(g_TO_AppData.HkTlm.usCmdCnt == 1, + "ProcessNewCmds - AppCmd Msg"); +} + + +void Test_TO_ProcessNewCmds_SendHk(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + TO_InitData(); + TO_InitPipe(); + + CFE_SB_SetMsgId(pMsg, TO_SEND_HK_MID); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + Ut_CFE_SB_AddMsgToPipe(pMsg, g_TO_AppData.CmdPipeId); + + TO_ProcessNewCmds(); + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 0, + "ProcessNewCmds - SendHk Msg"); +} + + + + +/******************************************************************************* +** +** TO_ProcessNewAppCmds Test +** +*******************************************************************************/ + +/*----------------------------------------------------------------------------*/ +void Test_TO_ProcessNewAppCmds_Noop(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_NOOP_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ProcessNewAppCmds - NOOP_CC - Invalid Len."); + + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdCnt == 1, + "ProcessNewAppCmds - NOOP_CC"); +} + + +void Test_TO_ProcessNewAppCmds_Reset(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_RESET_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ProcessNewAppCmds - RESET_CC - Invalid Len."); + + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 0, + "ProcessNewAppCmds - RESET_CC"); +} + + +void Test_TO_ProcessNewAppCmds_Custom(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + /* Send Noop Cmd Command */ + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, 40); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + Ut_TO_SetReturnCode(UT_TO_CUSTOMAPPCMDS_INDEX, + TO_ERROR, 1); + + TO_ProcessNewAppCmds(pMsg); + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ProcessNewCmds - Bad Custom Command"); + + TO_ProcessNewAppCmds(pMsg); + UtAssert_True(g_TO_AppData.HkTlm.usCmdCnt == 1, + "ProcessNewCmds - Custom Command"); + +} + + +/******************************************************************************* +** +** TO_EnableOutputCmd Test +** +*******************************************************************************/ +void Test_TO_EnableOutputCmd_MsgLength(void) +{ + TO_EnableOutputCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ENABLE_OUTPUT_CC - Invalid Len."); +} + + +void Test_TO_EnableOutputCmd(void) +{ + TO_EnableOutputCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + int32 expected = 1; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_EnableOutputCmd_t)); + + /* Setup */ + Ut_TO_SetReturnCode(UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX, + TO_ERROR, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "EnableOutputCmd - Custom fail."); + + /* Setup */ + Ut_TO_SetReturnCode(UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX, + 0xffffff, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "EnableOutputCmd - RouteMask exceeds TO_MAX_ROUTE_MASK."); + + + /* Setup */ + Ut_TO_SetReturnCode(UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX, + 0xffff, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "EnableOutputCmd - RouteMask includes un-configured routes"); + + /* Setup */ + g_TO_AppData.routes[0].usExists = 1; + TO_SetRouteAsConfigured(0); + Ut_TO_SetReturnCode(UT_TO_CUSTOMENABLEOUTPUTCMD_INDEX, + 0x0001, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.usOutputEnabled == 1 && + g_TO_AppData.routes[0].usIsEnabled == 1, + "EnableOutputCmd - Nominal."); +} + + +/******************************************************************************* +** +** TO_DisableOutputCmd Test +** +*******************************************************************************/ +void Test_TO_DisableOutputCmd_MsgLength(void) +{ + TO_DisableOutputCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "DISABLE_OUTPUT_CC - Invalid Len."); +} + + + +void Test_TO_DisableOutputCmd(void) +{ + int32 expected = 1; + TO_DisableOutputCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_DisableOutputCmd_t)); + + /* Setup */ + Ut_TO_SetReturnCode(UT_TO_CUSTOMDISABLEOUTPUTCMD_INDEX, + TO_ERROR, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "DisableOutputCmd - Custom fail."); + + /* Setup */ + Ut_TO_SetReturnCode(UT_TO_CUSTOMDISABLEOUTPUTCMD_INDEX, + 0xffffff, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "DisableOutputCmd - RouteMask exceeds TO_MAX_ROUTE_MASK."); + + + /* Setup */ + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.routes[0].usIsEnabled = 1; + cmdMsg.usRouteMask = 0x0000; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.usOutputEnabled == 0 && + g_TO_AppData.routes[0].usIsEnabled == 1, + "DisableOutputCmd - Nominal no routeMask."); + + /* Setup */ + g_TO_AppData.routes[0].usExists = 1; + TO_SetRouteAsConfigured(0); + g_TO_AppData.routes[0].usIsEnabled = 1; + g_TO_AppData.usOutputEnabled = 1; + cmdMsg.usRouteMask = 0x0001; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.usOutputEnabled == 0 && + g_TO_AppData.routes[0].usIsEnabled == 0, + "DisableOutputCmd - Nominal with routeMask."); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.usOutputEnabled == 0 && + g_TO_AppData.routes[0].usIsEnabled == 0, + "DisableOutputCmd - Second call ignored."); +} + +/******************************************************************************* +** +** TO_ActivateRoutesCmd Test +** +*******************************************************************************/ +void Test_TO_ActivateRoutesCmd_MsgLength(void) +{ + TO_RouteMaskArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ACTIVATE_ROUTES_CC - Invalid Len."); +} + + +void Test_TO_ActivateRoutesCmd(void) +{ + TO_RouteMaskArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ACTIVATE_ROUTES_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_RouteMaskArgCmd_t)); + + cmdMsg.usRouteMask = 0x0001; + + TO_SetRouteAsUnconfigured(0); + g_TO_AppData.routes[0].usIsEnabled = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ACTIVATE_ROUTES_CC - Non-configured routeMask"); + + + g_TO_AppData.routes[0].usExists = 1; + TO_SetRouteAsConfigured(0); + g_TO_AppData.routes[0].usIsEnabled = 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.routes[0].usIsEnabled == 1, + "ACTIVATE_ROUTES_CC - Route Already Enabled"); + + cmdMsg.usRouteMask = 0x0000; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usEnabledRoutes == 0x0001, + "ACTIVATE_ROUTES_CC - Empty routeMask check"); +} + + +/******************************************************************************* +** +** TO_DeactivateRoutesCmd Test +** +*******************************************************************************/ +void Test_TO_DeactivateRoutesCmd_MsgLength(void) +{ + TO_RouteMaskArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DEACTIVATE_ROUTES_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "DEACTIVATE_ROUTES_CC - Invalid Len."); +} + + +void Test_TO_DeactivateRoutesCmd(void) +{ + TO_RouteMaskArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DEACTIVATE_ROUTES_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_RouteMaskArgCmd_t)); + + g_TO_AppData.routes[0].usIsEnabled = 1; + g_TO_AppData.routes[1].usIsEnabled = 1; + g_TO_AppData.HkTlm.usEnabledRoutes = 0x0003; + cmdMsg.usRouteMask = 0x0001; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.routes[0].usIsEnabled == 0 && + g_TO_AppData.routes[1].usIsEnabled == 1 && + g_TO_AppData.HkTlm.usEnabledRoutes == 0x0002, + "DEACTIVATE_ROUTES_CC - Nominal"); +} + + +/******************************************************************************* +** +** TO_PauseOutputCmd Test +** +*******************************************************************************/ +void Test_TO_PauseOutputCmd_MsgLength(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_PAUSE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "PAUSE_OUTPUT_CC - Invalid Len."); +} + + +void Test_TO_PauseOutputCmd(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_PAUSE_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + g_TO_AppData.usOutputEnabled = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "PAUSE_OUTPUT_CC - Output Disabled, can't pause."); + + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.usOutputActive == 0, + "PAUSE_OUTPUT_CC - Nominal"); +} + + +/******************************************************************************* +** +** TO_ResumeOutputCmd Test +** +*******************************************************************************/ +void Test_TO_ResumeOutputCmd_MsgLength(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_RESUME_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "RESUME_OUTPUT_CC - Invalid Len."); +} + + +void Test_TO_ResumeOutputCmd(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_RESUME_OUTPUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + g_TO_AppData.usOutputEnabled = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "RESUME_OUTPUT_CC - Output Disabled, can't resume."); + + g_TO_AppData.usOutputEnabled = 1; + g_TO_AppData.usOutputActive = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.usOutputActive == 1, + "RESUME_OUTPUT_CC - Nominal"); +} + + +/******************************************************************************* +** +** TO_AddTblEntryCmd Test +** +*******************************************************************************/ +void Test_TO_AddTblEntryCmd_MsgLength(void) +{ + TO_AddTblEntryCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ADD_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ADD_TBL_ENTRY_CC - Invalid Len."); +} + + +void Test_TO_AddTblEntryCmd(void) +{ + int32 expected = 1; + TO_AddTblEntryCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ADD_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_AddTblEntryCmd_t)); + + cmdMsg.usMsgId = TO_UNUSED_ENTRY; + + /* Initialize Table */ + TO_InitTable(); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ADD_TBL_ENTRY_CC - Bad MID Arg."); + + cmdMsg.usMsgId = CFE_EVS_EVENT_MSG_MID; + + g_TO_AppData.pConfigTable->entries[3].usMsgId = TO_HK_TLM_MID; + g_TO_AppData.pConfigTable->entries[4].usMsgId = TO_HK_TLM_MID; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ADD_TBL_ENTRY_CC - Table Full"); + + cmdMsg.usMsgId = TO_HK_TLM_MID; + + g_TO_AppData.pConfigTable->entries[3].usMsgId = TO_UNUSED_ENTRY; + g_TO_AppData.pConfigTable->entries[4].usMsgId = TO_UNUSED_ENTRY; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ADD_TBL_ENTRY_CC - Duplicate MID entries"); + + g_TO_AppData.routes[0].usExists = 1; + cmdMsg.usMsgId = CFE_EVS_EVENT_MSG_MID; + cmdMsg.usRouteMask = 0x0001; + + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_SUBSCRIBEEX_INDEX, + -1, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ADD_TBL_ENTRY_CC - Subscription Failed"); + + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[3].usMsgId == CFE_EVS_EVENT_MSG_MID, + "ADD_TBL_ENTRY_CC - Nominal"); +} + + +/******************************************************************************* +** +** TO_RemoveTblEntryCmd - Test +** +*******************************************************************************/ +void Test_TO_RemoveTblEntryCmd_MsgLength(void) +{ + TO_MidArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_REMOVE_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "REMOVE_TBL_ENTRY_CC - Invalid Len."); +} + + +void Test_TO_RemoveTblEntryCmd(void) +{ + int32 expected = 1; + TO_MidArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_REMOVE_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_MidArgCmd_t)); + + cmdMsg.usMsgId = TO_UNUSED_ENTRY; + + /* Initialize Table */ + TO_InitTable(); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "REMOVE_TBL_ENTRY_CC - Bad MID Arg."); + + cmdMsg.usMsgId = CFE_EVS_EVENT_MSG_MID; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "REMOVE_TBL_ENTRY_CC - MID not found."); + + cmdMsg.usMsgId = TO_HK_TLM_MID; + g_TO_AppData.routes[0].usExists = 1; + + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_UNSUBSCRIBE_INDEX, + -1, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "REMOVE_TBL_ENTRY_CC - Unsubscription Failed"); + + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usMsgId == TO_REMOVED_ENTRY, + "REMOVE_TBL_ENTRY_CC - Nominal"); +} + + +/******************************************************************************* +** +** TO_EnableTblEntryCmd - Test +** +*******************************************************************************/ +void Test_TO_EnableTblEntryCmd_MsgLength(void) +{ + TO_MidArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ENABLE_TBL_ENTRY_CC - Invalid Len."); +} + + +void Test_TO_EnableTblEntryCmd(void) +{ + int32 expected = 1; + TO_MidArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_MidArgCmd_t)); + + cmdMsg.usMsgId = TO_UNUSED_ENTRY; + + /* Initialize Table */ + TO_InitTable(); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ENABLE_TBL_ENTRY_CC - Bad MID Arg."); + + cmdMsg.usMsgId = CFE_EVS_EVENT_MSG_MID; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ENABLE_TBL_ENTRY_CC - MID not found."); + + cmdMsg.usMsgId = TO_HK_TLM_MID; + g_TO_AppData.pConfigTable->entries[0].usState = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 1, + "ENABLE_TBL_ENTRY_CC - Nominal"); + + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 1, + "ENABLE_TBL_ENTRY_CC - Second call ignored"); +} + + +/******************************************************************************* +** +** TO_DisableTblEntryCmd - Test +** +*******************************************************************************/ +void Test_TO_DisableTblEntryCmd_MsgLength(void) +{ + TO_MidArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "DISABLE_TBL_ENTRY_CC - Invalid Len."); +} + + +void Test_TO_DisableTblEntryCmd(void) +{ + int32 expected = 1; + TO_MidArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_TBL_ENTRY_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_MidArgCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + cmdMsg.usMsgId = TO_UNUSED_ENTRY; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "DISABLE_TBL_ENTRY_CC - Bad MID Arg."); + + cmdMsg.usMsgId = CFE_EVS_EVENT_MSG_MID; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "DISABLE_TBL_ENTRY_CC - MID not found."); + + cmdMsg.usMsgId = TO_HK_TLM_MID; + g_TO_AppData.pConfigTable->entries[0].usState = 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 0, + "DISABLE_TBL_ENTRY_CC - Nominal"); + + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 0, + "DISABLE_TBL_ENTRY_CC - Second call ignored"); +} + +/******************************************************************************* +** +** TO_EnableGroupCmd - Test +** +*******************************************************************************/ +void Test_TO_EnableGroupCmd_MsgLength(void) +{ + TO_GroupArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_GROUP_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ENABLE_GROUP_CC - Invalid Len."); +} + +void Test_TO_EnableGroupCmd(void) +{ + int32 expected = 1; + TO_GroupArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_GROUP_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_GroupArgCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + cmdMsg.uiGroupData = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ENABLE_GROUP_CC - Bad Group Arg."); + + cmdMsg.uiGroupData = TO_MGROUP_TWO; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "ENABLE_GROUP_CC - Group not found."); + + cmdMsg.uiGroupData = TO_MGROUP_ONE; + + g_TO_AppData.pConfigTable->entries[0].usState = 0; + g_TO_AppData.pConfigTable->entries[1].usState = 0; + g_TO_AppData.pConfigTable->entries[2].usState = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 1, + "ENABLE_GROUP_CC - Nominal"); + + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 1, + "ENABLE_GROUP_CC - Second call ignored"); +} + + +/******************************************************************************* +** +** TO_DisableGroupCmd - Test +** +*******************************************************************************/ +void Test_TO_DisableGroupCmd_MsgLength(void) +{ + TO_GroupArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_GROUP_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "DISABLE_GROUP_CC - Invalid Len."); +} + +void Test_TO_DisableGroupCmd(void) +{ + int32 expected = 1; + TO_GroupArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_GROUP_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_GroupArgCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + cmdMsg.uiGroupData = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "DISABLE_GROUP_CC - Bad Group Arg."); + + cmdMsg.uiGroupData = TO_MGROUP_TWO; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "DISABLE_GROUP_CC - Group not found."); + + cmdMsg.uiGroupData = TO_MGROUP_ONE; + + g_TO_AppData.pConfigTable->entries[0].usState = 1; + g_TO_AppData.pConfigTable->entries[1].usState = 1; + g_TO_AppData.pConfigTable->entries[2].usState = 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 0, + "DISABLE_GROUP_CC - Nominal"); + + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 0, + "DISABLE_GROUP_CC - Second call ignored"); +} + +/******************************************************************************* +** +** TO_EnableAllCmd - Test +** +*******************************************************************************/ +void Test_TO_EnableAllCmd_MsgLength(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_ALL_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "ENABLE_ALL_CC - Invalid Len."); +} + +void Test_TO_EnableAllCmd(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_ENABLE_ALL_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + g_TO_AppData.pConfigTable->entries[0].usState = 0; + g_TO_AppData.pConfigTable->entries[1].usState = 0; + g_TO_AppData.pConfigTable->entries[2].usState = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 1, + "ENABLE_ALL_CC - Nominal"); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 1, + "ENABLE_ALL_CC - Second call ignored."); +} + +/******************************************************************************* +** +** TO_DisableAllCmd - Test +** +*******************************************************************************/ +void Test_TO_DisableAllCmd_MsgLength(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_ALL_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "DISABLE_ALL_CC - Invalid Len."); +} + +void Test_TO_DisableAllCmd(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_DISABLE_ALL_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + g_TO_AppData.pConfigTable->entries[0].usState = 1; + g_TO_AppData.pConfigTable->entries[1].usState = 1; + g_TO_AppData.pConfigTable->entries[2].usState = 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 0, + "DISABLE_ALL_CC - Nominal"); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usState == 0, + "DISABLE_ALL_CC - Second call ignored."); +} + +/******************************************************************************* +** +** TO_SetRouteByMidCmd - Test +** +*******************************************************************************/ +void Test_TO_SetRouteByMidCmd_MsgLength(void) +{ + TO_SetRouteByMidCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_ROUTE_BY_MID_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "SET_ROUTE_BY_MID_CC - Invalid Len."); +} + +void Test_TO_SetRouteByMidCmd(void) +{ + int32 expected = 1; + TO_SetRouteByMidCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_ROUTE_BY_MID_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_SetRouteByMidCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + cmdMsg.usMsgId = TO_UNUSED_ENTRY; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_BY_MID_CC - Bad MID Arg."); + + + cmdMsg.usMsgId = CFE_EVS_EVENT_MSG_MID; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_BY_MID_CC - MID not found."); + + cmdMsg.usMsgId = TO_HK_TLM_MID; + cmdMsg.usRouteMask = 0x0003; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[0].usRouteMask == 0x0003, + "SET_ROUTE_BY_MID_CC - Nominal"); +} + +/******************************************************************************* +** +** TO_SetRouteByGroupCmd - Test +** +*******************************************************************************/ +void Test_TO_SetRouteByGroupCmd_MsgLength(void) +{ + TO_SetRouteByGroupCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_ROUTE_BY_GROUP_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "SET_ROUTE_BY_GROUP_CC - Invalid Len."); +} + +void Test_TO_SetRouteByGroupCmd(void) +{ + int32 expected = 1; + TO_SetRouteByGroupCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_ROUTE_BY_GROUP_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_SetRouteByGroupCmd_t)); + + /* Initialize Table */ + TO_InitTable(); + + cmdMsg.uiGroupData = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_BY_GROUP_CC - Bad Group Arg."); + + + cmdMsg.uiGroupData = TO_MGROUP_TWO; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_BY_GROUP_CC - Group not found."); + + + cmdMsg.uiGroupData = TO_MGROUP_ONE; + cmdMsg.usRouteMask = 0x0003; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[1].usRouteMask == 0x0003, + "SET_ROUTE_BY_GROUP_CC - Nominal"); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.pConfigTable->entries[1].usRouteMask == 0x0003, + "SET_ROUTE_BY_GROUP_CC - Second call ignored"); +} + + +/******************************************************************************* +** +** TO_ManageTableCmd Test +** +*******************************************************************************/ +void Test_TO_ManageTableCmd_MsgLength(void) +{ + CFE_TBL_NotifyCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_MANAGE_TABLE_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "MANAGE_TABLE_CC - Invalid Len."); +} + + +void Test_TO_ManageTableCmd(void) +{ + int32 expected = 1; + CFE_TBL_NotifyCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_MANAGE_TABLE_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(cmdMsg)); + + TO_InitTable(); + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_RELEASEADDRESS_INDEX, -1, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "MANAGE_TABLE_CC - ReleaseAddress fail."); + + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_MANAGE_INDEX, -1, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "MANAGE_TABLE_CC - Manage fail."); + + Ut_CFE_TBL_SetReturnCode(UT_CFE_TBL_GETADDRESS_INDEX, -1, 1); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "MANAGE_TABLE_CC - GetAddress fail."); + + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_UNSUBSCRIBE_INDEX, -1, 1); + CFE_TBL_Load(g_TO_AppData.tableHandle, CFE_TBL_SRC_ADDRESS, TO_CONFIG_FILENAME); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "MANAGE_TABLE_CC - Unsubscribe fail."); + + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_SUBSCRIBEEX_INDEX, -1, 1); + CFE_TBL_Load(g_TO_AppData.tableHandle, CFE_TBL_SRC_ADDRESS, TO_CONFIG_FILENAME); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "MANAGE_TABLE_CC - Subscribe fail."); + + CFE_TBL_Load(g_TO_AppData.tableHandle, CFE_TBL_SRC_ADDRESS, TO_CONFIG_FILENAME); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usTblUpdateCnt == 1, + "MANAGE_TABLE_CC - Nominal."); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usTblUpdateCnt == 1, + "MANAGE_TABLE_CC - Second call ingored."); +} + +/******************************************************************************* +** +** TO_SetRoutePeriodCmd - Test +** +*******************************************************************************/ +void Test_TO_SetRoutePeriodCmd_MsgLength(void) +{ + TO_SetRoutePeriodCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_ROUTE_PERIOD_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "SET_ROUTE_PERIOD_CC - Invalid Len."); +} + +void Test_TO_SetRoutePeriodCmd(void) +{ + int32 expected = 1; + TO_SetRoutePeriodCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_ROUTE_PERIOD_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_SetRoutePeriodCmd_t)); + + g_TO_AppData.routes[0].usExists = 0; + cmdMsg.usRouteMask = 0x0001; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_PERIOD_CC - Route does not exist."); + + g_TO_AppData.routes[0].usExists = 1; + cmdMsg.usWakePeriod = TO_MAX_WAKEUP_COUNT + 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_PERIOD_CC - WakePeriod to large."); + + cmdMsg.usWakePeriod = TO_MAX_WAKEUP_COUNT - 1; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_ROUTE_PERIOD_CC - WakePeriod invalid."); + + cmdMsg.usWakePeriod = TO_MAX_WAKEUP_COUNT; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.routes[0].usWakePeriod = TO_MAX_WAKEUP_COUNT, + "SET_ROUTE_PERIOD_CC - Nominal"); +} + + +/******************************************************************************* +** +** TO_SetWakeupTimeoutCmd - Test +** +*******************************************************************************/ +void Test_TO_SetWakeupTimeoutCmd_MsgLength(void) +{ + TO_SetWakeupTimeoutCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_WAKEUP_TIMEOUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "SET_WAKEUP_TIMEOUT_CC - Invalid Len."); +} + +void Test_TO_SetWakeupTimeoutCmd(void) +{ + int32 expected = 1; + TO_SetWakeupTimeoutCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SET_WAKEUP_TIMEOUT_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_SetWakeupTimeoutCmd_t)); + + cmdMsg.uiWakeupTimeout = 0; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + expected += UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == expected, + "SET_WAKEUP_TIMEOUT_CC - WakeupTimeout too small."); + + cmdMsg.uiWakeupTimeout = CFE_SB_PEND_FOREVER; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.uiWakeupTimeout == CFE_SB_PEND_FOREVER, + "SET_WAKEUP_TIMEOUT_CC - Nominal (Pend forever)"); + + cmdMsg.uiWakeupTimeout = TO_MIN_WAKEUP_TIMEOUT; + + /* Execute test */ + TO_ProcessNewAppCmds(pMsg); + + UtAssert_True(g_TO_AppData.uiWakeupTimeout == TO_MIN_WAKEUP_TIMEOUT, + "SET_WAKEUP_TIMEOUT_CC - Nominal"); +} + +/******************************************************************************* +** +** TO_SendDataTypePktCmd - Test +** +*******************************************************************************/ +void Test_TO_SendDataTypePktCmd_MsgLength(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SEND_DATA_TYPE_CC); + CFE_SB_SetTotalMsgLength(pMsg, 20); + + /* Execute test */ + TO_SendDataTypePktCmd(pMsg); + + UtAssert_True(g_TO_AppData.HkTlm.usCmdErrCnt == 1, + "SEND_DATA_TYPE_CC - Invalid Len."); +} + +void Test_TO_SendDataTypePktCmd(void) +{ + TO_NoArgCmd_t cmdMsg; + CFE_SB_MsgPtr_t pMsg = (CFE_SB_MsgPtr_t) &cmdMsg; + + CFE_SB_SetMsgId(pMsg, TO_APP_CMD_MID); + CFE_SB_SetCmdCode(pMsg, TO_SEND_DATA_TYPE_CC); + CFE_SB_SetTotalMsgLength(pMsg, sizeof(TO_NoArgCmd_t)); + + /* Execute test */ + TO_SendDataTypePktCmd(pMsg); + + UtAssert_True(g_TO_AppData.uiWakeupTimeout == TO_MIN_WAKEUP_TIMEOUT, + "SEND_DATA_TYPE_CC - Nominal"); +} + + +/******************************************************************************* +** +** Utilities - Tests +** +*******************************************************************************/ +void Test_TO_DisableRoute(void) +{ + g_TO_AppData.routes[0].usIsEnabled = 1; + + /* Execute test */ + TO_DisableRoute(0); + + UtAssert_True(g_TO_AppData.routes[0].usIsEnabled == 0, + "TO_DisableRoute - Nominal"); +} + + +void Test_TO_GetRouteMask(void) +{ + uint16 routeMask; + + TO_InitTable(); + + /* Execute test */ + routeMask = TO_GetRouteMask(TO_MAX_TBL_ENTRIES); + + UtAssert_True(routeMask == 0x0000, + "TO_DisableRoute - Large table index"); + + + g_TO_AppData.pConfigTable->entries[0].usRouteMask = 0x0005; + routeMask = TO_GetRouteMask(0); + + UtAssert_True(routeMask == 0x0005, + "TO_DisableRoute - Nominal"); +} + + +void Test_TO_GetMessageID(void) +{ + CFE_SB_MsgId_t mid; + + TO_InitTable(); + + /* Execute test */ + mid = TO_GetMessageID(TO_MAX_TBL_ENTRIES); + + UtAssert_True(mid == 0, + "TO_GetMessageID - Large table index"); + + + mid = TO_GetMessageID(0); + + UtAssert_True(mid == TO_HK_TLM_MID, + "TO_GetMessageID - Nominal"); +} + + +void Test_TO_SubscribeAllMsgs(void) +{ + int32 actual; + + TO_InitTable(); + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_SUBSCRIBEEX_INDEX, + -1, 1); + + /* Execute test */ + actual = TO_SubscribeAllMsgs(); + + UtAssert_True(actual == TO_ERROR, + "TO_SubscribeAllMsgs - Subscribe Error"); +} + + +void Test_TO_SubscribeMsg(void) +{ + /* Execute test */ + int32 actual = TO_SubscribeMsg(NULL); + + UtAssert_True(actual == TO_BAD_ARG_ERR, + "TO_SubscribeMsg - NULL input arg."); +} + + +void Test_TO_UnsubscribeAllMsgs(void) +{ + int32 actual; + + /* Execute test */ + actual = TO_UnsubscribeAllMsgs(NULL); + + UtAssert_True(actual == TO_BAD_ARG_ERR, + "TO_UnsubscribeAllMsgs - NULL input arg."); + + TO_InitTable(); + + Ut_CFE_SB_SetReturnCode(UT_CFE_SB_UNSUBSCRIBE_INDEX, + -1, 1); + + /* Execute test */ + actual = TO_UnsubscribeAllMsgs(g_TO_AppData.pConfigTable); + + UtAssert_True(actual == TO_ERROR, + "TO_UnsubscribeAllMsgs - Unsubscribe fail."); + + + /* Execute test */ + actual = TO_UnsubscribeAllMsgs(g_TO_AppData.pConfigTable); + + UtAssert_True(actual == TO_SUCCESS, + "TO_UnsubscribeAllMsgs - Nominal."); +} + + +void Test_TO_UnsubscribeMsg(void) +{ + /* Execute test */ + int32 actual = TO_UnsubscribeMsg(NULL); + + UtAssert_True(actual == TO_BAD_ARG_ERR, + "TO_UnsubscribeMsg - NULL input arg."); +} + +/* ------------------- End of test cases --------------------------------------*/ + + + +/* + * TO_Setup + * + * Purpose: + * Called by the unit test tool to set up the app prior to each test + */ +void TO_Setup(void) +{ + Ut_OSAPI_Reset(); + Ut_CFE_SB_Reset(); + Ut_CFE_ES_Reset(); + Ut_CFE_EVS_Reset(); + Ut_CFE_TBL_Reset(); + + Ut_CFE_TBL_AddTable(TO_CONFIG_FILENAME, (void *) &to_ConfigTable); +} + +/* + * TO_TearDown + * + * Purpose: + * Called by the unit test tool to tear down the app after each test + */ +void TO_TearDown(void) +{ + CFE_PSP_MemSet((void*)&g_TO_AppData.HkTlm, 0x00, + sizeof(g_TO_AppData.HkTlm)); + Ut_CFE_SB_ClearPipes(); +} + + +/* TO_AddTestCase + * + * Purpose: + * Registers the test cases to execute with the unit test tool + */ +void TO_AddTestCase(void) +{ + /* TO_AppInit Tests */ + UtTest_Add(Test_TO_InitEvent_RegisterFail, TO_Setup, TO_TearDown, + "Test_TO_InitEvent_RegisterFail"); + UtTest_Add(Test_TO_InitEvent, TO_Setup, TO_TearDown, + "Test_TO_InitEvent"); + UtTest_Add(Test_TO_InitData, TO_Setup, TO_TearDown, + "Test_TO_InitData"); + UtTest_Add(Test_TO_CustomInit_Fail, TO_Setup, TO_TearDown, + "Test_TO_CustomInit_Fail"); + UtTest_Add(Test_TO_InitTable_RegisterFail, TO_Setup, TO_TearDown, + "Test_TO_InitTable_RegisterFail"); + UtTest_Add(Test_TO_InitTable_LoadFail, TO_Setup, TO_TearDown, + "Test_TO_InitTable_LoadFail"); + UtTest_Add(Test_TO_InitTable_ManageFail, TO_Setup, TO_TearDown, + "Test_TO_InitTable_ManageFail"); + UtTest_Add(Test_TO_InitTable_GetAddressFail, TO_Setup, TO_TearDown, + "Test_TO_InitTable_GetAddressFail"); + UtTest_Add(Test_TO_InitTable_NotifyByMessageFail, TO_Setup, TO_TearDown, + "Test_TO_InitTable_NotifyByMessageFail"); + UtTest_Add(Test_TO_InitTable, TO_Setup, TO_TearDown, + "Test_TO_InitTable"); + UtTest_Add(Test_TO_InitPipe_CreatePipeFail, TO_Setup, TO_TearDown, + "Test_TO_InitPipe_CreatePipeFail"); + UtTest_Add(Test_TO_InitPipe_CfChnlIdxFail, TO_Setup, TO_TearDown, + "Test_TO_InitPipe_CfChnlIdxFail"); + UtTest_Add(Test_TO_InitPipe_CfCountSemCreateFail, TO_Setup, TO_TearDown, + "Test_TO_InitPipe_CfCountSemCreateFail"); + UtTest_Add(Test_TO_InitPipe_SubscribeMsgFail, TO_Setup, TO_TearDown, + "Test_TO_InitPipe_SubscribeMsgFail"); + UtTest_Add(Test_TO_InitPipe, TO_Setup, TO_TearDown, + "Test_TO_InitPipe"); + UtTest_Add(Test_TO_AppInit, TO_Setup, TO_TearDown, + "Test_TO_AppInit"); + + /* TO_ValidateTable */ + UtTest_Add(Test_TO_ValidateTable_Gap, TO_Setup, TO_TearDown, + "Test_TO_ValidateTable_Gap"); + UtTest_Add(Test_TO_ValidateTable_Duplicate, TO_Setup, TO_TearDown, + "Test_TO_ValidateTable_Duplicate"); + UtTest_Add(Test_TO_ValidateTable_CriticalMid, TO_Setup, TO_TearDown, + "Test_TO_ValidateTable_CriticalMid"); + UtTest_Add(Test_TO_ValidateTable, TO_Setup, TO_TearDown, + "Test_TO_ValidateTable"); + + /* TO_AppMain */ + UtTest_Add(Test_TO_AppMain_RegisterFail, TO_Setup, TO_TearDown, + "Test_TO_AppMain_Registerfail"); + UtTest_Add(Test_TO_AppMain_InitFail, TO_Setup, TO_TearDown, + "Test_TO_AppMain_Initfail"); + UtTest_Add(Test_TO_AppMain_RcvMsgFail, TO_Setup, TO_TearDown, + "Test_TO_AppMain_RcvMsgfail"); + + /* TO_RcvMsg */ + UtTest_Add(Test_TO_RcvMsg_NoMsgError, TO_Setup, TO_TearDown, + "Test_TO_RcvMsg_NoMsgError"); + UtTest_Add(Test_TO_RcvMsg_BadMsg, TO_Setup, TO_TearDown, + "Test_TO_RcvMsg_BadMsg"); + UtTest_Add(Test_TO_RcvMsg_Wakeup, TO_Setup, TO_TearDown, + "Test_TO_RcvMsg_Wakeup"); + UtTest_Add(Test_TO_RcvMsg_Timeout, TO_Setup, TO_TearDown, + "Test_TO_RcvMsg_Timeout"); + + /* TO_ProcessTlmPipes */ + UtTest_Add(Test_TO_ProcessTlmPipes, TO_Setup, TO_TearDown, + "Test_TO_ProcessTlmPipes"); + + /* TO_ProcessNewData */ + UtTest_Add(Test_TO_ProcessNewData_FrameError, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewData_FrameError"); + UtTest_Add(Test_TO_ProcessNewData_BadMsg, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewData_BadMsg"); + UtTest_Add(Test_TO_ProcessNewData_CustomProcessError, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewData_CustomProcessError"); + UtTest_Add(Test_TO_ProcessNewData, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewData"); + + /* TO_ProcessNewCmds */ + UtTest_Add(Test_TO_ProcessNewCmds_BadMsg, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewCmds_BadMsg"); + UtTest_Add(Test_TO_ProcessNewCmds_AppCmd, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewCmds_AppCmd"); + UtTest_Add(Test_TO_ProcessNewCmds_SendHk, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewCmds_SendHk"); + + /* TO_ProcessNewAppCmds */ + UtTest_Add(Test_TO_ProcessNewAppCmds_Noop, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewAppCmds_Noop"); + UtTest_Add(Test_TO_ProcessNewAppCmds_Reset, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewAppCmds_Reset"); + UtTest_Add(Test_TO_ProcessNewAppCmds_Custom, TO_Setup, TO_TearDown, + "Test_TO_ProcessNewAppCmds_Custom"); + + /* Commands */ + UtTest_Add(Test_TO_EnableOutputCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_EnableOutputCmd_MsgLength"); + UtTest_Add(Test_TO_EnableOutputCmd, TO_Setup, TO_TearDown, + "Test_TO_EnableOutputCmd"); + + UtTest_Add(Test_TO_DisableOutputCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_DisableOutputCmd_MsgLength"); + UtTest_Add(Test_TO_DisableOutputCmd, TO_Setup, TO_TearDown, + "Test_TO_DisableOutputCmd"); + + UtTest_Add(Test_TO_ActivateRoutesCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_ActivateRoutesCmd_MsgLength"); + UtTest_Add(Test_TO_ActivateRoutesCmd, TO_Setup, TO_TearDown, + "Test_TO_ActivateRoutesCmd"); + + UtTest_Add(Test_TO_DeactivateRoutesCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_DeactivateRoutesCmd_MsgLength"); + UtTest_Add(Test_TO_DeactivateRoutesCmd, TO_Setup, TO_TearDown, + "Test_TO_DeactivateRoutesCmd"); + + UtTest_Add(Test_TO_PauseOutputCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_PauseOutputCmd_MsgLength"); + UtTest_Add(Test_TO_PauseOutputCmd, TO_Setup, TO_TearDown, + "Test_TO_PauseOutputCmd"); + + UtTest_Add(Test_TO_ResumeOutputCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_ResumeOutputCmd_MsgLength"); + UtTest_Add(Test_TO_ResumeOutputCmd, TO_Setup, TO_TearDown, + "Test_TO_ResumeOutputCmd"); + + UtTest_Add(Test_TO_AddTblEntryCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_AddTblEntryCmd_MsgLength"); + UtTest_Add(Test_TO_AddTblEntryCmd, TO_Setup, TO_TearDown, + "Test_TO_AddTblEntryCmd"); + + UtTest_Add(Test_TO_RemoveTblEntryCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_RemoveTblEntryCmd_MsgLength"); + UtTest_Add(Test_TO_RemoveTblEntryCmd, TO_Setup, TO_TearDown, + "Test_TO_RemoveTblEntryCmd"); + + UtTest_Add(Test_TO_EnableTblEntryCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_EnableTblEntryCmd_MsgLength"); + UtTest_Add(Test_TO_EnableTblEntryCmd, TO_Setup, TO_TearDown, + "Test_TO_EnableTblEntryCmd"); + + UtTest_Add(Test_TO_DisableTblEntryCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_DisableTblEntryCmd_MsgLength"); + UtTest_Add(Test_TO_DisableTblEntryCmd, TO_Setup, TO_TearDown, + "Test_TO_DisableTblEntryCmd"); + + UtTest_Add(Test_TO_EnableGroupCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_EnableGroupCmd_MsgLength"); + UtTest_Add(Test_TO_EnableGroupCmd, TO_Setup, TO_TearDown, + "Test_TO_EnableGroupCmd"); + + UtTest_Add(Test_TO_DisableGroupCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_DisableGroupCmd_MsgLength"); + UtTest_Add(Test_TO_DisableGroupCmd, TO_Setup, TO_TearDown, + "Test_TO_DisableGroupCmd"); + + UtTest_Add(Test_TO_EnableAllCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_EnableAllCmd_MsgLength"); + UtTest_Add(Test_TO_EnableAllCmd, TO_Setup, TO_TearDown, + "Test_TO_EnableAllCmd"); + + UtTest_Add(Test_TO_DisableAllCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_DisableAllCmd_MsgLength"); + UtTest_Add(Test_TO_DisableAllCmd, TO_Setup, TO_TearDown, + "Test_TO_DisableAllCmd"); + + UtTest_Add(Test_TO_SetRouteByMidCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_SetRouteByMidCmd_MsgLength"); + UtTest_Add(Test_TO_SetRouteByMidCmd, TO_Setup, TO_TearDown, + "Test_TO_SetRouteByMidCmd"); + + UtTest_Add(Test_TO_SetRouteByGroupCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_SetRouteByGroupCmd_MsgLength"); + UtTest_Add(Test_TO_SetRouteByGroupCmd, TO_Setup, TO_TearDown, + "Test_TO_SetRouteByGroupCmd"); + + UtTest_Add(Test_TO_ManageTableCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_ManageTableCmd_MsgLength"); + UtTest_Add(Test_TO_ManageTableCmd, TO_Setup, TO_TearDown, + "Test_TO_ManageTableCmd"); + + UtTest_Add(Test_TO_SetRoutePeriodCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_SetRoutePeriodCmd_MsgLength"); + UtTest_Add(Test_TO_SetRoutePeriodCmd, TO_Setup, TO_TearDown, + "Test_TO_SetRoutePeriodCmd"); + + UtTest_Add(Test_TO_SetWakeupTimeoutCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_SetWakeupTimeoutCmd_MsgLength"); + UtTest_Add(Test_TO_SetWakeupTimeoutCmd, TO_Setup, TO_TearDown, + "Test_TO_SetWakeupTimeoutCmd"); + + UtTest_Add(Test_TO_SendDataTypePktCmd_MsgLength, TO_Setup, TO_TearDown, + "Test_TO_SendDataTypePktCmd_MsgLength"); + UtTest_Add(Test_TO_SendDataTypePktCmd, TO_Setup, TO_TearDown, + "Test_TO_SendDataTypePktCmd"); + + + /* Utilities */ + UtTest_Add(Test_TO_DisableRoute, TO_Setup, TO_TearDown, + "Test_TO_DisableRoute"); + UtTest_Add(Test_TO_GetRouteMask, TO_Setup, TO_TearDown, + "Test_TO_GetRouteMask"); + UtTest_Add(Test_TO_GetMessageID, TO_Setup, TO_TearDown, + "Test_TO_GetMessageID"); + UtTest_Add(Test_TO_SubscribeAllMsgs, TO_Setup, TO_TearDown, + "Test_TO_SubscribeAllMsgs"); + UtTest_Add(Test_TO_SubscribeMsg, TO_Setup, TO_TearDown, + "Test_TO_SubscribeMsg"); + UtTest_Add(Test_TO_UnsubscribeAllMsgs, TO_Setup, TO_TearDown, + "Test_TO_UnsubscribeAllMsgs"); + UtTest_Add(Test_TO_UnsubscribeMsg, TO_Setup, TO_TearDown, + "Test_TO_UnsubscribeMsg"); +} diff --git a/fsw/unit_test/to_testrunner.c b/fsw/unit_test/to_testrunner.c new file mode 100644 index 0000000..e7bdbcf --- /dev/null +++ b/fsw/unit_test/to_testrunner.c @@ -0,0 +1,27 @@ + +void TO_AddTestCase(void); + +/* + * Filename: to_testrunner.c + * + * Purpose: This file contains a unit test runner for the CI Application. + * + */ + +/* + * Includes + */ + +#include "uttest.h" + +/* + * Function Definitions + */ + +int main(void) +{ + /* Call AddTestSuite or AddTestCase functions here */ + TO_AddTestCase(); + return(UtTest_Run()); +} + diff --git a/fsw/unit_test/ut-assert/doc/UT_Tool_Users_Guide.doc b/fsw/unit_test/ut-assert/doc/UT_Tool_Users_Guide.doc new file mode 100644 index 0000000..d4668b2 Binary files /dev/null and b/fsw/unit_test/ut-assert/doc/UT_Tool_Users_Guide.doc differ diff --git a/fsw/unit_test/ut-assert/doc/Ut Users Guide.docx b/fsw/unit_test/ut-assert/doc/Ut Users Guide.docx new file mode 100644 index 0000000..7ba77ff Binary files /dev/null and b/fsw/unit_test/ut-assert/doc/Ut Users Guide.docx differ diff --git a/fsw/unit_test/ut-assert/doc/Writing Better Unit Tests.ppt b/fsw/unit_test/ut-assert/doc/Writing Better Unit Tests.ppt new file mode 100644 index 0000000..c3f0c3a Binary files /dev/null and b/fsw/unit_test/ut-assert/doc/Writing Better Unit Tests.ppt differ diff --git a/fsw/unit_test/ut-assert/doc/ut Design.docx b/fsw/unit_test/ut-assert/doc/ut Design.docx new file mode 100644 index 0000000..29db357 Binary files /dev/null and b/fsw/unit_test/ut-assert/doc/ut Design.docx differ diff --git a/fsw/unit_test/ut-assert/doc/ut Requirements.docx b/fsw/unit_test/ut-assert/doc/ut Requirements.docx new file mode 100644 index 0000000..45bfac1 Binary files /dev/null and b/fsw/unit_test/ut-assert/doc/ut Requirements.docx differ diff --git a/fsw/unit_test/ut-assert/doc/ut_design.ppt b/fsw/unit_test/ut-assert/doc/ut_design.ppt new file mode 100644 index 0000000..cb02edf Binary files /dev/null and b/fsw/unit_test/ut-assert/doc/ut_design.ppt differ diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_es_hooks.h b/fsw/unit_test/ut-assert/inc/ut_cfe_es_hooks.h new file mode 100644 index 0000000..ee00c83 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_es_hooks.h @@ -0,0 +1,29 @@ +/* +** +** File: ut_cfe_es_hooks.h +** +** $Id: ut_cfe_es_hooks.h 1.1 2011/05/04 11:20:17EDT rmcgraw Exp $ +** +** Purpose: Unit test header file for cFE Executive Services hooks. +** +** $Log: ut_cfe_es_hooks.h $ +** Revision 1.1 2011/05/04 11:20:17EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:51EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/03/07 17:54:46EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_ES_HOOKS_H_ +#define UT_CFE_ES_HOOKS_H_ + +#include "cfe.h" + +int32 Ut_CFE_ES_RunLoopHook(uint32 *ExitStatus); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_es_stubs.h b/fsw/unit_test/ut-assert/inc/ut_cfe_es_stubs.h new file mode 100644 index 0000000..08b6d47 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_es_stubs.h @@ -0,0 +1,110 @@ +/* +** +** File: ut_cfe_es_stubs.h +** +** $Id: ut_cfe_es_stubs.h 1.2 2011/05/04 11:28:00EDT rmcgraw Exp $ +** +** Purpose: cFE Executive Services Header file for unit test stubs +** +** $Log: ut_cfe_es_stubs.h $ +** Revision 1.2 2011/05/04 11:28:00EDT rmcgraw +** Changed PoolCreateEx to have new parameter USE_MUTEX +** Revision 1.1 2011/05/04 11:20:18EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:51EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/02/15 11:12:32EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_ES_STUBS_H_ +#define UT_CFE_ES_STUBS_H_ + +typedef enum +{ + UT_CFE_ES_RESETCFE_INDEX, + UT_CFE_ES_RESTARTAPP_INDEX, + UT_CFE_ES_RELOADAPP_INDEX, + UT_CFE_ES_DELETEAPP_INDEX, + UT_CFE_ES_EXITAPP_INDEX, + UT_CFE_ES_RUNLOOP_INDEX, + UT_CFE_ES_WAITFORSTARTUPSYNC_INDEX, + UT_CFE_ES_REGISTERAPP_INDEX, + UT_CFE_ES_GETAPPID_INDEX, + UT_CFE_ES_GETAPPIDBYNAME_INDEX, + UT_CFE_ES_GETAPPNAME_INDEX, + UT_CFE_ES_GETAPPINFO_INDEX, + UT_CFE_ES_GETTASKINFO_INDEX, + UT_CFE_ES_REGISTERCHILDTASK_INDEX, + UT_CFE_ES_CREATECHILDTASK_INDEX, + UT_CFE_ES_DELETECHILDTASK_INDEX, + UT_CFE_ES_EXITCHILDTASK_INDEX, + UT_CFE_ES_INCREMENTTASKCOUNTER_INDEX, + UT_CFE_ES_WRITETOSYSLOG_INDEX, + UT_CFE_ES_REGISTERDRIVER_INDEX, + UT_CFE_ES_UNLOADDRIVER_INDEX, + UT_CFE_ES_CALCULATECRC_INDEX, + UT_CFE_ES_REGISTERCDS_INDEX, + UT_CFE_ES_COPYTOCDS_INDEX, + UT_CFE_ES_RESTOREFROMCDS_INDEX, + UT_CFE_ES_POOLCREATE_INDEX, + UT_CFE_ES_POOLCREATEEX_INDEX, + UT_CFE_ES_GETPOOLBUF_INDEX, + UT_CFE_ES_GETPOOLBUFINFO_INDEX, + UT_CFE_ES_PUTPOOLBUF_INDEX, + UT_CFE_ES_GETMEMPOOLSTATS_INDEX, + UT_CFE_ES_PERFLOGADD_INDEX, + UT_CFE_ES_MAX_INDEX +} Ut_CFE_ES_INDEX_t; + +typedef struct +{ + int32 (*CFE_ES_ResetCFE)(uint32 ResetType); + int32 (*CFE_ES_RestartApp)(uint32 AppID); + int32 (*CFE_ES_ReloadApp)(uint32 AppID_API, const char *AppFileName); + int32 (*CFE_ES_DeleteApp)(uint32 AppID); + int32 (*CFE_ES_ExitApp)(uint32 ExitStatus); + int32 (*CFE_ES_RunLoop)(uint32 *ExitStatus); + int32 (*CFE_ES_WaitForStartupSync)(uint32 TimeOutMilliseconds); + int32 (*CFE_ES_RegisterApp)(void); + int32 (*CFE_ES_GetAppID)(uint32 *AppIdPtr); + int32 (*CFE_ES_GetAppIDByName)(uint32 *AppIdPtr, char *AppName); + int32 (*CFE_ES_GetAppName)(char *AppName, uint32 AppId, uint32 BufferLength); + int32 (*CFE_ES_GetAppInfo)(CFE_ES_AppInfo_t *AppInfo, uint32 AppId); + int32 (*CFE_ES_GetTaskInfo)(CFE_ES_TaskInfo_t *TaskInfo, uint32 TaskId); + int32 (*CFE_ES_RegisterChildTask)(void); + int32 (*CFE_ES_CreateChildTask)(uint32 *TaskIdPtr, const char *TaskName, CFE_ES_ChildTaskMainFuncPtr_t FunctionPtr,const uint32 *StackPtr, uint32 StackSize, uint32 Priority, uint32 Flags); + int32 (*CFE_ES_DeleteChildTask)(uint32 TaskId); + int32 (*CFE_ES_ExitChildTask)(void); + int32 (*CFE_ES_IncrementTaskCounter)(void); + int32 (*CFE_ES_WriteToSysLog)(const char *SpecStringPtr, ...); + int32 (*CFE_ES_RegisterDriver)(uint32 *DriverIdPtr, uint32 *DriverDescPtr); + int32 (*CFE_ES_UnloadDriver)(uint32 DriverId); + int32 (*CFE_ES_CalculateCRC)(void *DataPtr, uint32 DataLength, uint32 InputCRC, uint32 TypeCRC); + int32 (*CFE_ES_RegisterCDS)(CFE_ES_CDSHandle_t *HandlePtr, int32 BlockSize, const char *Name); + int32 (*CFE_ES_CopyToCDS)(CFE_ES_CDSHandle_t Handle, void *DataToCopy); + int32 (*CFE_ES_RestoreFromCDS)(void *RestoreToMemory, CFE_ES_CDSHandle_t Handle); + int32 (*CFE_ES_PoolCreate)(uint32 *HandlePtr, uint8 *MemPtr, uint32 Size); + int32 (*CFE_ES_PoolCreateEx)(uint32 *HandlePtr, uint8 *MemPtr, uint32 Size, uint32 NumBlockSizes, uint32 *BlockSizes, uint16 UseMutex); + int32 (*CFE_ES_GetPoolBuf)(uint32 **BufPtr, CFE_ES_MemHandle_t HandlePtr, uint32 Size); + int32 (*CFE_ES_GetPoolBufInfo)(CFE_ES_MemHandle_t HandlePtr, uint32 *BufPtr); + int32 (*CFE_ES_PutPoolBuf)(CFE_ES_MemHandle_t HandlePtr, uint32 *BufPtr); + int32 (*CFE_ES_GetMemPoolStats)(CFE_ES_MemPoolStats_t *BufPtr, CFE_ES_MemHandle_t Handle); + int32 (*CFE_ES_PerfLogAdd)(uint32 Marker, uint32 EntryExit); +} Ut_CFE_ES_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_CFE_ES_ReturnCodeTable_t; + +void Ut_CFE_ES_Reset(void); +void Ut_CFE_ES_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_CFE_ES_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_evs_hooks.h b/fsw/unit_test/ut-assert/inc/ut_cfe_evs_hooks.h new file mode 100644 index 0000000..601014b --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_evs_hooks.h @@ -0,0 +1,50 @@ +/* +** +** File: ut_cfe_evs_hooks.h +** +** $Id: ut_cfe_evs_hooks.h 1.1 2011/05/04 11:20:18EDT rmcgraw Exp $ +** +** Purpose: Unit test header file for cFE Event Services hooks. +** +** $Log: ut_cfe_evs_hooks.h $ +** Revision 1.1 2011/05/04 11:20:18EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:52EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.3 2011/03/10 11:16:45EST sslegel +** Added EventNotSent and PacketNotSent asserts +** Revision 1.2 2011/02/16 17:06:44EST rmcgraw +** Added "extern UtListHead_t EventQueue;" to ut_cfe_evs_hooks.h +** Revision 1.1 2011/02/15 11:12:32EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_EVS_HOOKS_H_ +#define UT_CFE_EVS_HOOKS_H_ + +#include "cfe.h" +#include "utassert.h" +#include "utlist.h" + +extern UtListHead_t EventQueue; + +#define UtAssert_EventSent(EventID, EventType, EventText, Description) \ + UtAssert(Ut_CFE_EVS_EventSent(EventID, EventType, EventText), Description, __FILE__, __LINE__) + +#define UtAssert_EventNotSent(EventID, EventType, EventText, Description) \ + UtAssert(Ut_CFE_EVS_EventSent(EventID, EventType, EventText) == FALSE, Description, __FILE__, __LINE__) + +#define UtAssert_NoEventSent(Description) \ + UtAssert(UtList_IsEmpty(&EventQueue), Description, __FILE__, __LINE__) + +void Ut_CFE_EVS_ClearEventQueue(void); +uint32 Ut_CFE_EVS_GetEventQueueDepth(void); +uint32 Ut_CFE_EVS_GetEventCount(uint16 EventID, uint16 EventType, char *EventText); +int32 Ut_CFE_EVS_SendEventHook(uint16 EventID, uint16 EventType, char *EventText); +boolean Ut_CFE_EVS_EventSent(uint16 EventID, uint16 EventType, char *EventText); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_evs_stubs.h b/fsw/unit_test/ut-assert/inc/ut_cfe_evs_stubs.h new file mode 100644 index 0000000..cff6dbe --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_evs_stubs.h @@ -0,0 +1,50 @@ +/* +** +** File: ut_cfe_evs_stubs.h +** +** $Id: ut_cfe_evs_stubs.h 1.1 2011/05/04 11:20:19EDT rmcgraw Exp $ +** +** Purpose: cFE Event Services Header file for unit test stubs +** +** $Log: ut_cfe_evs_stubs.h $ +** Revision 1.1 2011/05/04 11:20:19EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:53EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/02/15 11:12:33EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_EVS_STUBS_H_ +#define UT_CFE_EVS_STUBS_H_ + +typedef enum +{ + UT_CFE_EVS_REGISTER_INDEX, + UT_CFE_EVS_SENDEVENT_INDEX, + UT_CFE_EVS_SENDTIMEDEVENT_INDEX, + UT_CFE_EVS_SENDEVENTWITHAPPID_INDEX, + UT_CFE_EVS_MAX_INDEX +} Ut_CFE_EVS_INDEX_t; + +typedef struct +{ + int32 (*CFE_EVS_Register)(void *Filters, uint16 NumEventFilters, uint16 FilterScheme); + int32 (*CFE_EVS_SendEvent)(uint16 EventID, uint16 EventType, char *EventText); +} Ut_CFE_EVS_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_CFE_EVS_ReturnCodeTable_t; + +void Ut_CFE_EVS_Reset(void); +void Ut_CFE_EVS_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_CFE_EVS_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_fs_stubs.h b/fsw/unit_test/ut-assert/inc/ut_cfe_fs_stubs.h new file mode 100644 index 0000000..96d3063 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_fs_stubs.h @@ -0,0 +1,56 @@ +/* +** +** File: ut_cfe_fs_stubs.h +** +** $Id: ut_cfe_fs_stubs.h 1.1 2011/05/04 11:20:20EDT rmcgraw Exp $ +** +** Purpose: cFE File System Header file for unit test stubs +** +** $Log: ut_cfe_fs_stubs.h $ +** Revision 1.1 2011/05/04 11:20:20EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:54EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/02/15 11:12:33EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_FS_STUBS_H_ +#define UT_CFE_FS_STUBS_H_ + +typedef enum +{ + UT_CFE_FS_READHDR_INDEX, + UT_CFE_FS_WRITEHDR_INDEX, + UT_CFE_FS_SETTIMESTAMP_INDEX, + UT_CFE_FS_ISGZFILE_INDEX, + UT_CFE_FS_EXTRACTFILENAMEFROMPATH_INDEX, + UT_CFE_FS_DECOMPRESS_INDEX, + UT_CFE_FS_MAX_INDEX +} Ut_CFE_FS_INDEX_t; + +typedef struct +{ + int32 (*CFE_FS_ReadHeader)(CFE_FS_Header_t *Hdr, int32 FileDes); + int32 (*CFE_FS_WriteHeader)(int32 FileDes, CFE_FS_Header_t *Hdr); + int32 (*CFE_FS_SetTimestamp)(int32 FileDes, CFE_TIME_SysTime_t NewTimestamp); + int32 (*CFE_FS_IsGzFile)(char *FileName); + int32 (*CFE_FS_ExtractFilenameFromPath)(char *OriginalPath, char *FileNameOnly); + int32 (*CFE_FS_Decompress)( char * SourceFile, char * DestinationFile ); +} Ut_CFE_FS_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_CFE_FS_ReturnCodeTable_t; + +void Ut_CFE_FS_Reset(void); +void Ut_CFE_FS_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_CFE_FS_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_sb_hooks.h b/fsw/unit_test/ut-assert/inc/ut_cfe_sb_hooks.h new file mode 100644 index 0000000..ec7c04f --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_sb_hooks.h @@ -0,0 +1,80 @@ +/* +** +** File: ut_cfe_sb_hooks.h +** +** $Id: ut_cfe_sb_hooks.h 1.1 2011/05/04 11:20:20EDT rmcgraw Exp $ +** +** Purpose: Unit test header file for cFE Software Bus hooks. +** +** $Log: ut_cfe_sb_hooks.h $ +** Revision 1.1 2011/05/04 11:20:20EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:54EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.2 2011/03/10 11:16:45EST sslegel +** Added EventNotSent and PacketNotSent asserts +** Revision 1.1 2011/02/15 11:12:33EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_SB_HOOKS_H_ +#define UT_CFE_SB_HOOKS_H_ + +#include "cfe.h" +#include "utassert.h" +#include "utlist.h" + +extern UtListHead_t MsgQueue; + +#define UtAssert_PacketSent(MessageID, Description) \ + UtAssert(Ut_CFE_SB_PacketSent(MessageID), Description, __FILE__, __LINE__) + +#define UtAssert_PacketNotSent(MessageID, Description) \ + UtAssert(Ut_CFE_SB_PacketSent(MessageID) == FALSE, Description, __FILE__, __LINE__) + +#define UtAssert_NoPacketSent(Description) \ + UtAssert(UtList_IsEmpty(&MsgQueue), Description, __FILE__, __LINE__) + +void Ut_CFE_SB_ClearMsgQueue(void); +uint32 Ut_CFE_SB_GetMsgQueueDepth(void); +uint32 Ut_CFE_SB_GetMsgCount(uint16 MessageID); +int32 Ut_CFE_SB_SendMsgHook(CFE_SB_Msg_t *MsgPtr); +boolean Ut_CFE_SB_PacketSent(uint16 MessageID); +void *Ut_CFE_SB_FindPacket(uint16 MessageID, uint32 MessageNumber); + +void Ut_CFE_SB_ClearPipes(void); +int32 Ut_CFE_SB_CreatePipe(char *PipeName); +int32 Ut_CFE_SB_GetPipeDepth(CFE_SB_PipeId_t PipeId); +int32 Ut_CFE_SB_FindPipe(char *PipeName); +void Ut_CFE_SB_AddMsgToPipe(void *MsgPtr, CFE_SB_PipeId_t PipeId); +int32 Ut_CFE_SB_CreatePipeHook(CFE_SB_PipeId_t *PipeIdPtr, uint16 Depth, char *PipeName); +int32 Ut_CFE_SB_RcvMsgHook(CFE_SB_MsgPtr_t *BufPtr, CFE_SB_PipeId_t PipeId, int32 TimeOut); + +void Ut_CFE_SB_InitMsgHook(void *MsgPtr,CFE_SB_MsgId_t MsgId, uint16 Length, boolean Clear); +uint16 Ut_CFE_SB_MsgHdrSizeHook(CFE_SB_MsgId_t MsgId); +void *Ut_CFE_SB_GetUserDataHook(CFE_SB_MsgPtr_t MsgPtr); +CFE_SB_MsgId_t Ut_CFE_SB_GetMsgIdHook(CFE_SB_MsgPtr_t MsgPtr); +void Ut_CFE_SB_SetMsgIdHook(CFE_SB_MsgPtr_t MsgPtr,CFE_SB_MsgId_t MsgId); +uint16 Ut_CFE_SB_GetUserDataLengthHook(CFE_SB_MsgPtr_t MsgPtr); +void Ut_CFE_SB_SetUserDataLengthHook(CFE_SB_MsgPtr_t MsgPtr,uint16 DataLength); +uint16 Ut_CFE_SB_GetTotalMsgLengthHook(CFE_SB_MsgPtr_t MsgPtr); +void Ut_CFE_SB_SetTotalMsgLengthHook(CFE_SB_MsgPtr_t MsgPtr,uint16 TotalLength); +CFE_TIME_SysTime_t Ut_CFE_SB_GetMsgTimeHook(CFE_SB_MsgPtr_t MsgPtr); +int32 Ut_CFE_SB_SetMsgTimeHook(CFE_SB_MsgPtr_t MsgPtr,CFE_TIME_SysTime_t Time); +void Ut_CFE_SB_TimeStampMsgHook(CFE_SB_MsgPtr_t MsgPtr); +uint16 Ut_CFE_SB_GetCmdCodeHook(CFE_SB_MsgPtr_t MsgPtr); +int32 Ut_CFE_SB_SetCmdCodeHook(CFE_SB_MsgPtr_t MsgPtr,uint16 CmdCode); +uint16 Ut_CFE_SB_GetChecksumHook(CFE_SB_MsgPtr_t MsgPtr); +void Ut_CFE_SB_GenerateChecksumHook(CFE_SB_MsgPtr_t MsgPtr); +boolean Ut_CFE_SB_ValidateChecksumHook(CFE_SB_MsgPtr_t MsgPtr); + +void CCSDS_LoadCheckSum (CCSDS_CmdPkt_t *PktPtr); +void CCSDS_InitPkt (CCSDS_PriHdr_t *PktPtr, uint16 StreamId, uint16 Length, boolean Clear); +boolean CCSDS_ValidCheckSum (CCSDS_CmdPkt_t *PktPtr); +uint8 CCSDS_ComputeCheckSum (CCSDS_CmdPkt_t *PktPtr); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_sb_stubs.h b/fsw/unit_test/ut-assert/inc/ut_cfe_sb_stubs.h new file mode 100644 index 0000000..fd27a18 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_sb_stubs.h @@ -0,0 +1,110 @@ +/* +** +** File: ut_cfe_sb_stubs.h +** +** $Id: ut_cfe_sb_stubs.h 1.1 2011/05/04 11:20:21EDT rmcgraw Exp $ +** +** Purpose: cFE Software Bus Header file for unit test stubs +** +** $Log: ut_cfe_sb_stubs.h $ +** Revision 1.1 2011/05/04 11:20:21EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:55EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/02/15 11:12:34EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_SB_STUBS_H_ +#define UT_CFE_SB_STUBS_H_ + +typedef enum +{ + UT_CFE_SB_CREATEPIPE_INDEX, + UT_CFE_SB_DELETEPIPE_INDEX, + UT_CFE_SB_SUBSCRIBEEX_INDEX, + UT_CFE_SB_SUBSCRIBE_INDEX, + UT_CFE_SB_SUBSCRIBELOCAL_INDEX, + UT_CFE_SB_UNSUBSCRIBE_INDEX, + UT_CFE_SB_UNSUBSCRIBELOCAL_INDEX, + UT_CFE_SB_SENDMSG_INDEX, + UT_CFE_SB_PASSMSG_INDEX, + UT_CFE_SB_RCVMSG_INDEX, + UT_CFE_SB_GETLASTSENDERID_INDEX, + UT_CFE_SB_ZEROCOPYGETPTR_INDEX, + UT_CFE_SB_ZEROCOPYRELEASEPTR_INDEX, + UT_CFE_SB_ZEROCOPYSEND_INDEX, + UT_CFE_SB_ZEROCOPYPASS_INDEX, + UT_CFE_SB_INITMSG_INDEX, + UT_CFE_SB_MSGHDRSIZE_INDEX, + UT_CFE_SB_GETUSERDATA_INDEX, + UT_CFE_SB_GETMSGID_INDEX, + UT_CFE_SB_SETMSGID_INDEX, + UT_CFE_SB_GETUSERDATALENGTH_INDEX, + UT_CFE_SB_SETUSERDATALENGTH_INDEX, + UT_CFE_SB_GETTOTALMSGLENGTH_INDEX, + UT_CFE_SB_SETTOTALMSGLENGTH_INDEX, + UT_CFE_SB_GETMSGTIME_INDEX, + UT_CFE_SB_SETMSGTIME_INDEX, + UT_CFE_SB_TIMESTAMPMSG_INDEX, + UT_CFE_SB_GETCMDCODE_INDEX, + UT_CFE_SB_SETCMDCODE_INDEX, + UT_CFE_SB_GETCHECKSUM_INDEX, + UT_CFE_SB_GENERATECHECKSUM_INDEX, + UT_CFE_SB_VALIDATECHECKSUM_INDEX, + UT_CFE_SB_CLEANUPAPP_INDEX, + UT_CFE_SB_MAX_INDEX +} Ut_CFE_SB_INDEX_t; + +typedef struct +{ + int32 (*CFE_SB_CreatePipe)(CFE_SB_PipeId_t *PipeIdPtr,uint16 Depth, char *PipeName); + int32 (*CFE_SB_DeletePipe)(CFE_SB_PipeId_t PipeId); + int32 (*CFE_SB_SubscribeEx)(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId,CFE_SB_Qos_t Quality, uint16 MsgLim); + int32 (*CFE_SB_Subscribe)(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); + int32 (*CFE_SB_SubscribeLocal)(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId, uint16 MsgLim); + int32 (*CFE_SB_Unsubscribe)(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); + int32 (*CFE_SB_UnsubscribeLocal)(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId); + int32 (*CFE_SB_SendMsg)(CFE_SB_Msg_t *MsgPtr); + int32 (*CFE_SB_PassMsg)(CFE_SB_Msg_t *MsgPtr); + int32 (*CFE_SB_RcvMsg)(CFE_SB_MsgPtr_t *BufPtr, CFE_SB_PipeId_t PipeId, int32 TimeOut); + int32 (*CFE_SB_GetLastSenderId)(CFE_SB_SenderId_t **Ptr,CFE_SB_PipeId_t PipeId); + int32 (*CFE_SB_ZeroCopyGetPtr)(uint16 MsgSize,CFE_SB_ZeroCopyHandle_t *BufferHandle); + int32 (*CFE_SB_ZeroCopyReleasePtr)(CFE_SB_Msg_t *Ptr2Release,CFE_SB_ZeroCopyHandle_t BufferHandle); + int32 (*CFE_SB_ZeroCopySend)(CFE_SB_Msg_t *MsgPtr,CFE_SB_ZeroCopyHandle_t BufferHandle); + int32 (*CFE_SB_ZeroCopyPass)(CFE_SB_Msg_t *MsgPtr,CFE_SB_ZeroCopyHandle_t BufferHandle); + int32 (*CFE_SB_InitMsg)(void *MsgPtr,CFE_SB_MsgId_t MsgId, uint16 Length, boolean Clear); + int32 (*CFE_SB_MsgHdrSize)(CFE_SB_MsgId_t MsgId); + void *(*CFE_SB_GetUserData)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_GetMsgId)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_SetMsgId)(CFE_SB_MsgPtr_t MsgPtr,CFE_SB_MsgId_t MsgId); + int32 (*CFE_SB_GetUserDataLength)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_SetUserDataLength)(CFE_SB_MsgPtr_t MsgPtr,uint16 DataLength); + int32 (*CFE_SB_GetTotalMsgLength)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_SetTotalMsgLength)(CFE_SB_MsgPtr_t MsgPtr,uint16 TotalLength); + CFE_TIME_SysTime_t (*CFE_SB_GetMsgTime)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_SetMsgTime)(CFE_SB_MsgPtr_t MsgPtr,CFE_TIME_SysTime_t Time); + int32 (*CFE_SB_TimeStampMsg)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_GetCmdCode)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_SetCmdCode)(CFE_SB_MsgPtr_t MsgPtr,uint16 CmdCode); + int32 (*CFE_SB_GetChecksum)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_GenerateChecksum)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_ValidateChecksum)(CFE_SB_MsgPtr_t MsgPtr); + int32 (*CFE_SB_CleanUpApp)(uint32 AppId); +} Ut_CFE_SB_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_CFE_SB_ReturnCodeTable_t; + +void Ut_CFE_SB_Reset(void); +void Ut_CFE_SB_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_CFE_SB_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_tbl_hooks.h b/fsw/unit_test/ut-assert/inc/ut_cfe_tbl_hooks.h new file mode 100644 index 0000000..d5f7828 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_tbl_hooks.h @@ -0,0 +1,40 @@ +/* +** +** File: ut_cfe_tbl_hooks.h +** +** $Id: ut_cfe_tbl_hooks.h 1.1 2011/05/04 11:20:22EDT rmcgraw Exp $ +** +** Purpose: Unit test header file for cFE Table Services hooks. +** +** $Log: ut_cfe_tbl_hooks.h $ +** Revision 1.1 2011/05/04 11:20:22EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:56EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.2 2011/02/18 15:57:43EST sslegel +** Added new hooks and return codes +** Changed Ut_CFE_TBL_LoadHook to automatically call the table validate function +** Revision 1.1 2011/02/15 11:12:34EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_TBL_HOOKS_H_ +#define UT_CFE_TBL_HOOKS_H_ + +#include "cfe.h" + +void Ut_CFE_TBL_ClearTables(void); +int32 Ut_CFE_TBL_RegisterTable(const char *Name, uint32 Size, uint16 TblOptionFlags, CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr); +int32 Ut_CFE_TBL_AddTable(char *Filename, void *TablePtr); +int32 Ut_CFE_TBL_LoadTable(CFE_TBL_Handle_t TblHandle, void *SrcDataPtr); +int32 Ut_CFE_TBL_FindTable(char *Filename); +void *Ut_CFE_TBL_GetAddress(CFE_TBL_Handle_t TblHandle); +int32 Ut_CFE_TBL_RegisterHook(CFE_TBL_Handle_t *TblHandlePtr, const char *Name, uint32 Size, uint16 TblOptionFlags, CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr); +int32 Ut_CFE_TBL_LoadHook(CFE_TBL_Handle_t TblHandle, CFE_TBL_SrcEnum_t SrcType, const void *SrcDataPtr); +int32 Ut_CFE_TBL_GetAddressHook(void **TblPtr, CFE_TBL_Handle_t TblHandle); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_tbl_stubs.h b/fsw/unit_test/ut-assert/inc/ut_cfe_tbl_stubs.h new file mode 100644 index 0000000..883db08 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_tbl_stubs.h @@ -0,0 +1,63 @@ +/* +** +** File: ut_cfe_tbl_stubs.h +** +** $Id: ut_cfe_tbl_stubs.h 1.1 2011/05/04 11:20:23EDT rmcgraw Exp $ +** +** Purpose: cFE Table Services Header file for unit test stubs +** +** $Log: ut_cfe_tbl_stubs.h $ +** Revision 1.1 2011/05/04 11:20:23EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:56EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.2 2011/02/18 15:57:43EST sslegel +** Added new hooks and return codes +** Changed Ut_CFE_TBL_LoadHook to automatically call the table validate function +** Revision 1.1 2011/02/15 11:12:35EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_TBL_STUBS_H_ +#define UT_CFE_TBL_STUBS_H_ + +typedef enum +{ + UT_CFE_TBL_REGISTER_INDEX, + UT_CFE_TBL_LOAD_INDEX, + UT_CFE_TBL_MANAGE_INDEX, + UT_CFE_TBL_GETADDRESS_INDEX, + UT_CFE_TBL_GETADDRESSES_INDEX, + UT_CFE_TBL_GETSTATUS_INDEX, + UT_CFE_TBL_GETINFO_INDEX, + UT_CFE_TBL_RELEASEADDRESS_INDEX, + UT_CFE_TBL_NOTIFYBYMESSAGE_INDEX, + UT_CFE_TBL_MAX_INDEX +} Ut_CFE_TBL_INDEX_t; + +typedef struct +{ + int32 (*CFE_TBL_Register)(CFE_TBL_Handle_t*, const char *,uint32, uint16, CFE_TBL_CallbackFuncPtr_t); + int32 (*CFE_TBL_Load)(CFE_TBL_Handle_t, CFE_TBL_SrcEnum_t, const void *); + int32 (*CFE_TBL_Manage)(CFE_TBL_Handle_t); + int32 (*CFE_TBL_GetAddress)(void **, CFE_TBL_Handle_t); + int32 (*CFE_TBL_GetAddresses)(void **[], uint16, const CFE_TBL_Handle_t []); + int32 (*CFE_TBL_GetInfo)(CFE_TBL_Info_t *TblInfoPtr, const char *TblName); + int32 (*CFE_TBL_NotifyByMessage)(CFE_TBL_Handle_t TblHandle, uint32 MsgId, uint16 CommandCode, uint32 Parameter); +} Ut_CFE_TBL_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_CFE_TBL_ReturnCodeTable_t; + +void Ut_CFE_TBL_Reset(void); +void Ut_CFE_TBL_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_CFE_TBL_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_cfe_time_stubs.h b/fsw/unit_test/ut-assert/inc/ut_cfe_time_stubs.h new file mode 100644 index 0000000..7597825 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_cfe_time_stubs.h @@ -0,0 +1,46 @@ +/* +** +** File: ut_cfe_time_stubs.h +** +** $Id: ut_cfe_time_stubs.h 1.1 2011/05/04 11:20:23EDT rmcgraw Exp $ +** +** Purpose: cFE Time Services Header file for unit test stubs +** +** $Log: ut_cfe_time_stubs.h $ +** Revision 1.1 2011/05/04 11:20:23EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:57EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/02/15 11:12:35EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_CFE_TIME_STUBS_H_ +#define UT_CFE_TIME_STUBS_H_ + +typedef enum +{ + UT_CFE_TIME_GETTIME_INDEX, + UT_CFE_TIME_MAX_INDEX +} Ut_CFE_TIME_INDEX_t; + +typedef struct +{ + CFE_TIME_SysTime_t (*CFE_TIME_GetTime)(void); +} Ut_CFE_TIME_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_CFE_TIME_ReturnCodeTable_t; + +void Ut_CFE_TIME_Reset(void); +void Ut_CFE_TIME_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_CFE_TIME_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_osapi_stubs.h b/fsw/unit_test/ut-assert/inc/ut_osapi_stubs.h new file mode 100644 index 0000000..fd1c25d --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_osapi_stubs.h @@ -0,0 +1,76 @@ +/* +** +** File: ut_osapi_stubs.h +** +** $Id: ut_osapi_stubs.h 1.2 2011/05/16 16:25:33EDT rmcgraw Exp $ +** +** Purpose: OSAPI Header file for unit test stubs +** +** $Log: ut_osapi_stubs.h $ +** Revision 1.2 2011/05/16 16:25:33EDT rmcgraw +** Added hook functionality to Count Semaphore APIs +** Revision 1.3 2011/05/16 14:42:41EDT rmcgraw +** Added SetRtnCode processing to Counting Semaphore APIs +** Revision 1.2 2011/03/08 15:42:03EST rmcgraw +** Added OS_CountSemGetIdByName +** Revision 1.1 2011/02/15 11:12:35EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_OSAPI_STUBS_H_ +#define UT_OSAPI_STUBS_H_ + +typedef enum +{ + UT_OSAPI_TASKDELAY_INDEX, + UT_OSAPI_BINSEMTAKE_INDEX, + UT_OSAPI_BINSEMTIMEDWAIT_INDEX, + UT_OSAPI_MUTSEMTAKE_INDEX, + UT_OSAPI_GETLOCALTIME_INDEX, + UT_OSAPI_QUEUEGET_INDEX, + UT_OSAPI_QUEUEPUT_INDEX, + UT_OSAPI_TASKDELETE_INDEX, + UT_OSAPI_BINSEMGIVE_INDEX, + UT_OSAPI_COUNTSEMCREATE_INDEX, + UT_OSAPI_COUNTSEMDELETE_INDEX, + UT_OSAPI_COUNTSEMGIVE_INDEX, + UT_OSAPI_COUNTSEMTAKE_INDEX, + UT_OSAPI_COUNTSEMTIMEDWAIT_INDEX, + UT_OSAPI_COUNTSEMGETIDBYNAME_INDEX, + UT_OSAPI_COUNTSEMGETINFO_INDEX, + UT_OSAPI_MAX_INDEX +} Ut_OSAPI_Index_t; + +typedef struct +{ + int32 (*OS_TaskDelay)(uint32); + int32 (*OS_BinSemTake)(uint32); + int32 (*OS_BinSemTimedWait)(uint32, uint32); + int32 (*OS_MutSemTake)(uint32); + int32 (*OS_GetLocalTime)(OS_time_t *); + int32 (*OS_QueueGet)(uint32, void *, uint32, uint32 *, int32); + int32 (*OS_QueuePut)(uint32, const void *, uint32, uint32); + int32 (*OS_TaskDelete)(uint32); + int32 (*OS_BinSemGive)(uint32); + int32 (*OS_CountSemCreate)(uint32 *sem_id, const char *sem_name, uint32 sem_initial_value, uint32 options); + int32 (*OS_CountSemDelete)(uint32 sem_id); + int32 (*OS_CountSemGive)(uint32 sem_id); + int32 (*OS_CountSemTake)(uint32 sem_id); + int32 (*OS_CountSemTimedWait)(uint32 sem_id, uint32 msecs); + int32 (*OS_CountSemGetIdByName)(uint32 *sem_id, const char *sem_name); + int32 (*OS_CountSemGetInfo)(uint32 sem_id, OS_count_sem_prop_t *count_prop); +} Ut_OSAPI_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_OSAPI_ReturnCodeTable_t; + +void Ut_OSAPI_Reset(void); +void Ut_OSAPI_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_OSAPI_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/ut_osfileapi_stubs.h b/fsw/unit_test/ut-assert/inc/ut_osfileapi_stubs.h new file mode 100644 index 0000000..fe9246b --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/ut_osfileapi_stubs.h @@ -0,0 +1,69 @@ +/* +** +** File: ut_osfileapi_stubs.h +** +** $Id: ut_osfileapi_stubs.h 1.1 2011/05/04 11:20:25EDT rmcgraw Exp $ +** +** Purpose: OSAPI File Services Header file for unit test stubs. +** +** $Log: ut_osfileapi_stubs.h $ +** Revision 1.1 2011/05/04 11:20:25EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.1 2011/04/08 16:25:59EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/inc/project.pj +** Revision 1.3 2011/03/30 09:58:56EDT rmcgraw +** Added Hook and Return enhancements to Directory APIs +** Revision 1.2 2011/03/24 13:14:54EDT rmcgraw +** Added Hook and RtnCode functionality to OS_stat +** Revision 1.1 2011/02/15 11:12:36EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/inc/project.pj +** +*/ + +#ifndef UT_OSFILEAPI_STUBS_H_ +#define UT_OSFILEAPI_STUBS_H_ + +typedef enum +{ + UT_OSFILEAPI_CREAT_INDEX, + UT_OSFILEAPI_WRITE_INDEX, + UT_OSFILEAPI_READ_INDEX, + UT_OSFILEAPI_OPENDIR_INDEX, + UT_OSFILEAPI_READDIR_INDEX, + UT_OSFILEAPI_CLOSE_INDEX, + UT_OSFILEAPI_OPEN_INDEX, + UT_OSFILEAPI_CLOSEDIR_INDEX, + UT_OSFILEAPI_STAT_INDEX, + UT_OSFILEAPI_FDGETINFO_INDEX, + UT_OSFILEAPI_MAX_INDEX +} Ut_OSFILEAPI_INDEX_t; + +typedef struct +{ + int32 (*OS_creat)(const char *,int32); + int32 (*OS_write)(int32, void *, uint32); + int32 (*OS_read)(int32, void *, uint32); + os_dirp_t (*OS_opendir)(const char *path); + os_dirent_t* (*OS_readdir)(os_dirp_t directory); + int32 (*OS_close)(int32 filedes); + int32 (*OS_open)(const char *path, int32 access, uint32 mode); + int32 (*OS_closedir)(os_dirp_t directory); + int32 (*OS_stat)(const char *path, os_fstat_t *filestats); + int32 (*OS_FDGetInfo) (int32 filedes, OS_FDTableEntry *fd_prop); + +} Ut_OSFILEAPI_HookTable_t; + +typedef struct +{ + int32 Value; + uint32 Count; +} Ut_OSFILEAPI_ReturnCodeTable_t; + +void Ut_OSFILEAPI_Reset(void); +void Ut_OSFILEAPI_SetFunctionHook(uint32 Index, void *FunPtr); +void Ut_OSFILEAPI_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/utassert.h b/fsw/unit_test/ut-assert/inc/utassert.h new file mode 100644 index 0000000..2ecba05 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/utassert.h @@ -0,0 +1,95 @@ + +/* + * Filename: utassert.h + * + * Purpose: This file contains a standard set of asserts for use in unit tests. + * + * Design Notes: + * - All asserts evaluate a expression as TRUE or FALSE to determine if a unit test has + * passed or failed. TRUE means the test passed, FALSE means the test failed. + * - All asserts return a boolen result to indicate the pass fail status. + * - All asserts are implemented as macros to hide the __LINE__ and __FILE__ macros. + * - All asserts must call the function UtAssert. + * + * References: + * + */ + +#ifndef _utassert_ +#define _utassert_ + +/* + * Includes + */ + +#include "common_types.h" +#include "uttools.h" +#include +#include +#include + +/* + * Macro Definitions + */ + +/* Evaluates a expression as either TRUE or FALSE. TRUE means the test passed, FALSE means the test failed. */ +#define UtAssert_True(Expression, Description) \ + UtAssert(Expression, Description, __FILE__, __LINE__) + +/* Evaluates a expression as either TRUE or FALSE. TRUE means the test passed, FALSE means the test failed. */ +#define UtAssert_Bool(Expression, Description) \ + UtAssert(Expression, Description, __FILE__, __LINE__) + +/* Asserts a test failure */ +#define UtAssert_Failed(Description) \ + UtAssert(FALSE, Description, __FILE__, __LINE__) + +/* Compares two floating point numbers and determines if they are equal within a specified absolute tolerance. */ +#define UtAssert_DoubleCmpAbs(x, y, Tolerance, Description) \ + UtAssert((fabs((x) - (y)) <= (Tolerance)), Description, __FILE__, __LINE__) + +/* Compares two floating point numbers and determines if they are equal within a specified relative tolerance. */ +#define UtAssert_DoubleCmpRel(x, y, Ratio, Description) \ + UtAssert((fabs((x) - (y))/(x) <= (Ratio)), Description, __FILE__, __LINE__) + +/* Compares two strings and determines if they are equal. */ +#define UtAssert_StrCmp(String1, String2, Description) \ + UtAssert((strcmp(String1, String2) == 0), Description, __FILE__, __LINE__) + +/* Compares at most Length characters of two strings and determines if they are equal. */ +#define UtAssert_StrnCmp(String1, String2, Length, Description) \ + UtAssert((strncmp(String1, String2, Length) == 0), Description, __FILE__, __LINE__) + +/* Compares two regions of memory and determines if they are equal. */ +#define UtAssert_MemCmp(Memory1, Memory2, Length, Description) \ + UtAssert((memcmp(Memory1, Memory2, Length) == 0), Description, __FILE__, __LINE__) + +/* Compares a region of memory to a static pattern and determines if they are equal. Note: Use UtMemSet to + * fill a region of memory with a static pattern. */ +#define UtAssert_MemCmpValue(Memory, Value, Length, Description) \ + UtAssert((UtMemCmpValue(Memory, Value, Length)), Description, __FILE__, __LINE__) + +/* Compares a region of memory to a byte count pattern and determines if they are equal. Note: Use UtMemFill to + * fill a region of memory with a byte count pattern. */ +#define UtAssert_MemCmpCount(Memory, Length, Description) \ + UtAssert((UtMemCmpCount(Memory, Length)), Description, __FILE__, __LINE__) + +/* Compares a region of memory with the contents of a binary file and determines if they are equal. Note: Use + * UtMem2BinFile to copy a region of memory to a binary file. */ +#define UtAssert_Mem2BinFileCmp(Memory, Filename, Description) \ + UtAssert((UtMem2BinFileCmp(Memory, Filename)), Description, __FILE__, __LINE__) + +/* + * Exported Functions + */ + +/* Returns the number of asserts that have passed. */ +uint32 UtAssert_GetPassCount(void); + +/* Returns the number of asserts that have failed. */ +uint32 UtAssert_GetFailCount(void); + +/* Base assert function. All asserts must call this function. */ +boolean UtAssert(boolean Expression, char *Description, char *File, uint32 Line); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/utlist.h b/fsw/unit_test/ut-assert/inc/utlist.h new file mode 100644 index 0000000..8a5c962 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/utlist.h @@ -0,0 +1,114 @@ + +/* + * Filename: utlist.h + * + * Purpose: This file contains functions to implement a generic linked list data structure. + * + * Design Notes: + * + * References: + * + */ + +#ifndef _utlist_ +#define _utlist_ + +/* + * Includes + */ + +#include "common_types.h" + +/* + * Macro Definitions + */ + +/* Macros to redefine list functions to look like stack and queue functions */ +#define UtStack_Push UtList_Add +#define UtStack_Pop UtList_RemoveLast +#define UtStack_IsEmpty UtList_IsEmpty +#define UtStack_Depth UtList_Depth + +#define UtQueue_Add UtList_Add +#define UtQueue_Get UtList_RemoveFirst +#define UtQueue_Look UtList_First +#define UtQueue_Delete UtList_DeleteFirst +#define UtQueue_IsEmpty UtList_IsEmpty +#define UtQueue_Depth UtList_Depth + +/* + * Type Definitions + */ + +typedef struct UtListNodeTag { + struct UtListNodeTag *Next; + struct UtListNodeTag *Prev; + void *Data; + uint32 DataSize; + uint32 Tag; +} UtListNode_t; + + typedef struct { + UtListNode_t *First; + UtListNode_t *Last; + uint32 NumberOfEntries; +} UtListHead_t; + +/* + * Exported Functions + */ + +/* Dynamically allocates a new list head. A list head could also just be declared, this function is useful + * if you need to dynamically allocate memory for a new list head. Note always free list heads allocated by + * this function by calling UtList_Destroy. */ +UtListHead_t *UtList_Create(void); + +/* Frees a list head created by UtList_Create. */ +void UtList_Destroy(UtListHead_t *ListHead); + +/* Deletes all nodes on the list. */ +void UtList_Reset(UtListHead_t *ListHead); + +/* Dynamically adds a new node to the list. Nodes are always added to the end of the list. Memory is dynamically + * allocated for the new node and to hold the data pointed to by Data. A Tag field is also provided to be used to + * store user defined information with the node. */ +void UtList_Add(UtListHead_t *ListHead, void *Data, uint32 DataSize, uint32 Tag); + +/* Deletes the first node from the list. */ +void UtList_DeleteFirst(UtListHead_t *ListHead); + +/* Deletes the last node from the list. */ +void UtList_DeleteLast(UtListHead_t *ListHead); + +/* Deletes the specified node from the list, this will screw up if you do not pass in a valid DeleteNode. I do not + * verify that DeleteNode is a member of the list. */ +void UtList_DeleteNode(UtListHead_t *ListHead, UtListNode_t *DeleteNode); + +/* Removes the first node from the list by first copying the data from the node to the memory buffer pointed to by the + * specified Data pointer and then the node is deleted from the list. Make sure the destination pointer points to a + * memory buffer large enough to hold the data. The size of the data on the node is available by referencing UtListNode->DataSize. */ +void UtList_RemoveFirst(UtListHead_t *ListHead, void *Data); + +/* Removes the last node from the list by first copying the data from the node to the memory buffer pointed to by the + * specified Data pointer and then the node is deleted from the list. Make sure the destination pointer points to a + * memory buffer large enough to hold the data. The size of the data on the node is available by referencing UtListNode->DataSize. */ +void UtList_RemoveLast(UtListHead_t *ListHead, void *Data); + +/* Removes the speciified RemoveNode from the list by first copying the data from the node to the memory buffer pointed to by the + * specified Data pointer and then the node is deleted from the list. Make sure the destination pointer points to a + * memory buffer large enough to hold the data. The size of the data on the node is available by referencing UtListNode->DataSize. */ +void UtList_RemoveNode(UtListHead_t *ListHead, void *Data, UtListNode_t *RemoveNode); + +/* Returns a pointer to the first node on the list. This is the same as (UtListHead->First). */ +UtListNode_t *UtList_First(UtListHead_t *ListHead); + +/* Returns a pointer to the last node on the list. This is the same as (UtListHead->Last). */ +UtListNode_t *UtList_Last(UtListHead_t *ListHead); + +/* Returns TRUE if the list is empty. This is the same as (UtListHead->NumberOfEntries == 0). */ +boolean UtList_IsEmpty(UtListHead_t *ListHead); + +/* Returns the number of nodes on the list. This is the same as (UtListHead->NumberOfEntries). */ +uint32 UtList_Depth(UtListHead_t *ListHead); + +#endif diff --git a/fsw/unit_test/ut-assert/inc/uttest.h b/fsw/unit_test/ut-assert/inc/uttest.h new file mode 100644 index 0000000..f926e94 --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/uttest.h @@ -0,0 +1,33 @@ + +/* + * Filename: uttest.h + * + * Purpose: This file contains functions to implement a standard way to execute unit tests. + * + * Design Notes: + * By default the only output that is printed to the console is assert failures + * and a summary of the test results after all tests have executed. To enable additional + * test output define the macro UT_VERBOSE. + * + * References: + * + */ + +#ifndef _uttest_ +#define _uttest_ + +/* + * Exported Functions + */ + +/* Adds a new unit test to the test database. */ +void UtTest_Add(void (*Test)(void), void (*Setup)(void), void (*Teardown)(void), char *TestName); + +/* Executes all unit tests contained in the test database. Once all tests have finished executing + * a results summary is printed to the console and the test database is deleted. This function also + * returns a boolean status indicating if any of the tests failed. (TRUE = at least one test failure + * has occurred, FALSE = all tests passed) */ +int UtTest_Run(void); + +#endif + diff --git a/fsw/unit_test/ut-assert/inc/uttools.h b/fsw/unit_test/ut-assert/inc/uttools.h new file mode 100644 index 0000000..ea5a44b --- /dev/null +++ b/fsw/unit_test/ut-assert/inc/uttools.h @@ -0,0 +1,69 @@ + +/* + * Filename: uttools.h + * + * Purpose: This file contains functions to implement a set of tools for use in unit testing. + * + * Design Notes: + * + * References: + * + */ + +#ifndef _uttools_ +#define _uttools_ + +/* + * Includes + */ + +#include "common_types.h" + +/* + * Macro Definitions + */ + +#define UtMemSet memset + +/* + * Exported Functions + */ + +/* Copies a region of memory to a binary file. This file can be reloaded by calling UtBinFile2Mem or it can be + * used to verify test results by calling UtMem2BinFileCmp. */ +boolean UtMem2BinFile(void *Memory, char *Filename, uint32 Length); + +/* Copies a binary file to a region of memory. */ +boolean UtBinFile2Mem(void *Memory, char *Filename, uint32 Length); + +/* Copies a region of memory to a hex file */ +boolean UtMem2HexFile(void *Memory, char *Filename, uint32 Length); + +/* Fills a region of memory with a byte count pattern. */ +void UtMemFill(void *Memory, uint32 Length); + +/* Just like the standard printf except it will supress its output unless the macro UT_VERBOSE + * is defined. */ +void UtPrintf(char *Spec, ...); + +/* Just like the standard sprintf except it returns a pointer to the result string. The result string + * cannot be larger than 256 bytes. */ +char *UtSprintf(char *Spec, ...); + +/* Calls UtPrintf to print a range of memory as hex bytes. */ +void UtPrintx(void *Memory, uint32 Length); + +/* Compares a region of memory to a static pattern and determines if they are equal. Note: Use UtMemSet to + * fill a region of memory with a static pattern. */ +boolean UtMemCmpValue(void *Memory, uint8 Value, uint32 Length); + +/* Compares a region of memory to a byte count pattern and determines if they are equal. Note: Use UtMemFill to + * fill a region of memory with a byte count pattern. */ +boolean UtMemCmpCount(void *Memory, uint32 Length); + +/* Compares a region of memory with the contents of a binary file and determines if they are equal. Note: Use + * UtMem2BinFile to copy a region of memory to a binary file. */ +boolean UtMem2BinFileCmp(void *Memory, char *Filename); + +#endif + diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_es_hooks.c b/fsw/unit_test/ut-assert/src/ut_cfe_es_hooks.c new file mode 100644 index 0000000..d1c3edd --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_es_hooks.c @@ -0,0 +1,32 @@ +/* +** +** File: ut_cfe_es_hooks.c +** +** $Id: ut_cfe_es_hooks.c 1.1 2011/05/04 11:20:51EDT rmcgraw Exp $ +** +** Purpose: Unit test hooks for cFE Executive Services routines +** +** $Log: ut_cfe_es_hooks.c $ +** Revision 1.1 2011/05/04 11:20:51EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:36EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/03/07 17:54:30EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" + +int32 Ut_CFE_ES_RunLoopHook(uint32 *ExitStatus) +{ + if (*ExitStatus == CFE_ES_APP_RUN) { + return(TRUE); + } + else { /* CFE_ES_APP_EXIT, CFE_ES_APP_ERROR */ + return(FALSE); + } +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_es_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_es_stubs.c new file mode 100644 index 0000000..7e748d8 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_es_stubs.c @@ -0,0 +1,327 @@ +/* +** +** File: ut_cfe_es_stubs.c +** +** $Id: ut_cfe_es_stubs.c 1.2 2011/05/04 11:28:00EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE Executive Services routines +** +** $Log: ut_cfe_es_stubs.c $ +** Revision 1.2 2011/05/04 11:28:00EDT rmcgraw +** Changed PoolCreateEx to have new parameter USE_MUTEX +** Revision 1.1 2011/05/04 11:20:51EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:37EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.5 2011/03/31 14:53:04EDT rmcgraw +** Added functionality and supressed compiler warnings +** Revision 1.4 2011/03/23 17:08:18EDT rmcgraw +** OS_FS_ERROR to OS_FS_SUCCESS for some OS file sys apis +** Revision 1.3 2011/03/09 10:26:12EST rmcgraw +** Added SetRtnCode logic to PoolCreateEx +** Revision 1.2 2011/03/07 17:53:39EST sslegel +** Added a default hook for ES_CFE_RunLoop +** Added additional return code support +** Revision 1.1 2011/02/15 11:13:01EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +/* +** Include section +*/ + +#include "cfe.h" +#include "ut_cfe_es_stubs.h" +#include "ut_cfe_es_hooks.h" +#include + +Ut_CFE_ES_HookTable_t Ut_CFE_ES_HookTable; +Ut_CFE_ES_ReturnCodeTable_t Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_MAX_INDEX]; + +void Ut_CFE_ES_Reset(void) +{ + memset(&Ut_CFE_ES_HookTable, 0, sizeof(Ut_CFE_ES_HookTable)); + memset(&Ut_CFE_ES_ReturnCodeTable, 0, sizeof(Ut_CFE_ES_ReturnCodeTable)); + + Ut_CFE_ES_SetFunctionHook(UT_CFE_ES_RUNLOOP_INDEX, &Ut_CFE_ES_RunLoopHook); +} + +void Ut_CFE_ES_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_CFE_ES_RESETCFE_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_ResetCFE = FunPtr; } + else if (Index == UT_CFE_ES_RESTARTAPP_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RestartApp = FunPtr; } + else if (Index == UT_CFE_ES_RELOADAPP_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_ReloadApp = FunPtr; } + else if (Index == UT_CFE_ES_DELETEAPP_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_DeleteApp = FunPtr; } + else if (Index == UT_CFE_ES_EXITAPP_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_ExitApp = FunPtr; } + else if (Index == UT_CFE_ES_RUNLOOP_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RunLoop = FunPtr; } + else if (Index == UT_CFE_ES_WAITFORSTARTUPSYNC_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_WaitForStartupSync = FunPtr; } + else if (Index == UT_CFE_ES_REGISTERAPP_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RegisterApp = FunPtr; } + else if (Index == UT_CFE_ES_GETAPPID_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetAppID = FunPtr; } + else if (Index == UT_CFE_ES_GETAPPIDBYNAME_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetAppIDByName = FunPtr; } + else if (Index == UT_CFE_ES_GETAPPNAME_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetAppName = FunPtr; } + else if (Index == UT_CFE_ES_GETAPPINFO_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetAppInfo = FunPtr; } + else if (Index == UT_CFE_ES_GETTASKINFO_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetTaskInfo = FunPtr; } + else if (Index == UT_CFE_ES_REGISTERCHILDTASK_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RegisterChildTask = FunPtr; } + else if (Index == UT_CFE_ES_CREATECHILDTASK_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_CreateChildTask = FunPtr; } + else if (Index == UT_CFE_ES_DELETECHILDTASK_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_DeleteChildTask = FunPtr; } + else if (Index == UT_CFE_ES_EXITCHILDTASK_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_ExitChildTask = FunPtr; } + else if (Index == UT_CFE_ES_INCREMENTTASKCOUNTER_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_IncrementTaskCounter = FunPtr; } + else if (Index == UT_CFE_ES_WRITETOSYSLOG_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_WriteToSysLog = FunPtr; } + else if (Index == UT_CFE_ES_REGISTERDRIVER_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RegisterDriver = FunPtr; } + else if (Index == UT_CFE_ES_UNLOADDRIVER_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_UnloadDriver = FunPtr; } + else if (Index == UT_CFE_ES_CALCULATECRC_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_CalculateCRC = FunPtr; } + else if (Index == UT_CFE_ES_REGISTERCDS_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RegisterCDS = FunPtr; } + else if (Index == UT_CFE_ES_COPYTOCDS_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_CopyToCDS = FunPtr; } + else if (Index == UT_CFE_ES_RESTOREFROMCDS_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_RestoreFromCDS = FunPtr; } + else if (Index == UT_CFE_ES_POOLCREATE_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_PoolCreate = FunPtr; } + else if (Index == UT_CFE_ES_POOLCREATEEX_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_PoolCreateEx = FunPtr; } + else if (Index == UT_CFE_ES_GETPOOLBUF_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetPoolBuf = FunPtr; } + else if (Index == UT_CFE_ES_GETPOOLBUFINFO_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetPoolBufInfo = FunPtr; } + else if (Index == UT_CFE_ES_PUTPOOLBUF_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_PutPoolBuf = FunPtr; } + else if (Index == UT_CFE_ES_GETMEMPOOLSTATS_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_GetMemPoolStats = FunPtr; } + else if (Index == UT_CFE_ES_PERFLOGADD_INDEX) { Ut_CFE_ES_HookTable.CFE_ES_PerfLogAdd = FunPtr; } + else { printf("Unsupported ES Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_CFE_ES_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_CFE_ES_MAX_INDEX) { + Ut_CFE_ES_ReturnCodeTable[Index].Value = RtnVal; + Ut_CFE_ES_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported ES Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_CFE_ES_UseReturnCode(uint32 Index) +{ + if (Ut_CFE_ES_ReturnCodeTable[Index].Count > 0) { + Ut_CFE_ES_ReturnCodeTable[Index].Count--; + if (Ut_CFE_ES_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +int32 CFE_ES_GetResetType(uint32 *ResetSubtypePtr) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_ResetCFE(uint32 ResetType) +{ + /* Check for specified return */ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_RESETCFE_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_RESETCFE_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_ES_RestartApp(uint32 AppID) +{ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_RESTARTAPP_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_RESTARTAPP_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_ES_ReloadApp(uint32 AppID, const char *AppFileName) +{ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_RELOADAPP_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_RELOADAPP_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_ES_DeleteApp(uint32 AppID) +{ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_DELETEAPP_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_DELETEAPP_INDEX].Value; + + return CFE_SUCCESS; +} + +void CFE_ES_ExitApp(uint32 ExitStatus) +{ + return; +} + +int32 CFE_ES_RunLoop(uint32 *ExitStatus) +{ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_RUNLOOP_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_RUNLOOP_INDEX].Value; + + if (Ut_CFE_ES_HookTable.CFE_ES_RunLoop) + return Ut_CFE_ES_HookTable.CFE_ES_RunLoop(ExitStatus); + + return TRUE; +} + +void CFE_ES_WaitForStartupSync(uint32 TimeOutMilliseconds) +{ + return; +} + +int32 CFE_ES_RegisterApp(void) +{ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_REGISTERAPP_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_REGISTERAPP_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_ES_GetAppID(uint32 *AppIdPtr) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_GetAppIDByName(uint32 *AppIdPtr, const char *AppName) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_GetAppName(char *AppName, uint32 AppId, uint32 BufferLength) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_GetAppInfo(CFE_ES_AppInfo_t *AppInfo, uint32 AppId) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_GetTaskInfo(CFE_ES_TaskInfo_t *TaskInfo, uint32 TaskId) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_RegisterChildTask(void) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_CreateChildTask(uint32 *TaskIdPtr, + const char *TaskName, + CFE_ES_ChildTaskMainFuncPtr_t FunctionPtr, + uint32 *StackPtr, + uint32 StackSize, + uint32 Priority, + uint32 Flags) +{ + /* Check for specified return */ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_CREATECHILDTASK_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_CREATECHILDTASK_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_ES_HookTable.CFE_ES_CreateChildTask) + return Ut_CFE_ES_HookTable.CFE_ES_CreateChildTask(TaskIdPtr, TaskName, FunctionPtr, StackPtr, StackSize, Priority, Flags); + + return CFE_SUCCESS; +} + +int32 CFE_ES_DeleteChildTask(uint32 TaskId) +{ + return CFE_SUCCESS; +} + +void CFE_ES_ExitChildTask(void) +{ + return; +} + +void CFE_ES_IncrementTaskCounter(void) +{ + return; +} + +int32 CFE_ES_WriteToSysLog(const char *SpecStringPtr, ...) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_RegisterDriver(uint32 *DriverIdPtr, uint32 *DriverDescPtr) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_UnloadDriver(uint32 DriverId) +{ + return CFE_SUCCESS; +} + +uint32 CFE_ES_CalculateCRC(const void *DataPtr, uint32 DataLength, uint32 InputCRC, uint32 TypeCRC) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_RegisterCDS(CFE_ES_CDSHandle_t *HandlePtr, int32 BlockSize, const char *Name) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_CopyToCDS(CFE_ES_CDSHandle_t Handle, void *DataToCopy) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_RestoreFromCDS(void *RestoreToMemory, CFE_ES_CDSHandle_t Handle) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_PoolCreate(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint32 Size) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_PoolCreateEx(CFE_ES_MemHandle_t *HandlePtr, uint8 *MemPtr, uint32 Size, uint32 NumBlockSizes, uint32 *BlockSizes, uint16 UseMutex) +{ + /* Check for specified return */ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_POOLCREATEEX_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_POOLCREATEEX_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_ES_GetPoolBuf(uint32 **BufPtr, CFE_ES_MemHandle_t HandlePtr, uint32 Size) +{ + /* Check for specified return */ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_GETPOOLBUF_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_GETPOOLBUF_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_ES_HookTable.CFE_ES_GetPoolBuf) + return Ut_CFE_ES_HookTable.CFE_ES_GetPoolBuf(BufPtr,HandlePtr,Size); + + return CFE_SUCCESS; +} + +int32 CFE_ES_GetPoolBufInfo(CFE_ES_MemHandle_t HandlePtr, uint32 *BufPtr) +{ + return CFE_SUCCESS; +} + +int32 CFE_ES_PutPoolBuf(CFE_ES_MemHandle_t HandlePtr, uint32 *BufPtr) +{ + /* Check for specified return */ + if (Ut_CFE_ES_UseReturnCode(UT_CFE_ES_PUTPOOLBUF_INDEX)) + return Ut_CFE_ES_ReturnCodeTable[UT_CFE_ES_PUTPOOLBUF_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_ES_GetMemPoolStats(CFE_ES_MemPoolStats_t *BufPtr, CFE_ES_MemHandle_t Handle) +{ + return CFE_SUCCESS; +} + +void CFE_ES_PerfLogAdd(uint32 Marker, uint32 EntryExit) +{ + return; +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_evs_hooks.c b/fsw/unit_test/ut-assert/src/ut_cfe_evs_hooks.c new file mode 100644 index 0000000..557ef92 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_evs_hooks.c @@ -0,0 +1,109 @@ +/* +** +** File: ut_cfe_evs_hooks.c +** +** $Id: ut_cfe_evs_hooks.c 1.1 2011/05/04 11:20:52EDT rmcgraw Exp $ +** +** Purpose: Unit test hooks for cFE Event Services routines +** +** $Log: ut_cfe_evs_hooks.c $ +** Revision 1.1 2011/05/04 11:20:52EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:38EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.2 2011/03/04 14:56:05EST sslegel +** Added a event text length check +** Revision 1.1 2011/02/15 11:13:01EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "utlist.h" +#include "uttools.h" +#include + +UtListHead_t EventQueue; + +typedef struct { + uint16 EventID; + uint16 EventType; + char EventText[CFE_EVS_MAX_MESSAGE_LENGTH]; +} Ut_CFE_EVS_Event_t; + +void Ut_CFE_EVS_ClearEventQueue(void) +{ + UtList_Reset(&EventQueue); +} + +uint32 Ut_CFE_EVS_GetEventQueueDepth(void) +{ + return(UtList_Depth(&EventQueue)); +} + +uint32 Ut_CFE_EVS_GetEventCount(uint16 EventID, uint16 EventType, char *EventText) +{ + UtListNode_t *CurrentNode; + Ut_CFE_EVS_Event_t *EventMessagePtr; + uint32 EventCount = 0; + + CurrentNode = UtList_First(&EventQueue); + while (CurrentNode) { + EventMessagePtr = CurrentNode->Data; + if ((EventMessagePtr->EventID == EventID) && + (EventMessagePtr->EventType == EventType) && + (strncmp(EventText, EventMessagePtr->EventText, strlen(EventText)) == 0)) { + EventCount++; + } + CurrentNode = CurrentNode->Next; + } + return(EventCount); +} + +int32 Ut_CFE_EVS_SendEventHook(uint16 EventID, uint16 EventType, char *EventText) +{ + Ut_CFE_EVS_Event_t EventMessage; + + if (strlen(EventText) >= CFE_EVS_MAX_MESSAGE_LENGTH) { + UtPrintf("WARNING - Event Message Too Long: %s", EventText); + } + + EventMessage.EventID = EventID; + EventMessage.EventType = EventType; + strncpy(&EventMessage.EventText[0], EventText, CFE_EVS_MAX_MESSAGE_LENGTH); + UtList_Add(&EventQueue, &EventMessage, sizeof(EventMessage), 0); + + if (EventType == CFE_EVS_DEBUG) + UtPrintf("DEBUG EVENT ID=%d %s\n", EventID, EventText); + else if (EventType == CFE_EVS_INFORMATION) + UtPrintf("INFO EVENT ID=%d %s\n", EventID, EventText); + else if (EventType == CFE_EVS_ERROR) + UtPrintf("ERROR EVENT ID=%d %s\n", EventID, EventText); + else if (EventType == CFE_EVS_CRITICAL) + UtPrintf("CRITICAL EVENT ID=%d %s\n", EventID, EventText); + else + UtPrintf("Invalid Event Type %d ID=%d %s\n", EventType, EventID, EventText); + + return CFE_SUCCESS; +} + +boolean Ut_CFE_EVS_EventSent(uint16 EventID, uint16 EventType, char *EventText) +{ + UtListNode_t *CurrentNode; + Ut_CFE_EVS_Event_t *EventMessagePtr; + + CurrentNode = UtList_First(&EventQueue); + while (CurrentNode) { + EventMessagePtr = CurrentNode->Data; + if ((EventMessagePtr->EventID == EventID) && + (EventMessagePtr->EventType == EventType) && + (strncmp(EventText, EventMessagePtr->EventText, strlen(EventText)) == 0)) { + return(TRUE); + } + CurrentNode = CurrentNode->Next; + } + return(FALSE); +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_evs_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_evs_stubs.c new file mode 100644 index 0000000..0d06c8d --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_evs_stubs.c @@ -0,0 +1,120 @@ +/* +** +** File: ut_cfe_evs_stubs.c +** +** $Id: ut_cfe_evs_stubs.c 1.1 2011/05/04 11:20:53EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE Event Services routines +** +** $Log: ut_cfe_evs_stubs.c $ +** Revision 1.1 2011/05/04 11:20:53EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:38EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/02/15 11:13:02EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +/* +** Include section +*/ + +#include "cfe.h" +#include "ut_cfe_evs_stubs.h" +#include "ut_cfe_evs_hooks.h" +#include + +Ut_CFE_EVS_HookTable_t Ut_CFE_EVS_HookTable; +Ut_CFE_EVS_ReturnCodeTable_t Ut_CFE_EVS_ReturnCodeTable[UT_CFE_EVS_MAX_INDEX]; + +void Ut_CFE_EVS_Reset(void) +{ + memset(&Ut_CFE_EVS_HookTable, 0, sizeof(Ut_CFE_EVS_HookTable)); + memset(&Ut_CFE_EVS_ReturnCodeTable, 0, sizeof(Ut_CFE_EVS_ReturnCodeTable)); + + Ut_CFE_EVS_SetFunctionHook(UT_CFE_EVS_SENDEVENT_INDEX, &Ut_CFE_EVS_SendEventHook); + Ut_CFE_EVS_ClearEventQueue(); +} + +void Ut_CFE_EVS_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_CFE_EVS_REGISTER_INDEX) { Ut_CFE_EVS_HookTable.CFE_EVS_Register = FunPtr; } + else if (Index == UT_CFE_EVS_SENDEVENT_INDEX) { Ut_CFE_EVS_HookTable.CFE_EVS_SendEvent = FunPtr; } + else { printf("Unsupported EVS Index In SetFunctionHook Call %u", Index); } +} + +void Ut_CFE_EVS_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_CFE_EVS_MAX_INDEX) { + Ut_CFE_EVS_ReturnCodeTable[Index].Value = RtnVal; + Ut_CFE_EVS_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported EVS Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_CFE_EVS_UseReturnCode(uint32 Index) +{ + if (Ut_CFE_EVS_ReturnCodeTable[Index].Count > 0) { + Ut_CFE_EVS_ReturnCodeTable[Index].Count--; + if (Ut_CFE_EVS_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +int32 CFE_EVS_Register (void *Filters, uint16 NumEventFilters, uint16 FilterScheme) +{ + if (Ut_CFE_EVS_UseReturnCode(UT_CFE_EVS_REGISTER_INDEX)) + return Ut_CFE_EVS_ReturnCodeTable[UT_CFE_EVS_REGISTER_INDEX].Value; + + if (Ut_CFE_EVS_HookTable.CFE_EVS_Register) + return(Ut_CFE_EVS_HookTable.CFE_EVS_Register(Filters, NumEventFilters, FilterScheme)); + + return CFE_SUCCESS; +} + +int32 CFE_EVS_SendEvent (uint16 EventID, uint16 EventType, const char *Spec, ... ) +{ + char BigBuf[CFE_EVS_MAX_MESSAGE_LENGTH]; + va_list Ptr; + + va_start(Ptr, Spec); + vsprintf(BigBuf, Spec, Ptr); + va_end(Ptr); + + if (Ut_CFE_EVS_UseReturnCode(UT_CFE_EVS_SENDEVENT_INDEX)) + return Ut_CFE_EVS_ReturnCodeTable[UT_CFE_EVS_SENDEVENT_INDEX].Value; + + if (Ut_CFE_EVS_HookTable.CFE_EVS_SendEvent) + return(Ut_CFE_EVS_HookTable.CFE_EVS_SendEvent(EventID, EventType, BigBuf)); + + return CFE_SUCCESS; +} + +int32 CFE_EVS_SendTimedEvent (CFE_TIME_SysTime_t Time, uint16 EventID, uint16 EventType, const char *Spec, ... ) +{ + if (Ut_CFE_EVS_UseReturnCode(UT_CFE_EVS_SENDTIMEDEVENT_INDEX)) + return Ut_CFE_EVS_ReturnCodeTable[UT_CFE_EVS_SENDTIMEDEVENT_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_EVS_SendEventWithAppID (uint16 EventID, uint16 EventType,uint32 AppID, const char *Spec, ... ) +{ + if (Ut_CFE_EVS_UseReturnCode(UT_CFE_EVS_SENDEVENTWITHAPPID_INDEX)) + return Ut_CFE_EVS_ReturnCodeTable[UT_CFE_EVS_SENDEVENTWITHAPPID_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_EVS_CleanUpApp (uint32 AppId) +{ + return CFE_SUCCESS; +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_fs_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_fs_stubs.c new file mode 100644 index 0000000..f18018f --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_fs_stubs.c @@ -0,0 +1,102 @@ +/* +** +** File: ut_cfe_fs_stubs.c +** +** $Id: ut_cfe_fs_stubs.c 1.1 2011/05/04 11:20:53EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE File system routines +** +** $Log: ut_cfe_fs_stubs.c $ +** Revision 1.1 2011/05/04 11:20:53EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:39EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.2 2011/03/22 14:19:02EDT rmcgraw +** Use Rtn Code Added to CFE_FS_WriteHeader +** Revision 1.1 2011/02/15 11:13:02EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "ut_cfe_fs_stubs.h" +#include + +Ut_CFE_FS_HookTable_t Ut_CFE_FS_HookTable; +Ut_CFE_FS_ReturnCodeTable_t Ut_CFE_FS_ReturnCodeTable[UT_CFE_FS_MAX_INDEX]; + +void Ut_CFE_FS_Reset(void) +{ + memset(&Ut_CFE_FS_HookTable, 0, sizeof(Ut_CFE_FS_HookTable)); + memset(&Ut_CFE_FS_ReturnCodeTable, 0, sizeof(Ut_CFE_FS_ReturnCodeTable)); +} + +void Ut_CFE_FS_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_CFE_FS_READHDR_INDEX) { Ut_CFE_FS_HookTable.CFE_FS_ReadHeader = FunPtr; } + else if (Index == UT_CFE_FS_WRITEHDR_INDEX) { Ut_CFE_FS_HookTable.CFE_FS_WriteHeader = FunPtr; } + else if (Index == UT_CFE_FS_SETTIMESTAMP_INDEX) { Ut_CFE_FS_HookTable.CFE_FS_SetTimestamp = FunPtr; } + else if (Index == UT_CFE_FS_ISGZFILE_INDEX) { Ut_CFE_FS_HookTable.CFE_FS_IsGzFile = FunPtr; } + else if (Index == UT_CFE_FS_EXTRACTFILENAMEFROMPATH_INDEX) { Ut_CFE_FS_HookTable.CFE_FS_ExtractFilenameFromPath = FunPtr; } + else if (Index == UT_CFE_FS_DECOMPRESS_INDEX) { Ut_CFE_FS_HookTable.CFE_FS_Decompress = FunPtr; } + else { printf("Invalid FS Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_CFE_FS_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_CFE_FS_MAX_INDEX) { + Ut_CFE_FS_ReturnCodeTable[Index].Value = RtnVal; + Ut_CFE_FS_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported FS Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_CFE_FS_UseReturnCode(uint32 Index) +{ + if (Ut_CFE_FS_ReturnCodeTable[Index].Count > 0) { + Ut_CFE_FS_ReturnCodeTable[Index].Count--; + if (Ut_CFE_FS_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +int32 CFE_FS_ReadHeader(CFE_FS_Header_t *Hdr, int32 FileDes) +{ + return CFE_SUCCESS; +} + +int32 CFE_FS_WriteHeader(int32 FileDes, CFE_FS_Header_t *Hdr) +{ + /* Check for specified return */ + if (Ut_CFE_FS_UseReturnCode(UT_CFE_FS_WRITEHDR_INDEX)) + return Ut_CFE_FS_ReturnCodeTable[UT_CFE_FS_WRITEHDR_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_FS_SetTimestamp(int32 FileDes, CFE_TIME_SysTime_t NewTimestamp) +{ + return CFE_SUCCESS; +} + +boolean CFE_FS_IsGzFile(const char *FileName) +{ + return TRUE; +} + +int32 CFE_FS_ExtractFilenameFromPath(const char *OriginalPath, char *FileNameOnly) +{ + return CFE_SUCCESS; +} + +int32 CFE_FS_Decompress( const char * SourceFile, const char * DestinationFile ) +{ + return CFE_SUCCESS; +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_psp_memutils_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_psp_memutils_stubs.c new file mode 100644 index 0000000..c2bfa23 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_psp_memutils_stubs.c @@ -0,0 +1,38 @@ +/* +** +** File: ut_cfe_psp_memutils_stubs.c +** +** $Id: ut_cfe_psp_memutils_stubs.c 1.1 2011/05/04 11:20:54EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE PSP Memory Utilities routines +** +** $Log: ut_cfe_psp_memutils_stubs.c $ +** Revision 1.1 2011/05/04 11:20:54EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:39EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/02/15 11:13:02EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +/* +** Include Files +*/ +#include "cfe.h" +#include + +int32 CFE_PSP_MemCpy(void *Dest, void *Src, uint32 Size) +{ + memcpy(Dest, Src, Size); + return(CFE_PSP_SUCCESS); +} + +int32 CFE_PSP_MemSet(void *Dest, uint8 Value, uint32 Size) +{ + memset(Dest, Value, Size); + return(CFE_PSP_SUCCESS); +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_sb_hooks.c b/fsw/unit_test/ut-assert/src/ut_cfe_sb_hooks.c new file mode 100644 index 0000000..0dec74a --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_sb_hooks.c @@ -0,0 +1,545 @@ +/* +** +** File: ut_cfe_sb_hooks.c +** +** $Id: ut_cfe_sb_hooks.c 1.1 2011/05/04 11:20:55EDT rmcgraw Exp $ +** +** Purpose: Unit test hooks for cFE Software Bus routines +** +** $Log: ut_cfe_sb_hooks.c $ +** Revision 1.1 2011/05/04 11:20:55EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:40EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.3 2011/03/08 15:49:26EST sslegel +** Changed the SB Create Pipe Hook so that if the pipe already exists then it just returns the existing pipe id. +** Revision 1.2 2011/03/04 14:56:54EST sslegel +** Added a define for the maximum number of pipes +** Revision 1.1 2011/02/15 11:13:03EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "utlist.h" +#include "uttools.h" +#include + +#define UT_CFE_SB_MAX_PIPES 32 + +typedef struct { + char PipeName[OS_MAX_API_NAME]; + UtListHead_t MsgQueue; + boolean InUse; +} Ut_CFE_SB_PipeTableEntry_t; + +UtListHead_t MsgQueue; +Ut_CFE_SB_PipeTableEntry_t PipeTable[UT_CFE_SB_MAX_PIPES]; + +void Ut_CFE_SB_ClearMsgQueue(void) +{ + UtList_Reset(&MsgQueue); +} + +uint32 Ut_CFE_SB_GetMsgQueueDepth(void) +{ + return(UtList_Depth(&MsgQueue)); +} + +uint32 Ut_CFE_SB_GetMsgCount(uint16 MessageID) +{ + UtListNode_t *CurrentNode; + CFE_SB_Msg_t *MessagePtr; + uint32 MessageCount = 0; + + CurrentNode = UtList_First(&MsgQueue); + while (CurrentNode) { + MessagePtr = CurrentNode->Data; + if (MessageID == CFE_SB_GetMsgId(MessagePtr)) { + MessageCount++; + } + CurrentNode = CurrentNode->Next; + } + return(MessageCount); +} + +int32 Ut_CFE_SB_SendMsgHook(CFE_SB_Msg_t *MsgPtr) +{ + UtList_Add(&MsgQueue, MsgPtr, CFE_SB_GetTotalMsgLength(MsgPtr), 0); + + UtPrintf("PKT: "); + UtPrintx(MsgPtr, (uint16)(CFE_SB_GetTotalMsgLength(MsgPtr))); + return CFE_SUCCESS; +} + +boolean Ut_CFE_SB_PacketSent(uint16 MessageID) +{ + UtListNode_t *CurrentNode; + CFE_SB_Msg_t *MessagePtr; + + CurrentNode = UtList_First(&MsgQueue); + while (CurrentNode) { + MessagePtr = CurrentNode->Data; + if (MessageID == CFE_SB_GetMsgId(MessagePtr)) { + return(TRUE); + } + CurrentNode = CurrentNode->Next; + } + return(FALSE); +} + +void *Ut_CFE_SB_FindPacket(uint16 MessageID, uint32 MessageNumber) +{ + UtListNode_t *CurrentNode; + CFE_SB_Msg_t *MessagePtr; + uint32 MessageCount = 0; + + CurrentNode = UtList_First(&MsgQueue); + while (CurrentNode) { + MessagePtr = CurrentNode->Data; + if (MessageID == CFE_SB_GetMsgId(MessagePtr)) { + MessageCount++; + if (MessageCount == MessageNumber) { + return(CurrentNode->Data); + } + } + CurrentNode = CurrentNode->Next; + } + return(NULL); +} + +void Ut_CFE_SB_ClearPipes(void) +{ + uint32 i; + + for (i=0; i < UT_CFE_SB_MAX_PIPES; i++) { + if (PipeTable[i].InUse == TRUE) { + UtList_Reset(&PipeTable[i].MsgQueue); + } + } + memset(&PipeTable, 0, sizeof(PipeTable)); +} + +int32 Ut_CFE_SB_CreatePipe(char *PipeName) +{ + uint32 i; + + for (i=0; i < UT_CFE_SB_MAX_PIPES; i++) { + if (PipeTable[i].InUse == FALSE) { + strncpy(PipeTable[i].PipeName, PipeName, OS_MAX_API_NAME); + PipeTable[i].InUse = TRUE; + return(i); + } + } + return(-1); +} + +int32 Ut_CFE_SB_GetPipeDepth(CFE_SB_PipeId_t PipeId) +{ + return(UtList_Depth(&PipeTable[PipeId].MsgQueue)); +} + +int32 Ut_CFE_SB_FindPipe(char *PipeName) +{ + uint32 i; + + for (i=0; i < UT_CFE_SB_MAX_PIPES; i++) { + if ((PipeTable[i].InUse == TRUE) && + (strncmp(PipeTable[i].PipeName, PipeName, strlen(PipeName)) == 0)) { + return(i); + } + } + return(-1); +} + +void Ut_CFE_SB_AddMsgToPipe(void *MsgPtr, CFE_SB_PipeId_t PipeId) +{ + if (PipeTable[PipeId].InUse == TRUE) { + UtList_Add(&PipeTable[PipeId].MsgQueue, MsgPtr, CFE_SB_GetTotalMsgLength((CFE_SB_MsgPtr_t)MsgPtr), 0); + } + else { + printf("Error - Invalid PipeId\n"); + } +} + +int32 Ut_CFE_SB_CreatePipeHook(CFE_SB_PipeId_t *PipeIdPtr, uint16 Depth, char *PipeName) +{ + if (Ut_CFE_SB_FindPipe(PipeName) == -1) { + *PipeIdPtr = Ut_CFE_SB_CreatePipe(PipeName); + } + else { + *PipeIdPtr = Ut_CFE_SB_FindPipe(PipeName); + } + return(CFE_SUCCESS); +} + +int32 Ut_CFE_SB_RcvMsgHook(CFE_SB_MsgPtr_t *BufPtr, CFE_SB_PipeId_t PipeId, int32 TimeOut) +{ + UtListNode_t *CurrentNode; + + if (PipeTable[PipeId].InUse == TRUE) { + + if (UtList_IsEmpty(&PipeTable[PipeId].MsgQueue) == FALSE) { + + CurrentNode = UtList_First(&PipeTable[PipeId].MsgQueue); + if (CurrentNode->Tag == TRUE) { /* Indicates buffer is in use */ + UtList_DeleteFirst(&PipeTable[PipeId].MsgQueue); + } + + if (UtList_IsEmpty(&PipeTable[PipeId].MsgQueue) == FALSE) { + + CurrentNode = UtList_First(&PipeTable[PipeId].MsgQueue); + CurrentNode->Tag = TRUE; /* Indicates buffer is in use */ + *BufPtr = CurrentNode->Data; + return(CFE_SUCCESS); + } + } + + if (TimeOut == CFE_SB_POLL) { + return(CFE_SB_NO_MESSAGE); + } + else { + return(CFE_SB_TIME_OUT); + } + } + else { + printf("Error - Invalid PipeId\n"); + return(CFE_SB_NO_MESSAGE); + } +} + +void Ut_CFE_SB_InitMsgHook(void *MsgPtr, CFE_SB_MsgId_t MsgId, uint16 Length, boolean Clear) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CCSDS_InitPkt ((CCSDS_PriHdr_t *)MsgPtr,(uint16)MsgId,Length,Clear); + +#endif +} /* end Ut_CFE_SB_InitMsgHook */ + +uint16 Ut_CFE_SB_MsgHdrSizeHook(CFE_SB_MsgId_t MsgId) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + uint16 size; + CCSDS_PriHdr_t CCSDSPriHdr; + CCSDS_WR_SID(CCSDSPriHdr,MsgId); + + /* if secondary hdr is not present... */ + if(CCSDS_RD_SHDR(CCSDSPriHdr) == 0){ + + size = sizeof(CCSDS_PriHdr_t); + + }else if(CCSDS_RD_TYPE(CCSDSPriHdr) == CCSDS_CMD){ + + size = CFE_SB_CMD_HDR_SIZE; + + }else{ + + size = CFE_SB_TLM_HDR_SIZE; + } + + return size; + +#endif +}/* end Ut_CFE_SB_MsgHdrSizeHook */ + +void *Ut_CFE_SB_GetUserDataHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + uint8 *BytePtr; + CFE_SB_MsgId_t MsgId; + uint16 HdrSize; + + BytePtr = (uint8 *)MsgPtr; + MsgId = CFE_SB_GetMsgId(MsgPtr); + HdrSize = CFE_SB_MsgHdrSize(MsgId); + + return (BytePtr + HdrSize); +#endif +}/* end Ut_CFE_SB_GetUserDataHook */ + +CFE_SB_MsgId_t Ut_CFE_SB_GetMsgIdHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + return CCSDS_RD_SID(MsgPtr->Hdr); + +#endif +}/* end Ut_CFE_SB_GetMsgIdHook */ + +void Ut_CFE_SB_SetMsgIdHook(CFE_SB_MsgPtr_t MsgPtr, + CFE_SB_MsgId_t MsgId) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CCSDS_WR_SID(MsgPtr->Hdr,MsgId); + +#endif +}/* end Ut_CFE_SB_SetMsgIdHook */ + +uint16 Ut_CFE_SB_GetUserDataLengthHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + uint16 TotalMsgSize; + uint16 HdrSize; + + CFE_SB_MsgId_t MsgId; + MsgId = CFE_SB_GetMsgId(MsgPtr); + + TotalMsgSize = CFE_SB_GetTotalMsgLength(MsgPtr); + HdrSize = CFE_SB_MsgHdrSize(MsgId); + + return (TotalMsgSize - HdrSize); +#endif +}/* end Ut_CFE_SB_GetUserDataLengthHook */ + +void Ut_CFE_SB_SetUserDataLengthHook(CFE_SB_MsgPtr_t MsgPtr,uint16 DataLength) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + uint32 TotalMsgSize, HdrSize; + CFE_SB_MsgId_t MsgId; + MsgId = CFE_SB_GetMsgId(MsgPtr); + + TotalMsgSize = CFE_SB_GetTotalMsgLength(MsgPtr); + HdrSize = CFE_SB_MsgHdrSize(MsgId); + + TotalMsgSize = HdrSize + DataLength; + + CCSDS_WR_LEN(MsgPtr->Hdr,TotalMsgSize); + +#endif +}/* end Ut_CFE_SB_SetUserDataLengthHook */ + +uint16 Ut_CFE_SB_GetTotalMsgLengthHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + return CCSDS_RD_LEN(MsgPtr->Hdr); + +#endif +}/* end Ut_CFE_SB_GetTotalMsgLengthHook */ + +void Ut_CFE_SB_SetTotalMsgLengthHook(CFE_SB_MsgPtr_t MsgPtr,uint16 TotalLength) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CCSDS_WR_LEN(MsgPtr->Hdr,TotalLength); + +#endif +}/* end Ut_CFE_SB_SetTotalMsgLengthHook */ + +CFE_TIME_SysTime_t Ut_CFE_SB_GetMsgTimeHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CFE_TIME_SysTime_t TimeFromMsg; + CFE_SB_TlmHdr_t *TlmHdrPtr; + + /* if msg type is a command or msg has no secondary hdr, return 0 */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_CMD)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + TimeFromMsg.Seconds = 0; + TimeFromMsg.Subseconds = 0; + }else{ + TlmHdrPtr = (CFE_SB_TlmHdr_t *)MsgPtr; + + TimeFromMsg.Seconds = *((uint32 *)&TlmHdrPtr->Sec.Time[0]); + + /* Get the 16 bit subsecond field from the header and place it in the */ + /* upper 16 bits of the 32 bit subsecond field of the CFE_TIME_SysTime_t */ + TimeFromMsg.Subseconds = *((uint16 *)&TlmHdrPtr->Sec.Time[4]) << 16; + + }/* end if */ + + return TimeFromMsg; + +#endif +}/* end Ut_CFE_SB_GetMsgTimeHook */ + +int32 Ut_CFE_SB_SetMsgTimeHook(CFE_SB_MsgPtr_t MsgPtr, + CFE_TIME_SysTime_t Time) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CFE_SB_TlmHdr_t *TlmHdrPtr; + + /* if msg type is a command or secondary header is not present... */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_CMD)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + return CFE_SB_WRONG_MSG_TYPE; + }/* end if */ + + TlmHdrPtr = (CFE_SB_TlmHdr_t *)MsgPtr; + + *((uint32 *)&TlmHdrPtr->Sec.Time[0]) = Time.Seconds; + *((uint16 *)&TlmHdrPtr->Sec.Time[4]) = Time.Subseconds >> 16; + + return CFE_SUCCESS; + +#endif +}/* end Ut_CFE_SB_SetMsgTimeHook */ + +//FIXME - not sure what to do about this yet, want to avoid any dependencies on other api functions if possible. +//void Ut_CFE_SB_TimeStampMsgHook(CFE_SB_MsgPtr_t MsgPtr) +//{ +// CFE_SB_SetMsgTime(MsgPtr,CFE_TIME_GetTime()); +// +//}/* end Ut_CFE_SB_TimeStampMsgHook */ + +uint16 Ut_CFE_SB_GetCmdCodeHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CFE_SB_CmdHdr_t *CmdHdrPtr; + + /* if msg type is telemetry or there is no secondary hdr, return 0 */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_TLM)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + return 0; + }/* end if */ + + /* Cast the input pointer to a Cmd Msg pointer */ + CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; + + return CCSDS_RD_FC(CmdHdrPtr->Sec); + +#endif +}/* end Ut_CFE_SB_GetCmdCodeHook */ + +int32 Ut_CFE_SB_SetCmdCodeHook(CFE_SB_MsgPtr_t MsgPtr, + uint16 CmdCode) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CFE_SB_CmdHdr_t *CmdHdrPtr; + + /* if msg type is telemetry or there is no secondary hdr... */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_TLM)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + return CFE_SB_WRONG_MSG_TYPE; + }/* end if */ + + /* Cast the input pointer to a Cmd Msg pointer */ + CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; + + CCSDS_WR_FC(CmdHdrPtr->Sec,CmdCode); + + return CFE_SUCCESS; + +#endif + +}/* end Ut_CFE_SB_SetCmdCodeHook */ + +uint16 Ut_CFE_SB_GetChecksumHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CFE_SB_CmdHdr_t *CmdHdrPtr; + + /* if msg type is telemetry or there is no secondary hdr... */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_TLM)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + return 0; + }/* end if */ + + /* cast the input pointer to a Cmd Msg pointer */ + CmdHdrPtr = (CFE_SB_CmdHdr_t *)MsgPtr; + + return CCSDS_RD_CHECKSUM(CmdHdrPtr->Sec); + +#endif +}/* end Ut_CFE_SB_GetChecksumHook */ + +void Ut_CFE_SB_GenerateChecksumHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CCSDS_CmdPkt_t *CmdPktPtr; + + /* if msg type is telemetry or there is no secondary hdr... */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_TLM)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + return; + }/* end if */ + + CmdPktPtr = (CCSDS_CmdPkt_t *)MsgPtr; + + CCSDS_LoadCheckSum(CmdPktPtr); + +#endif +}/* end Ut_CFE_SB_GenerateChecksumHook */ + +boolean Ut_CFE_SB_ValidateChecksumHook(CFE_SB_MsgPtr_t MsgPtr) +{ +#ifdef MESSAGE_FORMAT_IS_CCSDS + + CCSDS_CmdPkt_t *CmdPktPtr; + + /* if msg type is telemetry or there is no secondary hdr... */ + if((CCSDS_RD_TYPE(MsgPtr->Hdr) == CCSDS_TLM)||(CCSDS_RD_SHDR(MsgPtr->Hdr) == 0)){ + return FALSE; + }/* end if */ + + CmdPktPtr = (CCSDS_CmdPkt_t *)MsgPtr; + + return CCSDS_ValidCheckSum (CmdPktPtr); + +#endif +}/* end Ut_CFE_SB_ValidateChecksumHook */ + +void CCSDS_InitPkt (CCSDS_PriHdr_t *PktPtr, + uint16 StreamId, + uint16 Length, + boolean Clear ) +{ + uint16 SeqCount; + + /* Save the sequence count in case it must be preserved. */ + SeqCount = CCSDS_RD_SEQ(*PktPtr); + + /* Zero the entire packet if needed. */ + if (Clear) memset((void *)PktPtr, 0, Length); + + /* Clear the primary header. */ + CCSDS_CLR_PRI_HDR(*PktPtr); + + /* Set the stream ID and length fields in the primary header. */ + CCSDS_WR_SID(*PktPtr, StreamId); + CCSDS_WR_LEN(*PktPtr, Length); + + /* Restore the sequence count if needed. */ + if (!Clear) CCSDS_WR_SEQ(*PktPtr, SeqCount); + +} /* END CCSDS_InitPkt() */ + +void CCSDS_LoadCheckSum (CCSDS_CmdPkt_t *PktPtr) +{ + uint8 CheckSum; + + /* Clear the checksum field so the new checksum is correct. */ + CCSDS_WR_CHECKSUM(PktPtr->SecHdr, 0); + + /* Compute and load new checksum. */ + CheckSum = CCSDS_ComputeCheckSum(PktPtr); + CCSDS_WR_CHECKSUM(PktPtr->SecHdr, CheckSum); + +} /* END CCSDS_LoadCheckSum() */ + +boolean CCSDS_ValidCheckSum (CCSDS_CmdPkt_t *PktPtr) +{ + + return (CCSDS_ComputeCheckSum(PktPtr) == 0); + +} /* END CCSDS_ValidCheckSum() */ + +uint8 CCSDS_ComputeCheckSum (CCSDS_CmdPkt_t *PktPtr) +{ + uint16 PktLen = CCSDS_RD_LEN(PktPtr->PriHdr); + uint8 *BytePtr = (uint8 *)PktPtr; + uint8 CheckSum; + + CheckSum = 0xFF; + while (PktLen--) CheckSum ^= *(BytePtr++); + + return CheckSum; + +} /* END CCSDS_ComputeCheckSum() */ diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_sb_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_sb_stubs.c new file mode 100644 index 0000000..038b019 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_sb_stubs.c @@ -0,0 +1,427 @@ +/* +** +** File: ut_cfe_sb_stubs.c +** +** $Id: ut_cfe_sb_stubs.c 1.1 2011/05/04 11:20:56EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE Software Bus routines +** +** $Log: ut_cfe_sb_stubs.c $ +** Revision 1.1 2011/05/04 11:20:56EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:41EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.2 2011/03/10 11:18:33EST sslegel +** Added hook support to CFE_SB_Subscribe, CFE_SB_SubscribeEx, and CFE_SB_Unsunscribe +** Revision 1.1 2011/02/15 11:13:03EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "ut_cfe_sb_stubs.h" +#include "ut_cfe_sb_hooks.h" + +Ut_CFE_SB_HookTable_t Ut_CFE_SB_HookTable; +Ut_CFE_SB_ReturnCodeTable_t Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_MAX_INDEX]; + +void Ut_CFE_SB_Reset(void) +{ + memset(&Ut_CFE_SB_HookTable, 0, sizeof(Ut_CFE_SB_HookTable)); + memset(&Ut_CFE_SB_ReturnCodeTable, 0, sizeof(Ut_CFE_SB_ReturnCodeTable)); + + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_CREATEPIPE_INDEX, &Ut_CFE_SB_CreatePipeHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_SENDMSG_INDEX, &Ut_CFE_SB_SendMsgHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_RCVMSG_INDEX, &Ut_CFE_SB_RcvMsgHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_INITMSG_INDEX, &Ut_CFE_SB_InitMsgHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_MSGHDRSIZE_INDEX, &Ut_CFE_SB_MsgHdrSizeHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETUSERDATA_INDEX, &Ut_CFE_SB_GetUserDataHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETMSGID_INDEX, &Ut_CFE_SB_GetMsgIdHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_SETMSGID_INDEX, &Ut_CFE_SB_SetMsgIdHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETUSERDATALENGTH_INDEX, &Ut_CFE_SB_GetUserDataLengthHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_SETUSERDATALENGTH_INDEX, &Ut_CFE_SB_SetUserDataLengthHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETTOTALMSGLENGTH_INDEX, &Ut_CFE_SB_GetTotalMsgLengthHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_SETTOTALMSGLENGTH_INDEX, &Ut_CFE_SB_SetTotalMsgLengthHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETMSGTIME_INDEX, &Ut_CFE_SB_GetMsgTimeHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_SETMSGTIME_INDEX, &Ut_CFE_SB_SetMsgTimeHook); +// Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_TIMESTAMPMSG_INDEX, &Ut_CFE_SB_TimeStampMsgHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETCMDCODE_INDEX, &Ut_CFE_SB_GetCmdCodeHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_SETCMDCODE_INDEX, &Ut_CFE_SB_SetCmdCodeHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GETCHECKSUM_INDEX, &Ut_CFE_SB_GetChecksumHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_GENERATECHECKSUM_INDEX, &Ut_CFE_SB_GenerateChecksumHook); + Ut_CFE_SB_SetFunctionHook(UT_CFE_SB_VALIDATECHECKSUM_INDEX, &Ut_CFE_SB_ValidateChecksumHook); + + Ut_CFE_SB_ClearPipes(); + Ut_CFE_SB_ClearMsgQueue(); +} + +void Ut_CFE_SB_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_CFE_SB_CREATEPIPE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_CreatePipe = FunPtr; } + else if (Index == UT_CFE_SB_DELETEPIPE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_DeletePipe = FunPtr; } + else if (Index == UT_CFE_SB_SUBSCRIBEEX_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SubscribeEx = FunPtr; } + else if (Index == UT_CFE_SB_SUBSCRIBE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_Subscribe = FunPtr; } + else if (Index == UT_CFE_SB_SUBSCRIBELOCAL_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SubscribeLocal = FunPtr; } + else if (Index == UT_CFE_SB_UNSUBSCRIBE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_Unsubscribe = FunPtr; } + else if (Index == UT_CFE_SB_UNSUBSCRIBELOCAL_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_UnsubscribeLocal = FunPtr; } + else if (Index == UT_CFE_SB_SENDMSG_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SendMsg = FunPtr; } + else if (Index == UT_CFE_SB_PASSMSG_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_PassMsg = FunPtr; } + else if (Index == UT_CFE_SB_RCVMSG_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_RcvMsg = FunPtr; } + else if (Index == UT_CFE_SB_GETLASTSENDERID_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetLastSenderId = FunPtr; } + else if (Index == UT_CFE_SB_ZEROCOPYGETPTR_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_ZeroCopyGetPtr = FunPtr; } + else if (Index == UT_CFE_SB_ZEROCOPYRELEASEPTR_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_ZeroCopyReleasePtr = FunPtr; } + else if (Index == UT_CFE_SB_ZEROCOPYSEND_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_ZeroCopySend = FunPtr; } + else if (Index == UT_CFE_SB_ZEROCOPYPASS_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_ZeroCopyPass = FunPtr; } + else if (Index == UT_CFE_SB_INITMSG_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_InitMsg = FunPtr; } + else if (Index == UT_CFE_SB_MSGHDRSIZE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_MsgHdrSize = FunPtr; } + else if (Index == UT_CFE_SB_GETUSERDATA_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetUserData = FunPtr; } + else if (Index == UT_CFE_SB_GETMSGID_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetMsgId = FunPtr; } + else if (Index == UT_CFE_SB_SETMSGID_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SetMsgId = FunPtr; } + else if (Index == UT_CFE_SB_GETUSERDATALENGTH_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetUserDataLength = FunPtr; } + else if (Index == UT_CFE_SB_SETUSERDATALENGTH_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SetUserDataLength = FunPtr; } + else if (Index == UT_CFE_SB_GETTOTALMSGLENGTH_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetTotalMsgLength = FunPtr; } + else if (Index == UT_CFE_SB_SETTOTALMSGLENGTH_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SetTotalMsgLength = FunPtr; } + else if (Index == UT_CFE_SB_GETMSGTIME_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetMsgTime = FunPtr; } + else if (Index == UT_CFE_SB_SETMSGTIME_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SetMsgTime = FunPtr; } + else if (Index == UT_CFE_SB_TIMESTAMPMSG_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_TimeStampMsg = FunPtr; } + else if (Index == UT_CFE_SB_GETCMDCODE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetCmdCode = FunPtr; } + else if (Index == UT_CFE_SB_SETCMDCODE_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_SetCmdCode = FunPtr; } + else if (Index == UT_CFE_SB_GETCHECKSUM_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GetChecksum = FunPtr; } + else if (Index == UT_CFE_SB_GENERATECHECKSUM_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_GenerateChecksum = FunPtr; } + else if (Index == UT_CFE_SB_VALIDATECHECKSUM_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_ValidateChecksum = FunPtr; } + else if (Index == UT_CFE_SB_CLEANUPAPP_INDEX) { Ut_CFE_SB_HookTable.CFE_SB_CleanUpApp = FunPtr; } + else { printf("Unsupported SB Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_CFE_SB_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_CFE_SB_MAX_INDEX) { + Ut_CFE_SB_ReturnCodeTable[Index].Value = RtnVal; + Ut_CFE_SB_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported SB Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_CFE_SB_UseReturnCode(uint32 Index) +{ + if (Ut_CFE_SB_ReturnCodeTable[Index].Count > 0) { + Ut_CFE_SB_ReturnCodeTable[Index].Count--; + if (Ut_CFE_SB_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +int32 CFE_SB_CreatePipe (CFE_SB_PipeId_t *PipeIdPtr, uint16 Depth, const char *PipeName) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_CREATEPIPE_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_CREATEPIPE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_CreatePipe) + return Ut_CFE_SB_HookTable.CFE_SB_CreatePipe(PipeIdPtr, Depth, PipeName); + + return CFE_SUCCESS; +} + +int32 CFE_SB_DeletePipe (CFE_SB_PipeId_t PipeId) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_DELETEPIPE_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_DELETEPIPE_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_SB_SubscribeEx (CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId, + CFE_SB_Qos_t Quality, uint16 MsgLim) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_SUBSCRIBEEX_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_SUBSCRIBEEX_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SubscribeEx) + return Ut_CFE_SB_HookTable.CFE_SB_SubscribeEx(MsgId, PipeId, Quality, MsgLim); + + return CFE_SUCCESS; +} + +int32 CFE_SB_Subscribe(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_SUBSCRIBE_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_SUBSCRIBE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_Subscribe) + return Ut_CFE_SB_HookTable.CFE_SB_Subscribe(MsgId, PipeId); + + return CFE_SUCCESS; +} + +int32 CFE_SB_SubscribeLocal(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId,uint16 MsgLim) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_SUBSCRIBELOCAL_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_SUBSCRIBELOCAL_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_SB_Unsubscribe(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_UNSUBSCRIBE_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_UNSUBSCRIBE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_Unsubscribe) + return Ut_CFE_SB_HookTable.CFE_SB_Unsubscribe(MsgId, PipeId); + + return CFE_SUCCESS; +} + +int32 CFE_SB_UnsubscribeLocal(CFE_SB_MsgId_t MsgId, CFE_SB_PipeId_t PipeId) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_UNSUBSCRIBELOCAL_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_UNSUBSCRIBELOCAL_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_SB_SendMsg (CFE_SB_Msg_t *MsgPtr) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_SENDMSG_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_SENDMSG_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SendMsg) + return Ut_CFE_SB_HookTable.CFE_SB_SendMsg(MsgPtr); + + return CFE_SUCCESS; +} + +int32 CFE_SB_PassMsg (CFE_SB_Msg_t *MsgPtr) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_PASSMSG_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_PASSMSG_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_SB_RcvMsg (CFE_SB_MsgPtr_t *BufPtr, CFE_SB_PipeId_t PipeId, + int32 TimeOut) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_RCVMSG_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_RCVMSG_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_RcvMsg) + return Ut_CFE_SB_HookTable.CFE_SB_RcvMsg(BufPtr,PipeId,TimeOut); + + return CFE_SUCCESS; +} + +uint32 CFE_SB_GetLastSenderId(CFE_SB_SenderId_t **Ptr,CFE_SB_PipeId_t PipeId) +{ + return CFE_SUCCESS; +} + +CFE_SB_Msg_t *CFE_SB_ZeroCopyGetPtr(uint16 MsgSize,CFE_SB_ZeroCopyHandle_t *BufferHandle) +{ + return NULL; +} + +int32 CFE_SB_ZeroCopyReleasePtr(CFE_SB_Msg_t *Ptr2Release,CFE_SB_ZeroCopyHandle_t BufferHandle) +{ + return CFE_SUCCESS; +} + +int32 CFE_SB_ZeroCopySend(CFE_SB_Msg_t *MsgPtr, CFE_SB_ZeroCopyHandle_t BufferHandle) +{ + return CFE_SUCCESS; +} + +int32 CFE_SB_ZeroCopyPass(CFE_SB_Msg_t *MsgPtr, CFE_SB_ZeroCopyHandle_t BufferHandle) +{ + return CFE_SUCCESS; +} + +void CFE_SB_InitMsg (void *MsgPtr, CFE_SB_MsgId_t MsgId, uint16 Length, boolean Clear) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_InitMsg) + Ut_CFE_SB_HookTable.CFE_SB_InitMsg(MsgPtr,MsgId,Length,Clear); + + return; +} + +uint16 CFE_SB_MsgHdrSize (CFE_SB_MsgId_t MsgId) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_MsgHdrSize) + return Ut_CFE_SB_HookTable.CFE_SB_MsgHdrSize(MsgId); + + return CFE_SUCCESS; +} + +void *CFE_SB_GetUserData(CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetUserData) + return Ut_CFE_SB_HookTable.CFE_SB_GetUserData(MsgPtr); + + return NULL; +} + +CFE_SB_MsgId_t CFE_SB_GetMsgId (CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetMsgId) + return Ut_CFE_SB_HookTable.CFE_SB_GetMsgId(MsgPtr); + + return CFE_SUCCESS; +} + +void CFE_SB_SetMsgId (CFE_SB_MsgPtr_t MsgPtr, CFE_SB_MsgId_t MsgId) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SetMsgId) + Ut_CFE_SB_HookTable.CFE_SB_SetMsgId(MsgPtr,MsgId); + + return; +} + +uint16 CFE_SB_GetUserDataLength(CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetUserDataLength) + return Ut_CFE_SB_HookTable.CFE_SB_GetUserDataLength(MsgPtr); + + return CFE_SUCCESS; +}/* end CFE_SB_GetUserDataLength */ + +void CFE_SB_SetUserDataLength(CFE_SB_MsgPtr_t MsgPtr,uint16 DataLength) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SetUserDataLength) + Ut_CFE_SB_HookTable.CFE_SB_SetUserDataLength(MsgPtr,DataLength); + + return; +} + +uint16 CFE_SB_GetTotalMsgLength(CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetTotalMsgLength) + return Ut_CFE_SB_HookTable.CFE_SB_GetTotalMsgLength(MsgPtr); + + return CFE_SUCCESS; +} + +void CFE_SB_SetTotalMsgLength(CFE_SB_MsgPtr_t MsgPtr,uint16 TotalLength) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SetTotalMsgLength) + Ut_CFE_SB_HookTable.CFE_SB_SetTotalMsgLength(MsgPtr,TotalLength); + + return; +} + +CFE_TIME_SysTime_t CFE_SB_GetMsgTime (CFE_SB_MsgPtr_t MsgPtr) +{ + CFE_TIME_SysTime_t Time; + + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetMsgTime) + return Ut_CFE_SB_HookTable.CFE_SB_GetMsgTime(MsgPtr); + + Time.Seconds = 0; + Time.Subseconds = 0; + + return Time; +} + +int32 CFE_SB_SetMsgTime (CFE_SB_MsgPtr_t MsgPtr, CFE_TIME_SysTime_t time) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SetMsgTime) + return Ut_CFE_SB_HookTable.CFE_SB_SetMsgTime(MsgPtr, time); + + return CFE_SUCCESS; +} + +void CFE_SB_TimeStampMsg (CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_TimeStampMsg) + Ut_CFE_SB_HookTable.CFE_SB_TimeStampMsg(MsgPtr); + + return; +} + +uint16 CFE_SB_GetCmdCode (CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetCmdCode) + return Ut_CFE_SB_HookTable.CFE_SB_GetCmdCode(MsgPtr); + + return CFE_SUCCESS; +} + +int32 CFE_SB_SetCmdCode (CFE_SB_MsgPtr_t MsgPtr, uint16 CmdCode) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_SetCmdCode) + return Ut_CFE_SB_HookTable.CFE_SB_SetCmdCode(MsgPtr,CmdCode); + + return CFE_SUCCESS; +} + +uint16 CFE_SB_GetChecksum(CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GetChecksum) + return Ut_CFE_SB_HookTable.CFE_SB_GetChecksum(MsgPtr); + + return CFE_SUCCESS; +} + +void CFE_SB_GenerateChecksum(CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_GenerateChecksum) + Ut_CFE_SB_HookTable.CFE_SB_GenerateChecksum(MsgPtr); + + return; +} + +boolean CFE_SB_ValidateChecksum(CFE_SB_MsgPtr_t MsgPtr) +{ + /* Check for Function Hook */ + if (Ut_CFE_SB_HookTable.CFE_SB_ValidateChecksum) + return Ut_CFE_SB_HookTable.CFE_SB_ValidateChecksum(MsgPtr); + + return CFE_SUCCESS; +} + +int32 CFE_SB_CleanUpApp (uint32 AppId) +{ + /* Check for specified return */ + if (Ut_CFE_SB_UseReturnCode(UT_CFE_SB_CLEANUPAPP_INDEX)) + return Ut_CFE_SB_ReturnCodeTable[UT_CFE_SB_CLEANUPAPP_INDEX].Value; + + return CFE_SUCCESS; +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_tbl_hooks.c b/fsw/unit_test/ut-assert/src/ut_cfe_tbl_hooks.c new file mode 100644 index 0000000..ff2c8e3 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_tbl_hooks.c @@ -0,0 +1,185 @@ +/* +** +** File: ut_cfe_tbl_hooks.c +** +** $Id: ut_cfe_tbl_hooks.c 1.1 2011/05/04 11:20:57EDT rmcgraw Exp $ +** +** Purpose: Unit test hooks for cFE Table Services routines +** +** $Log: ut_cfe_tbl_hooks.c $ +** Revision 1.1 2011/05/04 11:20:57EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:42EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.5 2011/03/04 14:59:12EST sslegel +** Added a define for the maximum number of tables +** Fixed a memory leak in Ut_CFE_TBL_ClearTables +** Fixed a bug in Ut_CFE_TBL_RegisterTable where the table buffer was not cleared after the memory was allocated +** Revision 1.4 2011/02/21 16:15:32EST sslegel +** Renamed global tables +** Revision 1.3 2011/02/18 15:57:42EST sslegel +** Added new hooks and return codes +** Changed Ut_CFE_TBL_LoadHook to automatically call the table validate function +** Revision 1.2 2011/02/17 16:34:26EST rmcgraw +** Tbl GetAdr Hook change to return TBL_UPDATED after a TBL load +** Revision 1.1 2011/02/15 11:13:04EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "utlist.h" +#include + +#define UT_CFE_TBL_MAX_TABLES 32 + +typedef struct { + boolean InUse; + boolean TblUpdatedFlag; + void *Buffer; + char Name[CFE_TBL_MAX_FULL_NAME_LEN]; + uint32 Size; + uint16 TblOptionFlags; + CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr; +} Ut_CFE_TBL_Registry_t; + +typedef struct { + boolean InUse; + char Filename[OS_MAX_PATH_LEN]; + void *TablePtr; +} Ut_CFE_TBL_Images_t; + +Ut_CFE_TBL_Images_t Ut_CFE_TBL_Images[UT_CFE_TBL_MAX_TABLES]; +Ut_CFE_TBL_Registry_t Ut_CFE_TBL_Registry[UT_CFE_TBL_MAX_TABLES]; + +int32 Ut_CFE_TBL_RegisterTable(const char *Name, uint32 Size, uint16 TblOptionFlags, CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr) +{ + uint32 i; + + for (i=0; i < UT_CFE_TBL_MAX_TABLES; i++) { + if (Ut_CFE_TBL_Registry[i].InUse == FALSE) { + Ut_CFE_TBL_Registry[i].InUse = TRUE; + Ut_CFE_TBL_Registry[i].TblUpdatedFlag = FALSE; + Ut_CFE_TBL_Registry[i].Buffer = malloc(Size); + memset(Ut_CFE_TBL_Registry[i].Buffer, 0, Size); + strncpy(Ut_CFE_TBL_Registry[i].Name, Name, CFE_TBL_MAX_FULL_NAME_LEN); + Ut_CFE_TBL_Registry[i].Size = Size; + Ut_CFE_TBL_Registry[i].TblOptionFlags = TblOptionFlags; + Ut_CFE_TBL_Registry[i].TblValidationFuncPtr = TblValidationFuncPtr; + return(i); + } + } + + return(-1); +} + +int32 Ut_CFE_TBL_AddTable(char *Filename, void *TablePtr) +{ + uint32 i; + + for (i=0; i < UT_CFE_TBL_MAX_TABLES; i++) { + if (Ut_CFE_TBL_Images[i].InUse == FALSE) { + Ut_CFE_TBL_Images[i].InUse = TRUE; + strncpy(Ut_CFE_TBL_Images[i].Filename, Filename, OS_MAX_PATH_LEN); + Ut_CFE_TBL_Images[i].TablePtr = TablePtr; + return(i); + } + } + + return(-1); +} + +int32 Ut_CFE_TBL_LoadTable(CFE_TBL_Handle_t TblHandle, void *SrcDataPtr) +{ + if (Ut_CFE_TBL_Registry[TblHandle].InUse) { + memcpy(Ut_CFE_TBL_Registry[TblHandle].Buffer, SrcDataPtr, Ut_CFE_TBL_Registry[TblHandle].Size); + Ut_CFE_TBL_Registry[TblHandle].TblUpdatedFlag = TRUE; + return(CFE_SUCCESS); + } + else { + return(CFE_TBL_ERR_INVALID_HANDLE); + } +} + +void Ut_CFE_TBL_ClearTables(void) +{ + uint32 i; + + for (i=0; i < UT_CFE_TBL_MAX_TABLES; i++) { + if (Ut_CFE_TBL_Registry[i].InUse == TRUE && + Ut_CFE_TBL_Registry[i].Buffer != NULL) { + free(Ut_CFE_TBL_Registry[i].Buffer); + } + } + memset(&Ut_CFE_TBL_Registry, 0, sizeof(Ut_CFE_TBL_Registry)); + memset(&Ut_CFE_TBL_Images, 0, sizeof(Ut_CFE_TBL_Images)); +} + +int32 Ut_CFE_TBL_FindTable(char *Filename) +{ + uint32 i; + + for (i=0; i < UT_CFE_TBL_MAX_TABLES; i++) { + if ((Ut_CFE_TBL_Images[i].InUse == TRUE) && + (strncmp(Ut_CFE_TBL_Images[i].Filename, Filename, strlen(Filename)) == 0)) { + return(i); + } + } + return(-1); +} + +void *Ut_CFE_TBL_GetAddress(CFE_TBL_Handle_t TblHandle) +{ + if (Ut_CFE_TBL_Registry[TblHandle].InUse) { + return(Ut_CFE_TBL_Registry[TblHandle].Buffer); + } + else { + return(NULL); + } +} + +int32 Ut_CFE_TBL_RegisterHook(CFE_TBL_Handle_t *TblHandlePtr, const char *Name, uint32 Size, uint16 TblOptionFlags, CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr) +{ + *TblHandlePtr = Ut_CFE_TBL_RegisterTable(Name, Size, TblOptionFlags, TblValidationFuncPtr); + return(CFE_SUCCESS); +} + +int32 Ut_CFE_TBL_LoadHook(CFE_TBL_Handle_t TblHandle, CFE_TBL_SrcEnum_t SrcType, const void *SrcDataPtr) +{ + int32 TableIndex; + int32 Status; + + TableIndex = Ut_CFE_TBL_FindTable((char *)SrcDataPtr); + if (TableIndex >= 0) { + if (Ut_CFE_TBL_Registry[TblHandle].TblValidationFuncPtr != NULL) { + Status = Ut_CFE_TBL_Registry[TblHandle].TblValidationFuncPtr(Ut_CFE_TBL_Images[TableIndex].TablePtr); + if (Status != CFE_SUCCESS) + return(Status); + } + return(Ut_CFE_TBL_LoadTable(TblHandle, Ut_CFE_TBL_Images[TableIndex].TablePtr)); + } + else { + return(CFE_TBL_ERR_FILE_NOT_FOUND); + } +} + +int32 Ut_CFE_TBL_GetAddressHook(void **TblPtr, CFE_TBL_Handle_t TblHandle) +{ + if ((*TblPtr = Ut_CFE_TBL_GetAddress(TblHandle)) != NULL) { + + if(Ut_CFE_TBL_Registry[TblHandle].TblUpdatedFlag == TRUE) { + Ut_CFE_TBL_Registry[TblHandle].TblUpdatedFlag = FALSE; + return (CFE_TBL_INFO_UPDATED); + } + + return(CFE_SUCCESS); + } + else { + + return(CFE_TBL_ERR_INVALID_HANDLE); + } + +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_tbl_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_tbl_stubs.c new file mode 100644 index 0000000..883e801 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_tbl_stubs.c @@ -0,0 +1,242 @@ +/* +** +** File: ut_cfe_tbl_stubs.c +** +** $Id: ut_cfe_tbl_stubs.c 1.1 2011/05/04 11:20:57EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE Table Services routines +** +** $Log: ut_cfe_tbl_stubs.c $ +** Revision 1.1 2011/05/04 11:20:57EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:43EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.4 2011/03/10 11:19:20EST sslegel +** Added return code support to CFE_TBL_GetInfo +** Revision 1.3 2011/02/18 15:57:42EST sslegel +** Added new hooks and return codes +** Changed Ut_CFE_TBL_LoadHook to automatically call the table validate function +** Revision 1.2 2011/02/17 16:34:27EST rmcgraw +** Tbl GetAdr Hook change to return TBL_UPDATED after a TBL load +** Revision 1.1 2011/02/15 11:13:04EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "ut_cfe_tbl_stubs.h" +#include "ut_cfe_tbl_hooks.h" +#include + +Ut_CFE_TBL_HookTable_t Ut_CFE_TBL_HookTable; +Ut_CFE_TBL_ReturnCodeTable_t Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_MAX_INDEX]; + +void Ut_CFE_TBL_Reset(void) +{ + memset(&Ut_CFE_TBL_HookTable, 0, sizeof(Ut_CFE_TBL_HookTable)); + memset(&Ut_CFE_TBL_ReturnCodeTable, 0, sizeof(Ut_CFE_TBL_ReturnCodeTable)); + + Ut_CFE_TBL_SetFunctionHook(UT_CFE_TBL_REGISTER_INDEX, (void *)&Ut_CFE_TBL_RegisterHook); + Ut_CFE_TBL_SetFunctionHook(UT_CFE_TBL_LOAD_INDEX, (void *)&Ut_CFE_TBL_LoadHook); + Ut_CFE_TBL_SetFunctionHook(UT_CFE_TBL_GETADDRESS_INDEX, (void *)&Ut_CFE_TBL_GetAddressHook); + + Ut_CFE_TBL_ClearTables(); +} + +void Ut_CFE_TBL_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_CFE_TBL_REGISTER_INDEX) { Ut_CFE_TBL_HookTable.CFE_TBL_Register = FunPtr; } + else if (Index == UT_CFE_TBL_LOAD_INDEX) { Ut_CFE_TBL_HookTable.CFE_TBL_Load = FunPtr; } + else if (Index == UT_CFE_TBL_MANAGE_INDEX) { Ut_CFE_TBL_HookTable.CFE_TBL_Manage = FunPtr; } + else if (Index == UT_CFE_TBL_GETADDRESS_INDEX) { Ut_CFE_TBL_HookTable.CFE_TBL_GetAddress = FunPtr; } + else if (Index == UT_CFE_TBL_GETADDRESSES_INDEX) { Ut_CFE_TBL_HookTable.CFE_TBL_GetAddresses = FunPtr; } + else if (Index == UT_CFE_TBL_GETINFO_INDEX) { Ut_CFE_TBL_HookTable.CFE_TBL_GetInfo = FunPtr; } + else { printf("Unsupported TBL Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_CFE_TBL_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_CFE_TBL_MAX_INDEX) { + Ut_CFE_TBL_ReturnCodeTable[Index].Value = RtnVal; + Ut_CFE_TBL_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported TBL Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_CFE_TBL_UseReturnCode(uint32 Index) +{ + if (Ut_CFE_TBL_ReturnCodeTable[Index].Count > 0) { + Ut_CFE_TBL_ReturnCodeTable[Index].Count--; + if (Ut_CFE_TBL_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +int32 CFE_TBL_Register( CFE_TBL_Handle_t *TblHandlePtr, + const char *Name, + uint32 Size, + uint16 TblOptionFlags, + CFE_TBL_CallbackFuncPtr_t TblValidationFuncPtr ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_REGISTER_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_REGISTER_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_Register) + return(Ut_CFE_TBL_HookTable.CFE_TBL_Register(TblHandlePtr, Name, Size, TblOptionFlags,TblValidationFuncPtr)); + + return CFE_SUCCESS; +} + +int32 CFE_TBL_Share( CFE_TBL_Handle_t *TblHandlePtr, /* Returned Handle */ + const char *TblName ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_Unregister ( CFE_TBL_Handle_t TblHandle ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_Load( CFE_TBL_Handle_t TblHandle, + CFE_TBL_SrcEnum_t SrcType, + const void *SrcDataPtr ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_LOAD_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_LOAD_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_Load) + return(Ut_CFE_TBL_HookTable.CFE_TBL_Load(TblHandle, SrcType, SrcDataPtr)); + + return CFE_SUCCESS; +} + +int32 CFE_TBL_Update( CFE_TBL_Handle_t TblHandle ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_GetAddress( void **TblPtr, + CFE_TBL_Handle_t TblHandle ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_GETADDRESS_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_GETADDRESS_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_GetAddress) + return(Ut_CFE_TBL_HookTable.CFE_TBL_GetAddress(TblPtr, TblHandle)); + + return CFE_SUCCESS; +} + +int32 CFE_TBL_GetAddresses( void **TblPtrs[], + uint16 NumTables, + const CFE_TBL_Handle_t TblHandles[] ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_GETADDRESSES_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_GETADDRESSES_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_GetAddresses) + return(Ut_CFE_TBL_HookTable.CFE_TBL_GetAddresses(TblPtrs, NumTables, TblHandles)); + + return CFE_SUCCESS; +} + +int32 CFE_TBL_ReleaseAddress( CFE_TBL_Handle_t TblHandle ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_RELEASEADDRESS_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_RELEASEADDRESS_INDEX].Value; + + return CFE_SUCCESS; +} + + +int32 CFE_TBL_ReleaseAddresses( uint16 NumTables, + const CFE_TBL_Handle_t TblHandles[] ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_Validate( CFE_TBL_Handle_t TblHandle ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_Manage( CFE_TBL_Handle_t TblHandle ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_MANAGE_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_MANAGE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_Manage) + return(Ut_CFE_TBL_HookTable.CFE_TBL_Manage(TblHandle)); + + return CFE_SUCCESS; +} + +int32 CFE_TBL_GetStatus( CFE_TBL_Handle_t TblHandle ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_GETSTATUS_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_GETSTATUS_INDEX].Value; + + return CFE_SUCCESS; +} + +int32 CFE_TBL_GetInfo( CFE_TBL_Info_t *TblInfoPtr, const char *TblName ) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_GETINFO_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_GETINFO_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_GetInfo) + return(Ut_CFE_TBL_HookTable.CFE_TBL_GetInfo(TblInfoPtr, TblName)); + + return CFE_SUCCESS; +} + +int32 CFE_TBL_DumpToBuffer( CFE_TBL_Handle_t TblHandle ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_Modified( CFE_TBL_Handle_t TblHandle ) +{ + return CFE_SUCCESS; +} + +int32 CFE_TBL_CleanUpApp (uint32 AppId) +{ + return CFE_SUCCESS; +} + + +int32 CFE_TBL_NotifyByMessage(CFE_TBL_Handle_t TblHandle, uint32 MsgId, uint16 CommandCode, uint32 Parameter) +{ + /* Check for specified return */ + if (Ut_CFE_TBL_UseReturnCode(UT_CFE_TBL_NOTIFYBYMESSAGE_INDEX)) + return Ut_CFE_TBL_ReturnCodeTable[UT_CFE_TBL_NOTIFYBYMESSAGE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_CFE_TBL_HookTable.CFE_TBL_NotifyByMessage) + return (Ut_CFE_TBL_HookTable.CFE_TBL_NotifyByMessage(TblHandle, MsgId, CommandCode, Parameter)); + + return CFE_SUCCESS; +} diff --git a/fsw/unit_test/ut-assert/src/ut_cfe_time_stubs.c b/fsw/unit_test/ut-assert/src/ut_cfe_time_stubs.c new file mode 100644 index 0000000..ca66626 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_cfe_time_stubs.c @@ -0,0 +1,75 @@ +/* +** +** File: ut_cfe_time_stubs.c +** +** $Id: ut_cfe_time_stubs.c 1.1 2011/05/04 11:20:58EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for cFE Time Services routines +** +** $Log: ut_cfe_time_stubs.c $ +** Revision 1.1 2011/05/04 11:20:58EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:43EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/02/15 11:13:05EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "ut_cfe_time_stubs.h" +#include + +Ut_CFE_TIME_HookTable_t Ut_CFE_TIME_HookTable; +Ut_CFE_TIME_ReturnCodeTable_t Ut_CFE_TIME_ReturnCodeTable[UT_CFE_TIME_MAX_INDEX]; + +void Ut_CFE_TIME_Reset(void) +{ + memset(&Ut_CFE_TIME_HookTable, 0, sizeof(Ut_CFE_TIME_HookTable)); + memset(&Ut_CFE_TIME_ReturnCodeTable, 0, sizeof(Ut_CFE_TIME_ReturnCodeTable)); +} + +void Ut_CFE_TIME_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_CFE_TIME_GETTIME_INDEX) { Ut_CFE_TIME_HookTable.CFE_TIME_GetTime = FunPtr; } + else { printf("Unsupported TIME Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_CFE_TIME_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_CFE_TIME_MAX_INDEX) { + Ut_CFE_TIME_ReturnCodeTable[Index].Value = RtnVal; + Ut_CFE_TIME_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported TIME Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_CFE_TIME_UseReturnCode(uint32 Index) +{ + if (Ut_CFE_TIME_ReturnCodeTable[Index].Count > 0) { + Ut_CFE_TIME_ReturnCodeTable[Index].Count--; + if (Ut_CFE_TIME_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +CFE_TIME_SysTime_t CFE_TIME_GetTime(void) +{ + CFE_TIME_SysTime_t Time; + + /* Check for Function Hook */ + if (Ut_CFE_TIME_HookTable.CFE_TIME_GetTime) + return Ut_CFE_TIME_HookTable.CFE_TIME_GetTime(); + + Time.Seconds = 0; + Time.Subseconds = 0; + + return Time; +} diff --git a/fsw/unit_test/ut-assert/src/ut_osapi_stubs.c b/fsw/unit_test/ut-assert/src/ut_osapi_stubs.c new file mode 100644 index 0000000..fb79496 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_osapi_stubs.c @@ -0,0 +1,635 @@ +/* +** File: ut_osapi_stubs.c +** +** $Id: ut_osapi_stubs.c 1.2 2011/05/16 16:25:35EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for OSAPI routines. +** +** $Log: ut_osapi_stubs.c $ +** Revision 1.2 2011/05/16 16:25:35EDT rmcgraw +** Added hook functionality to Count Semaphore APIs +** Revision 1.4 2011/05/16 14:42:42EDT rmcgraw +** Added SetRtnCode processing to Counting Semaphore APIs +** Revision 1.3 2011/04/01 16:02:41EDT sslegel +** Added (void) to unused parameters to avoid compiler warnings +** Revision 1.2 2011/03/08 15:42:09EST rmcgraw +** Added OS_CountSemGetIdByName +** Revision 1.1 2011/02/15 11:13:05EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +*/ + +/* +** Include section +*/ +#include "cfe.h" +#include "ut_osapi_stubs.h" +#include +#include + +Ut_OSAPI_HookTable_t Ut_OSAPI_HookTable; +Ut_OSAPI_ReturnCodeTable_t Ut_OSAPI_ReturnCodeTable[UT_OSAPI_MAX_INDEX]; + +void Ut_OSAPI_Reset(void) +{ + memset(&Ut_OSAPI_HookTable, 0, sizeof(Ut_OSAPI_HookTable)); + memset(&Ut_OSAPI_ReturnCodeTable, 0, sizeof(Ut_OSAPI_ReturnCodeTable)); +} + +void Ut_OSAPI_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_OSAPI_TASKDELAY_INDEX) { Ut_OSAPI_HookTable.OS_TaskDelay = FunPtr; } + else if (Index == UT_OSAPI_BINSEMTAKE_INDEX) { Ut_OSAPI_HookTable.OS_BinSemTake = FunPtr; } + else if (Index == UT_OSAPI_BINSEMTIMEDWAIT_INDEX) { Ut_OSAPI_HookTable.OS_BinSemTimedWait = FunPtr; } + else if (Index == UT_OSAPI_MUTSEMTAKE_INDEX) { Ut_OSAPI_HookTable.OS_MutSemTake = FunPtr; } + else if (Index == UT_OSAPI_GETLOCALTIME_INDEX) { Ut_OSAPI_HookTable.OS_GetLocalTime = FunPtr; } + else if (Index == UT_OSAPI_QUEUEGET_INDEX) { Ut_OSAPI_HookTable.OS_QueueGet = FunPtr; } + else if (Index == UT_OSAPI_QUEUEPUT_INDEX) { Ut_OSAPI_HookTable.OS_QueuePut = FunPtr; } + else if (Index == UT_OSAPI_TASKDELETE_INDEX) { Ut_OSAPI_HookTable.OS_TaskDelete = FunPtr; } + else if (Index == UT_OSAPI_BINSEMGIVE_INDEX) { Ut_OSAPI_HookTable.OS_BinSemGive = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMCREATE_INDEX) { Ut_OSAPI_HookTable.OS_CountSemCreate = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMDELETE_INDEX) { Ut_OSAPI_HookTable.OS_CountSemDelete = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMGIVE_INDEX) { Ut_OSAPI_HookTable.OS_CountSemGive = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMTAKE_INDEX) { Ut_OSAPI_HookTable.OS_CountSemTake = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMTIMEDWAIT_INDEX) { Ut_OSAPI_HookTable.OS_CountSemTimedWait = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMGETIDBYNAME_INDEX) { Ut_OSAPI_HookTable.OS_CountSemGetIdByName = FunPtr; } + else if (Index == UT_OSAPI_COUNTSEMGETINFO_INDEX) { Ut_OSAPI_HookTable.OS_CountSemGetInfo = FunPtr; } + else { printf("Unsupported OSAPI Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_OSAPI_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_OSAPI_MAX_INDEX) { + Ut_OSAPI_ReturnCodeTable[Index].Value = RtnVal; + Ut_OSAPI_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported OSAPI Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_OSAPI_UseReturnCode(uint32 Index) +{ + if (Ut_OSAPI_ReturnCodeTable[Index].Count > 0) { + Ut_OSAPI_ReturnCodeTable[Index].Count--; + if (Ut_OSAPI_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +/********************************************************************************** + TASK API +**********************************************************************************/ + +int32 OS_TaskCreate(uint32 *task_id, const char *task_name, osal_task_entry function_pointer, uint32 *stack_pointer, + uint32 stack_size, uint32 priority, uint32 flags) +{ + (void) task_id; + (void) task_name; + (void) function_pointer; + (void) stack_pointer; + (void) stack_size; + (void) priority; + (void) flags; + + return(OS_SUCCESS); +} + +int32 OS_TaskDelete (uint32 task_id) +{ + if (Ut_OSAPI_HookTable.OS_TaskDelete) + return(Ut_OSAPI_HookTable.OS_TaskDelete(task_id)); + + return(OS_SUCCESS); +} + +int32 OS_TaskInstallDeleteHandler(osal_task_entry function_pointer) +{ + (void) function_pointer; + + return(OS_SUCCESS); +} + +void OS_TaskExit(void) +{ + return; +} + +int32 OS_TaskDelay(uint32 millisecond) +{ + (void) millisecond; + + if (Ut_OSAPI_HookTable.OS_TaskDelay) + return(Ut_OSAPI_HookTable.OS_TaskDelay(millisecond)); + + return(OS_SUCCESS); +} + +int32 OS_TaskSetPriority (uint32 task_id, uint32 new_priority) +{ + (void) task_id; + (void) new_priority; + + return (OS_SUCCESS); +} + +int32 OS_TaskRegister (void) +{ + return (OS_SUCCESS); +} + +uint32 OS_TaskGetId (void) +{ + return (uint32)(7); +} + +int32 OS_TaskGetIdByName (uint32 *task_id, const char *task_name) +{ + (void) task_id; + (void) task_name; + + return (uint32)(7); +} + +int32 OS_TaskGetInfo (uint32 task_id, OS_task_prop_t *task_prop) +{ + (void) task_id; + + task_prop = NULL; /* currently not implemented */ + return(OS_INVALID_POINTER); +} + +/**************************************************************************************** + MESSAGE QUEUE API +*****************************************************************************************/ + +int32 OS_QueueCreate (uint32 *queue_id, const char *queue_name, uint32 queue_depth, + uint32 data_size, uint32 flags) +{ + (void) queue_id; + (void) queue_name; + (void) queue_depth; + (void) data_size; + (void) flags; + + return (OS_SUCCESS); +} + +int32 OS_QueueDelete (uint32 queue_id) +{ + (void) queue_id; + + return (OS_SUCCESS); +} + +int32 OS_QueueGet (uint32 queue_id, void *data, uint32 size, uint32 *size_copied, int32 timeout) +{ + if (Ut_OSAPI_HookTable.OS_QueueGet) + return(Ut_OSAPI_HookTable.OS_QueueGet(queue_id, data, size, size_copied, timeout)); + + return (OS_SUCCESS); +} + +int32 OS_QueuePut (uint32 queue_id, const void *data, uint32 size, uint32 flags) +{ + if (Ut_OSAPI_HookTable.OS_QueuePut) + return(Ut_OSAPI_HookTable.OS_QueuePut(queue_id, data, size, flags)); + + return (OS_SUCCESS); +} + +int32 OS_QueueGetIdByName (uint32 *queue_id, const char *queue_name) +{ + (void) queue_id; + (void) queue_name; + + return (OS_SUCCESS); +} + +/****************************************************************************************** + SEMAPHORE API +******************************************************************************************/ + +int32 OS_BinSemCreate (uint32 *sem_id, const char *sem_name, uint32 sem_initial_value, uint32 options) +{ + (void) sem_id; + (void) sem_name; + (void) sem_initial_value; + (void) options; + + return (OS_SUCCESS); +} + +int32 OS_BinSemDelete (uint32 sem_id) +{ + (void) sem_id; + + return (OS_SUCCESS); +} + +int32 OS_BinSemGive (uint32 sem_id) +{ + if (Ut_OSAPI_HookTable.OS_BinSemGive) + return(Ut_OSAPI_HookTable.OS_BinSemGive(sem_id)); + + return (OS_SUCCESS); +} + +int32 OS_BinSemTake (uint32 sem_id) +{ + if (Ut_OSAPI_HookTable.OS_BinSemTake) + return(Ut_OSAPI_HookTable.OS_BinSemTake(sem_id)); + + return (OS_SUCCESS); +} + +int32 OS_BinSemTimedWait (uint32 sem_id, uint32 msecs) +{ + if (Ut_OSAPI_HookTable.OS_BinSemTimedWait) + return(Ut_OSAPI_HookTable.OS_BinSemTimedWait(sem_id, msecs)); + + return (OS_SUCCESS); +} + +int32 OS_BinSemGetIdByName (uint32 *sem_id, const char *sem_name) +{ + (void) sem_name; + + sem_id = NULL; /* currently not implemented */ + return(OS_INVALID_POINTER); +} + +int32 OS_BinSemGetInfo (uint32 sem_id, OS_bin_sem_prop_t *bin_prop) +{ + (void) sem_id; + + bin_prop = NULL; /* currently not implemented */ + return(OS_INVALID_POINTER); +} + +int32 OS_CountSemCreate (uint32 *sem_id, const char *sem_name, uint32 sem_initial_value, uint32 options) +{ + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMCREATE_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMCREATE_INDEX].Value; + + if (Ut_OSAPI_HookTable.OS_CountSemCreate) + return(Ut_OSAPI_HookTable.OS_CountSemCreate(sem_id, sem_name, sem_initial_value, options)); + + return (OS_SUCCESS); +} + +int32 OS_CountSemDelete (uint32 sem_id) +{ + (void) sem_id; + + if (Ut_OSAPI_HookTable.OS_CountSemDelete) + return(Ut_OSAPI_HookTable.OS_CountSemDelete(sem_id)); + + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMDELETE_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMDELETE_INDEX].Value; + + return (OS_SUCCESS); +} + +int32 OS_CountSemGive (uint32 sem_id) +{ + if (Ut_OSAPI_HookTable.OS_CountSemGive) + return(Ut_OSAPI_HookTable.OS_CountSemGive(sem_id)); + + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMGIVE_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMGIVE_INDEX].Value; + + return (OS_SUCCESS); +} + +int32 OS_CountSemTake (uint32 sem_id) +{ + if (Ut_OSAPI_HookTable.OS_CountSemTake) + return(Ut_OSAPI_HookTable.OS_CountSemTake(sem_id)); + + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMTAKE_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMTAKE_INDEX].Value; + + return OS_SUCCESS; +} + +int32 OS_CountSemTimedWait (uint32 sem_id, uint32 msecs) +{ + (void) sem_id; + (void) msecs; + + if (Ut_OSAPI_HookTable.OS_CountSemTimedWait) + return(Ut_OSAPI_HookTable.OS_CountSemTimedWait(sem_id,msecs)); + + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMTIMEDWAIT_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMTIMEDWAIT_INDEX].Value; + + return OS_SUCCESS; +} + +int32 OS_CountSemGetIdByName (uint32 *sem_id, const char *sem_name) +{ + + if (Ut_OSAPI_HookTable.OS_CountSemGetIdByName) + return(Ut_OSAPI_HookTable.OS_CountSemGetIdByName(sem_id, sem_name)); + + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMGETIDBYNAME_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMGETIDBYNAME_INDEX].Value; + + return OS_SUCCESS; +} + +int32 OS_CountSemGetInfo (uint32 sem_id, OS_count_sem_prop_t *count_prop) +{ + (void) sem_id; + (void) count_prop; + + if (Ut_OSAPI_HookTable.OS_CountSemGetInfo) + return(Ut_OSAPI_HookTable.OS_CountSemGetInfo(sem_id, count_prop)); + + if (Ut_OSAPI_UseReturnCode(UT_OSAPI_COUNTSEMGETINFO_INDEX)) + return Ut_OSAPI_ReturnCodeTable[UT_OSAPI_COUNTSEMGETINFO_INDEX].Value; + + return OS_SUCCESS; +} + +/**************************************************************************************** + MUTEX API +****************************************************************************************/ + +int32 OS_MutSemCreate (uint32 *sem_id, const char *sem_name, uint32 options) +{ + (void) sem_id; + (void) sem_name; + (void) options; + + return (OS_SUCCESS); +} + +int32 OS_MutSemDelete (uint32 sem_id) +{ + (void) sem_id; + + return (OS_SUCCESS); +} + +int32 OS_MutSemGive (uint32 sem_id) +{ + (void) sem_id; + + return (OS_SUCCESS); +} + +int32 OS_MutSemTake (uint32 sem_id) +{ + if (Ut_OSAPI_HookTable.OS_MutSemTake) + return(Ut_OSAPI_HookTable.OS_MutSemTake(sem_id)); + + return (OS_SUCCESS); +} + +int32 OS_MutSemGetIdByName (uint32 *sem_id, const char *sem_name) +{ + (void) sem_name; + + sem_id = NULL; /* currently not implemented */ + return(OS_INVALID_POINTER); +} + +int32 OS_MutSemGetInfo (uint32 sem_id, OS_mut_sem_prop_t *mut_prop) +{ + (void) sem_id; + + mut_prop = NULL; /* currently not implemented */ + return(OS_INVALID_POINTER); +} + +/**************************************************************************************** + Time/Tick Related API +****************************************************************************************/ + +int32 OS_Milli2Ticks(uint32 milli_seconds) +{ + uint32 num_of_ticks,tick_duration_usec ; + + tick_duration_usec = OS_Tick2Micros() ; + + num_of_ticks = ( (milli_seconds * 1000) + tick_duration_usec -1 ) / tick_duration_usec ; + + return(num_of_ticks) ; +} + +int32 OS_Tick2Micros (void) +{ + return((1/(CLOCKS_PER_SEC))*1000); +} + +int32 OS_GetLocalTime(OS_time_t *time_struct) +{ + if (Ut_OSAPI_HookTable.OS_GetLocalTime) + return(Ut_OSAPI_HookTable.OS_GetLocalTime(time_struct)); + + return (OS_SUCCESS); +} + +/**************************************************************************************** + Exception API +****************************************************************************************/ + +int32 OS_ExcAttachHandler(uint32 ExceptionNumber, void (*ExceptionHandler)(uint32, const void *,uint32), int32 Parameter) +{ + (void) ExceptionNumber; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_ExcEnable(int32 ExceptionNumber) +{ + (void) ExceptionNumber; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_ExcDisable(int32 ExceptionNumber) +{ + (void) ExceptionNumber; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +/**************************************************************************************** + Floating Point Unit API +****************************************************************************************/ + +int32 OS_FPUExcAttachHandler(uint32 ExceptionNumber, void * ExceptionHandler, int32 Parameter) +{ + (void) ExceptionNumber; + (void) ExceptionHandler; + (void) Parameter; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_FPUExcEnable(int32 ExceptionNumber) +{ + (void) ExceptionNumber; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_FPUExcDisable(int32 ExceptionNumber) +{ + (void) ExceptionNumber; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_FPUExcSetMask(uint32 Mask) +{ + (void) Mask; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_FPUExcGetMask(uint32 *Mask) +{ + (void) Mask; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +/**************************************************************************************** + Interrupt API +****************************************************************************************/ + +int32 OS_IntAttachHandler(uint32 InterruptNumber, osal_task_entry InterruptHandler, int32 Parameter) +{ + (void) InterruptNumber; + (void) InterruptHandler; + (void) Parameter; + + return(OS_SUCCESS); +} + +int32 OS_IntEnable(int32 Level) +{ + (void) Level; + + return(OS_SUCCESS); +} + +int32 OS_IntDisable(int32 Level) +{ + (void) Level; + + return(OS_SUCCESS); +} + +int32 OS_IntUnlock (int32 IntLevel) +{ + (void) IntLevel; + + return(OS_SUCCESS); +} + +int32 OS_IntLock (void) +{ + return(OS_SUCCESS); +} + +int32 OS_IntSetMask(uint32 Mask) +{ + (void) Mask; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_IntGetMask(uint32 *Mask) +{ + (void) Mask; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +int32 OS_IntAck(int32 InterruptNumber) +{ + (void) InterruptNumber; + + return(CFE_OSAPI_NOT_IMPLEMENTED); +} + +/**************************************************************************************** + Debug API +****************************************************************************************/ + +int32 OS_GetErrorName(int32 error_num, os_err_name_t * err_name) +{ + os_err_name_t local_name; + uint32 return_code; + + return_code = OS_SUCCESS; + + switch (error_num) + { + case OS_SUCCESS: + strcpy(local_name,"OS_SUCCESS"); break; + case OS_ERROR: + strcpy(local_name,"OS_ERROR"); break; + case OS_INVALID_POINTER: + strcpy(local_name,"OS_INVALID_POINTER"); break; + case OS_ERROR_ADDRESS_MISALIGNED: + strcpy(local_name,"OS_ADDRESS_MISALIGNED"); break; + case OS_ERROR_TIMEOUT: + strcpy(local_name,"OS_ERROR_TIMEOUT"); break; + case OS_INVALID_INT_NUM: + strcpy(local_name,"OS_INVALID_INT_NUM"); break; + case OS_SEM_FAILURE: + strcpy(local_name,"OS_SEM_FAILURE"); break; + case OS_SEM_TIMEOUT: + strcpy(local_name,"OS_SEM_TIMEOUT"); break; + case OS_QUEUE_EMPTY: + strcpy(local_name,"OS_QUEUE_EMPTY"); break; + case OS_QUEUE_FULL: + strcpy(local_name,"OS_QUEUE_FULL"); break; + case OS_QUEUE_TIMEOUT: + strcpy(local_name,"OS_QUEUE_TIMEOUT"); break; + case OS_QUEUE_INVALID_SIZE: + strcpy(local_name,"OS_QUEUE_INVALID_SIZE"); break; + case OS_QUEUE_ID_ERROR: + strcpy(local_name,"OS_QUEUE_ID_ERROR"); break; + case OS_ERR_NAME_TOO_LONG: + strcpy(local_name,"OS_ERR_NAME_TOO_LONG"); break; + case OS_ERR_NO_FREE_IDS: + strcpy(local_name,"OS_ERR_NO_FREE_IDS"); break; + case OS_ERR_NAME_TAKEN: + strcpy(local_name,"OS_ERR_NAME_TAKEN"); break; + case OS_ERR_INVALID_ID: + strcpy(local_name,"OS_ERR_INVALID_ID"); break; + case OS_ERR_NAME_NOT_FOUND: + strcpy(local_name,"OS_ERR_NAME_NOT_FOUND"); break; + case OS_ERR_SEM_NOT_FULL: + strcpy(local_name,"OS_ERR_SEM_NOT_FULL"); break; + case OS_ERR_INVALID_PRIORITY: + strcpy(local_name,"OS_ERR_INVALID_PRIORITY"); break; + + default: strcpy(local_name,"ERROR_UNKNOWN"); + return_code = OS_ERROR; + } + strcpy((char*) err_name, local_name); + return return_code; +} + +void OS_printf( const char *String, ...) +{ + va_list ptr; + char msg_buffer [OS_BUFFER_SIZE]; + + va_start(ptr,String); + vsprintf(&msg_buffer[0], String, ptr); + va_end(ptr); + + msg_buffer[OS_BUFFER_SIZE-1] = '\0'; + printf("%s", &msg_buffer[0]); //FIXME?? +} diff --git a/fsw/unit_test/ut-assert/src/ut_osfileapi_stubs.c b/fsw/unit_test/ut-assert/src/ut_osfileapi_stubs.c new file mode 100644 index 0000000..d898d1d --- /dev/null +++ b/fsw/unit_test/ut-assert/src/ut_osfileapi_stubs.c @@ -0,0 +1,268 @@ +/* +** +** File: ut_osfileapi_stubs.c +** +** $Id: ut_osfileapi_stubs.c 1.1 2011/05/04 11:21:00EDT rmcgraw Exp $ +** +** Purpose: Unit test stubs for the OSAPI File Services routines +** +** $Log: ut_osfileapi_stubs.c $ +** Revision 1.1 2011/05/04 11:21:00EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.1 2011/04/08 16:26:45EDT rmcgraw +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/CFS-REPOSITORY/cf/fsw/unit_test/ut-assert/src/project.pj +** Revision 1.6 2011/03/31 14:53:05EDT rmcgraw +** Added functionality and supressed compiler warnings +** Revision 1.5 2011/03/30 09:58:57EDT rmcgraw +** Added Hook and Return enhancements to Directory APIs +** Revision 1.4 2011/03/24 13:14:55EDT rmcgraw +** Added Hook and RtnCode functionality to OS_stat +** Revision 1.3 2011/03/23 17:18:08EDT rmcgraw +** correct OS_read return value +** Revision 1.2 2011/03/23 17:08:19EDT rmcgraw +** OS_FS_ERROR to OS_FS_SUCCESS for some OS file sys apis +** Revision 1.1 2011/02/15 11:13:05EST sslegel +** Initial revision +** Member added to project c:/MKSDATA/MKS-REPOSITORY/FSW-TOOLS-REPOSITORY/ut-assert/src/project.pj +** +*/ + +#include "cfe.h" +#include "ut_osfileapi_stubs.h" +#include + +Ut_OSFILEAPI_HookTable_t Ut_OSFILEAPI_HookTable; +Ut_OSFILEAPI_ReturnCodeTable_t Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_MAX_INDEX]; + +void Ut_OSFILEAPI_Reset(void) +{ + memset(&Ut_OSFILEAPI_HookTable, 0, sizeof(Ut_OSFILEAPI_HookTable)); + memset(&Ut_OSFILEAPI_ReturnCodeTable, 0, sizeof(Ut_OSFILEAPI_ReturnCodeTable)); +} + +void Ut_OSFILEAPI_SetFunctionHook(uint32 Index, void *FunPtr) +{ + if (Index == UT_OSFILEAPI_CREAT_INDEX) { Ut_OSFILEAPI_HookTable.OS_creat = FunPtr; } + else if (Index == UT_OSFILEAPI_WRITE_INDEX) { Ut_OSFILEAPI_HookTable.OS_write = FunPtr; } + else if (Index == UT_OSFILEAPI_READ_INDEX) { Ut_OSFILEAPI_HookTable.OS_read = FunPtr; } + else if (Index == UT_OSFILEAPI_OPENDIR_INDEX) { Ut_OSFILEAPI_HookTable.OS_opendir = FunPtr; } + else if (Index == UT_OSFILEAPI_READDIR_INDEX) { Ut_OSFILEAPI_HookTable.OS_readdir = FunPtr; } + else if (Index == UT_OSFILEAPI_CLOSE_INDEX) { Ut_OSFILEAPI_HookTable.OS_close = FunPtr; } + else if (Index == UT_OSFILEAPI_OPEN_INDEX) { Ut_OSFILEAPI_HookTable.OS_open = FunPtr; } + else if (Index == UT_OSFILEAPI_CLOSEDIR_INDEX) { Ut_OSFILEAPI_HookTable.OS_closedir = FunPtr; } + else if (Index == UT_OSFILEAPI_STAT_INDEX) { Ut_OSFILEAPI_HookTable.OS_stat = FunPtr; } + else if (Index == UT_OSFILEAPI_FDGETINFO_INDEX){ Ut_OSFILEAPI_HookTable.OS_FDGetInfo = FunPtr; } + else { printf("Unsupported OSFILEAPI Index In SetFunctionHook Call %u\n", Index); } +} + +void Ut_OSFILEAPI_SetReturnCode(uint32 Index, int32 RtnVal, uint32 CallCnt) +{ + if (Index < UT_OSFILEAPI_MAX_INDEX) { + Ut_OSFILEAPI_ReturnCodeTable[Index].Value = RtnVal; + Ut_OSFILEAPI_ReturnCodeTable[Index].Count = CallCnt; + } + else { + printf("Unsupported OSFILEAPI Index In SetReturnCode Call %u\n", Index); + } +} + +boolean Ut_OSFILEAPI_UseReturnCode(uint32 Index) +{ + if (Ut_OSFILEAPI_ReturnCodeTable[Index].Count > 0) { + Ut_OSFILEAPI_ReturnCodeTable[Index].Count--; + if (Ut_OSFILEAPI_ReturnCodeTable[Index].Count == 0) + return(TRUE); + } + + return(FALSE); +} + +/* +** Standard File system API +*/ + +int32 OS_creat (const char *path, int32 access) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_CREAT_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_CREAT_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_creat) + return Ut_OSFILEAPI_HookTable.OS_creat(path, access); + + return OS_FS_ERROR; +} + +int32 OS_open (const char *path, int32 access, uint32 mode) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_OPEN_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_OPEN_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_open) + return Ut_OSFILEAPI_HookTable.OS_open(path, access, mode); + + return OS_FS_ERROR; +} + +int32 OS_close (int32 filedes) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_CLOSE_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_CLOSE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_close) + return Ut_OSFILEAPI_HookTable.OS_close(filedes); + + return OS_FS_SUCCESS; +} + +int32 OS_read (int32 filedes, void *buffer, uint32 nbytes) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_READ_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_READ_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_read) + return Ut_OSFILEAPI_HookTable.OS_read(filedes, buffer, nbytes); + + return OS_FS_ERROR; +} + +int32 OS_write (int32 filedes, void *buffer, uint32 nbytes) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_WRITE_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_WRITE_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_write) + return Ut_OSFILEAPI_HookTable.OS_write(filedes, buffer, nbytes); + + return nbytes; +} + +int32 OS_chmod (const char *path, uint32 access) +{ + return OS_FS_SUCCESS; +} + +int32 OS_stat (const char *path, os_fstat_t *filestats) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_STAT_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_STAT_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_stat) + return Ut_OSFILEAPI_HookTable.OS_stat(path, filestats); + + return OS_FS_ERROR; +} + +int32 OS_lseek (int32 filedes, int32 offset, uint32 whence) +{ + return OS_FS_SUCCESS; +} + +int32 OS_remove (const char *path) +{ + return OS_FS_SUCCESS; +} + +int32 OS_rename (const char *old, const char *new) +{ + return OS_FS_SUCCESS; +} + +int32 OS_cp (const char *src, const char *dest) +{ + return OS_FS_SUCCESS; +} + +int32 OS_mv (const char *src, const char *dest) +{ + return OS_FS_SUCCESS; +} + +/* +** Directory API +*/ + +int32 OS_mkdir (const char *path, uint32 access) +{ + return OS_FS_SUCCESS; +} + +os_dirp_t OS_opendir (const char *path) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_OPENDIR_INDEX)) + return (os_dirp_t)Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_OPENDIR_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_opendir) + return Ut_OSFILEAPI_HookTable.OS_opendir(path); + + return NULL; +} + +int32 OS_closedir (os_dirp_t directory) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_CLOSEDIR_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_CLOSEDIR_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_closedir) + return Ut_OSFILEAPI_HookTable.OS_closedir(directory); + + return OS_FS_SUCCESS; +} + +os_dirent_t * OS_readdir (os_dirp_t directory) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_READDIR_INDEX)) + return (os_dirent_t *)Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_READDIR_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_readdir) + return Ut_OSFILEAPI_HookTable.OS_readdir(directory); + + return NULL; +} + +int32 OS_rmdir (const char *path) +{ + return OS_FS_ERROR; +} + +int32 OS_check_name_length(const char *path) +{ + return OS_FS_SUCCESS; +} + +int32 OS_ShellOutputToFile(char* Cmd, int32 OS_fd) +{ + return OS_FS_SUCCESS; +} + +int32 OS_FDGetInfo (int32 filedes, OS_FDTableEntry *fd_prop) +{ + /* Check for specified return */ + if (Ut_OSFILEAPI_UseReturnCode(UT_OSFILEAPI_FDGETINFO_INDEX)) + return Ut_OSFILEAPI_ReturnCodeTable[UT_OSFILEAPI_FDGETINFO_INDEX].Value; + + /* Check for Function Hook */ + if (Ut_OSFILEAPI_HookTable.OS_FDGetInfo) + return Ut_OSFILEAPI_HookTable.OS_FDGetInfo(filedes,fd_prop); + + return OS_FS_ERR_INVALID_FD; +} diff --git a/fsw/unit_test/ut-assert/src/utassert.c b/fsw/unit_test/ut-assert/src/utassert.c new file mode 100644 index 0000000..4395e3c --- /dev/null +++ b/fsw/unit_test/ut-assert/src/utassert.c @@ -0,0 +1,52 @@ + +/* + * Filename: utassert.c + * + * Purpose: This file contains a standard set of asserts for use in unit tests. + * + */ + +/* + * Includes + */ + +#include "common_types.h" +#include "utassert.h" +#include "uttools.h" + +/* + * Local Data + */ + +uint32 UtAssertPassCount = 0; +uint32 UtAssertFailCount = 0; + +/* + * Function Definitions + */ + +uint32 UtAssert_GetPassCount(void) +{ + return(UtAssertPassCount); +} + +uint32 UtAssert_GetFailCount(void) +{ + return(UtAssertFailCount); +} + +boolean UtAssert(boolean Expression, char *Description, char *File, uint32 Line) +{ + if (Expression) { + #ifdef UT_VERBOSE + printf("PASS: %s\n", Description); + #endif + UtAssertPassCount++; + return(TRUE); + } + else { + printf("FAIL: %s, File: %s, Line: %u\n", Description, File, Line); + UtAssertFailCount++; + return(FALSE); + } +} diff --git a/fsw/unit_test/ut-assert/src/utlist.c b/fsw/unit_test/ut-assert/src/utlist.c new file mode 100644 index 0000000..94b5b19 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/utlist.c @@ -0,0 +1,156 @@ + +/* + * Filename: utlist.c + * + * Purpose: This file contains functions to implement a generic linked list data structure. + * + */ + +/* + * Includes + */ + +#include "common_types.h" +#include "utlist.h" +#include +#include + +/* + * Function Definitions + */ + +UtListHead_t *UtList_Create(void) +{ + UtListHead_t *NewList; + + NewList = malloc(sizeof(UtListHead_t)); + NewList->First = NULL; + NewList->Last = NULL; + NewList->NumberOfEntries = 0; + return (NewList); +} + +void UtList_Destroy(UtListHead_t *ListHead) +{ + UtList_Reset(ListHead); + free(ListHead); +} + +void UtList_Reset(UtListHead_t *ListHead) +{ + while (!UtList_IsEmpty(ListHead)) { + UtList_DeleteFirst(ListHead); + } +} + +void UtList_Add(UtListHead_t *ListHead, void *Data, uint32 DataSize, uint32 Tag) +{ + UtListNode_t *NewNode = NULL; + + NewNode = malloc(sizeof(UtListNode_t)); + if (ListHead->NumberOfEntries == 0) { + + ListHead->First = NewNode; + ListHead->Last = NewNode; + ListHead->NumberOfEntries++; + + NewNode->Next = NULL; + NewNode->Prev = NULL; + NewNode->Tag = Tag; + NewNode->DataSize = DataSize; + NewNode->Data = malloc(DataSize); + memcpy(NewNode->Data, Data, DataSize); + } + else { + + NewNode->Next = NULL; + NewNode->Prev = ListHead->Last; + NewNode->Tag = Tag; + NewNode->DataSize = DataSize; + NewNode->Data = malloc(DataSize); + memcpy(NewNode->Data, Data, DataSize); + + ListHead->Last->Next = NewNode; + ListHead->Last = NewNode; + ListHead->NumberOfEntries++; + } +} + +void UtList_DeleteFirst(UtListHead_t *ListHead) +{ + UtList_DeleteNode(ListHead, ListHead->First); +} + +void UtList_DeleteLast(UtListHead_t *ListHead) +{ + UtList_DeleteNode(ListHead, ListHead->Last); +} + +void UtList_DeleteNode(UtListHead_t *ListHead, UtListNode_t *DeleteNode) +{ + + if (!UtList_IsEmpty(ListHead)) { + + if (ListHead->NumberOfEntries == 1) { + ListHead->First = NULL; + ListHead->Last = NULL; + ListHead->NumberOfEntries = 0; + } + else if (DeleteNode == ListHead->First) { + ListHead->First = DeleteNode->Next; + ListHead->First->Prev = NULL; + ListHead->NumberOfEntries--; + } + else if (DeleteNode == ListHead->Last) { + ListHead->Last = DeleteNode->Prev; + ListHead->Last->Next = NULL; + ListHead->NumberOfEntries--; + } + else { + DeleteNode->Prev->Next = DeleteNode->Next; + DeleteNode->Next->Prev = DeleteNode->Prev; + ListHead->NumberOfEntries--; + } + + free(DeleteNode->Data); + free(DeleteNode); + } +} + +void UtList_RemoveFirst(UtListHead_t *ListHead, void *Data) +{ + UtList_RemoveNode(ListHead, Data, ListHead->First); +} + +void UtList_RemoveLast(UtListHead_t *ListHead, void *Data) +{ + UtList_RemoveNode(ListHead, Data, ListHead->Last); +} + +void UtList_RemoveNode(UtListHead_t *ListHead, void *Data, UtListNode_t *CurrentNode) +{ + if (!UtList_IsEmpty(ListHead)) { + memcpy(Data, CurrentNode->Data, CurrentNode->DataSize); + UtList_DeleteNode(ListHead, CurrentNode); + } +} + +UtListNode_t *UtList_First(UtListHead_t *ListHead) +{ + return(ListHead->First); +} + +UtListNode_t *UtList_Last(UtListHead_t *ListHead) +{ + return(ListHead->Last); +} + +boolean UtList_IsEmpty(UtListHead_t *ListHead) +{ + return(ListHead->NumberOfEntries == 0); +} + +uint32 UtList_Depth(UtListHead_t *ListHead) +{ + return(ListHead->NumberOfEntries); +} diff --git a/fsw/unit_test/ut-assert/src/uttest.c b/fsw/unit_test/ut-assert/src/uttest.c new file mode 100644 index 0000000..98d0a91 --- /dev/null +++ b/fsw/unit_test/ut-assert/src/uttest.c @@ -0,0 +1,83 @@ + +/* + * Filename: uttest.c + * + * Purpose: This file contains functions to implement a standard way to execute unit tests. + * + */ + +/* + * Includes + */ + +#include "common_types.h" +#include "utassert.h" +#include "utlist.h" + +/* + * Type Definitions + */ + +typedef struct { + void (*Test)(void); + void (*Setup)(void); + void (*Teardown)(void); + char *TestName; +} UtTestDataBaseEntry_t; + +/* + * Local Data + */ + +UtListHead_t UtTestDataBase; +uint32 UtTestsExecutedCount = 0; + +/* + * Function Definitions + */ + +void UtTest_Add(void (*Test)(void), void (*Setup)(void), void (*Teardown)(void), char *TestName) +{ + UtTestDataBaseEntry_t UtTestDataBaseEntry; + + UtTestDataBaseEntry.Test = Test; + UtTestDataBaseEntry.Setup = Setup; + UtTestDataBaseEntry.Teardown = Teardown; + UtTestDataBaseEntry.TestName = TestName; + UtList_Add(&UtTestDataBase, &UtTestDataBaseEntry, sizeof(UtTestDataBaseEntry_t), 0); +} + +int UtTest_Run(void) +{ + uint32 i; + UtListNode_t *UtListNode; + UtTestDataBaseEntry_t *UtTestDataBaseEntry; + + if (UtTestDataBase.NumberOfEntries > 0) { + + UtListNode = UtTestDataBase.First; + for (i=0; i < UtTestDataBase.NumberOfEntries; i++) { + + UtTestDataBaseEntry = UtListNode->Data; + + #ifdef UT_VERBOSE + if (strlen(UtTestDataBaseEntry->TestName) > 0) { printf("\nRunning Test: %s\n", UtTestDataBaseEntry->TestName); } + #endif + + if (UtTestDataBaseEntry->Setup) { UtTestDataBaseEntry->Setup(); } + if (UtTestDataBaseEntry->Test) { UtTestDataBaseEntry->Test(); UtTestsExecutedCount++; } + if (UtTestDataBaseEntry->Teardown) { UtTestDataBaseEntry->Teardown(); } + + UtListNode = UtListNode->Next; + } + } + + printf("\n"); + printf("Tests Executed: %u\n", UtTestsExecutedCount); + printf("Assert Pass Count: %u\n", UtAssert_GetPassCount()); + printf("Assert Fail Count: %u\n", UtAssert_GetFailCount()); + + UtList_Reset(&UtTestDataBase); + + return (UtAssert_GetFailCount() > 0); +} diff --git a/fsw/unit_test/ut-assert/src/uttools.c b/fsw/unit_test/ut-assert/src/uttools.c new file mode 100644 index 0000000..25d233f --- /dev/null +++ b/fsw/unit_test/ut-assert/src/uttools.c @@ -0,0 +1,191 @@ + +/* + * Filename: uttools.c + * + * Purpose: This file contains functions to implement a set of tools for use in unit testing. + * + */ + +/* + * Includes + */ + +#include "common_types.h" +#include +#include +#include +#include +#include + +/* + * Function Definitions + */ + +boolean UtMem2BinFile(void *Memory, char *Filename, uint32 Length) +{ + FILE *fp; + + if ((fp = fopen(Filename, "w"))) { + fwrite(Memory, Length, 1, fp); + fclose(fp); + return(TRUE); + } + else { + printf("UtMem2BinFile: Error Opening File: %s, %s\n", Filename, strerror(errno)); + return(FALSE); + } +} + +boolean UtBinFile2Mem(void *Memory, char *Filename, uint32 Length) +{ + FILE *fp; + + if ((fp = fopen(Filename, "r"))) { + fread(Memory, Length, 1, fp); + fclose(fp); + return(TRUE); + } + else { + printf("UtBinFile2Mem: Error Opening File: %s, %s\n", Filename, strerror(errno)); + return(FALSE); + } +} + +boolean UtMem2HexFile(void *Memory, char *Filename, uint32 Length) +{ + FILE *fp; + uint32 i; + uint32 j; + + if ((fp = fopen(Filename, "w"))) { + + for (i=0; i < Length; i+=16) { + fprintf(fp, " %06X: ", i); + for (j=0; j < 16; j++) { + if ((i+j) < Length) + fprintf(fp, "%02X ", ((uint8 *)Memory)[i+j]); + else + fprintf(fp, " "); + } + fprintf(fp, " "); + for (j=0; j < 16; j++) { + if ((i+j) < Length) + fprintf(fp, "%c", isprint(((uint8 *)Memory)[i+j]) ? ((uint8 *)Memory)[i+j] : '.'); + } + fprintf(fp, "\n"); + } + fclose(fp); + return(TRUE); + } + else { + printf("UtMem2HexFile: Error Opening File: %s, %s\n", Filename, strerror(errno)); + return(FALSE); + } +} + +void UtMemFill(void *Memory, uint32 Length) +{ + uint32 i; + uint8 *Byte_ptr = Memory; + + for(i=0; i < Length; i++) { + Byte_ptr[i] = i; + } +} + +void UtPrintf(char *Spec, ...) +{ +#ifdef UT_VERBOSE + va_list Args; + static char Text[256]; + + va_start(Args, Spec); + vsprintf(Text, Spec, Args); + va_end(Args); + + printf("%s", Text); +#else + (void)Spec; +#endif +} + +char *UtSprintf(char *Spec, ...) +{ + va_list Args; + static char Text[10][256]; + static uint32 TextIndex = 0; + + if (TextIndex >= 10) TextIndex = 0; + + va_start(Args, Spec); + vsprintf(Text[TextIndex], Spec, Args); + va_end(Args); + + return(Text[TextIndex++]); +} + +void UtPrintx(void *Memory, uint32 Length) +{ + uint32 i; + uint8 *Byte_ptr = Memory; + + for (i=0; i < Length; i++) { + UtPrintf("%02X ", Byte_ptr[i]); + } + UtPrintf("\n"); +} + +boolean UtMemCmpValue(void *Memory, uint8 Value, uint32 Length) +{ + uint32 i; + uint8 *Byte_ptr = Memory; + + for (i=0; i < Length; i++) { + if (Byte_ptr[i] != Value) { + return(FALSE); + } + } + return (TRUE); +} + +boolean UtMemCmpCount(void *Memory, uint32 Length) +{ + uint32 i; + uint8 *Byte_ptr = Memory; + + for (i=0; i < Length; i++) { + if (Byte_ptr[i] != (i & 0xFF)) { + return(FALSE); + } + } + return (TRUE); +} + +boolean UtMem2BinFileCmp(void *Memory, char *Filename) +{ + FILE *fp; + uint8 *MemByte = Memory; + int FileByte; + boolean Success; + uint32 i; + + Success = TRUE; + if ((fp = fopen(Filename, "r"))) { + + for (i=0; (FileByte = fgetc(fp)) != EOF; i++) { + if (MemByte[i] != FileByte) { + Success = FALSE; + printf("UtMem2BinFileCmp: Miscompare in file: %s, byte offset: %u, expected: %u, found: %u\n", Filename, i, MemByte[i], FileByte); + break; + } + } + fclose(fp); + } + else { + Success = FALSE; + printf("UtMem2BinFileCmp: Error Opening File: %s, %s\n", Filename, strerror(errno)); + } + + return(Success); +} +